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 };
13 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
16 /*extern */int __ecereVMethodID_class_OnGetString;
23 a.OnGetString(null, null, null);
26 static bool editing = true;
28 enum CodeObjectType { typeClass, typeData, typeMethod, typeEvent, typeProperty, typeNameSpace, typeDataType, typeEnumValue, typeDataPrivate, typeMethodPrivate, typePropertyPrivate };
31 static FileFilter fileFilters[] =
34 "eC Shared Library files (*.dll, *.so, *.dylib)",
38 "eC Symbol files (*.sym)",
43 static char * iconNames[CodeObjectType] =
45 "<:ecere>constructs/class.png",
46 "<:ecere>constructs/data.png",
47 "<:ecere>constructs/method.png",
48 "<:ecere>constructs/event.png",
49 "<:ecere>constructs/property.png",
50 "<:ecere>constructs/namespace.png",
51 "<:ecere>constructs/dataType.png",
52 "<:ecere>constructs/enumValue.png",
53 "<:ecere>constructs/dataPrivate.png",
54 "<:ecere>constructs/methodPrivate.png",
55 "<:ecere>constructs/propertyPrivate.png"
58 IDESettings settings { }; // instantiate the IDESettings class from the IDESettings.ec file. Do this at a global level so that all methods can access settings.
60 IDESettingsContainer settingsContainer
64 dataOwner = &settings;
67 // WARNING : This function expects a null terminated string since it recursively concatenate...
68 static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
75 if(type._class && type._class.string)
78 strcat(string, type._class.string);
81 if(type._class.registered)
84 sprintf(hex, "%08x", type._class.registered);
85 strcat(string, "<a href=\"api://");
87 strcat(string, "\" style=\"text-decoration: none;\">");
88 strcat(string, type._class.registered.name);
89 strcat(string, "</a>");
92 strcat(string, type._class.string);
99 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
100 if(funcType && funcType.kind == functionType)
103 DocPrintType(funcType.returnType, string, false, fullName);
104 strcat(string, "(*");
105 if(printName || funcType.thisClass)
108 if(funcType.thisClass)
110 strcat(string, funcType.thisClass.string);
111 strcat(string, "::");
114 strcat(string, type.name);
116 strcat(string, ")(");
117 for(param = funcType.params.first; param; param = param.next)
119 DocPrintType(param, string, false, fullName);
120 if(param.next) strcat(string, ", ");
126 _PrintType(type.type, string, false /*printName*/, printFunction, fullName);
127 if(string[strlen(string)-1] == '(')
130 strcat(string, " *");
134 case voidType: strcat(string, "void"); break;
135 case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
136 case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
137 case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
138 case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
139 case floatType: strcat(string, "float"); break;
140 case doubleType: strcat(string, "double"); break;
144 strcat(string, "struct ");
145 strcat(string, type.enumName);
147 else if(type.typeName)
149 strcat(string, type.typeName);
154 strcat(string, "struct ");
155 strcat(string,"(unnamed)");
158 strcat(string, "struct {");
159 for(member = type.members.first; member; member = member.next)
161 DocPrintType(member, string, true, fullName);
170 strcat(string, "union ");
171 strcat(string, type.enumName);
173 else if(type.typeName)
175 strcat(string, type.typeName);
179 strcat(string, "union ");
180 strcat(string,"(unnamed)");
186 strcat(string, "enum ");
187 strcat(string, type.enumName);
189 else if(type.typeName)
191 strcat(string, type.typeName);
194 strcat(string, "enum");
201 strcat(string, "dllexport ");
202 DocPrintType(type.returnType, string, false, fullName);
206 // DANGER: Testing This
212 strcat(string, type.name);
215 char * name = RSearchString(type.name, "::", strlen(type.name), true, false);
216 if(name) name += 2; else name = type.name;
217 strcat(string, "<b>");
218 strcat(string, name);
219 strcat(string, "</b>");
232 for(param = type.params.first; param; param = param.next)
234 DocPrintType(param, string, true, fullName);
235 if(param.next) strcat(string, ", ");
244 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
245 if(funcType && funcType.kind == functionType)
248 DocPrintType(funcType.returnType, string, false, fullName);
249 strcat(string, "(*");
250 if(printName || funcType.thisClass)
253 if(funcType.thisClass)
255 strcat(string, funcType.thisClass.string);
256 strcat(string, "::");
259 strcat(string, type.name);
261 strcat(string, ")(");
262 for(param = funcType.params.first; param; param = param.next)
264 DocPrintType(param, string, false, fullName);
265 if(param.next) strcat(string, ", ");
271 char baseType[1024], size[256];
272 Type arrayType = type;
276 while(arrayType.kind == TypeKind::arrayType)
279 if(arrayType.enumClass)
280 strcat(size, arrayType.enumClass.string);
281 else if(arrayType.arraySizeExp)
282 PrintExpression(arrayType.arraySizeExp, size);
283 //sprintf(string, "%s[%s]", baseType, size);
286 arrayType = arrayType.arrayType;
288 _PrintType(arrayType, baseType, printName, printFunction, fullName);
289 strcat(string, baseType);
290 strcat(string, size);
294 DocPrintType(type.arrayType, baseType, printName, fullName);
296 strcpy(size, type.enumClass.string);
297 else if(type.arraySizeExp)
298 PrintExpression(type.arraySizeExp, size);
299 //sprintf(string, "%s[%s]", baseType, size);
300 strcat(string, baseType);
302 strcat(string, size);
310 strcat(string, "...");
313 _PrintType(type.method.dataType, string, false, printFunction, fullName);
316 strcat(string, "subclass(");
317 strcat(string, type._class ? type._class.string : "int");
323 if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
326 strcat(string, type.name);
331 void DocPrintType(Type type, char * string, bool printName, bool fullName)
334 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
335 if(funcType && funcType.kind == functionType && type != funcType)
337 char typeString[1024];
340 DocPrintType(funcType.returnType, string, false, fullName);
342 _PrintType(type, string, printName, false, fullName);
346 strcat(string, type.name);
353 for(param = funcType.params.first; param; param = param.next)
355 DocPrintType(param, string, true, fullName);
356 if(param.next) strcat(string, ", ");
361 _PrintType(type, string, printName, true, fullName);
364 void AddComponents(Module module, bool isDll)
369 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
371 row = mainForm.browser.AddRow();
372 row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
374 AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
377 for(m = module.modules.first; m; m = m.next)
379 if(m.importMode == publicAccess || !isDll)
380 AddComponents(m.module, true);
383 // PUT MODULE DESCRIPTION HERE
384 if(module.name && strcmp(module.name, "ecereCOM"))
386 row = mainForm.browser.AddRow();
387 row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
388 row.tag = (int)module;
389 AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
391 AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
403 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
408 virtual void Generate(File f)
414 enum DocumentationType
422 enum DocumentationItem
438 static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
440 NameSpace * nameSpace, * ns;
442 Method method = null;
443 GlobalFunction function = null;
444 char nsName[1024], temp[1024];
450 case nameSpaceDoc: nameSpace = object; break;
451 case classDoc: cl = (Class)object; nameSpace = cl.nameSpace; break;
452 case functionDoc: function = object; nameSpace = function.nameSpace; break;
453 case methodDoc: method = object; cl = method._class; nameSpace = cl.nameSpace; break;
458 while(ns && ns->name)
460 strcpy(temp, "namespaces/");
461 strcat(temp, ns->name);
463 strcat(temp, nsName);
464 strcpy(nsName, temp);
467 sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
469 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.
470 strcat(fileName, nsName);
474 strcat(fileName, "classes/");
475 strcat(fileName, cl.name);
476 strcat(fileName, "/");
481 strcat(fileName, "methods/");
482 strcat(fileName, method.name);
483 strcat(fileName, "/");
487 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
488 if(name) name += 2; else name = function.name;
489 strcat(fileName, "functions/");
490 strcat(fileName, name);
491 strcat(fileName, "/");
496 case description: strcat(fileName, "description"); break;
497 case usage: strcat(fileName, "usage"); break;
498 case remarks: strcat(fileName, "remarks"); break;
499 case example: strcat(fileName, "example"); break;
500 case seeAlso: strcat(fileName, "seeAlso"); break;
501 case returnValue: strcat(fileName, "returnValue"); break;
502 case enumerationValue:
503 strcat(fileName, "enumeration values/");
504 strcat(fileName, ((NamedLink)data).name);
507 strcat(fileName, "definitions/");
508 strcat(fileName, ((Definition)data).name);
512 char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
513 if(name) name += 2; else name = ((Property)data).name;
514 strcat(fileName, "conversions/");
515 strcat(fileName, name);
518 case memberDescription:
519 strcat(fileName, "data members/");
520 strcat(fileName, ((DataMember)data).name);
522 case propertyDescription:
523 strcat(fileName, "properties/");
524 strcat(fileName, ((Property)data).name);
531 strcat(fileName, "parameters/");
532 for(prev = data, count = 0; prev; prev = prev.prev, count++);
533 sprintf(name, "%s.%d", ((Type)data).name, count);
534 strcat(fileName, name);
540 static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
542 char fileName[MAX_LOCATION];
543 String contents = null;
546 FigureFileName(fileName, module, type, object, item, data);
547 file = FileOpen(fileName, read);
551 if((len = file.GetSize()))
553 contents = new char[len+1];
554 file.Read(contents, 1, len);
555 contents[len] = '\0';
562 for(c = 0; contents[c]; c++)
563 if(!isspace(contents[c])) break;
567 if(editing && !contents)
568 contents = CopyString("[Add Text]");
572 class APIPageNameSpace : APIPage
574 NameSpace * nameSpace;
577 void Generate(File f)
580 char nsName[1024], temp[1024];
587 while(ns && ns->name)
589 strcpy(temp, ns->name);
590 if(nsName[0]) strcat(temp, "::");
591 strcat(temp, nsName);
592 strcpy(nsName, temp);
595 // Generate Class Page
596 f.Printf("<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
599 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
600 tag = (uint)nameSpace;
601 f.Printf("Module: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
605 tag = (uint)((!module || !module.name || !strcmp(nsName, "ecere::com") ? null : module));
606 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
610 ns = nameSpace->parent;
611 while(ns && ns->name)
613 strcpy(temp, ns->name);
614 if(nsName[0]) strcat(temp, "::");
615 strcat(temp, nsName);
616 strcpy(nsName, temp);
620 f.Printf("Parent namespace: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
624 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
627 f.Printf("<H3>Description</H3><br><br>\n");
630 char fileName[MAX_LOCATION];
631 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
632 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
634 f.Printf("</a><br><br>");
637 f.Printf("%s<br><br>", desc);
642 if(nameSpace->nameSpaces.first)
645 for(ns = (NameSpace *)nameSpace->nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
647 char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
650 f.Printf("<H3>Sub Namespaces</H3><br><br>\n");
651 f.Printf("<TABLE >\n");
655 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeNameSpace], ns, ns->name);
660 char fileName[MAX_LOCATION];
661 FigureFileName(fileName, module, nameSpaceDoc, ns, description, null);
662 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
664 f.Printf("</a></TD>");
667 f.Printf("<TD valign=top height=22> %s</TD>", desc);
670 f.Printf("</TR><br>\n");
673 f.Printf("</TABLE><br>\n");
676 if(nameSpace->classes.first)
679 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
681 Class cl = link.data;
682 if(!cl.templateClass)
684 char * desc = ReadDoc(module, classDoc, cl, description, null);
688 f.Printf("<a name=Classes></a><H3>Classes</H3><br><br>\n");
689 f.Printf("<TABLE >\n");
695 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a></TD>", (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? iconNames[typeDataType] : iconNames[typeClass], cl, cl.name);
700 char fileName[MAX_LOCATION];
701 FigureFileName(fileName, module, classDoc, cl, description, null);
702 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
704 f.Printf("</a></TD>");
707 f.Printf("<TD valign=top height=22>%s</TD>", desc);
714 f.Printf("</TABLE><br>\n");
717 if(nameSpace->functions.first)
720 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
722 GlobalFunction function = link.data;
723 char * desc = ReadDoc(module, functionDoc, function, description, null);
724 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
725 if(name) name += 2; else name = function.name;
728 f.Printf("<a name=Functions></a><H3>Functions</H3><br><br>\n");
729 f.Printf("<TABLE >\n");
733 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeMethod], function, name);
738 char fileName[MAX_LOCATION];
739 FigureFileName(fileName, module, functionDoc, function, description, null);
740 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
742 f.Printf("</a></TD>");
745 f.Printf("<TD valign=top height=22> %s</TD>", desc);
748 f.Printf("</TR><br>\n");
751 f.Printf("</TABLE><br>\n");
754 if(nameSpace->defines.first)
757 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
759 DefinedExpression def = link.data;
760 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
763 f.Printf("<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
764 f.Printf("<TABLE >\n");
768 f.Printf("<TD valign=top height=22 nowrap=1><a name=%08x></a><img valign=center src=\"%s\"> %s</TD>", def, iconNames[typeData], def.name);
769 f.Printf("<TD valign=top height=22>%s</TD>", def.value);
774 char fileName[MAX_LOCATION];
775 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, definition, def);
776 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
778 f.Printf("</a></TD>");
781 f.Printf("<TD valign=top height=22> %s</TD>", desc);
784 f.Printf("</TR><br>\n");
787 f.Printf("</TABLE><br>\n");
790 f.Printf("</FONT></BODY></HTML>\n");
794 class APIPageClass : APIPage
798 void Generate(File f)
804 char nsName[1024], temp[1024];
805 NameSpace * ns = cl.nameSpace;
806 Module module = cl.module;
809 while(ns && ns->name)
811 strcpy(temp, ns->name);
812 if(nsName[0]) strcat(temp, "::");
813 strcat(temp, nsName);
814 strcpy(nsName, temp);
817 // Generate Class Page
818 f.Printf("<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
819 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
821 f.Printf("Module: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
823 f.Printf("Namespace: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
826 char * classType = null;
830 classType = "Bit Collection";
833 classType = "Enumeration";
836 classType = "Structure";
842 classType = "Class (No header)";
848 classType = "Basic Data Type";
851 f.Printf("Type: %s<br>\n", classType);
854 if(cl.type != systemClass && cl.base)
856 f.Printf("Base Class: ");
857 if(!strcmp(cl.base.name, "struct") || !strcmp(cl.base.name, "class"))
859 f.Printf(cl.type == bitClass ? cl.dataTypeString : "None");
861 else if(cl.type == enumClass && !strcmp(cl.base.name, "enum"))
862 f.Printf("%s", cl.dataTypeString);
864 f.Printf("<a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a>", cl.base, cl.base.name);
869 char * desc = ReadDoc(module, classDoc, cl, description, null);
872 f.Printf("<br><H3>Description</H3><br><br>\n");
875 char fileName[MAX_LOCATION];
876 FigureFileName(fileName, module, classDoc, cl, description, null);
877 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
879 f.Printf("</a><br><br>");
882 f.Printf("%s<br><br>", desc);
887 if(cl.type == enumClass)
889 EnumClassData enumeration = (EnumClassData)cl.data;
890 if(enumeration.values.first)
894 f.Printf("<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
895 f.Printf("<TABLE >\n");
897 for(item = enumeration.values.first; item; item = item.next)
899 char * desc = ReadDoc(module, classDoc, cl, enumerationValue, item);
900 bool needClass = true;
903 while(base.type == enumClass) base = base.base;
905 if(base.type == systemClass ||
906 (base.type == bitClass && base.membersAndProperties.first && !strcmp(cl.fullName, ((DataMember)base.membersAndProperties.first).dataTypeString)))
909 base.dataType = ProcessTypeString(base.dataTypeString, false);
911 if(base.dataType.kind != classType)
916 PrintType(base.dataType, string, false, true);
917 classSym = FindClass(string);
918 dataClass = classSym ? classSym.registered : null;
921 dataClass = base.dataType._class ? base.dataType._class.registered : null;
927 f.Printf("<TD valign=top height=22 nowrap=1><a name=%08x></a><img valign=center src=\"%s\"> %s</TD>", item, iconNames[typeEnumValue], item.name);
928 if(dataClass.type == systemClass)
931 dataClass._vTbl[__ecereVMethodID_class_OnGetString](dataClass, &item.data, string, sizeof(string), &needClass);
934 eSystem_FindClass(componentsApp, "class")._vTbl[__ecereVMethodID_class_OnGetString](dataClass, &item.data, string, sizeof(string), &needClass);
936 f.Printf("<TD valign=top height=22 nowrap=1>%s { %s }</TD>", dataClass.name, string);
938 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
943 char fileName[MAX_LOCATION];
944 FigureFileName(fileName, module, classDoc, cl, enumerationValue, item);
945 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
947 f.Printf("</a></TD>");
950 f.Printf("<TD valign=top height=22>%s</TD>", desc);
955 f.Printf("</TABLE><BR>\n");
959 if(cl.conversions.first)
961 f.Printf("<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
962 f.Printf("<TABLE >\n");
963 for(prop = cl.conversions.first; prop; prop = prop.next)
965 if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
967 char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
970 Type type = ProcessTypeString(prop.name, false);
971 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
972 if(name) name += 2; else name = prop.name;
977 DocPrintType(type, string, true, false);
979 f.Printf("<TD valign=top height=22 nowrap=1><a name=%08x></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeDataType], string);
984 char fileName[MAX_LOCATION];
985 FigureFileName(fileName, module, classDoc, cl, conversion, prop);
986 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
988 f.Printf("</a></TD>");
991 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1000 f.Printf("</TABLE><br>\n");
1003 if(cl.membersAndProperties.first)
1006 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1008 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1012 f.Printf("<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
1013 f.Printf("<TABLE >\n");
1019 char * desc = ReadDoc(module, classDoc, cl, propertyDescription, prop);
1021 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1025 DocPrintType(prop.dataType, string, true, false);
1027 f.Printf("<TD valign=top height=22 nowrap=1><a name=%08x></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeProperty], prop.name);
1028 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
1033 char fileName[MAX_LOCATION];
1034 FigureFileName(fileName, module, classDoc, cl, propertyDescription, prop);
1035 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1037 f.Printf("</a></TD>");
1040 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1043 f.Printf("</TR>\n");
1047 AddDataMemberToPage(f, (DataMember)prop, 0, showPrivate);
1052 f.Printf("</TABLE><br>\n");
1055 if(cl.methods.first)
1059 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1061 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type == virtualMethod)
1063 char * desc = ReadDoc(module, methodDoc, method, description, null);
1066 f.Printf("<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
1067 f.Printf("<TABLE >\n");
1070 if(!method.dataType)
1071 ProcessMethodType(method);
1074 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a></TD>", method.dataType.thisClass ? iconNames[typeEvent] : iconNames[typeMethod], method, method.name);
1079 char fileName[MAX_LOCATION];
1080 FigureFileName(fileName, module, methodDoc, method, description, null);
1081 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1083 f.Printf("</a></TD>");
1086 f.Printf("<TD valign=top height=22> %s</TD>", desc);
1089 f.Printf("</TR><br>\n");
1093 f.Printf("</TABLE><br>\n");
1095 // Non-Virtual Methods
1097 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1099 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type != virtualMethod)
1101 char * desc = ReadDoc(module, methodDoc, method, description, null);
1104 f.Printf("<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
1105 f.Printf("<TABLE >\n");
1109 if(!method.dataType)
1110 ProcessMethodType(method);
1113 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeMethod], method, method.name);
1118 char fileName[MAX_LOCATION];
1119 FigureFileName(fileName, module, methodDoc, method, description, null);
1120 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1122 f.Printf("</a></TD>");
1125 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1129 f.Printf("</TR><br>\n");
1133 f.Printf("</TABLE><br>\n");
1136 char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
1139 f.Printf("<H3>Usage</H3><br>\n");
1142 char fileName[MAX_LOCATION];
1143 FigureFileName(fileName, module, classDoc, cl, usage, null);
1144 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1149 f.Printf("<br>%s\n", usageDoc);
1150 f.Printf("<br><br>\n");
1155 char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
1158 f.Printf("<H3>Example</H3><br>\n");
1159 f.Printf("<FONT face=\"Courier New\">\n");
1160 f.Printf("<br><TABLE >\n");
1163 char fileName[MAX_LOCATION];
1164 FigureFileName(fileName, module, classDoc, cl, example, null);
1165 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1167 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1170 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1172 f.Printf("</TABLE></FONT>\n");
1178 char * remarksDoc = ReadDoc(module, classDoc, cl, remarks, null);
1182 f.Printf("<H3>Remarks</H3><br>\n");
1185 char fileName[MAX_LOCATION];
1186 FigureFileName(fileName, module, classDoc, cl, remarks, null);
1187 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1192 f.Printf("<br>%s\n", remarksDoc);
1193 f.Printf("<br><br>\n");
1198 if(cl.type != systemClass)
1202 for(c = cl.derivatives.first; c; c = c.next)
1204 Class deriv = c.data;
1205 // TO VERIFY: Does this properly check public status?
1206 if(eSystem_FindClass(componentsApp, deriv.fullName))
1210 f.Printf("<H3>Derived Classes</H3><br>\n");
1216 f.Printf("<a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
1220 f.Printf("<br><br>\n");
1223 char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
1226 f.Printf("<H3>See Also</H3><br>\n");
1229 char fileName[MAX_LOCATION];
1230 FigureFileName(fileName, module, classDoc, cl, seeAlso, null);
1231 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1236 f.Printf("<br>%s\n", seeAlsoDoc);
1237 f.Printf("<br><br>\n");
1241 f.Printf("</FONT></BODY></HTML>\n");
1245 class APIPageMethod : APIPage
1248 void Generate(File f)
1250 Class cl = method._class;
1252 Module module = cl.module;
1254 char nsName[1024], temp[1024];
1255 NameSpace * ns = cl.nameSpace;
1258 while(ns && ns->name)
1260 strcpy(temp, ns->name);
1261 if(nsName[0]) strcat(temp, "::");
1262 strcat(temp, nsName);
1263 strcpy(nsName, temp);
1267 f.Printf("<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1268 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1270 f.Printf("Module: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
1272 f.Printf("Namespace: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
1273 f.Printf("Class: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", cl, cl.name);
1274 if(method.dataType.staticMethod)
1276 f.Printf("this pointer class: None<br>\n");
1278 else if(method.dataType.thisClass && method.dataType.thisClass.registered && (method.dataType.thisClass.registered != method._class || method.type == virtualMethod))
1280 f.Printf("this pointer class: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", method.dataType.thisClass.registered, method.dataType.thisClass.registered.name);
1283 // Generate Method Page
1285 if(!method.dataType.name)
1286 method.dataType.name = CopyString(method.name);
1287 DocPrintType(method.dataType, string, true, false);
1288 f.Printf("<br>%s", string);
1291 char * desc = ReadDoc(module, methodDoc, method, description, null);
1294 f.Printf("<br><br><H3>Description</H3><br><br>\n");
1297 char fileName[MAX_LOCATION];
1298 FigureFileName(fileName, module, methodDoc, method, description, null);
1299 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1304 f.Printf("%s", desc);
1309 f.Printf("<br><br>\n");
1310 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1312 f.Printf("<H3>Parameters</H3><br><br>\n");
1314 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1315 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1317 f.Printf("<TABLE valign=center>\n");
1320 for(param = method.dataType.params.first; param; param = param.next)
1322 // ADD DESCRIPTION HERE
1323 if(param.kind != voidType)
1325 char * desc = ReadDoc(module, methodDoc, method, parameter, param);
1328 DocPrintType(param, string, false, false);
1330 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1331 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1336 char fileName[MAX_LOCATION];
1337 FigureFileName(fileName, module, methodDoc, method, parameter, param);
1338 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1340 f.Printf("s</a> </TD>\n");
1343 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1347 f.Printf("</TR>\n");
1350 if(method.dataType.returnType && method.dataType.returnType.kind != voidType)
1352 char * desc = ReadDoc(module, methodDoc, method, returnValue, null);
1353 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1355 f.Printf("<TR><TD> </TD></TR>");
1358 f.Printf("<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1360 DocPrintType(method.dataType.returnType, string, false, false);
1361 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1366 char fileName[MAX_LOCATION];
1367 FigureFileName(fileName, module, methodDoc, method, returnValue, null);
1368 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1370 f.Printf("</a> </TD>\n");
1373 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1376 f.Printf("</TR>\n");
1377 f.Printf("</TABLE>\n");
1379 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1380 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1382 f.Printf("</TABLE><br>\n");
1385 char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
1388 f.Printf("<H3>Usage</H3><br>\n");
1391 char fileName[MAX_LOCATION];
1392 FigureFileName(fileName, module, methodDoc, method, usage, null);
1393 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1398 f.Printf("<br>%s\n", usageDoc);
1399 f.Printf("<br><br>\n");
1404 char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
1407 f.Printf("<H3>Example</H3><br>\n");
1408 f.Printf("<FONT face=\"Courier New\">\n");
1409 f.Printf("<br><TABLE >\n");
1412 char fileName[MAX_LOCATION];
1413 FigureFileName(fileName, module, methodDoc, method, example, null);
1414 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1416 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1419 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1420 f.Printf("</TABLE></FONT>\n");
1426 char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
1429 f.Printf("<H3>Remarks</H3><br>\n");
1432 char fileName[MAX_LOCATION];
1433 FigureFileName(fileName, module, methodDoc, method, remarks, null);
1434 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1439 f.Printf("<br>%s\n", method, remarksDoc);
1440 f.Printf("<br><br>\n");
1445 char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
1448 f.Printf("<H3>See Also</H3><br>\n");
1451 char fileName[MAX_LOCATION];
1452 FigureFileName(fileName, module, methodDoc, method, seeAlso, null);
1453 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1458 f.Printf("<br>%s\n", method, seeAlsoDoc);
1460 f.Printf("<br><br>\n");
1464 f.Printf("</FONT></BODY></HTML>\n");
1468 class APIPageFunction : APIPage
1470 GlobalFunction function;
1471 void Generate(File f)
1474 Module module = function.module;
1476 char nsName[1024], temp[1024];
1477 NameSpace * ns = function.nameSpace;
1480 while(ns && ns->name)
1482 strcpy(temp, ns->name);
1483 if(nsName[0]) strcat(temp, "::");
1484 strcat(temp, nsName);
1485 strcpy(nsName, temp);
1489 f.Printf("<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1490 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1492 f.Printf("Module: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
1494 f.Printf("Namespace: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", function.nameSpace, nsName);
1496 if(!function.dataType)
1497 function.dataType = ProcessTypeString(function.dataTypeString, false);
1499 if(function.dataType.thisClass && function.dataType.thisClass.registered)
1501 f.Printf("this pointer class: <a href=\"api://%08x\" style=\"text-decoration: none;\">%s</a><br>\n", function.dataType.thisClass.registered, function.dataType.thisClass.registered.name);
1504 // Generate Method Page
1506 if(!function.dataType.name)
1507 function.dataType.name = CopyString(function.name);
1508 DocPrintType(function.dataType, string, true, false);
1509 f.Printf("<br>%s", string);
1512 char * desc = ReadDoc(module, functionDoc, function, description, null);
1515 f.Printf("<br><br><H3>Description</H3><br><br>\n");
1518 char fileName[MAX_LOCATION];
1519 FigureFileName(fileName, module, functionDoc, function, description, null);
1520 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1525 f.Printf("%s", desc);
1529 f.Printf("<br><br>\n");
1530 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1532 f.Printf("<H3>Parameters</H3><br><br>\n");
1534 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1535 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1537 f.Printf("<TABLE valign=center>\n");
1540 for(param = function.dataType.params.first; param; param = param.next)
1542 // ADD DESCRIPTION HERE
1543 if(param.kind != voidType)
1545 char * desc = ReadDoc(module, functionDoc, function, parameter, param);
1548 DocPrintType(param, string, false, false);
1550 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1551 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1556 char fileName[MAX_LOCATION];
1557 FigureFileName(fileName, module, functionDoc, function, parameter, param);
1558 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1560 f.Printf("</a> </TD>\n");
1563 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1566 f.Printf("</TR>\n");
1569 if(function.dataType.returnType && function.dataType.returnType.kind != voidType)
1571 char * desc = ReadDoc(module, functionDoc, function, returnValue, null);
1572 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1574 f.Printf("<TR><TD> </TD></TR>");
1577 f.Printf("<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1579 DocPrintType(function.dataType.returnType, string, false, false);
1580 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1585 char fileName[MAX_LOCATION];
1586 FigureFileName(fileName, module, functionDoc, function, returnValue, null);
1587 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1589 f.Printf("</a> </TD>\n");
1592 f.Printf("<TD valign=top height=22>%s </TD>\n", function, desc);
1595 f.Printf("</TR>\n");
1596 f.Printf("</TABLE>\n");
1598 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1599 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1601 f.Printf("</TABLE><br>\n");
1604 char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
1607 f.Printf("<H3>Usage</H3><br>\n");
1610 char fileName[MAX_LOCATION];
1611 FigureFileName(fileName, module, functionDoc, function, usage, null);
1612 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1617 f.Printf("<br>%s\n", usageDoc);
1618 f.Printf("<br><br>\n");
1623 char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
1626 f.Printf("<H3>Example</H3><br>\n");
1627 f.Printf("<FONT face=\"Courier New\">\n");
1628 f.Printf("<br><TABLE >\n");
1631 char fileName[MAX_LOCATION];
1632 FigureFileName(fileName, module, functionDoc, function, example, null);
1633 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1635 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1638 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1639 f.Printf("</TABLE></FONT>\n");
1645 char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
1648 f.Printf("<H3>Remarks</H3><br>\n");
1651 char fileName[MAX_LOCATION];
1652 FigureFileName(fileName, module, functionDoc, function, remarks, null);
1653 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1658 f.Printf("<br>%s\n", remarksDoc);
1659 f.Printf("<br><br>\n");
1664 char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
1667 f.Printf("<H3>See Also</H3><br>\n");
1670 char fileName[MAX_LOCATION];
1671 FigureFileName(fileName, module, functionDoc, function, seeAlso, null);
1672 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1677 f.Printf("<br>%s\n", seeAlsoDoc);
1678 f.Printf("<br><br>\n");
1682 f.Printf("</FONT></BODY></HTML>\n");
1686 static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, char * parentName, bool showPrivate)
1690 NameSpace * nameSpace = mainNameSpace;
1692 DataRow classesRow = null;
1693 DataRow functionsRow = null, definesRow = null;
1696 char fileName[MAX_LOCATION];
1698 strcpy(nsName, parentName ? parentName : "");
1702 strcat(nsName, "::");
1703 strcat(nsName, nameSpace->name);
1708 row = parentRow.AddRow();
1709 row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
1710 row.tag = (int)nameSpace;
1711 row.icon = mainForm.icons[typeNameSpace];
1715 // "Global NameSpace"
1717 page = parentRow.GetData(null);
1723 for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1725 NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
1726 AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
1728 if(comNameSpace != null)
1730 for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1732 if(!mainNameSpace.nameSpaces.FindString(ns->name))
1734 AddNameSpace(row, module, ns, null, nsName, showPrivate);
1739 if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
1741 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1743 if(nameSpace->classes.first)
1747 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
1750 if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
1752 if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { "Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
1753 AddClass(classesRow, module, cl, nsName, showPrivate);
1760 if(mainNameSpace.functions.first || (comNameSpace && comNameSpace.functions.first))
1762 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1764 if(nameSpace->functions.first)
1768 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
1771 if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
1773 char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
1775 if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { "Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
1776 fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int)fn;
1783 if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
1785 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1787 if(nameSpace->defines.first)
1791 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
1794 //if(def.module == module)
1796 char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
1798 if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { "Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
1799 defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int)def;
1807 static void AddDataMemberToPage(File f, DataMember member, int indent, bool showPrivate)
1811 if(!member.dataType)
1812 member.dataType = ProcessTypeString(member.dataTypeString, false);
1816 DocPrintType(member.dataType, string, true, false);
1818 f.Printf("<TD valign=top height=22 nowrap=1><a name=%08x></a>", member);
1819 for(c = 0; c<indent; c++)
1820 f.Printf(" ");
1821 f.Printf("<img valign=center src=\"%s\"> %s</TD>", iconNames[typeData], member.name ? member.name : ((member.type == structMember) ? "(struct)" : "(union)"));
1822 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", (member.type == normalMember) ? string : "");
1823 if(member.type == normalMember)
1825 char * desc = ReadDoc(member._class.module, classDoc, member._class, memberDescription, member);
1830 char fileName[MAX_LOCATION];
1831 FigureFileName(fileName, member._class.module, classDoc, member._class, memberDescription, member);
1832 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1834 f.Printf("</a></TD>");
1837 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1842 f.Printf("<TD valign=top height=22></TD>");
1844 if(member.type != normalMember)
1846 DataMember subMember;
1847 for(subMember = member.members.first; subMember; subMember = subMember.next)
1849 if((subMember.memberAccess == publicAccess || (subMember.memberAccess == privateAccess && showPrivate)))
1851 AddDataMemberToPage(f, subMember, indent + 1, showPrivate);
1855 f.Printf("</TR><br>\n");
1858 static void AddDataMember(DataRow parentRow, APIPage page, DataMember member)
1861 if(member.type == normalMember)
1863 row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
1864 row.tag = (int)member;
1869 row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
1870 row.icon = mainForm.icons[typeData];
1871 row.tag = (int)member;
1873 for(m = member.members.first; m; m = m.next)
1875 if(m.memberAccess == publicAccess || (m.memberAccess == privateAccess && page.showPrivate))
1876 AddDataMember(row, page, m);
1881 static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
1883 char fileName[MAX_LOCATION];
1890 DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
1891 DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
1894 row = parentRow.AddRow();
1895 row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
1897 row.collapsed = true;
1898 row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
1901 if(cl.methods.first)
1903 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1905 if(method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate))
1908 if(!method.dataType)
1909 ProcessMethodType(method);
1910 if(method.type == virtualMethod)
1912 if(method.dataType.thisClass)
1914 if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { "Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
1915 mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
1916 mRow.tag = (int)method;
1920 if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { "Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
1921 mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
1922 mRow.tag = (int)method;
1927 if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { "Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
1928 mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
1929 mRow.tag = (int)method;
1935 if(cl.membersAndProperties.first)
1937 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1939 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1942 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1946 if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { "Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
1947 mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
1948 mRow.tag = (int)prop;
1952 if(!membersRow) { membersRow = row.AddRow(); membersRow.SetData(null, APIPage { "Data Members", page = page }); membersRow.collapsed = true; membersRow.icon = mainForm.icons[typeData]; membersRow.tag = 6; }
1953 AddDataMember(membersRow, page, (DataMember)prop);
1959 if(cl.conversions.first)
1961 for(prop = cl.conversions.first; prop; prop = prop.next)
1965 if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { "Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
1966 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
1967 if(name) name += 2; else name = prop.name;
1968 mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
1969 mRow.tag = (int)prop;
1972 if(cl.type == enumClass)
1974 EnumClassData enumeration = (EnumClassData)cl.data;
1976 for(item = enumeration.values.first; item; item = item.next)
1979 if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { "Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
1980 mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
1981 mRow.tag = (int)item;
1986 class MainForm : Window
1988 size = { 1000, 600 };
1990 borderStyle = sizable;
1993 text = "API Documentation Browser";
1995 nativeDecorations = true;
1997 BitmapResource icons[CodeObjectType];
2002 for(c = 0; c < CodeObjectType::enumSize; c++)
2004 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2006 browser.AddField(DataField { dataType = class(APIPage) });
2011 Menu fileMenu { menu, "File", f };
2012 FileDialog fileDialog
2014 filters = fileFilters, sizeFilters = sizeof(fileFilters)
2016 MenuItem fileOpenItem
2018 fileMenu, "Open...", o, ctrlO;
2020 bool NotifySelect(MenuItem selection, Modifiers mods)
2022 if(fileDialog.Modal() == ok)
2024 OpenModule(fileDialog.filePath);
2029 MenuItem fileSettingsItem
2031 fileMenu, "Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2033 bool NotifySelect(MenuItem selection, Modifiers mods)
2035 SettingsDialog { master = this }.Modal(); // Open the settings dialog to allow the user to change the directory for the eCdoc files
2038 MenuDivider { fileMenu };
2039 MenuItem fileExit { fileMenu, "Exit", x, altF4, NotifySelect = MenuFileExit };
2041 void OpenModule(char * filePath)
2043 char extension[MAX_EXTENSION];
2044 Module module = null;
2045 static char symbolsDir[MAX_LOCATION];
2047 FreeContext(globalContext);
2048 FreeExcludedSymbols(excludedSymbols);
2049 ::defines.Free(FreeModuleDefine);
2050 imports.Free(FreeModuleImport);
2052 FreeGlobalData(globalData);
2053 FreeTypeData(componentsApp);
2055 delete componentsApp;
2057 SetGlobalContext(globalContext);
2058 componentsApp = __ecere_COM_Initialize(false, 1, null);
2059 SetPrivateModule(componentsApp);
2061 StripLastDirectory(filePath, symbolsDir);
2062 SetSymbolsDir(symbolsDir);
2064 GetExtension(filePath, extension);
2066 mainForm.browser.Clear();
2068 ImportModule(filePath, normalImport, publicAccess, false);
2070 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll"))
2071 componentsApp.name = CopyString(filePath);
2073 for(module = componentsApp.allModules.first; module; module = module.next)
2075 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2079 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2080 AddComponents(componentsApp, false);
2082 for(module = componentsApp.allModules.first; module; module = module.next)
2084 if(module.name && (!strcmp(module.name, filePath)))
2087 if(!module) module = componentsApp;
2088 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int)module));
2090 SetSymbolsDir(null);
2095 this, anchor = { left = 0, top = 0, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2096 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2099 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2101 APIPage page = row.GetData(null);
2102 if(view.edit) view.OnLeftButtonDown(0,0,0);
2103 if(page && page.page) page = page.page;
2105 view.PositionCaret(true);
2106 if(page != view.page)
2108 Window activeChild = this.activeChild;
2113 activeChild.Activate();
2115 else if(!view.created)
2119 page = row.GetData(null);
2120 if(page && page.page)
2124 case 1: view.GoToAnchor("Classes"); break;
2125 case 2: view.GoToAnchor("Functions"); break;
2126 case 3: view.GoToAnchor("Definitions"); break;
2127 case 4: view.GoToAnchor("VirtualMethods"); break;
2128 case 5: view.GoToAnchor("Methods"); break;
2129 case 6: view.GoToAnchor("Members"); break;
2130 case 7: view.GoToAnchor("Conversions"); break;
2131 case 8: view.GoToAnchor("EnumerationValues"); break;
2135 sprintf(hex, "%08x", row.tag);
2136 view.GoToAnchor(hex);
2142 view.SetScrollPosition(0, 0);
2150 this, anchor = { top = 0, bottom = 0, right = 0 };
2155 this, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2158 bool OnClose(bool parentClosing)
2161 view.OnLeftButtonDown(0,0,0);
2167 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2168 //mainForm.OpenModule("ec");
2169 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2170 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2172 int index = mainForm.browser.currentRow.index;
2173 int rowHeight = mainForm.browser.rowHeight;
2174 int height = mainForm.browser.clientSize.h;
2176 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2182 class EditDialog : Window
2184 borderStyle = sizable;
2185 size = { 600, 400 };
2190 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2194 this, text = "Save Changes", anchor = { horz = 184, vert = 160 }
2198 this, text = "Cancel", anchor = { horz = 254, vert = 160 }
2202 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2203 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2205 class HelpView : HTMLView
2209 hasVertScroll = true;
2210 hasHorzScroll = true;
2212 char editString[MAX_LOCATION];
2217 page = mainForm.browser.currentRow.GetData(null);
2223 GoToAnchor(page.label);
2225 if(page.page) page = page.page;
2228 return HTMLView::OnCreate();
2237 char archiveFile[MAX_LOCATION];
2238 char fileName[MAX_FILENAME];
2239 char directory[MAX_LOCATION];
2242 SplitArchivePath(editString, archiveFile, &location);
2243 GetLastDirectory(location, fileName);
2244 StripLastDirectory(location, directory);
2245 archive = ArchiveOpen(archiveFile, { true } );
2249 ArchiveDir dir = archive.OpenDirectory(directory, null, replace);
2252 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2254 if(block.type == TEXT && block.textLen)
2262 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2264 if(block.type == BR)
2266 else if(block.type == TEXT)
2267 f.Write(block.text, 1, block.textLen);
2271 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2277 Block parent = textBlock.parent;
2278 while((block = parent.subBlocks.first))
2280 parent.subBlocks.Remove(block);
2283 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2284 textBlock.text = CopyString("[Add Text]");
2285 textBlock.textLen = strlen(textBlock.text);
2286 parent.subBlocks.Add(textBlock);
2294 PositionCaret(true);
2300 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2305 HTMLView::OnMouseMove(x, y, mods);
2306 if(textBlock && overLink == textBlock.parent)
2308 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock);
2309 PositionCaret(true);
2314 HTMLView::OnLeftButtonDown(x, y, mods);
2318 return HTMLView::OnLeftButtonDown(x, y, mods);
2321 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2323 if(!edit || !textBlock || clickedLink != textBlock.parent)
2325 HTMLView::OnLeftButtonUp(x, y, mods);
2328 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock);
2329 PositionCaret(true);
2335 // Returns true if it needs scrolling
2337 bool FindMouse(int px, int py, int * tx, int * ty, EditLine * tline, bool half)
2343 bool needHScroll = false;
2350 line = this.viewLine ? (void *)this.viewLine.prev : null;
2355 line = (void *)this.lines.first;
2360 py = Min(py, clientSize.h);
2362 py = Min(py, this.lineCount);
2364 for(c = 0, line = this.viewLine; (line != (void *)this.lines.last && c<py); line = line.next, c++)
2370 if( (px >= clientSize.w || px < clientSize.w/2) && this.viewX)
2373 px = Min(px,clientSize.w+this.space.w);
2377 *tx = AdjustXPosition(line, px + viewX, half, null, MAXINT, 0);
2380 if(tline) *tline = line;
2383 // Prevent divide by 0 from non valid this.font
2385 return (y < this.viewY) || needHScroll;
2387 return (y < this.viewY || y >= this.viewY + clientSize.h / this.space.h) || needHScroll;
2392 bool OnLeftButtonDown(int mx, int my, Modifiers mods)
2397 if(style.noSelect) return true;
2399 if(!mods.isActivate)
2405 mouseX = mx - XOFFSET;
2408 FindMouse(mouseX, mouseY, &x, &y, &line, true);
2414 else if(IsMouseOnSelection() && !mods.isActivate)
2424 if(!mouseMove && !wordSelect && (!mods.isActivate || style.multiLine))
2426 if(mods.shift && !mods.isActivate)
2441 this.selLine = this.line;
2450 UpdateCaretPosition(true);
2455 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2459 mouseSelect = false;
2470 FindMouse(mouseX, mouseY, &x, &y, &line, true);
2476 mouseMove = IsMouseOnSelection();
2480 int size = SelSize();
2483 char * text = new char[size+1];
2487 GetSel(text, false);
2489 if(Max(selY, this.y) == dropY)
2493 if(this.dropX > this.selX)
2494 moveX = this.x - this.selX;
2498 if(this.dropX > this.x)
2499 moveX = this.selX - this.x;
2503 this.dropX -= moveX;
2504 this.selX = this.x = this.dropX;
2505 this.selY = this.y = this.dropY;
2506 this.selLine = this.line = this.dropLine;
2508 SetViewToCursor(true);
2533 FindMouse(mouseX, mouseY, &x, &y, &line, true);
2535 NotifyDropped(master, this, x, y);
2542 bool OnMouseMove(int mx, int my, Modifiers mods)
2548 if(mods != -1 && mods.isSideEffect)
2553 if(style.noSelect) return true;
2554 if(wordSelect) return true;
2555 mouseX = mx - XOFFSET;
2558 needScroll = FindMouse(this.mouseX, this.mouseY, &x, &y, &line, true);
2560 if(this.mouseMove || this.mouseSelect)
2569 ((style.hScroll) || (style.vScroll)))
2576 DirtyLine(this.dropY);
2579 DirtyLine(this.dropY);
2580 this.dropLine = line;
2581 SetViewToCursor(true);
2583 else if(this.mouseSelect)
2585 DirtyLine(this.selY);
2592 SetViewToCursor(true);
2599 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2606 if(style.noSelect) return true;
2607 FindMouse(mx, my, &x, &y, &line, false);
2608 if(!NotifyDoubleClick(master, this, line, mods))
2615 for(c = x; c >= 0; c--)
2618 while(c > 0 && !UTF8_IS_FIRST(line.buffer[c])) c--;
2619 ch = UTF8_GET_CHAR(line.buffer + c, numBytes);
2626 for(c = start; c<line.count; c += numBytes)
2628 unichar ch = UTF8_GET_CHAR(line.buffer + c, numBytes);
2639 this.line = this.selLine = line;
2640 this.wordSelect = (c != start);
2647 bool OnOpen(char * href)
2649 if(!strncmp(href, "api://", 6))
2651 int tag = strtoul(href + 6, null, 16);
2652 DataRow row = mainForm.browser.FindSubRow(tag);
2656 mainForm.browser.SelectRow(row);
2657 while((row = row.parent))
2658 row.collapsed = false;
2659 row = mainForm.browser.currentRow;
2660 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2663 else if(!strncmp(href, "edit://", 7))
2666 int startX = clickedLink.startX, startY = clickedLink.startY;
2667 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2669 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2670 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2672 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2674 display.FontExtent(block.font.font, " ", 1, null, &th);
2677 block.parent.subBlocks.Insert(null, newBlock);
2682 block.parent.subBlocks.Insert(block, newBlock);
2685 newBlock.startX = startX;
2686 newBlock.startY = startY;
2687 newBlock.text = new0 char[1];
2691 textBlock = (Block)clickedLink.subBlocks.first;
2692 if(!strcmp(textBlock.text, "[Add Text]"))
2694 textBlock.text[0] = 0;
2695 textBlock.textLen = 0;
2698 strcpy(editString, href + 7);
2699 selPosition = curPosition = 0;
2702 PositionCaret(true);
2709 int curPosition, selPosition;
2711 bool OnKeyDown(Key key, unichar ch)
2718 OnLeftButtonDown(0,0,0);
2721 selPosition = curPosition = textBlock.textLen;
2722 PositionCaret(true);
2726 selPosition = curPosition = 0;
2727 PositionCaret(true);
2731 selPosition = curPosition = 0;
2732 while(textBlock.prev)
2733 textBlock = textBlock.prev.prev;
2734 PositionCaret(true);
2738 while(textBlock.next && textBlock.next.next)
2739 textBlock = textBlock.next.next;
2740 selPosition = curPosition = textBlock.textLen;
2741 PositionCaret(true);
2747 return HTMLView::OnKeyDown(key, ch);
2750 bool OnKeyHit(Key key, unichar ch)
2758 if(caretY == textBlock.startY)
2762 textBlock = textBlock.prev.prev;
2763 selPosition = curPosition = Min(curPosition, textBlock.textLen);
2764 PositionCaret(false);
2774 int sx = textBlock.startX, sy = textBlock.startY;
2775 char * text = textBlock.text;
2777 Block block = textBlock;
2778 while(block && block.type != TD) block = block.parent;
2781 Block table = block;
2782 while(table && table.type != TABLE) table = table.parent;
2784 maxW = block.w - 2* table.cellPadding;
2786 maxW = clientSize.w - 10 - sx;
2789 maxW = clientSize.w - 10 - sx;
2790 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
2794 int startPos = textPos;
2797 bool lineComplete = false;
2798 for(; textPos<textBlock.textLen && !lineComplete;)
2802 char * nextSpace = strchr(text + textPos, ' ');
2805 len = (nextSpace - (text + textPos)) + 1;
2807 len = textBlock.textLen - textPos;
2809 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
2811 if(x + width + w > maxW && x > 0)
2813 lineComplete = true;
2823 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
2826 curPosition = textPos;
2827 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
2830 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
2831 len = curPosition - startPos;
2832 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
2834 selPosition = curPosition;
2835 PositionCaret(false);
2839 if(sy == caretY - th || textPos == textBlock.textLen)
2841 if(textPos != textBlock.textLen)
2843 int c = textPos - 1;
2844 while(c > 0 && text[c] == ' ') c--;
2845 selPosition = curPosition = c + 1;
2848 selPosition = curPosition = textBlock.textLen;
2849 PositionCaret(false);
2853 sx = textBlock.startX;
2854 } while(textPos < textBlock.textLen);
2863 int sx = textBlock.startX, sy = textBlock.startY;
2864 char * text = textBlock.text;
2866 Block block = textBlock;
2867 while(block && block.type != TD) block = block.parent;
2870 Block table = block;
2871 while(table && table.type != TABLE) table = table.parent;
2873 maxW = block.w - 2* table.cellPadding;
2875 maxW = clientSize.w - 10 - sx;
2878 maxW = clientSize.w - 10 - sx;
2879 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
2881 while(!textPos || textPos < textBlock.textLen)
2883 int startPos = textPos;
2886 bool lineComplete = false;
2887 for(; (textPos < textBlock.textLen) && !lineComplete;)
2891 char * nextSpace = strchr(text + textPos, ' ');
2894 len = (nextSpace - (text + textPos)) + 1;
2896 len = textBlock.textLen - textPos;
2898 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
2900 if(x + width + w > maxW && x > 0)
2902 lineComplete = true;
2912 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
2914 curPosition = textPos;
2916 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
2919 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
2920 len = curPosition - startPos;
2921 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
2923 selPosition = curPosition;
2924 PositionCaret(false);
2930 selPosition = curPosition = textBlock.textLen;
2931 PositionCaret(false);
2934 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
2938 textBlock = textBlock.next.next;
2939 sy = textBlock.startY;
2940 sx = textBlock.startX;
2941 text = textBlock.text;
2946 sx = textBlock.startX;
2950 /*if(textBlock.next && textBlock.next.next)
2952 textBlock = textBlock.next.next;
2953 selPosition = curPosition = Min(curPosition, textBlock.textLen);
2954 PositionCaret(false);
2958 #define IS_ALUNDER(ch) ((ch) == '_' || isalnum((ch)))
2961 // SELECTION CTRL-RIGHT
2963 bool foundAlpha = false;
2965 Block line, lastLine;
2968 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
2970 int start = (line == textBlock) ? curPosition : 0;
2972 for(c = start; c < line.textLen; c++)
2974 if(IS_ALUNDER(line.text[c]))
2986 if(!found && (c != curPosition || line != textBlock))
2990 lastC = line.textLen-1;
2996 selPosition = curPosition = lastC+1;
2997 textBlock = lastLine;
2998 PositionCaret(true);
3002 bool foundAlpha = false;
3006 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3008 int start = (line == textBlock) ? curPosition : 0;
3010 for(c = start; c < line.textLen; c++)
3012 if(!IS_ALUNDER(line.text[c]))
3017 selPosition = curPosition = c;
3019 PositionCaret(true);
3023 // No next word found,
3024 if(!found && (c != curPosition || line != textBlock))
3027 selPosition = curPosition = line.textLen;
3029 PositionCaret(true);
3037 bool foundAlpha = false;
3039 Block line, lastLine;
3042 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3045 if(curPosition == 0 && line != textBlock)
3048 lastC = line.textLen;
3052 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3053 for(c = start; c>=0; c--)
3055 if(IS_ALUNDER(line.text[c]))
3070 // No next word found,
3071 if(!found && curPosition > 0)
3081 textBlock = lastLine;
3082 selPosition = curPosition = lastC;
3083 PositionCaret(true);
3088 if(curPosition < textBlock.textLen)
3090 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3091 PositionCaret(true);
3092 selPosition = curPosition;
3094 else if(textBlock.next && textBlock.next.next)
3096 textBlock = textBlock.next.next;
3097 selPosition = curPosition = 0;
3098 PositionCaret(true);
3104 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3105 PositionCaret(true);
3106 selPosition = curPosition;
3108 else if(textBlock.prev)
3110 textBlock = textBlock.prev.prev;
3111 selPosition = curPosition = textBlock.textLen;
3112 PositionCaret(true);
3118 int c = curPosition;
3120 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3121 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3122 textBlock.textLen -= nb;
3123 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3125 selPosition = curPosition;
3127 //Clear(html.block);
3128 //CreateForms(html.block);
3133 PositionCaret(true);
3136 else if(textBlock.prev)
3138 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3139 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3140 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3142 selPosition = curPosition = prevBlock.textLen;
3143 prevBlock.textLen += textBlock.textLen;
3144 textBlock.parent.subBlocks.Remove(prev);
3146 textBlock.parent.subBlocks.Remove(textBlock);
3148 textBlock = prevBlock;
3151 //Clear(html.block);
3152 //CreateForms(html.block);
3157 PositionCaret(true);
3162 if(textBlock.textLen > curPosition)
3164 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3165 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3166 textBlock.textLen -= nb;
3167 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3169 //Clear(html.block);
3170 //CreateForms(html.block);
3175 PositionCaret(true);
3178 else if(textBlock.next && textBlock.next.next)
3180 Block next = textBlock.next, nextBlock = textBlock.next.next;
3181 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3182 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3184 textBlock.textLen += nextBlock.textLen;
3185 textBlock.parent.subBlocks.Remove(next);
3187 textBlock.parent.subBlocks.Remove(nextBlock);
3191 //Clear(html.block);
3192 //CreateForms(html.block);
3197 PositionCaret(true);
3203 Block block { type = BR, parent = textBlock.parent, font = textBlock.font };
3204 Block newBlock { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3205 int startY = textBlock.startY, startX = textBlock.startX;
3208 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3209 textBlock.parent.subBlocks.Insert(textBlock, block);
3210 textBlock.parent.subBlocks.Insert(block, newBlock);
3214 newBlock.textLen = textBlock.textLen - curPosition;
3215 newBlock.text = new char[newBlock.textLen+1];
3216 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3217 textBlock.textLen = curPosition;
3218 textBlock.text[curPosition] = 0;
3220 newBlock.startY = startY;
3221 newBlock.startX = startX;
3222 selPosition = curPosition = 0;
3224 //Clear(html.block);
3225 //CreateForms(html.block);
3230 textBlock = newBlock;
3231 PositionCaret(true);
3238 ClipBoard clipBoard { };
3239 if(clipBoard.Load())
3242 char * text = clipBoard.memory;
3245 Block parent = textBlock.parent;
3246 FontEntry font = textBlock.font;
3250 if(ch == '\n' || ch == '\r' || !ch)
3252 int len = c - start;
3253 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3254 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3255 memcpy(textBlock.text + curPosition, text + start, len);
3256 textBlock.textLen += len;
3258 selPosition = curPosition;
3261 Block block { type = BR, parent = parent, font = font };
3262 Block newBlock { type = TEXT, parent = parent, font = font };
3263 int startY = textBlock.startY, startX = textBlock.startX;
3266 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3267 textBlock.parent.subBlocks.Insert(textBlock, block);
3268 textBlock.parent.subBlocks.Insert(block, newBlock);
3272 newBlock.textLen = textBlock.textLen - curPosition;
3273 newBlock.text = new char[newBlock.textLen+1];
3274 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3275 textBlock.textLen = curPosition;
3276 textBlock.text[curPosition] = 0;
3278 newBlock.startY = startY;
3279 newBlock.startX = startX;
3280 selPosition = curPosition = 0;
3281 textBlock = newBlock;
3283 if(ch == '\r' && text[c+1] == '\n') c++;
3289 PositionCaret(true);
3297 // eC BUG HERE: (Should be fixed)
3298 if(key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3301 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3304 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3305 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3307 for(c = 0; c<len; c++)
3309 textBlock.text[curPosition] = string[c];
3310 textBlock.textLen++;
3313 selPosition = curPosition;
3316 //Clear(html.block);
3317 //CreateForms(html.block);
3322 PositionCaret(true);
3331 void OnResize(int width, int height)
3333 HTMLView::OnResize(width, height);
3334 PositionCaret(true);
3338 void PositionCaret(bool setCaretX)
3344 int sx = textBlock.startX, sy = textBlock.startY;
3345 char * text = textBlock.text;
3347 Block block = textBlock;
3348 while(block && block.type != TD) block = block.parent;
3351 Block table = block;
3352 while(table && table.type != TABLE) table = table.parent;
3354 maxW = block.w - 2* table.cellPadding;
3356 maxW = clientSize.w - 10 - sx;
3359 maxW = clientSize.w - 10 - sx;
3361 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3363 while(textPos < textBlock.textLen)
3365 int startPos = textPos;
3368 bool lineComplete = false;
3370 for(; textPos<textBlock.textLen && !lineComplete;)
3374 char * nextSpace = strchr(text + textPos, ' ');
3377 len = (nextSpace - (text + textPos)) + 1;
3379 len = textBlock.textLen - textPos;
3381 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3383 if(x + width + w > maxW && x > 0)
3385 lineComplete = true;
3398 if(curPosition < textPos || textPos == textBlock.textLen)
3400 int len = curPosition - startPos;
3401 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3406 sx = textBlock.startX;
3411 SetCaret(sx, sy, th);
3413 Point scrollPos = scroll;
3414 bool doScroll = false;
3415 if(sy - scroll.y + th > clientSize.h)
3417 scrollPos.y = sy + th - clientSize.h;
3420 else if(sy - scroll.y < 0)
3425 if(sx - scroll.x + 10 > clientSize.w)
3427 scrollPos.x = sx + 10 - clientSize.w;
3430 else if(sx - scroll.x < 10)
3432 scrollPos.x = sx - 10;
3443 // Returns a character offset into the TextBlock from a window coordinate
3444 int TextPosFromPoint(int px, int py, Block * block)
3446 Block parentBlock = this.textBlock.parent;
3449 *block = this.textBlock;
3454 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3456 int sx = textBlock.startX, sy = textBlock.startY;
3459 char * text = textBlock.text;
3461 Block b = textBlock;
3464 if(textBlock.type != TEXT) continue;
3466 while(b && b.type != TD) b = b.parent;
3470 while(table && table.type != TABLE) table = table.parent;
3472 maxW = b.w - 2* table.cellPadding;
3474 maxW = clientSize.w - 10 - sx;
3477 maxW = clientSize.w - 10 - sx;
3479 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3480 //space = space/2+2;
3483 while(textPos < textBlock.textLen)
3485 int startPos = textPos;
3488 bool lineComplete = false;
3490 for(; textPos<textBlock.textLen && !lineComplete;)
3494 char * nextSpace = strchr(text + textPos, ' ');
3497 len = (nextSpace - (text + textPos)) + 1;
3499 len = textBlock.textLen - textPos;
3501 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3503 sx = x + textBlock.startX;
3504 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3509 for(c = textPos; (ch = text[c]); c += numBytes)
3511 numBytes = UTF8_NUM_BYTES(ch);
3512 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3513 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + w -w/2-space)
3520 if(x + width + w > maxW && x > 0)
3522 lineComplete = true;
3535 if(/*py >= sy && */py < sy + th)
3538 return textBlock.textLen;
3543 result = textBlock.textLen;
3549 Application componentsApp;
3551 class Documentor : GuiApplication
3555 Platform os = GetRuntimePlatform();
3556 componentsApp = __ecere_COM_Initialize(false, 1, null);
3557 SetPrivateModule(componentsApp);
3558 SetGlobalContext(globalContext);
3559 SetExcludedSymbols(&excludedSymbols);
3560 SetDefines(&::defines);
3561 SetImports(&imports);
3563 SetGlobalData(globalData);
3565 settingsContainer.dataOwner = &settings;
3566 settingsContainer.Load();
3567 if(!settings.docDir || !settings.docDir[0] )
3569 if(os == win32) // if Windows OS then
3571 char programFilesDir[MAX_LOCATION];
3572 char appData[MAX_LOCATION];
3573 char homeDrive[MAX_LOCATION];
3574 char winDir[MAX_LOCATION];
3575 GetEnvironment("APPDATA", appData, sizeof(appData));
3576 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3577 GetEnvironment("windir", winDir, sizeof(winDir));
3578 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3580 PathCat(programFilesDir, "ECERE SDK\\doc");
3581 settings.docDir = programFilesDir;
3583 else if(homeDrive && homeDrive[0])
3585 PathCat(homeDrive, "ECERE SDK\\doc");
3586 settings.docDir = homeDrive;
3588 else if(winDir && winDir[0])
3590 PathCat(winDir, "..\\ECERE SDK\\doc");
3591 settings.docDir = winDir;
3594 settings.docDir = "C:\\ECERE SDK\\doc";
3596 else // if Os is Linux, or Mac OSX or something else
3597 settings.docDir = "/usr/share/ecere/doc/";
3598 settingsContainer.Save();
3604 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3606 AddComponents(module, true);
3607 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int)module);
3608 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int)eSystem_FindClass(componentsApp, "Window"));
3609 while((row = row.parent))
3610 row.collapsed = false;
3618 FreeContext(globalContext);
3619 FreeExcludedSymbols(excludedSymbols);
3620 ::defines.Free(FreeModuleDefine);
3621 imports.Free(FreeModuleImport);
3623 FreeGlobalData(globalData);
3624 FreeTypeData(componentsApp);
3626 delete componentsApp;
3630 MainForm mainForm { };