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 nativeDecorations = true;
2186 icon = { ":documentorIcon.png" };
2187 text = $"API Documentation Browser";
2189 BitmapResource icons[CodeObjectType];
2194 for(c = 0; c < CodeObjectType::enumSize; c++)
2196 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2198 browser.AddField(DataField { dataType = class(APIPage) });
2203 Menu fileMenu { menu, $"File", f };
2204 Array<FileFilter> fileFilters
2206 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2207 { $"eC Symbol files (*.sym)", "sym" }
2210 FileDialog fileDialog
2212 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2214 MenuItem fileOpenItem
2216 fileMenu, $"Open...", o, ctrlO;
2218 bool NotifySelect(MenuItem selection, Modifiers mods)
2220 if(fileDialog.Modal() == ok)
2222 OpenModule(fileDialog.filePath);
2227 MenuItem fileSettingsItem
2229 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2231 bool NotifySelect(MenuItem selection, Modifiers mods)
2233 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2243 MenuDivider { fileMenu };
2244 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2246 void OpenModule(char * filePath)
2248 char moduleName[MAX_LOCATION];
2249 char extension[MAX_EXTENSION];
2250 Module module = null;
2251 static char symbolsDir[MAX_LOCATION];
2255 FreeContext(globalContext);
2256 FreeExcludedSymbols(excludedSymbols);
2257 ::defines.Free(FreeModuleDefine);
2258 imports.Free(FreeModuleImport);
2260 FreeGlobalData(globalData);
2261 FreeTypeData(componentsApp);
2263 delete componentsApp;
2265 SetGlobalContext(globalContext);
2266 componentsApp = __ecere_COM_Initialize(false, 1, null);
2267 SetPrivateModule(componentsApp);
2269 StripLastDirectory(filePath, symbolsDir);
2270 SetSymbolsDir(symbolsDir);
2272 GetExtension(filePath, extension);
2274 mainForm.browser.Clear();
2276 ImportModule(filePath, normalImport, publicAccess, false);
2278 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
2279 componentsApp.name = CopyString(filePath);
2281 for(module = componentsApp.allModules.first; module; module = module.next)
2283 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2287 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2288 AddComponents(componentsApp, false);
2290 GetLastDirectory(filePath, moduleName);
2291 // Extension, path and lib prefix get removed in Module::name
2294 StripExtension(moduleName);
2295 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
2297 int len = strlen(moduleName) - 3;
2298 memmove(moduleName, moduleName + 3, len);
2299 moduleName[len] = 0;
2303 for(module = componentsApp.allModules.first; module; module = module.next)
2305 if(module.name && (!strcmp(module.name, moduleName)))
2308 if(!module) module = componentsApp;
2309 homeModule = module;
2310 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2312 SetSymbolsDir(null);
2315 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2318 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2319 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2322 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2324 APIPage page = row.GetData(null);
2325 if(view.edit) view.OnLeftButtonDown(0,0,0);
2326 if(page && page.page) page = page.page;
2328 view.PositionCaret(true);
2329 if(page != view.page)
2331 Window activeChild = this.activeChild;
2333 // Back / Forward Support
2334 if(row && !dontRecordHistory)
2336 if(history.count > historyPos+1)
2337 history.count = historyPos+1;
2338 historyPos = history.count-1;
2339 addressBar.back.disabled = (historyPos == 0);
2340 addressBar.forward.disabled = (historyPos >= history.count-1);
2342 history.Add((Instance)(uint64)row.tag);
2343 historyPos = history.count-1;
2345 addressBar.back.disabled = (historyPos == 0);
2346 addressBar.forward.disabled = (historyPos >= history.count-1);
2352 activeChild.Activate();
2354 else if(!view.created)
2358 page = row.GetData(null);
2359 if(page && page.page)
2363 case 1: view.GoToAnchor("Classes"); break;
2364 case 2: view.GoToAnchor("Functions"); break;
2365 case 3: view.GoToAnchor("Definitions"); break;
2366 case 4: view.GoToAnchor("VirtualMethods"); break;
2367 case 5: view.GoToAnchor("Methods"); break;
2368 case 6: view.GoToAnchor("Members"); break;
2369 case 7: view.GoToAnchor("Conversions"); break;
2370 case 8: view.GoToAnchor("EnumerationValues"); break;
2374 sprintf(hex, "%p", row.tag);
2375 view.GoToAnchor(hex);
2381 view.SetScrollPosition(0, 0);
2389 this, anchor = { top = 26, bottom = 0, right = 0 };
2394 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2397 bool OnClose(bool parentClosing)
2400 view.OnLeftButtonDown(0,0,0);
2406 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2407 //mainForm.OpenModule("ec");
2408 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2409 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2411 int index = mainForm.browser.currentRow.index;
2412 int rowHeight = mainForm.browser.rowHeight;
2413 int height = mainForm.browser.clientSize.h;
2415 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2420 Array<Instance> history { };
2422 bool dontRecordHistory;
2427 if(historyPos < history.count-1)
2431 addressBar.back.disabled = (historyPos == 0);
2432 addressBar.forward.disabled = (historyPos >= history.count-1);
2433 sprintf(location, "api://%p", history[historyPos]);
2434 dontRecordHistory = true;
2435 view.OnOpen(location);
2436 dontRecordHistory = false;
2448 addressBar.back.disabled = (historyPos == 0);
2449 addressBar.forward.disabled = (historyPos >= history.count-1);
2450 sprintf(location, "api://%p", history[historyPos]);
2451 dontRecordHistory = true;
2452 view.OnOpen(location);
2453 dontRecordHistory = false;
2461 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2465 class EditDialog : Window
2467 borderStyle = sizable;
2468 size = { 600, 400 };
2473 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2477 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2481 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2485 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2486 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2488 class HelpView : HTMLView
2492 hasVertScroll = true;
2493 hasHorzScroll = true;
2495 char editString[MAX_LOCATION];
2501 page = mainForm.browser.currentRow.GetData(null);
2506 char docFile[MAX_LOCATION];
2508 Module module = page ? page.GetModule() : null;
2509 NameSpace * ns = page ? page.GetNameSpace() : null;
2511 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2512 if(FileExists(docFile))
2514 archive = ArchiveOpen(docFile, { true } );
2515 readOnly = archive == null;
2521 archive = ArchiveOpen(docFile, { true } );
2524 // Must create root directory on archive creation
2525 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2537 GoToAnchor(page.label);
2539 if(page.page) page = page.page;
2542 return HTMLView::OnCreate();
2551 char archiveFile[MAX_LOCATION];
2552 char fileName[MAX_FILENAME];
2553 char directory[MAX_LOCATION];
2555 Archive archive = null;
2556 if(SplitArchivePath(editString, archiveFile, &location))
2558 GetLastDirectory(location, fileName);
2559 StripLastDirectory(location, directory);
2560 archive = ArchiveOpen(archiveFile, { true } );
2564 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2567 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2569 if(block.type == TEXT && block.textLen)
2577 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2579 if(block.type == BR)
2581 else if(block.type == TEXT)
2582 f.Write(block.text, 1, block.textLen);
2587 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2593 Block parent = textBlock.parent;
2594 while((block = parent.subBlocks.first))
2596 parent.subBlocks.Remove(block);
2599 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2600 textBlock.text = CopyString($"[Add Text]");
2601 textBlock.textLen = strlen(textBlock.text);
2602 parent.subBlocks.Add(textBlock);
2610 PositionCaret(true);
2616 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2620 if(edit && (!textBlock || overLink != textBlock.parent))
2624 HTMLView::OnLeftButtonDown(x, y, mods);
2625 selPosition = curPosition = 0;
2626 selBlock = textBlock;
2630 result = HTMLView::OnLeftButtonDown(x, y, mods);
2632 if(!edit && clickedLink)
2635 if(clickedLink == overLink && clickedLink.href)
2637 if(OnOpen(clickedLink.href))
2645 if(textBlock && overLink == textBlock.parent)
2647 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2648 selBlock = textBlock;
2649 PositionCaret(true);
2657 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2659 if(!edit || !textBlock || clickedLink != textBlock.parent)
2661 HTMLView::OnLeftButtonUp(x, y, mods);
2664 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2665 selBlock = textBlock;
2666 PositionCaret(true);
2677 bool OnMouseMove(int x, int y, Modifiers mods)
2679 if(edit && selecting)
2681 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2682 PositionCaret(true);
2685 return HTMLView::OnMouseMove(x, y, mods);
2688 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2690 if(edit && textBlock)
2696 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2697 selBlock = textBlock;
2698 for(c = curPosition; c >= 0; c--)
2701 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2702 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2703 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2709 for(c = start; c < textBlock.textLen; c += numBytes)
2711 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2712 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2715 selPosition = start;
2718 PositionCaret(true);
2726 bool OnOpen(char * href)
2728 if(!strncmp(href, "api://", 6))
2730 int64 tag = (int64)strtoull(href + 6, null, 16);
2731 DataRow row = mainForm.browser.FindSubRow(tag);
2735 mainForm.browser.SelectRow(row);
2736 while((row = row.parent))
2737 row.collapsed = false;
2738 row = mainForm.browser.currentRow;
2739 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2742 else if(!strncmp(href, "edit://", 7))
2745 int startX = clickedLink.startX, startY = clickedLink.startY;
2746 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2748 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2749 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2751 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2753 display.FontExtent(block.font.font, " ", 1, null, &th);
2756 block.parent.subBlocks.Insert(null, newBlock);
2761 block.parent.subBlocks.Insert(block, newBlock);
2762 startY += block.prev.height;
2764 newBlock.startX = startX;
2765 newBlock.startY = startY;
2766 newBlock.text = new0 char[1];
2770 textBlock = (Block)clickedLink.subBlocks.first;
2771 if(!strcmp(textBlock.text, $"[Add Text]"))
2773 textBlock.text[0] = 0;
2774 textBlock.textLen = 0;
2777 strcpy(editString, href + 7);
2778 selPosition = curPosition = 0;
2779 selBlock = textBlock;
2782 // PositionCaret(true);
2789 void DeleteSelection()
2791 if(textBlock != selBlock || curPosition != selPosition)
2793 if(textBlock == selBlock)
2795 // Within same block
2796 int start = Min(curPosition, selPosition);
2797 int end = Max(curPosition, selPosition);
2798 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2799 textBlock.textLen -= end-start;
2800 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2801 curPosition = start;
2802 selPosition = start;
2806 int startSel, endSel;
2807 Block startSelBlock = null, endSelBlock = null, b, next;
2809 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2811 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2812 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2814 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2815 for(b = startSelBlock.next; b; b = next)
2817 bool isEnd = b == endSelBlock;
2818 next = GetNextBlock(b);
2819 b.parent.subBlocks.Remove(b);
2824 textBlock = startSelBlock;
2825 selBlock = startSelBlock;
2826 curPosition = startSel;
2827 selPosition = startSel;
2831 PositionCaret(true);
2836 String GetSelectionString()
2838 String selection = null;
2839 if(textBlock == selBlock)
2841 // Within same block
2842 int start = Min(curPosition, selPosition);
2843 int end = Max(curPosition, selPosition);
2844 int len = end - start;
2845 selection = new char[len + 1];
2846 memcpy(selection, textBlock.text + start, len);
2851 int startSel, endSel;
2852 Block startSelBlock = null, endSelBlock = null, b;
2855 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2858 for(b = startSelBlock; b; b = GetNextBlock(b))
2860 int start = (b == startSelBlock) ? startSel : 0;
2861 int end = (b == endSelBlock) ? endSel : b.textLen;
2862 int len = end - start;
2864 if(b == endSelBlock)
2866 else if(b.type == TEXT)
2870 selection = new char[totalLen + 1];
2872 for(b = startSelBlock; b; b = GetNextBlock(b))
2874 int start = (b == startSelBlock) ? startSel : 0;
2875 int end = (b == endSelBlock) ? endSel : b.textLen;
2876 int len = end - start;
2877 memcpy(selection + totalLen, b.text + start, len);
2879 if(b == endSelBlock)
2881 else if(b.type == TEXT)
2882 selection[totalLen++] = '\n';
2884 selection[totalLen] = 0;
2889 void CopySelection()
2891 String s = GetSelectionString();
2894 int len = strlen(s);
2896 if(cb.Allocate(len + 1))
2898 memcpy(cb.text, s, len + 1);
2906 bool OnKeyDown(Key key, unichar ch)
2913 OnLeftButtonDown(0,0,0);
2915 case Key { end, shift = true }:
2917 curPosition = textBlock.textLen;
2920 selPosition = curPosition;
2921 selBlock = textBlock;
2923 PositionCaret(true);
2926 case Key { home, shift = true }:
2931 selPosition = curPosition;
2932 selBlock = textBlock;
2934 PositionCaret(true);
2937 case Key { home, ctrl = true, shift = true }:
2940 while(textBlock.prev)
2941 textBlock = textBlock.prev.prev;
2944 selPosition = curPosition;
2945 selBlock = textBlock;
2947 PositionCaret(true);
2950 case Key { end, ctrl = true, shift = true }:
2952 while(textBlock.next && textBlock.next.next)
2953 textBlock = textBlock.next.next;
2954 curPosition = textBlock.textLen;
2957 selPosition = curPosition;
2958 selBlock = textBlock;
2960 PositionCaret(true);
2966 return HTMLView::OnKeyDown(key, ch);
2970 bool OnKeyHit(Key key, unichar ch)
2976 case Key { up, shift = true }:
2979 if(caretY == textBlock.startY)
2983 textBlock = textBlock.prev.prev;
2984 curPosition = Min(curPosition, textBlock.textLen);
2987 selPosition = curPosition;
2988 selBlock = textBlock;
2991 PositionCaret(false);
3001 int sx = textBlock.startX, sy = textBlock.startY;
3002 char * text = textBlock.text;
3004 Block block = textBlock;
3005 while(block && block.type != TD) block = block.parent;
3008 Block table = block;
3009 while(table && table.type != TABLE) table = table.parent;
3011 maxW = block.w - 2* table.cellPadding;
3013 maxW = clientSize.w - 10 - sx;
3016 maxW = clientSize.w - 10 - sx;
3017 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3021 int startPos = textPos;
3024 bool lineComplete = false;
3025 for(; textPos<textBlock.textLen && !lineComplete;)
3029 char * nextSpace = strchr(text + textPos, ' ');
3032 len = (nextSpace - (text + textPos)) + 1;
3034 len = textBlock.textLen - textPos;
3036 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3038 if(x + width + w > maxW && x > 0)
3040 lineComplete = true;
3050 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3053 curPosition = textPos;
3054 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3057 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3058 len = curPosition - startPos;
3059 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3063 selPosition = curPosition;
3064 selBlock = textBlock;
3068 PositionCaret(false);
3072 if(sy == caretY - th || textPos == textBlock.textLen)
3074 if(textPos != textBlock.textLen)
3076 int c = textPos - 1;
3077 while(c > 0 && text[c] == ' ') c--;
3078 curPosition = c + 1;
3081 selPosition = curPosition;
3082 selBlock = textBlock;
3088 curPosition = textBlock.textLen;
3091 selPosition = curPosition;
3092 selBlock = textBlock;
3096 PositionCaret(false);
3100 sx = textBlock.startX;
3101 } while(textPos < textBlock.textLen);
3106 case Key { down, shift = true }:
3111 int sx = textBlock.startX, sy = textBlock.startY;
3112 char * text = textBlock.text;
3114 Block block = textBlock;
3115 while(block && block.type != TD) block = block.parent;
3118 Block table = block;
3119 while(table && table.type != TABLE) table = table.parent;
3121 maxW = block.w - 2* table.cellPadding;
3123 maxW = clientSize.w - 10 - sx;
3126 maxW = clientSize.w - 10 - sx;
3127 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3129 while(!textPos || textPos < textBlock.textLen)
3131 int startPos = textPos;
3134 bool lineComplete = false;
3135 for(; (textPos < textBlock.textLen) && !lineComplete;)
3139 char * nextSpace = strchr(text + textPos, ' ');
3142 len = (nextSpace - (text + textPos)) + 1;
3144 len = textBlock.textLen - textPos;
3146 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3148 if(x + width + w > maxW && x > 0)
3150 lineComplete = true;
3160 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3162 curPosition = textPos;
3164 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3167 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3168 len = curPosition - startPos;
3169 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3173 selPosition = curPosition;
3174 selBlock = textBlock;
3177 PositionCaret(false);
3183 curPosition = textBlock.textLen;
3186 selPosition = curPosition;
3187 selBlock = textBlock;
3190 PositionCaret(false);
3193 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3197 textBlock = textBlock.next.next;
3198 sy = textBlock.startY;
3199 sx = textBlock.startX;
3200 text = textBlock.text;
3205 sx = textBlock.startX;
3209 /*if(textBlock.next && textBlock.next.next)
3211 textBlock = textBlock.next.next;
3212 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3213 selBlock = textBlock;
3214 PositionCaret(false);
3218 case Key { right, shift = true, ctrl = true }:
3221 bool foundAlpha = false;
3223 Block line, lastLine;
3226 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3228 int start = (line == textBlock) ? curPosition : 0;
3230 for(c = start; c < line.textLen; c++)
3232 char ch = line.text[c];
3233 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3234 if(key.shift ? isAlUnder : !isAlUnder)
3248 selPosition = curPosition;
3249 selBlock = textBlock;
3253 PositionCaret(true);
3258 // No next word found,
3259 if(!found && (c != curPosition || line != textBlock))
3263 lastC = line.textLen-1;
3268 curPosition = line.textLen;
3271 selPosition = curPosition;
3272 selBlock = textBlock;
3277 PositionCaret(true);
3283 if(key.shift && found)
3285 curPosition = lastC+1;
3286 textBlock = lastLine;
3287 PositionCaret(true);
3292 case Key { left, ctrl = true, shift = true }:
3295 bool foundAlpha = false;
3297 Block line, lastLine;
3300 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3303 if(curPosition == 0 && line != textBlock)
3306 lastC = line.textLen;
3310 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3311 for(c = start; c>=0; c--)
3313 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3328 // No next word found,
3329 if(!found && curPosition > 0)
3339 textBlock = lastLine;
3340 curPosition = lastC;
3343 selPosition = curPosition;
3344 selBlock = textBlock;
3346 PositionCaret(true);
3351 case Key { right, shift = true }:
3353 if(curPosition < textBlock.textLen)
3355 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3358 selPosition = curPosition;
3359 selBlock = textBlock;
3361 PositionCaret(true);
3364 else if(textBlock.next && textBlock.next.next)
3366 textBlock = textBlock.next.next;
3370 selPosition = curPosition;
3371 selBlock = textBlock;
3373 PositionCaret(true);
3377 case Key { left, shift = true }:
3381 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3384 selPosition = curPosition;
3385 selBlock = textBlock;
3387 PositionCaret(true);
3390 else if(textBlock.prev)
3392 textBlock = textBlock.prev.prev;
3393 curPosition = textBlock.textLen;
3396 selPosition = curPosition;
3397 selBlock = textBlock;
3399 PositionCaret(true);
3405 if(textBlock == selBlock && curPosition == selPosition)
3409 int c = curPosition;
3411 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3412 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3413 textBlock.textLen -= nb;
3414 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3416 selPosition = curPosition;
3417 selBlock = textBlock;
3421 PositionCaret(true);
3424 else if(textBlock.prev)
3426 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3427 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3428 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3430 selPosition = curPosition = prevBlock.textLen;
3431 selBlock = textBlock;
3432 prevBlock.textLen += textBlock.textLen;
3433 textBlock.parent.subBlocks.Remove(prev);
3434 if(prev == selBlock)
3436 selBlock = textBlock;
3437 selPosition = curPosition;
3440 textBlock.parent.subBlocks.Remove(textBlock);
3441 if(textBlock == selBlock)
3443 selBlock = prevBlock;
3444 selPosition = curPosition;
3447 textBlock = prevBlock;
3451 PositionCaret(true);
3460 if(textBlock != selBlock || curPosition != selPosition)
3462 else if(textBlock.textLen > curPosition)
3464 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3465 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3466 textBlock.textLen -= nb;
3467 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3472 PositionCaret(true);
3475 else if(textBlock.next && textBlock.next.next)
3477 Block next = textBlock.next, nextBlock = textBlock.next.next;
3478 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3479 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3481 textBlock.textLen += nextBlock.textLen;
3482 textBlock.parent.subBlocks.Remove(next);
3483 if(next == selBlock)
3485 selBlock = textBlock;
3486 selPosition = curPosition;
3489 textBlock.parent.subBlocks.Remove(nextBlock);
3490 if(nextBlock == selBlock)
3492 selBlock = textBlock;
3493 selPosition = curPosition;
3499 PositionCaret(true);
3513 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3514 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3515 startY = textBlock.startY;
3516 startX = textBlock.startX;
3518 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3519 textBlock.parent.subBlocks.Insert(textBlock, block);
3520 textBlock.parent.subBlocks.Insert(block, newBlock);
3524 newBlock.textLen = textBlock.textLen - curPosition;
3525 newBlock.text = new char[newBlock.textLen+1];
3526 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3527 textBlock.textLen = curPosition;
3528 textBlock.text[curPosition] = 0;
3530 newBlock.startY = startY;
3531 newBlock.startX = startX;
3532 selPosition = curPosition = 0;
3537 textBlock = newBlock;
3538 selBlock = textBlock;
3539 PositionCaret(true);
3544 case Key { del, shift = true }:
3559 ClipBoard clipBoard { };
3560 if(clipBoard.Load())
3563 char * text = clipBoard.memory;
3571 parent = textBlock.parent;
3572 font = textBlock.font;
3577 if(ch == '\n' || ch == '\r' || !ch)
3579 int len = c - start;
3580 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3581 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3582 memcpy(textBlock.text + curPosition, text + start, len);
3583 textBlock.textLen += len;
3585 selPosition = curPosition;
3586 selBlock = textBlock;
3589 Block block { type = BR, parent = parent, font = font };
3590 Block newBlock { type = TEXT, parent = parent, font = font };
3591 int startY = textBlock.startY, startX = textBlock.startX;
3594 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3595 textBlock.parent.subBlocks.Insert(textBlock, block);
3596 textBlock.parent.subBlocks.Insert(block, newBlock);
3600 newBlock.textLen = textBlock.textLen - curPosition;
3601 newBlock.text = new char[newBlock.textLen+1];
3602 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3603 textBlock.textLen = curPosition;
3604 textBlock.text[curPosition] = 0;
3606 newBlock.startY = startY;
3607 newBlock.startX = startX;
3608 selPosition = curPosition = 0;
3609 selBlock = textBlock;
3610 textBlock = newBlock;
3612 if(ch == '\r' && text[c+1] == '\n') c++;
3618 PositionCaret(true);
3626 // eC BUG HERE: (Should be fixed)
3627 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3630 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3635 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3636 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3638 for(c = 0; c<len; c++)
3640 textBlock.text[curPosition] = string[c];
3641 textBlock.textLen++;
3644 selPosition = curPosition;
3645 selBlock = textBlock;
3648 //Clear(html.block);
3649 //CreateForms(html.block);
3654 PositionCaret(true);
3663 void OnResize(int width, int height)
3665 HTMLView::OnResize(width, height);
3666 PositionCaret(true);
3670 void PositionCaret(bool setCaretX)
3676 int sx = textBlock.startX, sy = textBlock.startY;
3677 char * text = textBlock.text;
3679 Block block = textBlock;
3680 while(block && block.type != TD) block = block.parent;
3683 Block table = block;
3684 while(table && table.type != TABLE) table = table.parent;
3686 maxW = block.w - 2* table.cellPadding;
3688 maxW = clientSize.w - 10 - sx;
3691 maxW = clientSize.w - 10 - sx;
3693 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3695 while(textPos < textBlock.textLen)
3697 int startPos = textPos;
3700 bool lineComplete = false;
3702 for(; textPos<textBlock.textLen && !lineComplete;)
3706 char * nextSpace = strchr(text + textPos, ' ');
3709 len = (nextSpace - (text + textPos)) + 1;
3711 len = textBlock.textLen - textPos;
3713 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3715 if(x + width + w > maxW && x > 0)
3717 lineComplete = true;
3730 if(curPosition < textPos || textPos == textBlock.textLen)
3732 int len = curPosition - startPos;
3733 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3738 sx = textBlock.startX;
3743 SetCaret(sx, sy, th);
3745 Point scrollPos = scroll;
3746 bool doScroll = false;
3747 if(sy - scroll.y + th > clientSize.h)
3749 scrollPos.y = sy + th - clientSize.h;
3752 else if(sy - scroll.y < 0)
3757 if(sx - scroll.x + 10 > clientSize.w)
3759 scrollPos.x = sx + 10 - clientSize.w;
3762 else if(sx - scroll.x < 10)
3764 scrollPos.x = sx - 10;
3775 // Returns a character offset into the TextBlock from a window coordinate
3776 int TextPosFromPoint(int px, int py, Block * block, bool half)
3778 Block parentBlock = this.textBlock.parent;
3781 *block = this.textBlock;
3786 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3788 int sx = textBlock.startX, sy = textBlock.startY;
3791 char * text = textBlock.text;
3793 Block b = textBlock;
3796 if(textBlock.type != TEXT) continue;
3798 while(b && b.type != TD) b = b.parent;
3802 while(table && table.type != TABLE) table = table.parent;
3804 maxW = b.w - 2* table.cellPadding;
3806 maxW = clientSize.w - 10 - sx;
3809 maxW = clientSize.w - 10 - sx;
3811 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3812 //space = space/2+2;
3815 while(textPos < textBlock.textLen)
3817 int startPos = textPos;
3820 bool lineComplete = false;
3822 for(; textPos<textBlock.textLen && !lineComplete;)
3826 char * nextSpace = strchr(text + textPos, ' ');
3829 len = (nextSpace - (text + textPos)) + 1;
3831 len = textBlock.textLen - textPos;
3833 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3835 sx = x + textBlock.startX;
3836 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3841 for(c = textPos; (ch = text[c]); c += numBytes)
3843 numBytes = UTF8_NUM_BYTES(ch);
3844 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3845 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3852 if(x + width + w > maxW && x > 0)
3854 lineComplete = true;
3867 if(/*py >= sy && */py < sy + th)
3870 return textBlock.textLen;
3875 result = textBlock.textLen;
3881 Application componentsApp;
3883 class Documentor : GuiApplication
3887 Platform os = GetRuntimePlatform();
3888 componentsApp = __ecere_COM_Initialize(false, 1, null);
3889 SetPrivateModule(componentsApp);
3890 SetGlobalContext(globalContext);
3891 SetExcludedSymbols(&excludedSymbols);
3892 SetDefines(&::defines);
3893 SetImports(&imports);
3895 SetGlobalData(globalData);
3897 settingsContainer.dataOwner = &settings;
3898 settingsContainer.Load();
3899 if(!settings.docDir || !settings.docDir[0] )
3901 if(os == win32) // if Windows OS then
3903 char programFilesDir[MAX_LOCATION];
3904 char appData[MAX_LOCATION];
3905 char homeDrive[MAX_LOCATION];
3906 char winDir[MAX_LOCATION];
3907 GetEnvironment("APPDATA", appData, sizeof(appData));
3908 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3909 GetEnvironment("windir", winDir, sizeof(winDir));
3910 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3912 PathCat(programFilesDir, "ECERE SDK\\doc");
3913 settings.docDir = programFilesDir;
3915 else if(homeDrive && homeDrive[0])
3917 PathCat(homeDrive, "ECERE SDK\\doc");
3918 settings.docDir = homeDrive;
3920 else if(winDir && winDir[0])
3922 PathCat(winDir, "..\\ECERE SDK\\doc");
3923 settings.docDir = winDir;
3926 settings.docDir = "C:\\ECERE SDK\\doc";
3928 else // if Os is Linux, or Mac OSX or something else
3929 settings.docDir = "/usr/share/ecere/doc/";
3930 settingsContainer.Save();
3936 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3938 AddComponents(module, true);
3939 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3940 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3941 while((row = row.parent))
3942 row.collapsed = false;
3946 commandThread.Create();
3950 bool Cycle(bool idle)
3953 mainForm.Destroy(0);
3962 if(commandThread.created)
3964 console.CloseInput();
3965 console.CloseOutput();
3967 commandThread.Wait();
3971 FreeContext(globalContext);
3972 FreeExcludedSymbols(excludedSymbols);
3973 ::defines.Free(FreeModuleDefine);
3974 imports.Free(FreeModuleImport);
3976 FreeGlobalData(globalData);
3977 FreeTypeData(componentsApp);
3979 delete componentsApp;
3983 ConsoleFile console { };
3984 MainForm mainForm { };
3987 Thread commandThread
3994 console.GetLine(command, sizeof(command));
3995 if(!quit && command[0])
3998 if(!strcmpi(command, "Activate"))
3999 mainForm.Activate();
4000 else if(!strcmpi(command, "Quit"))