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 const char * iconNames[CodeObjectType] =
35 "<:ecere>constructs/class.png",
36 "<:ecere>constructs/data.png",
37 "<:ecere>constructs/method.png",
38 "<:ecere>constructs/event.png",
39 "<:ecere>constructs/property.png",
40 "<:ecere>constructs/namespace.png",
41 "<:ecere>constructs/dataType.png",
42 "<:ecere>constructs/enumValue.png",
43 "<:ecere>constructs/dataPrivate.png",
44 "<:ecere>constructs/methodPrivate.png",
45 "<:ecere>constructs/propertyPrivate.png"
48 IDESettings settings { }; // instantiate the IDESettings class from the IDESettings.ec file. Do this at a global level so that all methods can access settings.
50 IDESettingsContainer settingsContainer
54 dataOwner = &settings;
57 void GetTemplateString(Class c, char * templateString)
59 Module m = c.module.application;
60 const char * n = c.name;
61 char * lt = strchr(n, '<');
67 memcpy(templateString, n, lt-n);
68 templateString[lt-n] = 0;
69 strcat(templateString, "</a>");
71 for(s = lt; (ch = *s); s++)
73 if(ch == '<' || ch == '>' || ch == ',')
78 char * d = templateString + strlen(templateString);
80 pc = eSystem_FindClass(m, curName);
82 sprintf(d, "<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", pc, pc.name);
87 strcat(templateString, "<");
89 strcat(templateString, ">");
91 strcat(templateString, ", ");
100 strcat(templateString, curName);
108 // WARNING : This function expects a null terminated string since it recursively concatenate...
109 static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
113 if(type.constant && (type.kind != pointerType && type.kind != arrayType))
114 strcat(string, "const ");
118 if(type._class && type._class.string)
121 strcat(string, type._class.string);
124 if(type._class.registered)
127 const char * s = type._class.registered.name;
128 sprintf(hex, "%p", type._class.registered.templateClass ? type._class.registered.templateClass : type._class.registered);
129 strcat(string, "<a href=\"api://");
131 strcat(string, "\" style=\"text-decoration: none;\">");
135 GetTemplateString(type._class.registered, n);
139 strcat(string, type._class.registered.name);
140 strcat(string, "</a>");
143 strcat(string, type._class.string);
150 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
151 if(funcType && funcType.kind == functionType)
154 DocPrintType(funcType.returnType, string, false, fullName);
155 strcat(string, "(*");
156 if(printName || funcType.thisClass)
159 if(funcType.thisClass)
161 strcat(string, funcType.thisClass.string);
162 strcat(string, "::");
165 strcat(string, type.name);
167 strcat(string, ")(");
168 for(param = funcType.params.first; param; param = param.next)
170 DocPrintType(param, string, false, fullName);
171 if(param.next) strcat(string, ", ");
177 _PrintType(type.type, string, false /*printName*/, printFunction, fullName);
178 if(string[strlen(string)-1] == '(')
181 strcat(string, " *");
185 case voidType: strcat(string, "void"); break;
186 case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
187 case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
188 case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
189 case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
190 case floatType: strcat(string, "float"); break;
191 case doubleType: strcat(string, "double"); break;
195 strcat(string, "struct ");
196 strcat(string, type.enumName);
198 else if(type.typeName)
200 strcat(string, type.typeName);
205 strcat(string, "struct ");
206 strcat(string,"(unnamed)");
209 strcat(string, "struct {");
210 for(member = type.members.first; member; member = member.next)
212 DocPrintType(member, string, true, fullName);
221 strcat(string, "union ");
222 strcat(string, type.enumName);
224 else if(type.typeName)
226 strcat(string, type.typeName);
230 strcat(string, "union ");
231 strcat(string,"(unnamed)");
237 strcat(string, "enum ");
238 strcat(string, type.enumName);
240 else if(type.typeName)
242 strcat(string, type.typeName);
245 strcat(string, "enum");
252 strcat(string, "dllexport ");
253 DocPrintType(type.returnType, string, false, fullName);
257 // DANGER: Testing This
263 strcat(string, type.name);
266 char * name = RSearchString(type.name, "::", strlen(type.name), true, false);
267 if(name) name += 2; else name = type.name;
268 strcat(string, "<b>");
269 strcat(string, name);
270 strcat(string, "</b>");
283 for(param = type.params.first; param; param = param.next)
285 DocPrintType(param, string, true, fullName);
286 if(param.next) strcat(string, ", ");
295 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
296 if(funcType && funcType.kind == functionType)
299 DocPrintType(funcType.returnType, string, false, fullName);
300 strcat(string, "(*");
301 if(printName || funcType.thisClass)
304 if(funcType.thisClass)
306 strcat(string, funcType.thisClass.string);
307 strcat(string, "::");
310 strcat(string, type.name);
312 strcat(string, ")(");
313 for(param = funcType.params.first; param; param = param.next)
315 DocPrintType(param, string, false, fullName);
316 if(param.next) strcat(string, ", ");
322 char baseType[1024], size[256];
323 Type arrayType = type;
327 while(arrayType.kind == TypeKind::arrayType)
330 if(arrayType.enumClass)
331 strcat(size, arrayType.enumClass.string);
332 else if(arrayType.arraySizeExp)
333 PrintExpression(arrayType.arraySizeExp, size);
334 //sprintf(string, "%s[%s]", baseType, size);
337 arrayType = arrayType.arrayType;
339 _PrintType(arrayType, baseType, printName, printFunction, fullName);
340 strcat(string, baseType);
341 strcat(string, size);
345 DocPrintType(type.arrayType, baseType, printName, fullName);
347 strcpy(size, type.enumClass.string);
348 else if(type.arraySizeExp)
349 PrintExpression(type.arraySizeExp, size);
350 //sprintf(string, "%s[%s]", baseType, size);
351 strcat(string, baseType);
353 strcat(string, size);
361 strcat(string, "...");
364 _PrintType(type.method.dataType, string, false, printFunction, fullName);
367 strcat(string, "subclass(");
368 strcat(string, type._class ? type._class.string : "int");
374 if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
377 strcat(string, type.name);
382 void DocPrintType(Type type, char * string, bool printName, bool fullName)
385 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
386 if(funcType && funcType.kind == functionType && type != funcType)
388 char typeString[1024];
391 DocPrintType(funcType.returnType, string, false, fullName);
393 _PrintType(type, string, printName, false, fullName);
397 strcat(string, type.name);
404 for(param = funcType.params.first; param; param = param.next)
406 DocPrintType(param, string, true, fullName);
407 if(param.next) strcat(string, ", ");
412 _PrintType(type, string, printName, true, fullName);
415 void AddComponents(Module module, bool isDll)
420 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
422 row = mainForm.browser.AddRow();
423 row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
424 row.tag = (int64)null;
425 AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
428 for(m = module.modules.first; m; m = m.next)
430 if(m.importMode == publicAccess || !isDll)
431 AddComponents(m.module, true);
434 // PUT MODULE DESCRIPTION HERE
435 if(module.name && strcmp(module.name, "ecereCOM"))
437 row = mainForm.browser.AddRow();
438 row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
439 row.tag = (int64)module;
440 AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
442 AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
454 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
459 virtual void Generate(File f)
464 virtual Module GetModule()
466 return page ? page.GetModule() : null;
469 virtual NameSpace * GetNameSpace()
471 return page ? page.GetNameSpace() : null;
475 enum DocumentationType
483 enum DocumentationItem
499 static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
501 NameSpace * nameSpace, * ns;
503 Method method = null;
504 GlobalFunction function = null;
505 char nsName[1024], temp[1024];
511 case nameSpaceDoc: nameSpace = object; break;
512 case classDoc: cl = (Class)object; nameSpace = cl.nameSpace; break;
513 case functionDoc: function = object; nameSpace = function.nameSpace; break;
514 case methodDoc: method = object; cl = method._class; nameSpace = cl.nameSpace; break;
519 while(ns && ns->name)
521 strcpy(temp, "namespaces/");
522 strcat(temp, ns->name);
524 strcat(temp, nsName);
525 strcpy(nsName, temp);
528 sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
529 if(strchr(docFile, DIR_SEP))
531 GetLastDirectory(docFile, temp);
532 strcpy(docFile, temp);
535 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.
536 strcat(fileName, nsName);
540 strcat(fileName, "classes/");
541 strcat(fileName, cl.name);
542 strcat(fileName, "/");
547 strcat(fileName, "methods/");
548 strcat(fileName, method.name);
549 strcat(fileName, "/");
553 const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
554 if(name) name += 2; else name = function.name;
555 strcat(fileName, "functions/");
556 strcat(fileName, name);
557 strcat(fileName, "/");
562 case description: strcat(fileName, "description"); break;
563 case usage: strcat(fileName, "usage"); break;
564 case remarks: strcat(fileName, "remarks"); break;
565 case example: strcat(fileName, "example"); break;
566 case seeAlso: strcat(fileName, "seeAlso"); break;
567 case returnValue: strcat(fileName, "returnValue"); break;
568 case enumerationValue:
569 strcat(fileName, "enumeration values/");
570 strcat(fileName, ((NamedLink)data).name);
573 strcat(fileName, "definitions/");
574 strcat(fileName, ((Definition)data).name);
578 const char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
579 if(name) name += 2; else name = ((Property)data).name;
580 strcat(fileName, "conversions/");
581 strcat(fileName, name);
584 case memberDescription:
585 strcat(fileName, "data members/");
586 strcat(fileName, ((DataMember)data).name);
588 case propertyDescription:
589 strcat(fileName, "properties/");
590 strcat(fileName, ((Property)data).name);
597 strcat(fileName, "parameters/");
598 for(prev = data, count = 0; prev; prev = prev.prev, count++);
599 sprintf(name, "%s.%d", ((Type)data).name, count);
600 strcat(fileName, name);
606 static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
608 char fileName[MAX_LOCATION];
609 String contents = null;
612 FigureFileName(fileName, module, type, object, item, data);
613 file = FileOpen(fileName, read);
617 if((len = file.GetSize()))
619 contents = new char[len+1];
620 file.Read(contents, 1, len);
621 contents[len] = '\0';
628 for(c = 0; contents[c]; c++)
629 if(!isspace(contents[c])) break;
633 if(editing && !contents && !readOnly)
634 contents = CopyString($"[Add Text]");
638 class APIPageNameSpace : APIPage
640 NameSpace * nameSpace;
648 NameSpace * GetNameSpace()
653 void Generate(File f)
656 char nsName[1024], temp[1024];
663 while(ns && ns->name)
665 strcpy(temp, ns->name);
666 if(nsName[0]) strcat(temp, "::");
667 strcat(temp, nsName);
668 strcpy(nsName, temp);
671 // Generate Class Page
672 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
675 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
676 tag = (int64)nameSpace;
677 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);
681 tag = (int64)(!module || !module.name || !strcmp(nsName, "ecere::com") ? null : module);
682 f.Printf($"<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
686 ns = nameSpace->parent;
687 while(ns && ns->name)
689 strcpy(temp, ns->name);
690 if(nsName[0]) strcat(temp, "::");
691 strcat(temp, nsName);
692 strcpy(nsName, temp);
696 f.Printf($"Parent namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
700 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
703 f.Printf($"<H3>Description</H3><br><br>\n");
706 char fileName[MAX_LOCATION];
707 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
708 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
710 f.Printf("</a><br><br>");
713 f.Printf("%s<br><br>", desc);
718 if(nameSpace->nameSpaces.first)
721 for(ns = (NameSpace *)nameSpace->nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
723 char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
726 f.Printf($"<H3>Sub Namespaces</H3><br><br>\n");
727 f.Printf("<TABLE>\n");
731 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);
736 char fileName[MAX_LOCATION];
737 FigureFileName(fileName, module, nameSpaceDoc, ns, description, null);
738 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
740 f.Printf("</a></TD>");
743 f.Printf("<TD valign=top height=22> %s</TD>", desc);
746 f.Printf("</TR><br>\n");
749 f.Printf("</TABLE><br>\n");
752 if(nameSpace->classes.first)
755 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
757 Class cl = link.data;
758 if(!cl.templateClass)
760 char * desc = ReadDoc(module, classDoc, cl, description, null);
764 f.Printf($"<a name=Classes></a><H3>Classes</H3><br><br>\n");
765 f.Printf("<TABLE>\n");
771 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);
776 char fileName[MAX_LOCATION];
777 FigureFileName(fileName, module, classDoc, cl, description, null);
778 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
780 f.Printf("</a></TD>");
783 f.Printf("<TD valign=top height=22>%s</TD>", desc);
790 f.Printf("</TABLE><br>\n");
793 if(nameSpace->functions.first)
796 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
798 GlobalFunction function = link.data;
799 char * desc = ReadDoc(module, functionDoc, function, description, null);
800 const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
801 if(name) name += 2; else name = function.name;
804 f.Printf($"<a name=Functions></a><H3>Functions</H3><br><br>\n");
805 f.Printf("<TABLE>\n");
809 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);
814 char fileName[MAX_LOCATION];
815 FigureFileName(fileName, module, functionDoc, function, description, null);
816 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
818 f.Printf("</a></TD>");
821 f.Printf("<TD valign=top height=22> %s</TD>", desc);
824 f.Printf("</TR><br>\n");
827 f.Printf("</TABLE><br>\n");
830 if(nameSpace->defines.first)
833 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
835 DefinedExpression def = link.data;
836 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
839 f.Printf($"<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
840 f.Printf("<TABLE>\n");
844 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);
845 f.Printf("<TD valign=top height=22>%s</TD>", def.value);
850 char fileName[MAX_LOCATION];
851 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, definition, def);
852 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
854 f.Printf("</a></TD>");
857 f.Printf("<TD valign=top height=22> %s</TD>", desc);
860 f.Printf("</TR><br>\n");
863 f.Printf("</TABLE><br>\n");
866 f.Printf("</FONT></BODY></HTML>\n");
870 class APIPageClass : APIPage
879 NameSpace * GetNameSpace()
884 void Generate(File f)
890 char nsName[1024], temp[1024];
891 NameSpace * ns = cl.nameSpace;
892 Module module = cl.module;
895 while(ns && ns->name)
897 strcpy(temp, ns->name);
898 if(nsName[0]) strcat(temp, "::");
899 strcat(temp, nsName);
900 strcpy(nsName, temp);
903 // Generate Class Page
904 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
905 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
907 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);
909 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
912 const char * classType = null;
916 classType = $"Bit Collection";
919 classType = $"Enumeration";
922 classType = $"Structure";
925 classType = $"Class";
928 classType = $"Class (No header)";
934 classType = $"Basic Data Type";
937 f.Printf($"Type: %s<br>\n", classType);
940 if(cl.type != systemClass && cl.base)
942 f.Printf($"Base Class: ");
943 if(!strcmp(cl.base.name, "struct") || !strcmp(cl.base.name, "class"))
945 f.Printf(cl.type == bitClass ? cl.dataTypeString : $"None");
947 else if(cl.type == enumClass && !strcmp(cl.base.name, "enum"))
948 f.Printf("%s", cl.dataTypeString);
950 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", cl.base.templateClass ? cl.base.templateClass : cl.base, cl.base.name);
955 char * desc = ReadDoc(module, classDoc, cl, description, null);
958 f.Printf($"<br><H3>Description</H3><br><br>\n");
961 char fileName[MAX_LOCATION];
962 FigureFileName(fileName, module, classDoc, cl, description, null);
963 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
965 f.Printf("</a><br><br>");
968 f.Printf("%s<br><br>", desc);
973 if(cl.type == enumClass)
975 EnumClassData enumeration = (EnumClassData)cl.data;
976 if(enumeration.values.first)
980 f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
981 f.Printf("<TABLE>\n");
983 for(item = enumeration.values.first; item; item = item.next)
985 char * desc = ReadDoc(module, classDoc, cl, enumerationValue, item);
986 bool needClass = true;
989 char tempString[1024];
991 while(base.type == enumClass) base = base.base;
993 if(base.type == systemClass ||
994 (base.type == bitClass && base.membersAndProperties.first && !strcmp(cl.fullName, ((DataMember)base.membersAndProperties.first).dataTypeString)))
997 base.dataType = ProcessTypeString(base.dataTypeString, false);
999 if(base.dataType.kind != classType)
1004 PrintType(base.dataType, string, false, true);
1005 classSym = FindClass(string);
1006 dataClass = classSym ? classSym.registered : null;
1009 dataClass = base.dataType._class ? base.dataType._class.registered : null;
1015 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);
1016 if(dataClass.type == systemClass)
1019 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)dataClass._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1022 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)eSystem_FindClass(componentsApp, "class")._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1024 f.Printf("<TD valign=top height=22 nowrap=1>%s { %s }</TD>", dataClass.name, s);
1026 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", s);
1031 char fileName[MAX_LOCATION];
1032 FigureFileName(fileName, module, classDoc, cl, enumerationValue, item);
1033 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1035 f.Printf("</a></TD>");
1038 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1043 f.Printf("</TABLE><BR>\n");
1047 if(cl.conversions.first)
1049 f.Printf($"<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
1050 f.Printf("<TABLE>\n");
1051 for(prop = cl.conversions.first; prop; prop = prop.next)
1053 if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
1055 char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
1058 Type type = ProcessTypeString(prop.name, false);
1059 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
1060 if(name) name += 2; else name = prop.name;
1065 DocPrintType(type, string, true, false);
1067 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeDataType], string);
1072 char fileName[MAX_LOCATION];
1073 FigureFileName(fileName, module, classDoc, cl, conversion, prop);
1074 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1076 f.Printf("</a></TD>");
1079 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1083 f.Printf("</TR>\n");
1088 f.Printf("</TABLE><br>\n");
1091 if(cl.membersAndProperties.first)
1094 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1096 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1100 f.Printf($"<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
1101 f.Printf("<TABLE>\n");
1107 char * desc = ReadDoc(module, classDoc, cl, propertyDescription, prop);
1109 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1113 DocPrintType(prop.dataType, string, true, false);
1115 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);
1116 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
1121 char fileName[MAX_LOCATION];
1122 FigureFileName(fileName, module, classDoc, cl, propertyDescription, prop);
1123 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1125 f.Printf("</a></TD>");
1128 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1131 f.Printf("</TR>\n");
1135 AddDataMemberToPage(f, (DataMember)prop, 0, showPrivate);
1140 f.Printf("</TABLE><br>\n");
1143 if(cl.methods.first)
1147 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1149 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type == virtualMethod)
1151 char * desc = ReadDoc(module, methodDoc, method, description, null);
1154 f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
1155 f.Printf("<TABLE>\n");
1158 if(!method.dataType)
1159 ProcessMethodType(method);
1162 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);
1167 char fileName[MAX_LOCATION];
1168 FigureFileName(fileName, module, methodDoc, method, description, null);
1169 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1171 f.Printf("</a></TD>");
1174 f.Printf("<TD valign=top height=22> %s</TD>", desc);
1177 f.Printf("</TR><br>\n");
1181 f.Printf("</TABLE><br>\n");
1183 // Non-Virtual Methods
1185 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1187 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type != virtualMethod)
1189 char * desc = ReadDoc(module, methodDoc, method, description, null);
1192 f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
1193 f.Printf("<TABLE>\n");
1197 if(!method.dataType)
1198 ProcessMethodType(method);
1201 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);
1206 char fileName[MAX_LOCATION];
1207 FigureFileName(fileName, module, methodDoc, method, description, null);
1208 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1210 f.Printf("</a></TD>");
1213 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1217 f.Printf("</TR><br>\n");
1221 f.Printf("</TABLE><br>\n");
1224 char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
1227 f.Printf($"<H3>Usage</H3><br>\n");
1230 char fileName[MAX_LOCATION];
1231 FigureFileName(fileName, module, classDoc, cl, usage, null);
1232 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1237 f.Printf("<br>%s\n", usageDoc);
1238 f.Printf("<br><br>\n");
1243 char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
1246 f.Printf($"<H3>Example</H3><br>\n");
1247 f.Printf($"<FONT face=\"Courier New\">\n");
1248 f.Printf("<br><TABLE>\n");
1251 char fileName[MAX_LOCATION];
1252 FigureFileName(fileName, module, classDoc, cl, example, null);
1253 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1255 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1258 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1260 f.Printf("</TABLE></FONT>\n");
1266 char * remarksDoc = ReadDoc(module, classDoc, cl, remarks, null);
1270 f.Printf($"<H3>Remarks</H3><br>\n");
1273 char fileName[MAX_LOCATION];
1274 FigureFileName(fileName, module, classDoc, cl, remarks, null);
1275 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1280 f.Printf("<br>%s\n", remarksDoc);
1281 f.Printf("<br><br>\n");
1286 if(cl.type != systemClass)
1290 for(c = cl.derivatives.first; c; c = c.next)
1292 Class deriv = c.data;
1293 // TO VERIFY: Does this properly check public status?
1294 if(eSystem_FindClass(componentsApp, deriv.fullName))
1298 f.Printf($"<H3>Derived Classes</H3><br>\n");
1304 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
1308 f.Printf("<br><br>\n");
1311 char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
1314 f.Printf($"<H3>See Also</H3><br>\n");
1317 char fileName[MAX_LOCATION];
1318 FigureFileName(fileName, module, classDoc, cl, seeAlso, null);
1319 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1324 f.Printf("<br>%s\n", seeAlsoDoc);
1325 f.Printf("<br><br>\n");
1329 f.Printf("</FONT></BODY></HTML>\n");
1333 class APIPageMethod : APIPage
1339 return method._class.module;
1342 NameSpace * GetNameSpace()
1344 return method._class.nameSpace;
1347 void Generate(File f)
1349 Class cl = method._class;
1351 Module module = cl.module;
1353 char nsName[1024], temp[1024];
1354 NameSpace * ns = cl.nameSpace;
1357 while(ns && ns->name)
1359 strcpy(temp, ns->name);
1360 if(nsName[0]) strcat(temp, "::");
1361 strcat(temp, nsName);
1362 strcpy(nsName, temp);
1366 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1367 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1369 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);
1371 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
1372 f.Printf("Class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl, cl.name);
1373 if(method.dataType.staticMethod)
1375 f.Printf($"this pointer class: None<br>\n");
1377 else if(method.dataType.thisClass && method.dataType.thisClass.registered && (method.dataType.thisClass.registered != method._class || method.type == virtualMethod))
1379 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);
1382 // Generate Method Page
1384 if(!method.dataType.name)
1385 method.dataType.name = CopyString(method.name);
1386 DocPrintType(method.dataType, string, true, false);
1387 f.Printf("<br>%s", string);
1390 char * desc = ReadDoc(module, methodDoc, method, description, null);
1393 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1396 char fileName[MAX_LOCATION];
1397 FigureFileName(fileName, module, methodDoc, method, description, null);
1398 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1403 f.Printf("%s", desc);
1408 f.Printf("<br><br>\n");
1409 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1411 f.Printf($"<H3>Parameters</H3><br><br>\n");
1413 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1414 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1416 f.Printf("<TABLE valign=center>\n");
1419 for(param = method.dataType.params.first; param; param = param.next)
1421 // ADD DESCRIPTION HERE
1422 if(param.kind != voidType)
1424 char * desc = ReadDoc(module, methodDoc, method, parameter, param);
1427 DocPrintType(param, string, false, false);
1429 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1430 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1435 char fileName[MAX_LOCATION];
1436 FigureFileName(fileName, module, methodDoc, method, parameter, param);
1437 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1439 f.Printf("</a></TD>\n");
1442 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1446 f.Printf("</TR>\n");
1449 if(method.dataType.returnType && method.dataType.returnType.kind != voidType)
1451 char * desc = ReadDoc(module, methodDoc, method, returnValue, null);
1452 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1454 f.Printf("<TR><TD> </TD></TR>");
1457 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1459 DocPrintType(method.dataType.returnType, string, false, false);
1460 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1465 char fileName[MAX_LOCATION];
1466 FigureFileName(fileName, module, methodDoc, method, returnValue, null);
1467 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1469 f.Printf("</a> </TD>\n");
1472 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1475 f.Printf("</TR>\n");
1476 f.Printf("</TABLE>\n");
1478 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1479 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1481 f.Printf("</TABLE><br>\n");
1484 char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
1487 f.Printf($"<H3>Usage</H3><br>\n");
1490 char fileName[MAX_LOCATION];
1491 FigureFileName(fileName, module, methodDoc, method, usage, null);
1492 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1497 f.Printf("<br>%s\n", usageDoc);
1498 f.Printf("<br><br>\n");
1503 char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
1506 f.Printf($"<H3>Example</H3><br>\n");
1507 f.Printf($"<FONT face=\"Courier New\">\n");
1508 f.Printf("<br><TABLE>\n");
1511 char fileName[MAX_LOCATION];
1512 FigureFileName(fileName, module, methodDoc, method, example, null);
1513 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1515 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1518 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1519 f.Printf("</TABLE></FONT>\n");
1525 char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
1528 f.Printf($"<H3>Remarks</H3><br>\n");
1531 char fileName[MAX_LOCATION];
1532 FigureFileName(fileName, module, methodDoc, method, remarks, null);
1533 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1538 f.Printf("<br>%s\n", method, remarksDoc);
1539 f.Printf("<br><br>\n");
1544 char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
1547 f.Printf($"<H3>See Also</H3><br>\n");
1550 char fileName[MAX_LOCATION];
1551 FigureFileName(fileName, module, methodDoc, method, seeAlso, null);
1552 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1557 f.Printf("<br>%s\n", method, seeAlsoDoc);
1559 f.Printf("<br><br>\n");
1563 f.Printf("</FONT></BODY></HTML>\n");
1567 class APIPageFunction : APIPage
1569 GlobalFunction function;
1573 return function.module;
1576 NameSpace * GetNameSpace()
1578 return function.nameSpace;
1581 void Generate(File f)
1584 Module module = function.module;
1586 char nsName[1024], temp[1024];
1587 NameSpace * ns = function.nameSpace;
1590 while(ns && ns->name)
1592 strcpy(temp, ns->name);
1593 if(nsName[0]) strcat(temp, "::");
1594 strcat(temp, nsName);
1595 strcpy(nsName, temp);
1599 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1600 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1602 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);
1605 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", function.nameSpace, nsName);
1607 if(!function.dataType)
1608 function.dataType = ProcessTypeString(function.dataTypeString, false);
1610 if(function.dataType.thisClass && function.dataType.thisClass.registered)
1612 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);
1615 // Generate Method Page
1617 if(!function.dataType.name)
1618 function.dataType.name = CopyString(function.name);
1619 DocPrintType(function.dataType, string, true, false);
1620 f.Printf("<br>%s", string);
1623 char * desc = ReadDoc(module, functionDoc, function, description, null);
1626 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1629 char fileName[MAX_LOCATION];
1630 FigureFileName(fileName, module, functionDoc, function, description, null);
1631 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1636 f.Printf("%s", desc);
1640 f.Printf("<br><br>\n");
1641 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1643 f.Printf($"<H3>Parameters</H3><br><br>\n");
1645 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1646 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1648 f.Printf("<TABLE valign=center>\n");
1651 for(param = function.dataType.params.first; param; param = param.next)
1653 // ADD DESCRIPTION HERE
1654 if(param.kind != voidType)
1656 char * desc = ReadDoc(module, functionDoc, function, parameter, param);
1659 DocPrintType(param, string, false, false);
1661 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1662 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1667 char fileName[MAX_LOCATION];
1668 FigureFileName(fileName, module, functionDoc, function, parameter, param);
1669 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1672 f.Printf("</a> </TD>\n");
1675 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1678 f.Printf("</TR>\n");
1681 if(function.dataType.returnType && function.dataType.returnType.kind != voidType)
1683 char * desc = ReadDoc(module, functionDoc, function, returnValue, null);
1684 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1686 f.Printf("<TR><TD> </TD></TR>");
1689 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1691 DocPrintType(function.dataType.returnType, string, false, false);
1692 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1697 char fileName[MAX_LOCATION];
1698 FigureFileName(fileName, module, functionDoc, function, returnValue, null);
1699 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1701 f.Printf("</a> </TD>\n");
1704 f.Printf("<TD valign=top height=22>%s </TD>\n", function, desc);
1707 f.Printf("</TR>\n");
1708 f.Printf("</TABLE>\n");
1710 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1711 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1713 f.Printf("</TABLE><br>\n");
1716 char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
1719 f.Printf($"<H3>Usage</H3><br>\n");
1722 char fileName[MAX_LOCATION];
1723 FigureFileName(fileName, module, functionDoc, function, usage, null);
1724 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1729 f.Printf("<br>%s\n", usageDoc);
1730 f.Printf("<br><br>\n");
1735 char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
1738 f.Printf($"<H3>Example</H3><br>\n");
1739 f.Printf($"<FONT face=\"Courier New\">\n");
1740 f.Printf("<br><TABLE>\n");
1743 char fileName[MAX_LOCATION];
1744 FigureFileName(fileName, module, functionDoc, function, example, null);
1745 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1747 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1750 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1751 f.Printf("</TABLE></FONT>\n");
1757 char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
1760 f.Printf($"<H3>Remarks</H3><br>\n");
1763 char fileName[MAX_LOCATION];
1764 FigureFileName(fileName, module, functionDoc, function, remarks, null);
1765 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1770 f.Printf("<br>%s\n", remarksDoc);
1771 f.Printf("<br><br>\n");
1776 char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
1779 f.Printf($"<H3>See Also</H3><br>\n");
1782 char fileName[MAX_LOCATION];
1783 FigureFileName(fileName, module, functionDoc, function, seeAlso, null);
1784 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1789 f.Printf("<br>%s\n", seeAlsoDoc);
1790 f.Printf("<br><br>\n");
1794 f.Printf("</FONT></BODY></HTML>\n");
1798 static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, const char * parentName, bool showPrivate)
1802 NameSpace * nameSpace = mainNameSpace;
1804 DataRow classesRow = null;
1805 DataRow functionsRow = null, definesRow = null;
1808 char fileName[MAX_LOCATION];
1810 strcpy(nsName, parentName ? parentName : "");
1814 strcat(nsName, "::");
1815 strcat(nsName, nameSpace->name);
1820 row = parentRow.AddRow();
1821 row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
1822 row.tag = (int64)nameSpace;
1823 row.icon = mainForm.icons[typeNameSpace];
1827 // "Global NameSpace"
1829 page = parentRow.GetData(null);
1835 for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1837 NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
1838 AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
1840 if(comNameSpace != null)
1842 for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1844 if(!mainNameSpace.nameSpaces.FindString(ns->name))
1846 AddNameSpace(row, module, ns, null, nsName, showPrivate);
1851 if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
1853 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1855 if(nameSpace->classes.first)
1859 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
1862 if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
1864 if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { $"Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
1865 AddClass(classesRow, module, cl, nsName, showPrivate);
1872 if(mainNameSpace.functions.first || (comNameSpace && comNameSpace.functions.first))
1874 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1876 if(nameSpace->functions.first)
1880 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
1883 if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
1885 const char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
1887 if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
1888 fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int64)fn;
1895 if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
1897 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1899 if(nameSpace->defines.first)
1903 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
1906 //if(def.module == module)
1908 char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
1910 if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
1911 defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int64)def;
1919 static void AddDataMemberToPage(File f, DataMember member, int indent, bool showPrivate)
1923 if(!member.dataType)
1924 member.dataType = ProcessTypeString(member.dataTypeString, false);
1928 DocPrintType(member.dataType, string, true, false);
1930 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a>", member);
1931 for(c = 0; c<indent; c++)
1932 f.Printf(" ");
1933 f.Printf("<img valign=center src=\"%s\"> %s</TD>", iconNames[typeData], member.name ? member.name : ((member.type == structMember) ? "(struct)" : "(union)"));
1934 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", (member.type == normalMember) ? string : "");
1935 if(member.type == normalMember)
1937 char * desc = ReadDoc(member._class.module, classDoc, member._class, memberDescription, member);
1942 char fileName[MAX_LOCATION];
1943 FigureFileName(fileName, member._class.module, classDoc, member._class, memberDescription, member);
1944 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1946 f.Printf("</a></TD>");
1949 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1954 f.Printf("<TD valign=top height=22></TD>");
1956 if(member.type != normalMember)
1958 DataMember subMember;
1959 for(subMember = member.members.first; subMember; subMember = subMember.next)
1961 if((subMember.memberAccess == publicAccess || (subMember.memberAccess == privateAccess && showPrivate)))
1963 AddDataMemberToPage(f, subMember, indent + 1, showPrivate);
1967 f.Printf("</TR><br>\n");
1970 static void AddDataMember(DataRow parentRow, APIPage page, DataMember member)
1973 if(member.type == normalMember)
1975 row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
1976 row.tag = (int64)member;
1981 row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
1982 row.icon = mainForm.icons[typeData];
1983 row.tag = (int64)member;
1985 for(m = member.members.first; m; m = m.next)
1987 if(m.memberAccess == publicAccess || (m.memberAccess == privateAccess && page.showPrivate))
1988 AddDataMember(row, page, m);
1993 static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
1995 char fileName[MAX_LOCATION];
2002 DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
2003 DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
2006 row = parentRow.AddRow();
2007 row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
2008 row.tag = (int64)cl;
2009 row.collapsed = true;
2010 row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
2013 if(cl.methods.first)
2015 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
2017 if(method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate))
2020 if(!method.dataType)
2021 ProcessMethodType(method);
2022 if(method.type == virtualMethod)
2024 if(method.dataType.thisClass)
2026 if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { $"Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
2027 mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
2028 mRow.tag = (int64)method;
2032 if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { $"Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
2033 mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2034 mRow.tag = (int64)method;
2039 if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { $"Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
2040 mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2041 mRow.tag = (int64)method;
2047 if(cl.membersAndProperties.first)
2049 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
2051 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
2054 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
2058 if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { $"Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
2059 mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
2060 mRow.tag = (int64)prop;
2064 if(!membersRow) { membersRow = row.AddRow(); membersRow.SetData(null, APIPage { $"Data Members", page = page }); membersRow.collapsed = true; membersRow.icon = mainForm.icons[typeData]; membersRow.tag = 6; }
2065 AddDataMember(membersRow, page, (DataMember)prop);
2071 if(cl.conversions.first)
2073 for(prop = cl.conversions.first; prop; prop = prop.next)
2077 if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { $"Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
2078 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
2079 if(name) name += 2; else name = prop.name;
2080 mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
2081 mRow.tag = (int64)prop;
2084 if(cl.type == enumClass)
2086 EnumClassData enumeration = (EnumClassData)cl.data;
2088 for(item = enumeration.values.first; item; item = item.next)
2091 if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
2092 mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
2093 mRow.tag = (int64)item;
2098 class AddressBar : Window
2100 background = activeBorder;
2104 this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, bitmap = { ":actions/docOpen.png" };
2106 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2108 MainForm mainForm = (MainForm)parent;
2109 FileDialog fileDialog = mainForm.fileDialog;
2110 if(fileDialog.Modal() == ok)
2111 mainForm.OpenModule(fileDialog.filePath);
2117 this, bevelOver = true, inactive = true, anchor = Anchor { left = 28, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
2120 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2122 ((MainForm)parent).Back();
2128 this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
2131 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2133 ((MainForm)parent).Forward();
2139 this, bevelOver = true, inactive = true, anchor = Anchor { left = 80, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
2141 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2143 ((MainForm)parent).Home();
2147 /* TODO: Search (#143/#441)
2148 When there's something in the search box, list matching sections, the exact match first,instead of the Hierarchy in the ListBox.
2149 Update this in the NotifyUpdate. Enter goes to the exact match.
2151 Label { this, anchor = Anchor { left = (124+12) }, labeledWindow = search };
2155 this, text = "Search:", anchor = Anchor { left = (16+48+124), right = 60, top = 0, bottom = 0 }, hotKey = altD;
2157 bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
2159 if(!disabled && (SmartKey)key == enter)
2160 ((MainForm)parent).Go(editBox.contents);
2164 void NotifyUpdate(EditBox editBox)
2166 String location = ((MainForm)parent).view.location;
2167 disabled = !strcmp(location ? location : "", editBox.contents);
2172 bool OnKeyHit(Key key, unichar ch)
2175 ((MainForm)parent).view.MakeActive();
2180 class MainForm : Window
2182 size = { 1000, 600 };
2184 borderStyle = sizable;
2187 icon = { ":documentorIcon.png" };
2188 text = $"API Documentation Browser";
2190 BitmapResource icons[CodeObjectType];
2195 for(c = 0; c < CodeObjectType::enumSize; c++)
2197 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2199 browser.AddField(DataField { dataType = class(APIPage) });
2204 Menu fileMenu { menu, $"File", f };
2205 Array<FileFilter> fileFilters
2207 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2208 { $"eC Symbol files (*.sym)", "sym" }
2211 FileDialog fileDialog
2213 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2215 MenuItem fileOpenItem
2217 fileMenu, $"Open...", o, ctrlO;
2219 bool NotifySelect(MenuItem selection, Modifiers mods)
2221 if(fileDialog.Modal() == ok)
2223 OpenModule(fileDialog.filePath);
2228 MenuItem fileSettingsItem
2230 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2232 bool NotifySelect(MenuItem selection, Modifiers mods)
2234 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2244 MenuDivider { fileMenu };
2245 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2247 void OpenModule(const char * filePath)
2249 char moduleName[MAX_LOCATION];
2250 char extension[MAX_EXTENSION];
2251 Module module = null;
2252 static char symbolsDir[MAX_LOCATION];
2256 FreeContext(globalContext);
2257 FreeExcludedSymbols(excludedSymbols);
2258 ::defines.Free(FreeModuleDefine);
2259 imports.Free(FreeModuleImport);
2261 FreeGlobalData(globalData);
2262 FreeTypeData(componentsApp);
2264 delete componentsApp;
2266 SetGlobalContext(globalContext);
2267 componentsApp = __ecere_COM_Initialize(false, 1, null);
2268 SetPrivateModule(componentsApp);
2270 StripLastDirectory(filePath, symbolsDir);
2271 SetSymbolsDir(symbolsDir);
2273 GetExtension(filePath, extension);
2275 mainForm.browser.Clear();
2277 ImportModule(filePath, normalImport, publicAccess, false);
2279 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
2280 componentsApp.name = CopyString(filePath);
2282 for(module = componentsApp.allModules.first; module; module = module.next)
2284 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2288 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2289 AddComponents(componentsApp, false);
2291 GetLastDirectory(filePath, moduleName);
2292 // Extension, path and lib prefix get removed in Module::name
2295 StripExtension(moduleName);
2296 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
2298 int len = strlen(moduleName) - 3;
2299 memmove(moduleName, moduleName + 3, len);
2300 moduleName[len] = 0;
2304 for(module = componentsApp.allModules.first; module; module = module.next)
2306 if(module.name && (!strcmp(module.name, moduleName)))
2309 if(!module) module = componentsApp;
2310 homeModule = module;
2311 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2313 SetSymbolsDir(null);
2316 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2319 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2320 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2323 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2325 APIPage page = row.GetData(null);
2326 if(view.edit) view.OnLeftButtonDown(0,0,0);
2327 if(page && page.page) page = page.page;
2329 view.PositionCaret(true);
2330 if(page != view.page)
2332 Window activeChild = this.activeChild;
2334 // Back / Forward Support
2335 if(row && !dontRecordHistory)
2337 if(history.count > historyPos+1)
2338 history.count = historyPos+1;
2339 historyPos = history.count-1;
2340 addressBar.back.disabled = (historyPos == 0);
2341 addressBar.forward.disabled = (historyPos >= history.count-1);
2343 history.Add((Instance)(uint64)row.tag);
2344 historyPos = history.count-1;
2346 addressBar.back.disabled = (historyPos == 0);
2347 addressBar.forward.disabled = (historyPos >= history.count-1);
2353 activeChild.Activate();
2355 else if(!view.created)
2359 page = row.GetData(null);
2360 if(page && page.page)
2364 case 1: view.GoToAnchor("Classes"); break;
2365 case 2: view.GoToAnchor("Functions"); break;
2366 case 3: view.GoToAnchor("Definitions"); break;
2367 case 4: view.GoToAnchor("VirtualMethods"); break;
2368 case 5: view.GoToAnchor("Methods"); break;
2369 case 6: view.GoToAnchor("Members"); break;
2370 case 7: view.GoToAnchor("Conversions"); break;
2371 case 8: view.GoToAnchor("EnumerationValues"); break;
2375 sprintf(hex, "%p", row.tag);
2376 view.GoToAnchor(hex);
2382 view.SetScrollPosition(0, 0);
2390 this, anchor = { top = 26, bottom = 0, right = 0 };
2395 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2398 bool OnClose(bool parentClosing)
2401 view.OnLeftButtonDown(0,0,0);
2407 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2408 //mainForm.OpenModule("ec");
2409 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2410 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2412 int index = mainForm.browser.currentRow.index;
2413 int rowHeight = mainForm.browser.rowHeight;
2414 int height = mainForm.browser.clientSize.h;
2416 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2421 Array<Instance> history { };
2423 bool dontRecordHistory;
2428 if(historyPos < history.count-1)
2432 addressBar.back.disabled = (historyPos == 0);
2433 addressBar.forward.disabled = (historyPos >= history.count-1);
2434 sprintf(location, "api://%p", history[historyPos]);
2435 dontRecordHistory = true;
2436 view.OnOpen(location);
2437 dontRecordHistory = false;
2449 addressBar.back.disabled = (historyPos == 0);
2450 addressBar.forward.disabled = (historyPos >= history.count-1);
2451 sprintf(location, "api://%p", history[historyPos]);
2452 dontRecordHistory = true;
2453 view.OnOpen(location);
2454 dontRecordHistory = false;
2462 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2466 class EditDialog : Window
2468 borderStyle = sizable;
2469 size = { 600, 400 };
2474 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2478 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2482 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2486 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2487 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2489 class HelpView : HTMLView
2493 hasVertScroll = true;
2494 hasHorzScroll = true;
2496 char editString[MAX_LOCATION];
2502 page = mainForm.browser.currentRow.GetData(null);
2507 char docFile[MAX_LOCATION];
2509 Module module = page ? page.GetModule() : null;
2510 NameSpace * ns = page ? page.GetNameSpace() : null;
2512 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2513 if(FileExists(docFile))
2515 archive = ArchiveOpen(docFile, { true } );
2516 readOnly = archive == null;
2522 archive = ArchiveOpen(docFile, { true } );
2525 // Must create root directory on archive creation
2526 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2538 GoToAnchor(page.label);
2540 if(page.page) page = page.page;
2543 return HTMLView::OnCreate();
2552 char archiveFile[MAX_LOCATION];
2553 char fileName[MAX_FILENAME];
2554 char directory[MAX_LOCATION];
2556 Archive archive = null;
2557 if(SplitArchivePath(editString, archiveFile, &location))
2559 GetLastDirectory(location, fileName);
2560 StripLastDirectory(location, directory);
2561 archive = ArchiveOpen(archiveFile, { true } );
2565 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2568 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2570 if(block.type == TEXT && block.textLen)
2578 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2580 if(block.type == BR)
2582 else if(block.type == TEXT)
2583 f.Write(block.text, 1, block.textLen);
2588 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2594 Block parent = textBlock.parent;
2595 while((block = parent.subBlocks.first))
2597 parent.subBlocks.Remove(block);
2600 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2601 textBlock.text = CopyString($"[Add Text]");
2602 textBlock.textLen = strlen(textBlock.text);
2603 parent.subBlocks.Add(textBlock);
2611 PositionCaret(true);
2617 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2621 if(edit && (!textBlock || overLink != textBlock.parent))
2625 HTMLView::OnLeftButtonDown(x, y, mods);
2626 selPosition = curPosition = 0;
2627 selBlock = textBlock;
2631 result = HTMLView::OnLeftButtonDown(x, y, mods);
2633 if(!edit && clickedLink)
2636 if(clickedLink == overLink && clickedLink.href)
2638 if(OnOpen(clickedLink.href))
2646 if(textBlock && overLink == textBlock.parent)
2648 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2649 selBlock = textBlock;
2650 PositionCaret(true);
2658 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2660 if(!edit || !textBlock || clickedLink != textBlock.parent)
2662 HTMLView::OnLeftButtonUp(x, y, mods);
2665 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2666 selBlock = textBlock;
2667 PositionCaret(true);
2678 bool OnMouseMove(int x, int y, Modifiers mods)
2680 if(edit && selecting)
2682 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2683 PositionCaret(true);
2686 return HTMLView::OnMouseMove(x, y, mods);
2689 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2691 if(edit && textBlock)
2697 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2698 selBlock = textBlock;
2699 for(c = curPosition; c >= 0; c--)
2702 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2703 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2704 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2710 for(c = start; c < textBlock.textLen; c += numBytes)
2712 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2713 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2716 selPosition = start;
2719 PositionCaret(true);
2727 bool OnOpen(char * href)
2729 if(!strncmp(href, "api://", 6))
2731 int64 tag = (int64)strtoull(href + 6, null, 16);
2732 DataRow row = mainForm.browser.FindSubRow(tag);
2736 mainForm.browser.SelectRow(row);
2737 while((row = row.parent))
2738 row.collapsed = false;
2739 row = mainForm.browser.currentRow;
2740 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2743 else if(!strncmp(href, "edit://", 7))
2746 int startX = clickedLink.startX, startY = clickedLink.startY;
2747 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2749 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2750 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2752 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2754 display.FontExtent(block.font.font, " ", 1, null, &th);
2757 block.parent.subBlocks.Insert(null, newBlock);
2762 block.parent.subBlocks.Insert(block, newBlock);
2763 startY += block.prev.height;
2765 newBlock.startX = startX;
2766 newBlock.startY = startY;
2767 newBlock.text = new0 char[1];
2771 textBlock = (Block)clickedLink.subBlocks.first;
2772 if(!strcmp(textBlock.text, $"[Add Text]"))
2774 textBlock.text[0] = 0;
2775 textBlock.textLen = 0;
2778 strcpy(editString, href + 7);
2779 selPosition = curPosition = 0;
2780 selBlock = textBlock;
2783 // PositionCaret(true);
2790 void DeleteSelection()
2792 if(textBlock != selBlock || curPosition != selPosition)
2794 if(textBlock == selBlock)
2796 // Within same block
2797 int start = Min(curPosition, selPosition);
2798 int end = Max(curPosition, selPosition);
2799 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2800 textBlock.textLen -= end-start;
2801 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2802 curPosition = start;
2803 selPosition = start;
2807 int startSel, endSel;
2808 Block startSelBlock = null, endSelBlock = null, b, next;
2810 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2812 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2813 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2815 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2816 for(b = startSelBlock.next; b; b = next)
2818 bool isEnd = b == endSelBlock;
2819 next = GetNextBlock(b);
2820 b.parent.subBlocks.Remove(b);
2825 textBlock = startSelBlock;
2826 selBlock = startSelBlock;
2827 curPosition = startSel;
2828 selPosition = startSel;
2832 PositionCaret(true);
2837 String GetSelectionString()
2839 String selection = null;
2840 if(textBlock == selBlock)
2842 // Within same block
2843 int start = Min(curPosition, selPosition);
2844 int end = Max(curPosition, selPosition);
2845 int len = end - start;
2846 selection = new char[len + 1];
2847 memcpy(selection, textBlock.text + start, len);
2852 int startSel, endSel;
2853 Block startSelBlock = null, endSelBlock = null, b;
2856 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2859 for(b = startSelBlock; b; b = GetNextBlock(b))
2861 int start = (b == startSelBlock) ? startSel : 0;
2862 int end = (b == endSelBlock) ? endSel : b.textLen;
2863 int len = end - start;
2865 if(b == endSelBlock)
2867 else if(b.type == TEXT)
2871 selection = new char[totalLen + 1];
2873 for(b = startSelBlock; b; b = GetNextBlock(b))
2875 int start = (b == startSelBlock) ? startSel : 0;
2876 int end = (b == endSelBlock) ? endSel : b.textLen;
2877 int len = end - start;
2878 memcpy(selection + totalLen, b.text + start, len);
2880 if(b == endSelBlock)
2882 else if(b.type == TEXT)
2883 selection[totalLen++] = '\n';
2885 selection[totalLen] = 0;
2890 void CopySelection()
2892 String s = GetSelectionString();
2895 int len = strlen(s);
2897 if(cb.Allocate(len + 1))
2899 memcpy(cb.text, s, len + 1);
2907 bool OnKeyDown(Key key, unichar ch)
2914 OnLeftButtonDown(0,0,0);
2916 case Key { end, shift = true }:
2918 curPosition = textBlock.textLen;
2921 selPosition = curPosition;
2922 selBlock = textBlock;
2924 PositionCaret(true);
2927 case Key { home, shift = true }:
2932 selPosition = curPosition;
2933 selBlock = textBlock;
2935 PositionCaret(true);
2938 case Key { home, ctrl = true, shift = true }:
2941 while(textBlock.prev)
2942 textBlock = textBlock.prev.prev;
2945 selPosition = curPosition;
2946 selBlock = textBlock;
2948 PositionCaret(true);
2951 case Key { end, ctrl = true, shift = true }:
2953 while(textBlock.next && textBlock.next.next)
2954 textBlock = textBlock.next.next;
2955 curPosition = textBlock.textLen;
2958 selPosition = curPosition;
2959 selBlock = textBlock;
2961 PositionCaret(true);
2967 return HTMLView::OnKeyDown(key, ch);
2971 bool OnKeyHit(Key key, unichar ch)
2977 case Key { up, shift = true }:
2980 if(caretY == textBlock.startY)
2984 textBlock = textBlock.prev.prev;
2985 curPosition = Min(curPosition, textBlock.textLen);
2988 selPosition = curPosition;
2989 selBlock = textBlock;
2992 PositionCaret(false);
3002 int sx = textBlock.startX, sy = textBlock.startY;
3003 char * text = textBlock.text;
3005 Block block = textBlock;
3006 while(block && block.type != TD) block = block.parent;
3009 Block table = block;
3010 while(table && table.type != TABLE) table = table.parent;
3012 maxW = block.w - 2* table.cellPadding;
3014 maxW = clientSize.w - 10 - sx;
3017 maxW = clientSize.w - 10 - sx;
3018 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3022 int startPos = textPos;
3025 bool lineComplete = false;
3026 for(; textPos<textBlock.textLen && !lineComplete;)
3030 char * nextSpace = strchr(text + textPos, ' ');
3033 len = (nextSpace - (text + textPos)) + 1;
3035 len = textBlock.textLen - textPos;
3037 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3039 if(x + width + w > maxW && x > 0)
3041 lineComplete = true;
3051 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3054 curPosition = textPos;
3055 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3058 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3059 len = curPosition - startPos;
3060 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3064 selPosition = curPosition;
3065 selBlock = textBlock;
3069 PositionCaret(false);
3073 if(sy == caretY - th || textPos == textBlock.textLen)
3075 if(textPos != textBlock.textLen)
3077 int c = textPos - 1;
3078 while(c > 0 && text[c] == ' ') c--;
3079 curPosition = c + 1;
3082 selPosition = curPosition;
3083 selBlock = textBlock;
3089 curPosition = textBlock.textLen;
3092 selPosition = curPosition;
3093 selBlock = textBlock;
3097 PositionCaret(false);
3101 sx = textBlock.startX;
3102 } while(textPos < textBlock.textLen);
3107 case Key { down, shift = true }:
3112 int sx = textBlock.startX, sy = textBlock.startY;
3113 char * text = textBlock.text;
3115 Block block = textBlock;
3116 while(block && block.type != TD) block = block.parent;
3119 Block table = block;
3120 while(table && table.type != TABLE) table = table.parent;
3122 maxW = block.w - 2* table.cellPadding;
3124 maxW = clientSize.w - 10 - sx;
3127 maxW = clientSize.w - 10 - sx;
3128 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3130 while(!textPos || textPos < textBlock.textLen)
3132 int startPos = textPos;
3135 bool lineComplete = false;
3136 for(; (textPos < textBlock.textLen) && !lineComplete;)
3140 char * nextSpace = strchr(text + textPos, ' ');
3143 len = (nextSpace - (text + textPos)) + 1;
3145 len = textBlock.textLen - textPos;
3147 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3149 if(x + width + w > maxW && x > 0)
3151 lineComplete = true;
3161 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3163 curPosition = textPos;
3165 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3168 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3169 len = curPosition - startPos;
3170 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3174 selPosition = curPosition;
3175 selBlock = textBlock;
3178 PositionCaret(false);
3184 curPosition = textBlock.textLen;
3187 selPosition = curPosition;
3188 selBlock = textBlock;
3191 PositionCaret(false);
3194 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3198 textBlock = textBlock.next.next;
3199 sy = textBlock.startY;
3200 sx = textBlock.startX;
3201 text = textBlock.text;
3206 sx = textBlock.startX;
3210 /*if(textBlock.next && textBlock.next.next)
3212 textBlock = textBlock.next.next;
3213 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3214 selBlock = textBlock;
3215 PositionCaret(false);
3219 case Key { right, shift = true, ctrl = true }:
3222 bool foundAlpha = false;
3224 Block line, lastLine;
3227 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3229 int start = (line == textBlock) ? curPosition : 0;
3231 for(c = start; c < line.textLen; c++)
3233 char ch = line.text[c];
3234 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3235 if(key.shift ? isAlUnder : !isAlUnder)
3249 selPosition = curPosition;
3250 selBlock = textBlock;
3254 PositionCaret(true);
3259 // No next word found,
3260 if(!found && (c != curPosition || line != textBlock))
3264 lastC = line.textLen-1;
3269 curPosition = line.textLen;
3272 selPosition = curPosition;
3273 selBlock = textBlock;
3278 PositionCaret(true);
3284 if(key.shift && found)
3286 curPosition = lastC+1;
3287 textBlock = lastLine;
3288 PositionCaret(true);
3293 case Key { left, ctrl = true, shift = true }:
3296 bool foundAlpha = false;
3298 Block line, lastLine;
3301 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3304 if(curPosition == 0 && line != textBlock)
3307 lastC = line.textLen;
3311 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3312 for(c = start; c>=0; c--)
3314 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3329 // No next word found,
3330 if(!found && curPosition > 0)
3340 textBlock = lastLine;
3341 curPosition = lastC;
3344 selPosition = curPosition;
3345 selBlock = textBlock;
3347 PositionCaret(true);
3352 case Key { right, shift = true }:
3354 if(curPosition < textBlock.textLen)
3356 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3359 selPosition = curPosition;
3360 selBlock = textBlock;
3362 PositionCaret(true);
3365 else if(textBlock.next && textBlock.next.next)
3367 textBlock = textBlock.next.next;
3371 selPosition = curPosition;
3372 selBlock = textBlock;
3374 PositionCaret(true);
3378 case Key { left, shift = true }:
3382 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3385 selPosition = curPosition;
3386 selBlock = textBlock;
3388 PositionCaret(true);
3391 else if(textBlock.prev)
3393 textBlock = textBlock.prev.prev;
3394 curPosition = textBlock.textLen;
3397 selPosition = curPosition;
3398 selBlock = textBlock;
3400 PositionCaret(true);
3406 if(textBlock == selBlock && curPosition == selPosition)
3410 int c = curPosition;
3412 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3413 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3414 textBlock.textLen -= nb;
3415 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3417 selPosition = curPosition;
3418 selBlock = textBlock;
3422 PositionCaret(true);
3425 else if(textBlock.prev)
3427 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3428 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3429 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3431 selPosition = curPosition = prevBlock.textLen;
3432 selBlock = textBlock;
3433 prevBlock.textLen += textBlock.textLen;
3434 textBlock.parent.subBlocks.Remove(prev);
3435 if(prev == selBlock)
3437 selBlock = textBlock;
3438 selPosition = curPosition;
3441 textBlock.parent.subBlocks.Remove(textBlock);
3442 if(textBlock == selBlock)
3444 selBlock = prevBlock;
3445 selPosition = curPosition;
3448 textBlock = prevBlock;
3452 PositionCaret(true);
3461 if(textBlock != selBlock || curPosition != selPosition)
3463 else if(textBlock.textLen > curPosition)
3465 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3466 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3467 textBlock.textLen -= nb;
3468 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3473 PositionCaret(true);
3476 else if(textBlock.next && textBlock.next.next)
3478 Block next = textBlock.next, nextBlock = textBlock.next.next;
3479 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3480 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3482 textBlock.textLen += nextBlock.textLen;
3483 textBlock.parent.subBlocks.Remove(next);
3484 if(next == selBlock)
3486 selBlock = textBlock;
3487 selPosition = curPosition;
3490 textBlock.parent.subBlocks.Remove(nextBlock);
3491 if(nextBlock == selBlock)
3493 selBlock = textBlock;
3494 selPosition = curPosition;
3500 PositionCaret(true);
3514 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3515 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3516 startY = textBlock.startY;
3517 startX = textBlock.startX;
3519 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3520 textBlock.parent.subBlocks.Insert(textBlock, block);
3521 textBlock.parent.subBlocks.Insert(block, newBlock);
3525 newBlock.textLen = textBlock.textLen - curPosition;
3526 newBlock.text = new char[newBlock.textLen+1];
3527 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3528 textBlock.textLen = curPosition;
3529 textBlock.text[curPosition] = 0;
3531 newBlock.startY = startY;
3532 newBlock.startX = startX;
3533 selPosition = curPosition = 0;
3538 textBlock = newBlock;
3539 selBlock = textBlock;
3540 PositionCaret(true);
3545 case Key { del, shift = true }:
3560 ClipBoard clipBoard { };
3561 if(clipBoard.Load())
3564 char * text = clipBoard.memory;
3572 parent = textBlock.parent;
3573 font = textBlock.font;
3578 if(ch == '\n' || ch == '\r' || !ch)
3580 int len = c - start;
3581 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3582 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3583 memcpy(textBlock.text + curPosition, text + start, len);
3584 textBlock.textLen += len;
3586 selPosition = curPosition;
3587 selBlock = textBlock;
3590 Block block { type = BR, parent = parent, font = font };
3591 Block newBlock { type = TEXT, parent = parent, font = font };
3592 int startY = textBlock.startY, startX = textBlock.startX;
3595 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3596 textBlock.parent.subBlocks.Insert(textBlock, block);
3597 textBlock.parent.subBlocks.Insert(block, newBlock);
3601 newBlock.textLen = textBlock.textLen - curPosition;
3602 newBlock.text = new char[newBlock.textLen+1];
3603 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3604 textBlock.textLen = curPosition;
3605 textBlock.text[curPosition] = 0;
3607 newBlock.startY = startY;
3608 newBlock.startX = startX;
3609 selPosition = curPosition = 0;
3610 selBlock = textBlock;
3611 textBlock = newBlock;
3613 if(ch == '\r' && text[c+1] == '\n') c++;
3619 PositionCaret(true);
3627 // eC BUG HERE: (Should be fixed)
3628 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3631 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3636 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3637 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3639 for(c = 0; c<len; c++)
3641 textBlock.text[curPosition] = string[c];
3642 textBlock.textLen++;
3645 selPosition = curPosition;
3646 selBlock = textBlock;
3649 //Clear(html.block);
3650 //CreateForms(html.block);
3655 PositionCaret(true);
3664 void OnResize(int width, int height)
3666 HTMLView::OnResize(width, height);
3667 PositionCaret(true);
3671 void PositionCaret(bool setCaretX)
3677 int sx = textBlock.startX, sy = textBlock.startY;
3678 char * text = textBlock.text;
3680 Block block = textBlock;
3681 while(block && block.type != TD) block = block.parent;
3684 Block table = block;
3685 while(table && table.type != TABLE) table = table.parent;
3687 maxW = block.w - 2* table.cellPadding;
3689 maxW = clientSize.w - 10 - sx;
3692 maxW = clientSize.w - 10 - sx;
3694 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3696 while(textPos < textBlock.textLen)
3698 int startPos = textPos;
3701 bool lineComplete = false;
3703 for(; textPos<textBlock.textLen && !lineComplete;)
3707 char * nextSpace = strchr(text + textPos, ' ');
3710 len = (nextSpace - (text + textPos)) + 1;
3712 len = textBlock.textLen - textPos;
3714 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3716 if(x + width + w > maxW && x > 0)
3718 lineComplete = true;
3731 if(curPosition < textPos || textPos == textBlock.textLen)
3733 int len = curPosition - startPos;
3734 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3739 sx = textBlock.startX;
3744 SetCaret(sx, sy, th);
3746 Point scrollPos = scroll;
3747 bool doScroll = false;
3748 if(sy - scroll.y + th > clientSize.h)
3750 scrollPos.y = sy + th - clientSize.h;
3753 else if(sy - scroll.y < 0)
3758 if(sx - scroll.x + 10 > clientSize.w)
3760 scrollPos.x = sx + 10 - clientSize.w;
3763 else if(sx - scroll.x < 10)
3765 scrollPos.x = sx - 10;
3776 // Returns a character offset into the TextBlock from a window coordinate
3777 int TextPosFromPoint(int px, int py, Block * block, bool half)
3779 Block parentBlock = this.textBlock.parent;
3782 *block = this.textBlock;
3787 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3789 int sx = textBlock.startX, sy = textBlock.startY;
3792 char * text = textBlock.text;
3794 Block b = textBlock;
3797 if(textBlock.type != TEXT) continue;
3799 while(b && b.type != TD) b = b.parent;
3803 while(table && table.type != TABLE) table = table.parent;
3805 maxW = b.w - 2* table.cellPadding;
3807 maxW = clientSize.w - 10 - sx;
3810 maxW = clientSize.w - 10 - sx;
3812 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3813 //space = space/2+2;
3816 while(textPos < textBlock.textLen)
3818 int startPos = textPos;
3821 bool lineComplete = false;
3823 for(; textPos<textBlock.textLen && !lineComplete;)
3827 char * nextSpace = strchr(text + textPos, ' ');
3830 len = (nextSpace - (text + textPos)) + 1;
3832 len = textBlock.textLen - textPos;
3834 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3836 sx = x + textBlock.startX;
3837 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3842 for(c = textPos; (ch = text[c]); c += numBytes)
3844 numBytes = UTF8_NUM_BYTES(ch);
3845 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3846 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3853 if(x + width + w > maxW && x > 0)
3855 lineComplete = true;
3868 if(/*py >= sy && */py < sy + th)
3871 return textBlock.textLen;
3876 result = textBlock.textLen;
3882 Application componentsApp;
3884 class Documentor : GuiApplication
3888 Platform os = GetRuntimePlatform();
3889 componentsApp = __ecere_COM_Initialize(false, 1, null);
3890 SetPrivateModule(componentsApp);
3891 SetGlobalContext(globalContext);
3892 SetExcludedSymbols(&excludedSymbols);
3893 SetDefines(&::defines);
3894 SetImports(&imports);
3896 SetGlobalData(globalData);
3898 settingsContainer.dataOwner = &settings;
3899 settingsContainer.Load();
3900 if(!settings.docDir || !settings.docDir[0] )
3902 if(os == win32) // if Windows OS then
3904 char programFilesDir[MAX_LOCATION];
3905 char appData[MAX_LOCATION];
3906 char homeDrive[MAX_LOCATION];
3907 char winDir[MAX_LOCATION];
3908 GetEnvironment("APPDATA", appData, sizeof(appData));
3909 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3910 GetEnvironment("windir", winDir, sizeof(winDir));
3911 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3913 PathCat(programFilesDir, "ECERE SDK\\doc");
3914 settings.docDir = programFilesDir;
3916 else if(homeDrive && homeDrive[0])
3918 PathCat(homeDrive, "ECERE SDK\\doc");
3919 settings.docDir = homeDrive;
3921 else if(winDir && winDir[0])
3923 PathCat(winDir, "..\\ECERE SDK\\doc");
3924 settings.docDir = winDir;
3927 settings.docDir = "C:\\ECERE SDK\\doc";
3929 else // if Os is Linux, or Mac OSX or something else
3930 settings.docDir = "/usr/share/ecere/doc/";
3931 settingsContainer.Save();
3937 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3939 AddComponents(module, true);
3940 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3941 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3942 while((row = row.parent))
3943 row.collapsed = false;
3947 commandThread.Create();
3951 bool Cycle(bool idle)
3954 mainForm.Destroy(0);
3963 if(commandThread.created)
3965 console.CloseInput();
3966 console.CloseOutput();
3968 commandThread.Wait();
3972 FreeContext(globalContext);
3973 FreeExcludedSymbols(excludedSymbols);
3974 ::defines.Free(FreeModuleDefine);
3975 imports.Free(FreeModuleImport);
3977 FreeGlobalData(globalData);
3978 FreeTypeData(componentsApp);
3980 delete componentsApp;
3984 ConsoleFile console { };
3985 MainForm mainForm { };
3988 Thread commandThread
3995 console.GetLine(command, sizeof(command));
3996 if(!quit && command[0])
3999 if(!strcmpi(command, "Activate"))
4000 mainForm.Activate();
4001 else if(!strcmpi(command, "Quit"))