5 import "SettingsDialog"
7 uint64 strtoull(const char * nptr, char ** endptr, int base);
9 static Context globalContext { };
10 static OldList defines { };
11 static OldList imports { };
12 static NameSpace globalData;
13 static OldList excludedSymbols { offset = (uint)&((Symbol)0).left };
16 define app = (GuiApplication)__thisModule.application;
18 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
21 /*extern */int __ecereVMethodID_class_OnGetString;
28 a.OnGetString(null, null, null);
31 static bool editing = true;
33 enum CodeObjectType { typeClass, typeData, typeMethod, typeEvent, typeProperty, typeNameSpace, typeDataType, typeEnumValue, typeDataPrivate, typeMethodPrivate, typePropertyPrivate };
35 static char * iconNames[CodeObjectType] =
37 "<:ecere>constructs/class.png",
38 "<:ecere>constructs/data.png",
39 "<:ecere>constructs/method.png",
40 "<:ecere>constructs/event.png",
41 "<:ecere>constructs/property.png",
42 "<:ecere>constructs/namespace.png",
43 "<:ecere>constructs/dataType.png",
44 "<:ecere>constructs/enumValue.png",
45 "<:ecere>constructs/dataPrivate.png",
46 "<:ecere>constructs/methodPrivate.png",
47 "<:ecere>constructs/propertyPrivate.png"
50 IDESettings settings { }; // instantiate the IDESettings class from the IDESettings.ec file. Do this at a global level so that all methods can access settings.
52 IDESettingsContainer settingsContainer
56 dataOwner = &settings;
59 void GetTemplateString(Class c, char * templateString)
61 Module m = c.module.application;
63 char * lt = strchr(n, '<');
69 memcpy(templateString, n, lt-n);
70 templateString[lt-n] = 0;
71 strcat(templateString, "</a>");
73 for(s = lt; (ch = *s); s++)
75 if(ch == '<' || ch == '>' || ch == ',')
80 char * d = templateString + strlen(templateString);
82 pc = eSystem_FindClass(m, curName);
84 sprintf(d, "<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", pc, pc.name);
89 strcat(templateString, "<");
91 strcat(templateString, ">");
93 strcat(templateString, ", ");
100 curName[len++] = ' ';
102 strcat(templateString, curName);
110 // WARNING : This function expects a null terminated string since it recursively concatenate...
111 static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
118 if(type._class && type._class.string)
121 strcat(string, type._class.string);
124 if(type._class.registered)
127 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 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 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 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 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 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, 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 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 nativeDecorations = true;
2188 icon = { ":documentorIcon.png" };
2189 text = $"API Documentation Browser";
2191 BitmapResource icons[CodeObjectType];
2196 for(c = 0; c < CodeObjectType::enumSize; c++)
2198 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2200 browser.AddField(DataField { dataType = class(APIPage) });
2205 Menu fileMenu { menu, $"File", f };
2206 Array<FileFilter> fileFilters
2208 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2209 { $"eC Symbol files (*.sym)", "sym" }
2212 FileDialog fileDialog
2214 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2216 MenuItem fileOpenItem
2218 fileMenu, $"Open...", o, ctrlO;
2220 bool NotifySelect(MenuItem selection, Modifiers mods)
2222 if(fileDialog.Modal() == ok)
2224 OpenModule(fileDialog.filePath);
2229 MenuItem fileSettingsItem
2231 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2233 bool NotifySelect(MenuItem selection, Modifiers mods)
2235 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2245 MenuDivider { fileMenu };
2246 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2248 void OpenModule(char * filePath)
2250 char moduleName[MAX_LOCATION];
2251 char extension[MAX_EXTENSION];
2252 Module module = null;
2253 static char symbolsDir[MAX_LOCATION];
2257 FreeContext(globalContext);
2258 FreeExcludedSymbols(excludedSymbols);
2259 ::defines.Free(FreeModuleDefine);
2260 imports.Free(FreeModuleImport);
2262 FreeGlobalData(globalData);
2263 FreeTypeData(componentsApp);
2265 delete componentsApp;
2267 SetGlobalContext(globalContext);
2268 componentsApp = __ecere_COM_Initialize(false, 1, null);
2269 SetPrivateModule(componentsApp);
2271 StripLastDirectory(filePath, symbolsDir);
2272 SetSymbolsDir(symbolsDir);
2274 GetExtension(filePath, extension);
2276 mainForm.browser.Clear();
2278 ImportModule(filePath, normalImport, publicAccess, false);
2280 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
2281 componentsApp.name = CopyString(filePath);
2283 for(module = componentsApp.allModules.first; module; module = module.next)
2285 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2289 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2290 AddComponents(componentsApp, false);
2292 GetLastDirectory(filePath, moduleName);
2293 // Extension, path and lib prefix get removed in Module::name
2296 StripExtension(moduleName);
2297 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
2299 int len = strlen(moduleName) - 3;
2300 memmove(moduleName, moduleName + 3, len);
2301 moduleName[len] = 0;
2305 for(module = componentsApp.allModules.first; module; module = module.next)
2307 if(module.name && (!strcmp(module.name, moduleName)))
2310 if(!module) module = componentsApp;
2311 homeModule = module;
2312 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2314 SetSymbolsDir(null);
2317 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2320 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2321 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2324 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2326 APIPage page = row.GetData(null);
2327 if(view.edit) view.OnLeftButtonDown(0,0,0);
2328 if(page && page.page) page = page.page;
2330 view.PositionCaret(true);
2331 if(page != view.page)
2333 Window activeChild = this.activeChild;
2335 // Back / Forward Support
2336 if(row && !dontRecordHistory)
2338 if(history.count > historyPos+1)
2339 history.count = historyPos+1;
2340 historyPos = history.count-1;
2341 addressBar.back.disabled = (historyPos == 0);
2342 addressBar.forward.disabled = (historyPos >= history.count-1);
2344 history.Add((Instance)(uint64)row.tag);
2345 historyPos = history.count-1;
2347 addressBar.back.disabled = (historyPos == 0);
2348 addressBar.forward.disabled = (historyPos >= history.count-1);
2354 activeChild.Activate();
2356 else if(!view.created)
2360 page = row.GetData(null);
2361 if(page && page.page)
2365 case 1: view.GoToAnchor("Classes"); break;
2366 case 2: view.GoToAnchor("Functions"); break;
2367 case 3: view.GoToAnchor("Definitions"); break;
2368 case 4: view.GoToAnchor("VirtualMethods"); break;
2369 case 5: view.GoToAnchor("Methods"); break;
2370 case 6: view.GoToAnchor("Members"); break;
2371 case 7: view.GoToAnchor("Conversions"); break;
2372 case 8: view.GoToAnchor("EnumerationValues"); break;
2376 sprintf(hex, "%p", row.tag);
2377 view.GoToAnchor(hex);
2383 view.SetScrollPosition(0, 0);
2391 this, anchor = { top = 26, bottom = 0, right = 0 };
2396 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2399 bool OnClose(bool parentClosing)
2402 view.OnLeftButtonDown(0,0,0);
2408 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2409 //mainForm.OpenModule("ec");
2410 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2411 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2413 int index = mainForm.browser.currentRow.index;
2414 int rowHeight = mainForm.browser.rowHeight;
2415 int height = mainForm.browser.clientSize.h;
2417 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2422 Array<Instance> history { };
2424 bool dontRecordHistory;
2429 if(historyPos < history.count-1)
2433 addressBar.back.disabled = (historyPos == 0);
2434 addressBar.forward.disabled = (historyPos >= history.count-1);
2435 sprintf(location, "api://%p", history[historyPos]);
2436 dontRecordHistory = true;
2437 view.OnOpen(location);
2438 dontRecordHistory = false;
2450 addressBar.back.disabled = (historyPos == 0);
2451 addressBar.forward.disabled = (historyPos >= history.count-1);
2452 sprintf(location, "api://%p", history[historyPos]);
2453 dontRecordHistory = true;
2454 view.OnOpen(location);
2455 dontRecordHistory = false;
2463 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2467 class EditDialog : Window
2469 borderStyle = sizable;
2470 size = { 600, 400 };
2475 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2479 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2483 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2487 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2488 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2490 class HelpView : HTMLView
2494 hasVertScroll = true;
2495 hasHorzScroll = true;
2497 char editString[MAX_LOCATION];
2503 page = mainForm.browser.currentRow.GetData(null);
2508 char docFile[MAX_LOCATION];
2510 Module module = page ? page.GetModule() : null;
2511 NameSpace * ns = page ? page.GetNameSpace() : null;
2513 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2514 if(FileExists(docFile))
2516 archive = ArchiveOpen(docFile, { true } );
2517 readOnly = archive == null;
2523 archive = ArchiveOpen(docFile, { true } );
2526 // Must create root directory on archive creation
2527 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2539 GoToAnchor(page.label);
2541 if(page.page) page = page.page;
2544 return HTMLView::OnCreate();
2553 char archiveFile[MAX_LOCATION];
2554 char fileName[MAX_FILENAME];
2555 char directory[MAX_LOCATION];
2557 Archive archive = null;
2558 if(SplitArchivePath(editString, archiveFile, &location))
2560 GetLastDirectory(location, fileName);
2561 StripLastDirectory(location, directory);
2562 archive = ArchiveOpen(archiveFile, { true } );
2566 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2569 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2571 if(block.type == TEXT && block.textLen)
2579 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2581 if(block.type == BR)
2583 else if(block.type == TEXT)
2584 f.Write(block.text, 1, block.textLen);
2589 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2595 Block parent = textBlock.parent;
2596 while((block = parent.subBlocks.first))
2598 parent.subBlocks.Remove(block);
2601 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2602 textBlock.text = CopyString($"[Add Text]");
2603 textBlock.textLen = strlen(textBlock.text);
2604 parent.subBlocks.Add(textBlock);
2612 PositionCaret(true);
2618 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2622 if(edit && (!textBlock || overLink != textBlock.parent))
2626 HTMLView::OnLeftButtonDown(x, y, mods);
2627 selPosition = curPosition = 0;
2628 selBlock = textBlock;
2632 result = HTMLView::OnLeftButtonDown(x, y, mods);
2634 if(!edit && clickedLink)
2637 if(clickedLink == overLink && clickedLink.href)
2639 if(OnOpen(clickedLink.href))
2647 if(textBlock && overLink == textBlock.parent)
2649 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2650 selBlock = textBlock;
2651 PositionCaret(true);
2659 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2661 if(!edit || !textBlock || clickedLink != textBlock.parent)
2663 HTMLView::OnLeftButtonUp(x, y, mods);
2666 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2667 selBlock = textBlock;
2668 PositionCaret(true);
2679 bool OnMouseMove(int x, int y, Modifiers mods)
2681 if(edit && selecting)
2683 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2684 PositionCaret(true);
2687 return HTMLView::OnMouseMove(x, y, mods);
2690 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2692 if(edit && textBlock)
2698 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2699 selBlock = textBlock;
2700 for(c = curPosition; c >= 0; c--)
2703 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2704 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2705 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2711 for(c = start; c < textBlock.textLen; c += numBytes)
2713 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2714 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2717 selPosition = start;
2720 PositionCaret(true);
2728 bool OnOpen(char * href)
2730 if(!strncmp(href, "api://", 6))
2732 int64 tag = (int64)strtoull(href + 6, null, 16);
2733 DataRow row = mainForm.browser.FindSubRow(tag);
2737 mainForm.browser.SelectRow(row);
2738 while((row = row.parent))
2739 row.collapsed = false;
2740 row = mainForm.browser.currentRow;
2741 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2744 else if(!strncmp(href, "edit://", 7))
2747 int startX = clickedLink.startX, startY = clickedLink.startY;
2748 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2750 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2751 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2753 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2755 display.FontExtent(block.font.font, " ", 1, null, &th);
2758 block.parent.subBlocks.Insert(null, newBlock);
2763 block.parent.subBlocks.Insert(block, newBlock);
2764 startY += block.prev.height;
2766 newBlock.startX = startX;
2767 newBlock.startY = startY;
2768 newBlock.text = new0 char[1];
2772 textBlock = (Block)clickedLink.subBlocks.first;
2773 if(!strcmp(textBlock.text, $"[Add Text]"))
2775 textBlock.text[0] = 0;
2776 textBlock.textLen = 0;
2779 strcpy(editString, href + 7);
2780 selPosition = curPosition = 0;
2781 selBlock = textBlock;
2784 // PositionCaret(true);
2791 void DeleteSelection()
2793 if(textBlock != selBlock || curPosition != selPosition)
2795 if(textBlock == selBlock)
2797 // Within same block
2798 int start = Min(curPosition, selPosition);
2799 int end = Max(curPosition, selPosition);
2800 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2801 textBlock.textLen -= end-start;
2802 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2803 curPosition = start;
2804 selPosition = start;
2808 int startSel, endSel;
2809 Block startSelBlock = null, endSelBlock = null, b, next;
2811 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2813 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2814 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2816 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2817 for(b = startSelBlock.next; b; b = next)
2819 bool isEnd = b == endSelBlock;
2820 next = GetNextBlock(b);
2821 b.parent.subBlocks.Remove(b);
2826 textBlock = startSelBlock;
2827 selBlock = startSelBlock;
2828 curPosition = startSel;
2829 selPosition = startSel;
2833 PositionCaret(true);
2838 String GetSelectionString()
2840 String selection = null;
2841 if(textBlock == selBlock)
2843 // Within same block
2844 int start = Min(curPosition, selPosition);
2845 int end = Max(curPosition, selPosition);
2846 int len = end - start;
2847 selection = new char[len + 1];
2848 memcpy(selection, textBlock.text + start, len);
2853 int startSel, endSel;
2854 Block startSelBlock = null, endSelBlock = null, b;
2857 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2860 for(b = startSelBlock; b; b = GetNextBlock(b))
2862 int start = (b == startSelBlock) ? startSel : 0;
2863 int end = (b == endSelBlock) ? endSel : b.textLen;
2864 int len = end - start;
2866 if(b == endSelBlock)
2868 else if(b.type == TEXT)
2872 selection = new char[totalLen + 1];
2874 for(b = startSelBlock; b; b = GetNextBlock(b))
2876 int start = (b == startSelBlock) ? startSel : 0;
2877 int end = (b == endSelBlock) ? endSel : b.textLen;
2878 int len = end - start;
2879 memcpy(selection + totalLen, b.text + start, len);
2881 if(b == endSelBlock)
2883 else if(b.type == TEXT)
2884 selection[totalLen++] = '\n';
2886 selection[totalLen] = 0;
2891 void CopySelection()
2893 String s = GetSelectionString();
2896 int len = strlen(s);
2898 if(cb.Allocate(len + 1))
2900 memcpy(cb.text, s, len + 1);
2908 bool OnKeyDown(Key key, unichar ch)
2915 OnLeftButtonDown(0,0,0);
2917 case Key { end, shift = true }:
2919 curPosition = textBlock.textLen;
2922 selPosition = curPosition;
2923 selBlock = textBlock;
2925 PositionCaret(true);
2928 case Key { home, shift = true }:
2933 selPosition = curPosition;
2934 selBlock = textBlock;
2936 PositionCaret(true);
2939 case Key { home, ctrl = true, shift = true }:
2942 while(textBlock.prev)
2943 textBlock = textBlock.prev.prev;
2946 selPosition = curPosition;
2947 selBlock = textBlock;
2949 PositionCaret(true);
2952 case Key { end, ctrl = true, shift = true }:
2954 while(textBlock.next && textBlock.next.next)
2955 textBlock = textBlock.next.next;
2956 curPosition = textBlock.textLen;
2959 selPosition = curPosition;
2960 selBlock = textBlock;
2962 PositionCaret(true);
2968 return HTMLView::OnKeyDown(key, ch);
2972 bool OnKeyHit(Key key, unichar ch)
2978 case Key { up, shift = true }:
2981 if(caretY == textBlock.startY)
2985 textBlock = textBlock.prev.prev;
2986 curPosition = Min(curPosition, textBlock.textLen);
2989 selPosition = curPosition;
2990 selBlock = textBlock;
2993 PositionCaret(false);
3003 int sx = textBlock.startX, sy = textBlock.startY;
3004 char * text = textBlock.text;
3006 Block block = textBlock;
3007 while(block && block.type != TD) block = block.parent;
3010 Block table = block;
3011 while(table && table.type != TABLE) table = table.parent;
3013 maxW = block.w - 2* table.cellPadding;
3015 maxW = clientSize.w - 10 - sx;
3018 maxW = clientSize.w - 10 - sx;
3019 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3023 int startPos = textPos;
3026 bool lineComplete = false;
3027 for(; textPos<textBlock.textLen && !lineComplete;)
3031 char * nextSpace = strchr(text + textPos, ' ');
3034 len = (nextSpace - (text + textPos)) + 1;
3036 len = textBlock.textLen - textPos;
3038 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3040 if(x + width + w > maxW && x > 0)
3042 lineComplete = true;
3052 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3055 curPosition = textPos;
3056 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3059 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3060 len = curPosition - startPos;
3061 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3065 selPosition = curPosition;
3066 selBlock = textBlock;
3070 PositionCaret(false);
3074 if(sy == caretY - th || textPos == textBlock.textLen)
3076 if(textPos != textBlock.textLen)
3078 int c = textPos - 1;
3079 while(c > 0 && text[c] == ' ') c--;
3080 curPosition = c + 1;
3083 selPosition = curPosition;
3084 selBlock = textBlock;
3090 curPosition = textBlock.textLen;
3093 selPosition = curPosition;
3094 selBlock = textBlock;
3098 PositionCaret(false);
3102 sx = textBlock.startX;
3103 } while(textPos < textBlock.textLen);
3108 case Key { down, shift = true }:
3113 int sx = textBlock.startX, sy = textBlock.startY;
3114 char * text = textBlock.text;
3116 Block block = textBlock;
3117 while(block && block.type != TD) block = block.parent;
3120 Block table = block;
3121 while(table && table.type != TABLE) table = table.parent;
3123 maxW = block.w - 2* table.cellPadding;
3125 maxW = clientSize.w - 10 - sx;
3128 maxW = clientSize.w - 10 - sx;
3129 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3131 while(!textPos || textPos < textBlock.textLen)
3133 int startPos = textPos;
3136 bool lineComplete = false;
3137 for(; (textPos < textBlock.textLen) && !lineComplete;)
3141 char * nextSpace = strchr(text + textPos, ' ');
3144 len = (nextSpace - (text + textPos)) + 1;
3146 len = textBlock.textLen - textPos;
3148 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3150 if(x + width + w > maxW && x > 0)
3152 lineComplete = true;
3162 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3164 curPosition = textPos;
3166 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3169 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3170 len = curPosition - startPos;
3171 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3175 selPosition = curPosition;
3176 selBlock = textBlock;
3179 PositionCaret(false);
3185 curPosition = textBlock.textLen;
3188 selPosition = curPosition;
3189 selBlock = textBlock;
3192 PositionCaret(false);
3195 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3199 textBlock = textBlock.next.next;
3200 sy = textBlock.startY;
3201 sx = textBlock.startX;
3202 text = textBlock.text;
3207 sx = textBlock.startX;
3211 /*if(textBlock.next && textBlock.next.next)
3213 textBlock = textBlock.next.next;
3214 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3215 selBlock = textBlock;
3216 PositionCaret(false);
3220 case Key { right, shift = true, ctrl = true }:
3223 bool foundAlpha = false;
3225 Block line, lastLine;
3228 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3230 int start = (line == textBlock) ? curPosition : 0;
3232 for(c = start; c < line.textLen; c++)
3234 char ch = line.text[c];
3235 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3236 if(key.shift ? isAlUnder : !isAlUnder)
3250 selPosition = curPosition;
3251 selBlock = textBlock;
3255 PositionCaret(true);
3260 // No next word found,
3261 if(!found && (c != curPosition || line != textBlock))
3265 lastC = line.textLen-1;
3270 curPosition = line.textLen;
3273 selPosition = curPosition;
3274 selBlock = textBlock;
3279 PositionCaret(true);
3285 if(key.shift && found)
3287 curPosition = lastC+1;
3288 textBlock = lastLine;
3289 PositionCaret(true);
3294 case Key { left, ctrl = true, shift = true }:
3297 bool foundAlpha = false;
3299 Block line, lastLine;
3302 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3305 if(curPosition == 0 && line != textBlock)
3308 lastC = line.textLen;
3312 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3313 for(c = start; c>=0; c--)
3315 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3330 // No next word found,
3331 if(!found && curPosition > 0)
3341 textBlock = lastLine;
3342 curPosition = lastC;
3345 selPosition = curPosition;
3346 selBlock = textBlock;
3348 PositionCaret(true);
3353 case Key { right, shift = true }:
3355 if(curPosition < textBlock.textLen)
3357 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3360 selPosition = curPosition;
3361 selBlock = textBlock;
3363 PositionCaret(true);
3366 else if(textBlock.next && textBlock.next.next)
3368 textBlock = textBlock.next.next;
3372 selPosition = curPosition;
3373 selBlock = textBlock;
3375 PositionCaret(true);
3379 case Key { left, shift = true }:
3383 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3386 selPosition = curPosition;
3387 selBlock = textBlock;
3389 PositionCaret(true);
3392 else if(textBlock.prev)
3394 textBlock = textBlock.prev.prev;
3395 curPosition = textBlock.textLen;
3398 selPosition = curPosition;
3399 selBlock = textBlock;
3401 PositionCaret(true);
3407 if(textBlock == selBlock && curPosition == selPosition)
3411 int c = curPosition;
3413 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3414 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3415 textBlock.textLen -= nb;
3416 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3418 selPosition = curPosition;
3419 selBlock = textBlock;
3423 PositionCaret(true);
3426 else if(textBlock.prev)
3428 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3429 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3430 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3432 selPosition = curPosition = prevBlock.textLen;
3433 selBlock = textBlock;
3434 prevBlock.textLen += textBlock.textLen;
3435 textBlock.parent.subBlocks.Remove(prev);
3436 if(prev == selBlock)
3438 selBlock = textBlock;
3439 selPosition = curPosition;
3442 textBlock.parent.subBlocks.Remove(textBlock);
3443 if(textBlock == selBlock)
3445 selBlock = prevBlock;
3446 selPosition = curPosition;
3449 textBlock = prevBlock;
3453 PositionCaret(true);
3462 if(textBlock != selBlock || curPosition != selPosition)
3464 else if(textBlock.textLen > curPosition)
3466 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3467 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3468 textBlock.textLen -= nb;
3469 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3474 PositionCaret(true);
3477 else if(textBlock.next && textBlock.next.next)
3479 Block next = textBlock.next, nextBlock = textBlock.next.next;
3480 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3481 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3483 textBlock.textLen += nextBlock.textLen;
3484 textBlock.parent.subBlocks.Remove(next);
3485 if(next == selBlock)
3487 selBlock = textBlock;
3488 selPosition = curPosition;
3491 textBlock.parent.subBlocks.Remove(nextBlock);
3492 if(nextBlock == selBlock)
3494 selBlock = textBlock;
3495 selPosition = curPosition;
3501 PositionCaret(true);
3515 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3516 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3517 startY = textBlock.startY;
3518 startX = textBlock.startX;
3520 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3521 textBlock.parent.subBlocks.Insert(textBlock, block);
3522 textBlock.parent.subBlocks.Insert(block, newBlock);
3526 newBlock.textLen = textBlock.textLen - curPosition;
3527 newBlock.text = new char[newBlock.textLen+1];
3528 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3529 textBlock.textLen = curPosition;
3530 textBlock.text[curPosition] = 0;
3532 newBlock.startY = startY;
3533 newBlock.startX = startX;
3534 selPosition = curPosition = 0;
3539 textBlock = newBlock;
3540 selBlock = textBlock;
3541 PositionCaret(true);
3546 case Key { del, shift = true }:
3561 ClipBoard clipBoard { };
3562 if(clipBoard.Load())
3565 char * text = clipBoard.memory;
3573 parent = textBlock.parent;
3574 font = textBlock.font;
3579 if(ch == '\n' || ch == '\r' || !ch)
3581 int len = c - start;
3582 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3583 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3584 memcpy(textBlock.text + curPosition, text + start, len);
3585 textBlock.textLen += len;
3587 selPosition = curPosition;
3588 selBlock = textBlock;
3591 Block block { type = BR, parent = parent, font = font };
3592 Block newBlock { type = TEXT, parent = parent, font = font };
3593 int startY = textBlock.startY, startX = textBlock.startX;
3596 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3597 textBlock.parent.subBlocks.Insert(textBlock, block);
3598 textBlock.parent.subBlocks.Insert(block, newBlock);
3602 newBlock.textLen = textBlock.textLen - curPosition;
3603 newBlock.text = new char[newBlock.textLen+1];
3604 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3605 textBlock.textLen = curPosition;
3606 textBlock.text[curPosition] = 0;
3608 newBlock.startY = startY;
3609 newBlock.startX = startX;
3610 selPosition = curPosition = 0;
3611 selBlock = textBlock;
3612 textBlock = newBlock;
3614 if(ch == '\r' && text[c+1] == '\n') c++;
3620 PositionCaret(true);
3628 // eC BUG HERE: (Should be fixed)
3629 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3632 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3637 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3638 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3640 for(c = 0; c<len; c++)
3642 textBlock.text[curPosition] = string[c];
3643 textBlock.textLen++;
3646 selPosition = curPosition;
3647 selBlock = textBlock;
3650 //Clear(html.block);
3651 //CreateForms(html.block);
3656 PositionCaret(true);
3665 void OnResize(int width, int height)
3667 HTMLView::OnResize(width, height);
3668 PositionCaret(true);
3672 void PositionCaret(bool setCaretX)
3678 int sx = textBlock.startX, sy = textBlock.startY;
3679 char * text = textBlock.text;
3681 Block block = textBlock;
3682 while(block && block.type != TD) block = block.parent;
3685 Block table = block;
3686 while(table && table.type != TABLE) table = table.parent;
3688 maxW = block.w - 2* table.cellPadding;
3690 maxW = clientSize.w - 10 - sx;
3693 maxW = clientSize.w - 10 - sx;
3695 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3697 while(textPos < textBlock.textLen)
3699 int startPos = textPos;
3702 bool lineComplete = false;
3704 for(; textPos<textBlock.textLen && !lineComplete;)
3708 char * nextSpace = strchr(text + textPos, ' ');
3711 len = (nextSpace - (text + textPos)) + 1;
3713 len = textBlock.textLen - textPos;
3715 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3717 if(x + width + w > maxW && x > 0)
3719 lineComplete = true;
3732 if(curPosition < textPos || textPos == textBlock.textLen)
3734 int len = curPosition - startPos;
3735 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3740 sx = textBlock.startX;
3745 SetCaret(sx, sy, th);
3747 Point scrollPos = scroll;
3748 bool doScroll = false;
3749 if(sy - scroll.y + th > clientSize.h)
3751 scrollPos.y = sy + th - clientSize.h;
3754 else if(sy - scroll.y < 0)
3759 if(sx - scroll.x + 10 > clientSize.w)
3761 scrollPos.x = sx + 10 - clientSize.w;
3764 else if(sx - scroll.x < 10)
3766 scrollPos.x = sx - 10;
3777 // Returns a character offset into the TextBlock from a window coordinate
3778 int TextPosFromPoint(int px, int py, Block * block, bool half)
3780 Block parentBlock = this.textBlock.parent;
3783 *block = this.textBlock;
3788 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3790 int sx = textBlock.startX, sy = textBlock.startY;
3793 char * text = textBlock.text;
3795 Block b = textBlock;
3798 if(textBlock.type != TEXT) continue;
3800 while(b && b.type != TD) b = b.parent;
3804 while(table && table.type != TABLE) table = table.parent;
3806 maxW = b.w - 2* table.cellPadding;
3808 maxW = clientSize.w - 10 - sx;
3811 maxW = clientSize.w - 10 - sx;
3813 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3814 //space = space/2+2;
3817 while(textPos < textBlock.textLen)
3819 int startPos = textPos;
3822 bool lineComplete = false;
3824 for(; textPos<textBlock.textLen && !lineComplete;)
3828 char * nextSpace = strchr(text + textPos, ' ');
3831 len = (nextSpace - (text + textPos)) + 1;
3833 len = textBlock.textLen - textPos;
3835 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3837 sx = x + textBlock.startX;
3838 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3843 for(c = textPos; (ch = text[c]); c += numBytes)
3845 numBytes = UTF8_NUM_BYTES(ch);
3846 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3847 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3854 if(x + width + w > maxW && x > 0)
3856 lineComplete = true;
3869 if(/*py >= sy && */py < sy + th)
3872 return textBlock.textLen;
3877 result = textBlock.textLen;
3883 Application componentsApp;
3885 class Documentor : GuiApplication
3889 Platform os = GetRuntimePlatform();
3890 componentsApp = __ecere_COM_Initialize(false, 1, null);
3891 SetPrivateModule(componentsApp);
3892 SetGlobalContext(globalContext);
3893 SetExcludedSymbols(&excludedSymbols);
3894 SetDefines(&::defines);
3895 SetImports(&imports);
3897 SetGlobalData(globalData);
3899 settingsContainer.dataOwner = &settings;
3900 settingsContainer.Load();
3901 if(!settings.docDir || !settings.docDir[0] )
3903 if(os == win32) // if Windows OS then
3905 char programFilesDir[MAX_LOCATION];
3906 char appData[MAX_LOCATION];
3907 char homeDrive[MAX_LOCATION];
3908 char winDir[MAX_LOCATION];
3909 GetEnvironment("APPDATA", appData, sizeof(appData));
3910 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3911 GetEnvironment("windir", winDir, sizeof(winDir));
3912 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3914 PathCat(programFilesDir, "ECERE SDK\\doc");
3915 settings.docDir = programFilesDir;
3917 else if(homeDrive && homeDrive[0])
3919 PathCat(homeDrive, "ECERE SDK\\doc");
3920 settings.docDir = homeDrive;
3922 else if(winDir && winDir[0])
3924 PathCat(winDir, "..\\ECERE SDK\\doc");
3925 settings.docDir = winDir;
3928 settings.docDir = "C:\\ECERE SDK\\doc";
3930 else // if Os is Linux, or Mac OSX or something else
3931 settings.docDir = "/usr/share/ecere/doc/";
3932 settingsContainer.Save();
3938 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3940 AddComponents(module, true);
3941 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3942 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3943 while((row = row.parent))
3944 row.collapsed = false;
3948 commandThread.Create();
3952 bool Cycle(bool idle)
3955 mainForm.Destroy(0);
3964 if(commandThread.created)
3966 console.CloseInput();
3967 console.CloseOutput();
3969 commandThread.Wait();
3973 FreeContext(globalContext);
3974 FreeExcludedSymbols(excludedSymbols);
3975 ::defines.Free(FreeModuleDefine);
3976 imports.Free(FreeModuleImport);
3978 FreeGlobalData(globalData);
3979 FreeTypeData(componentsApp);
3981 delete componentsApp;
3985 ConsoleFile console { };
3986 MainForm mainForm { };
3989 Thread commandThread
3996 console.GetLine(command, sizeof(command));
3997 if(!quit && command[0])
4000 if(!strcmpi(command, "Activate"))
4001 mainForm.Activate();
4002 else if(!strcmpi(command, "Quit"))