import "ecere"
+#if !defined(EAR_TO_ECON_ECDOC)
import "ec"
import "HTMLView"
import "IDESettings"
import "SettingsDialog"
+IDESettings ideSettings;
+
+IDESettingsContainer settingsContainer
+{
+ dataOwner = &ideSettings;
+ dataClass = class(IDESettings);
+};
+
static Context globalContext { };
static OldList defines { };
static OldList imports { };
static NameSpace globalData;
-static OldList excludedSymbols { offset = (uint)&((Symbol)0).left };
+static OldList excludedSymbols { offset = (uint)(uintptr)&((Symbol)0).left };
+static bool readOnly;
+
+define app = (GuiApplication)__thisModule.application;
#define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
private:
-static void Dummy()
+static __attribute__((unused)) void Dummy()
{
-int a;
-a.OnGetString(null, null, null);
+ int a;
+ a.OnGetString(null, null, null);
}
static bool editing = true;
enum CodeObjectType { typeClass, typeData, typeMethod, typeEvent, typeProperty, typeNameSpace, typeDataType, typeEnumValue, typeDataPrivate, typeMethodPrivate, typePropertyPrivate };
-static char * iconNames[CodeObjectType] =
+static const char * iconNames[CodeObjectType] =
{
"<:ecere>constructs/class.png",
"<:ecere>constructs/data.png",
"<:ecere>constructs/propertyPrivate.png"
};
-IDESettings settings { }; // instantiate the IDESettings class from the IDESettings.ec file. Do this at a global level so that all methods can access settings.
-
-IDESettingsContainer settingsContainer
+void GetTemplateString(Class c, char * templateString)
{
- driver = "JSON";
- data = settings;
- dataOwner = &settings;
-};
+ Module m = c.module.application;
+ const char * n = c.name;
+ char * lt = strchr(n, '<');
+ char * s;
+ char ch;
+ char curName[256];
+ int len = 0;
+
+ memcpy(templateString, n, lt-n);
+ templateString[lt-n] = 0;
+ strcat(templateString, "</a>");
+
+ for(s = lt; (ch = *s); s++)
+ {
+ if(ch == '<' || ch == '>' || ch == ',')
+ {
+ if(len)
+ {
+ Class pc;
+ char * d = templateString + strlen(templateString);
+ curName[len] = 0;
+ TrimLSpaces(curName, curName);
+ TrimRSpaces(curName, curName);
+ pc = eSystem_FindClass(m, curName);
+ if(pc)
+ sprintf(d, "%s<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", !strncmp(curName, "const ", 6) ? "const " : "", pc, pc.name);
+ else
+ strcat(d, curName);
+ }
+ if(ch == '<')
+ strcat(templateString, "<");
+ else if(ch == '>')
+ strcat(templateString, ">");
+ else
+ strcat(templateString, ", ");
+ len = 0;
+ }
+ else if(ch == '=')
+ {
+ curName[len++] = ' ';
+ curName[len++] = ch;
+ curName[len++] = ' ';
+ curName[0] = 0;
+ strcat(templateString, curName);
+ len = 0;
+ }
+ else
+ curName[len++] = ch;
+ }
+}
// WARNING : This function expects a null terminated string since it recursively concatenate...
static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
{
if(type)
{
+ if(type.constant && (type.kind != pointerType && type.kind != arrayType))
+ strcat(string, "const ");
switch(type.kind)
{
case classType:
if(type._class.registered)
{
char hex[20];
- sprintf(hex, "%p", type._class.registered);
+ const char * s = type._class.registered.name;
+ sprintf(hex, "%p", type._class.registered.templateClass ? type._class.registered.templateClass : type._class.registered);
strcat(string, "<a href=\"api://");
strcat(string, hex);
strcat(string, "\" style=\"text-decoration: none;\">");
- strcat(string, type._class.registered.name);
+ if(strchr(s, '<'))
+ {
+ char n[1024];
+ GetTemplateString(type._class.registered, n);
+ strcat(string, n);
+ }
+ else
+ strcat(string, type._class.registered.name);
strcat(string, "</a>");
}
else
DocPrintType(type.returnType, string, false, fullName);
strcat(string, " ");
}
-
+
// DANGER: Testing This
if(printName)
{
strcat(string, "</b>");
}
}
- else
- {
- printf("");
- }
}
if(printFunction)
strcat(size, arrayType.enumClass.string);
else if(arrayType.arraySizeExp)
PrintExpression(arrayType.arraySizeExp, size);
- //sprintf(string, "%s[%s]", baseType, size);
+ //sprintf(string, "%s[%s]", baseType, size);
strcat(size, "]");
arrayType = arrayType.arrayType;
strcpy(size, type.enumClass.string);
else if(type.arraySizeExp)
PrintExpression(type.arraySizeExp, size);
- //sprintf(string, "%s[%s]", baseType, size);
+ //sprintf(string, "%s[%s]", baseType, size);
strcat(string, baseType);
strcat(string, "[");
- strcat(string, size);
+ strcat(string, size);
strcat(string, "]");
*/
strcat(string, ")");
break;
default:
- printf("");
+ break;
}
if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
{
for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
if(funcType && funcType.kind == functionType && type != funcType)
{
- char typeString[1024];
Type param;
DocPrintType(funcType.returnType, string, false, fullName);
_PrintType(type, string, printName, true, fullName);
}
+Map<String, bool> modulesAdded { };
void AddComponents(Module module, bool isDll)
{
DataRow row = null;
SubModule m;
- if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
+ if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")) && !modulesAdded["ecereCOM"])
{
row = mainForm.browser.AddRow();
+ modulesAdded["ecereCOM"] = true;
row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
- row.tag = (int)null;
+ row.tag = (int64)null;
AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
}
}
// PUT MODULE DESCRIPTION HERE
- if(module.name && strcmp(module.name, "ecereCOM"))
+ if(module.name && !modulesAdded[module.name] && strcmp(module.name, "ecereCOM"))
{
row = mainForm.browser.AddRow();
+ modulesAdded[module.name] = true;
row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
- row.tag = (int)module;
+ row.tag = (int64)module;
AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
if(!isDll)
AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
class APIPage
{
public:
- char * name;
+ const char * name;
APIPage page;
- char * label;
+ const char * label;
bool showPrivate;
- char * OnGetString(char * tempString, void * fieldData, bool * needClass)
+ const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
{
return name;
}
{
page.Generate(f);
}
+
+ virtual Module GetModule()
+ {
+ return page ? page.GetModule() : null;
+ }
+
+ virtual NameSpace * GetNameSpace()
+ {
+ return page ? page.GetNameSpace() : null;
+ }
};
enum DocumentationType
{
+ unset,
nameSpaceDoc,
classDoc,
functionDoc,
enum DocumentationItem
{
+ unset,
description,
usage,
remarks,
static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
{
+ char hex[20];
+ fileName[0] = 0;
+ sprintf(hex, "%p", module);
+ strcat(fileName, hex);
+ strcat(fileName, "/");
+ sprintf(hex, "%p", object);
+ strcat(fileName, hex);
+ strcat(fileName, "/");
+ sprintf(hex, "%p", data);
+ strcat(fileName, hex);
+ strcat(fileName, "/");
+ if(type == nameSpaceDoc)
+ strcat(fileName, "namespace");
+ else if(type == functionDoc)
+ strcat(fileName, "function");
+ else if(type == classDoc)
+ strcat(fileName, "class");
+ else if(type == methodDoc)
+ strcat(fileName, "method");
+ strcat(fileName, "/");
+ if(item == description)
+ strcat(fileName, "description");
+ else if(item == usage)
+ strcat(fileName, "usage");
+ else if(item == remarks)
+ strcat(fileName, "remarks");
+ else if(item == example)
+ strcat(fileName, "example");
+ else if(item == seeAlso)
+ strcat(fileName, "seeAlso");
+ else if(item == enumerationValue)
+ strcat(fileName, "enumerationValue");
+ else if(item == definition)
+ strcat(fileName, "definition");
+ else if(item == conversion)
+ strcat(fileName, "conversion");
+ else if(item == memberDescription)
+ strcat(fileName, "memberDescription");
+ else if(item == propertyDescription)
+ strcat(fileName, "propertyDescription");
+ else if(item == parameter)
+ strcat(fileName, "parameter");
+ else if(item == returnValue)
+ strcat(fileName, "returnValue");
+}
+
+static void FigureFilePath(char * path, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
+{
+ char docPath[MAX_LOCATION];
NameSpace * nameSpace, * ns;
Class cl = null;
Method method = null;
GlobalFunction function = null;
char nsName[1024], temp[1024];
- char docFile[1024];
-
-
switch(type)
{
case nameSpaceDoc: nameSpace = object; break;
}
nsName[0] = 0;
+ temp[0] = 0;
ns = nameSpace;
while(ns && ns->name)
{
- strcpy(temp, "namespaces/");
- strcat(temp, ns->name);
+ strcpy(temp, ns->name);
strcat(temp, "/");
strcat(temp, nsName);
strcpy(nsName, temp);
ns = ns->parent;
}
- sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
-
- 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.
- strcat(fileName, nsName);
+ docPath[0] = 0;
+ PathCatSlash(docPath, (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
+ //ChangeExtension(docPath, "eCdoc", docPath);
+ PathCatSlash(docPath, nsName);
if(cl)
{
- strcat(fileName, "classes/");
- strcat(fileName, cl.name);
- strcat(fileName, "/");
- }
-
- if(method)
- {
- strcat(fileName, "methods/");
- strcat(fileName, method.name);
- strcat(fileName, "/");
- }
- else if(function)
- {
- char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
- if(name) name += 2; else name = function.name;
- strcat(fileName, "functions/");
- strcat(fileName, name);
- strcat(fileName, "/");
- }
-
- switch(item)
- {
- case description: strcat(fileName, "description"); break;
- case usage: strcat(fileName, "usage"); break;
- case remarks: strcat(fileName, "remarks"); break;
- case example: strcat(fileName, "example"); break;
- case seeAlso: strcat(fileName, "seeAlso"); break;
- case returnValue: strcat(fileName, "returnValue"); break;
- case enumerationValue:
- strcat(fileName, "enumeration values/");
- strcat(fileName, ((NamedLink)data).name);
- break;
- case definition:
- strcat(fileName, "definitions/");
- strcat(fileName, ((Definition)data).name);
- break;
- case conversion:
- {
- char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
- if(name) name += 2; else name = ((Property)data).name;
- strcat(fileName, "conversions/");
- strcat(fileName, name);
- break;
- }
- case memberDescription:
- strcat(fileName, "data members/");
- strcat(fileName, ((DataMember)data).name);
- break;
- case propertyDescription:
- strcat(fileName, "properties/");
- strcat(fileName, ((Property)data).name);
- break;
- case parameter:
- {
- int count;
- char name[1024];
- Type prev;
- strcat(fileName, "parameters/");
- for(prev = data, count = 0; prev; prev = prev.prev, count++);
- sprintf(name, "%s.%d", ((Type)data).name, count);
- strcat(fileName, name);
- break;
- }
+ char * name = getDocFileNameFromTypeName(cl.name);
+ PathCatSlash(docPath, name);
+ delete name;
}
+ else
+ PathCatSlash(docPath, "_global-defs");
+ ChangeExtension(docPath, "econ", docPath);
+
+ path[0] = 0;
+ strcpy(path, ideSettings.docDir);
+ PathCatSlash(path, docPath);
}
static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
{
- char fileName[MAX_LOCATION];
String contents = null;
- File file;
+ NamespaceDoc nsDoc = null;
+ ClassDoc clDoc = null;
+ FunctionDoc fnDoc = null;
+ MethodDoc mdDoc = null;
+ String s = null;
+ char filePath[MAX_LOCATION];
+ Method method = null;
+ GlobalFunction function = null;
- FigureFileName(fileName, module, type, object, item, data);
- file = FileOpen(fileName, read);
- if(file)
+ ItemDoc doc = getDoc(filePath, module, type, object, item, data, false);
+
+ switch(type)
{
- uint len;
- if((len = file.GetSize()))
+ case functionDoc: function = object; break;
+ case methodDoc: method = object; break;
+ }
+
+ if(doc)
+ {
+ if(eClass_IsDerived(doc._class, class(ClassDoc)))
{
- contents = new char[len+1];
- file.Read(contents, 1, len);
- contents[len] = '\0';
+ clDoc = (ClassDoc)doc;
+ }
+ else if(eClass_IsDerived(doc._class, class(NamespaceDoc)))
+ {
+ nsDoc = (NamespaceDoc)doc;
}
- delete file;
}
- if(contents)
+
+ if(clDoc || nsDoc)
{
- int c;
- for(c = 0; contents[c]; c++)
- if(!isspace(contents[c])) break;
- if(!contents[c])
- delete contents;
+ ItemDoc itDoc = null;
+ if(type == functionDoc)
+ {
+ MapIterator<String, FunctionDoc> it { map = nsDoc.functions };
+ const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
+ if(name) name += 2; else name = function.name;
+ if(it.Index(name, false))
+ fnDoc = it.data;
+ }
+ else if(type == methodDoc)
+ {
+ MapIterator<String, MethodDoc> it { map = clDoc.methods };
+ if(it.Index(method.name, false))
+ mdDoc = it.data;
+ }
+
+ switch(item)
+ {
+ case description: s = type == methodDoc ? mdDoc.description : type == functionDoc ? fnDoc.description : type == classDoc ? clDoc.description : nsDoc.description; break;
+ case usage: s = type == methodDoc ? mdDoc.usage : type == functionDoc ? fnDoc.usage : type == classDoc ? clDoc.usage : null; break;
+ case remarks: s = type == methodDoc ? mdDoc.remarks : type == functionDoc ? fnDoc.remarks : type == classDoc ? clDoc.remarks : null; break;
+ case example: s = type == methodDoc ? mdDoc.example : type == functionDoc ? fnDoc.example : type == classDoc ? clDoc.example : null; break;
+ case seeAlso: s = type == methodDoc ? mdDoc.also : type == functionDoc ? fnDoc.also : type == classDoc ? clDoc.also : null; break;
+ case returnValue: s = type == methodDoc ? mdDoc.returnValue : type == functionDoc ? fnDoc.returnValue : null; break;
+ case enumerationValue:
+ if(clDoc && clDoc.values)
+ {
+ itDoc = clDoc.values[((NamedLink)data).name];
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ case definition:
+ if(nsDoc && nsDoc.defines)
+ {
+ itDoc = nsDoc.defines[((Definition)data).name];
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ case conversion:
+ if(clDoc && clDoc.conversions)
+ {
+ const char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
+ if(name) name += 2; else name = ((Property)data).name;
+ itDoc = clDoc.conversions[name];
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ case memberDescription:
+ if(clDoc && clDoc.fields)
+ {
+ itDoc = clDoc.fields[((DataMember)data).name];
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ case propertyDescription:
+ if(clDoc && clDoc.properties)
+ {
+ itDoc = clDoc.properties[((Property)data).name];
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ case parameter:
+ if((type == functionDoc && fnDoc && fnDoc.parameters) || (type == methodDoc && mdDoc && mdDoc.parameters))
+ {
+ char * name = ((Type)data).name;
+ itDoc = ((type == functionDoc) ? fnDoc.parameters : mdDoc.parameters)[name] ;
+ if(itDoc) s = itDoc.description;
+ }
+ break;
+ }
+ if(s)
+ contents = CopyString(s);
}
- if(editing && !contents)
+ if(editing && !contents && !readOnly)
contents = CopyString($"[Add Text]");
+ delete doc;
return contents;
}
+ // The filePath is returned!
+ItemDoc getDoc(char * filePath, Module module, DocumentationType type, void * object, DocumentationItem item, void * data, bool create)
+{
+ ItemDoc doc = null;
+ Class cl = null;
+ Method method = null;
+ DocCacheEntry entry;
+ Time now;
+
+ switch(type)
+ {
+ case classDoc: cl = (Class)object; break;
+ case methodDoc: method = object; cl = method._class; break;
+ }
+
+ FigureFilePath(filePath, module, type, object, item, data);
+
+ entry = docCache[filePath];
+ if(entry)
+ doc = entry.doc;
+
+ if(!doc)
+ {
+ File f = FileOpen(filePath, read);
+ if(f)
+ {
+ ECONParser parser { f = f };
+ JSONResult jsonResult = parser.GetObject(cl ? class(ClassDoc) : class(NamespaceDoc), &doc);
+ delete parser;
+ delete f;
+
+ if(jsonResult != success)
+ {
+ PrintLn("error: problem parsing file: ", filePath);
+ delete doc;
+ }
+ }
+ if(!doc)
+ doc = cl ? (ItemDoc)ClassDoc { } : (ItemDoc)NamespaceDoc { };
+ }
+
+ incref doc; // Reference to return
+
+ now = GetTime();
+ // Add to the cache
+ if(entry)
+ entry.timeStamp = now;
+ else
+ {
+ docCache[filePath] = { now, doc };
+ incref doc; // Reference for the cache
+ }
+
+ //void pruneDocCache()
+ // NOTE: If we want time stamp to be last retrieved, the pruning should be done before the retrieval
+ {
+ MapIterator<String, DocCacheEntry> it { map = docCache };
+ Array<const String> toRemove { };
+ for(entry : docCache; now - entry.timeStamp > 30)
+ toRemove.Add(&entry);
+ while(toRemove.count)
+ {
+ if(it.Index(toRemove.lastIterator.data, false))
+ {
+ delete it.data;
+ it.Remove();
+ }
+ toRemove.Remove(toRemove.lastIterator.pointer);
+ }
+ delete toRemove;
+ }
+ return doc;
+}
class APIPageNameSpace : APIPage
{
NameSpace * nameSpace;
Module module;
-
+
+ Module GetModule()
+ {
+ return module;
+ }
+
+ NameSpace * GetNameSpace()
+ {
+ return nameSpace;
+ }
+
void Generate(File f)
{
- char string[1024];
char nsName[1024], temp[1024];
NameSpace * ns;
BTNamedLink link;
- uint tag;
nsName[0] = 0;
ns = nameSpace;
if(nsName[0])
{
f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
- tag = (uint)nameSpace;
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);
}
else
- {
- tag = (uint)((!module || !module.name || !strcmp(nsName, "ecere::com") ? null : module));
f.Printf($"<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
- }
nsName[0] = 0;
ns = nameSpace->parent;
strcpy(nsName, temp);
ns = ns->parent;
}
- if(nsName[0])
+ if(nsName[0])
f.Printf($"Parent namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
f.Printf("<br>");
char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
if(desc)
{
- f.Printf($"<H3>Description</H3><br><br>\n");
+ f.Printf($"<H3>Description</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
f.Puts(desc);
- f.Printf("</a><br><br>");
+ f.Printf("</a>");
}
else
- f.Printf("%s<br><br>", desc);
+ f.Printf("%s", desc);
+ f.Printf("<br><br><br>");
delete desc;
}
}
char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
if(first)
{
- f.Printf($"<H3>Sub Namespaces</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<H3>Sub Namespaces</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
f.Printf("<TR>");
f.Printf("</TR><br>\n");
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
if(nameSpace->classes.first)
for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
{
Class cl = link.data;
- if(!cl.templateClass)
+ Module module = cl.module ? cl.module : this.module;
+ if(!cl.templateClass) // && !cl.internalDecl)
{
char * desc = ReadDoc(module, classDoc, cl, description, null);
if(first)
{
- f.Printf($"<a name=Classes></a><H3>Classes</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Classes></a><H3>Classes</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
}
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
if(nameSpace->functions.first)
for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
{
GlobalFunction function = link.data;
+ Module module = function.module ? function.module : this.module;
char * desc = ReadDoc(module, functionDoc, function, description, null);
- char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
+ const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
if(name) name += 2; else name = function.name;
if(first)
{
- f.Printf($"<a name=Functions></a><H3>Functions</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Functions></a><H3>Functions</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
f.Printf("<TR>");
f.Printf("</TR><br>\n");
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
if(nameSpace->defines.first)
char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
if(first)
{
- f.Printf($"<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Definitions></a><H3>Definitions</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
f.Printf("<TR>");
f.Printf("</TR><br>\n");
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
f.Printf("</FONT></BODY></HTML>\n");
{
Class cl;
+ Module GetModule()
+ {
+ return cl.module;
+ }
+
+ NameSpace * GetNameSpace()
+ {
+ return cl.nameSpace;
+ }
+
void Generate(File f)
{
char string[1024];
Method method;
Property prop;
- DataMember member;
char nsName[1024], temp[1024];
NameSpace * ns = cl.nameSpace;
Module module = cl.module;
f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
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);
- if(nsName[0])
+ if(nsName[0])
f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
{
- char * classType = null;
+ const char * classType = null;
switch(cl.type)
{
case bitClass:
}
f.Printf($"Type: %s<br>\n", classType);
}
-
+
if(cl.type != systemClass && cl.base)
{
f.Printf($"Base Class: ");
char * desc = ReadDoc(module, classDoc, cl, description, null);
if(desc)
{
- f.Printf($"<br><H3>Description</H3><br><br>\n");
+ f.Printf($"<br><H3>Description</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
FigureFileName(fileName, module, classDoc, cl, description, null);
f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
f.Puts(desc);
- f.Printf("</a><br><br>");
+ f.Printf("</a>");
}
else
- f.Printf("%s<br><br>", desc);
+ f.Printf("%s", desc);
+ f.Printf("<br><br><br>");
delete desc;
}
}
if(enumeration.values.first)
{
NamedLink item;
-
- f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+
+ f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><BR>\n");
+ f.Printf("<TABLE>\n");
for(item = enumeration.values.first; item; item = item.next)
{
}
else
dataClass = base;
-
+
f.Printf("<TR>");
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);
if(dataClass.type == systemClass)
if(cl.conversions.first)
{
- f.Printf($"<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Conversions></a><H3>Conversions</H3><BR>\n");
+ f.Printf("<TABLE>\n");
for(prop = cl.conversions.first; prop; prop = prop.next)
{
if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
{
char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
- DataRow mRow;
- char * name;
+ const char * name;
Type type = ProcessTypeString(prop.name, false);
name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
if(name) name += 2; else name = prop.name;
f.Printf("<TR>");
-
+
string[0] = 0;
DocPrintType(type, string, true, false);
-
+
f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeDataType], string);
if(desc)
{
f.Printf("<TD valign=top height=22>%s</TD>", desc);
delete desc;
}
-
+
f.Printf("</TR>\n");
-
+
FreeType(type);
}
}
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
if(cl.membersAndProperties.first)
{
if(first)
{
- f.Printf($"<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Members></a><H3>Properties and Members</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
}
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
if(cl.methods.first)
char * desc = ReadDoc(module, methodDoc, method, description, null);
if(first)
{
- f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
if(!method.dataType)
}
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
// Non-Virtual Methods
first = true;
char * desc = ReadDoc(module, methodDoc, method, description, null);
if(first)
{
- f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
- f.Printf("<TABLE >\n");
+ f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><BR>\n");
+ f.Printf("<TABLE>\n");
first = false;
}
f.Printf("<TD valign=top height=22>%s</TD>", desc);
delete desc;
}
-
+
f.Printf("</TR><br>\n");
}
}
if(!first)
- f.Printf("</TABLE><br>\n");
+ f.Printf("</TABLE><br><br>\n");
}
{
char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
if(usageDoc)
{
- f.Printf($"<H3>Usage</H3><br>\n");
+ f.Printf($"<H3>Usage</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", usageDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete usageDoc;
}
}
char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
if(exampleDoc)
{
- f.Printf($"<H3>Example</H3><br>\n");
+ f.Printf($"<H3>Example</H3><BR>\n");
f.Printf($"<FONT face=\"Courier New\">\n");
- f.Printf("<br><TABLE >\n");
+ f.Printf("<br><TABLE>\n");
if(editing)
{
char fileName[MAX_LOCATION];
f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
f.Printf("</TABLE></FONT>\n");
- f.Printf("<br>\n");
+ f.Printf("<br><br>\n");
delete exampleDoc;
}
}
if(remarksDoc)
{
- f.Printf($"<H3>Remarks</H3><br>\n");
+ f.Printf($"<H3>Remarks</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", remarksDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete remarksDoc;
}
}
-
+
if(cl.type != systemClass)
{
bool first = true;
{
if(first)
{
- f.Printf($"<H3>Derived Classes</H3><br>\n");
- f.Printf("<br>");
+ f.Printf($"<H3>Derived Classes</H3><BR>\n");
first = false;
}
else
char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
if(seeAlsoDoc)
{
- f.Printf($"<H3>See Also</H3><br>\n");
+ f.Printf($"<H3>See Also</H3>\n");
if(editing)
{
char fileName[MAX_LOCATION];
class APIPageMethod : APIPage
{
Method method;
+
+ Module GetModule()
+ {
+ return method._class.module;
+ }
+
+ NameSpace * GetNameSpace()
+ {
+ return method._class.nameSpace;
+ }
+
void Generate(File f)
{
Class cl = method._class;
char * desc = ReadDoc(module, methodDoc, method, description, null);
if(desc)
{
- f.Printf($"<br><br><H3>Description</H3><br><br>\n");
+ f.Printf($"<br><br><H3>Description</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("%s", desc);
+ f.Printf("<BR><BR>");
delete desc;
}
}
f.Printf("<br><br>\n");
if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
{
- f.Printf($"<H3>Parameters</H3><br><br>\n");
+ f.Printf($"<H3>Parameters</H3><BR>\n");
}
if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
FigureFileName(fileName, module, methodDoc, method, parameter, param);
f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
f.Puts(desc);
- f.Printf("s</a> </TD>\n");
+ f.Printf("</a></TD>\n");
}
else
f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
delete desc;
}
-
+
f.Printf("</TR>\n");
}
}
char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
if(usageDoc)
{
- f.Printf($"<H3>Usage</H3><br>\n");
+ f.Printf($"<H3>Usage</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", usageDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete usageDoc;
}
}
char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
if(exampleDoc)
{
- f.Printf($"<H3>Example</H3><br>\n");
+ f.Printf($"<H3>Example</H3><BR>\n");
f.Printf($"<FONT face=\"Courier New\">\n");
- f.Printf("<br><TABLE >\n");
+ f.Printf("<br><TABLE>\n");
if(editing)
{
char fileName[MAX_LOCATION];
else
f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
f.Printf("</TABLE></FONT>\n");
- f.Printf("<br>\n");
+ f.Printf("<br><br>\n");
delete exampleDoc;
}
}
char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
if(remarksDoc)
{
- f.Printf($"<H3>Remarks</H3><br>\n");
+ f.Printf($"<H3>Remarks</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", method, remarksDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete remarksDoc;
}
}
char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
if(seeAlsoDoc)
{
- f.Printf($"<H3>See Also</H3><br>\n");
+ f.Printf($"<H3>See Also</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", method, seeAlsoDoc);
-
- f.Printf("<br><br>\n");
+
+ f.Printf("<br><br><br>\n");
delete seeAlsoDoc;
}
}
class APIPageFunction : APIPage
{
GlobalFunction function;
+
+ Module GetModule()
+ {
+ return function.module;
+ }
+
+ NameSpace * GetNameSpace()
+ {
+ return function.nameSpace;
+ }
+
void Generate(File f)
{
char string[1024];
char * desc = ReadDoc(module, functionDoc, function, description, null);
if(desc)
{
- f.Printf($"<br><br><H3>Description</H3><br><br>\n");
+ f.Printf($"<br><br><H3>Description</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
else
f.Printf("%s", desc);
delete desc;
+ f.Printf("<BR><BR>");
}
}
f.Printf("<br><br>\n");
if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
{
- f.Printf($"<H3>Parameters</H3><br><br>\n");
+ f.Printf($"<H3>Parameters</H3><BR>\n");
}
if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
char fileName[MAX_LOCATION];
FigureFileName(fileName, module, functionDoc, function, parameter, param);
f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
- f.Puts(desc);
+ if(desc)
+ f.Puts(desc);
f.Printf("</a> </TD>\n");
}
else
char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
if(usageDoc)
{
- f.Printf($"<H3>Usage</H3><br>\n");
+ f.Printf($"<H3>Usage</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", usageDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete usageDoc;
}
}
char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
if(exampleDoc)
{
- f.Printf($"<H3>Example</H3><br>\n");
+ f.Printf($"<H3>Example</H3><BR>\n");
f.Printf($"<FONT face=\"Courier New\">\n");
- f.Printf("<br><TABLE >\n");
+ f.Printf("<br><TABLE>\n");
if(editing)
{
char fileName[MAX_LOCATION];
else
f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
f.Printf("</TABLE></FONT>\n");
- f.Printf("<br>\n");
+ f.Printf("<br><br>\n");
delete exampleDoc;
}
}
char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
if(remarksDoc)
{
- f.Printf($"<H3>Remarks</H3><br>\n");
+ f.Printf($"<H3>Remarks</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", remarksDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete remarksDoc;
}
}
char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
if(seeAlsoDoc)
{
- f.Printf($"<H3>See Also</H3><br>\n");
+ f.Printf($"<H3>See Also</H3><BR>\n");
if(editing)
{
char fileName[MAX_LOCATION];
}
else
f.Printf("<br>%s\n", seeAlsoDoc);
- f.Printf("<br><br>\n");
+ f.Printf("<br><br><br>\n");
delete seeAlsoDoc;
}
}
}
}
-static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, char * parentName, bool showPrivate)
+static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, const char * parentName, bool showPrivate)
{
char nsName[1024];
NameSpace * ns;
DataRow functionsRow = null, definesRow = null;
APIPage page;
- char fileName[MAX_LOCATION];
-
strcpy(nsName, parentName ? parentName : "");
if(nameSpace->name)
{
{
row = parentRow.AddRow();
row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
- row.tag = (int)nameSpace;
+ row.tag = (int64)nameSpace;
row.icon = mainForm.icons[typeNameSpace];
}
else
page = parentRow.GetData(null);
}
+ for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
{
- bool first = true;
-
- for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
- {
- NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
- AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
- }
- if(comNameSpace != null)
+ NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
+ AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
+ }
+ if(comNameSpace != null)
+ {
+ for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
{
- for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
+ if(!mainNameSpace.nameSpaces.FindString(ns->name))
{
- if(!mainNameSpace.nameSpaces.FindString(ns->name))
- {
- AddNameSpace(row, module, ns, null, nsName, showPrivate);
- }
+ AddNameSpace(row, module, ns, null, nsName, showPrivate);
}
}
}
+
if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
{
for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
{
cl = link.data;
- if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
+ if(!cl.templateClass /*&& !cl.internalDecl*/ && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
{
if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { $"Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
AddClass(classesRow, module, cl, nsName, showPrivate);
{
for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
{
- if(nameSpace->functions.first)
+ if(nameSpace->functions.first)
{
BTNamedLink link;
GlobalFunction fn;
fn = link.data;
if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
{
- char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
+ const char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
DataRow fnRow;
if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
- fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int)fn;
+ fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int64)fn;
}
}
}
}
}
-
+
if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
{
for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
DataRow defRow;
if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
- defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int)def;
+ defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int64)def;
}
}
}
}
else
f.Printf("<TD valign=top height=22></TD>");
-
+
if(member.type != normalMember)
{
DataMember subMember;
if(member.type == normalMember)
{
row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
- row.tag = (int)member;
+ row.tag = (int64)member;
}
else
{
DataMember m;
row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
row.icon = mainForm.icons[typeData];
- row.tag = (int)member;
+ row.tag = (int64)member;
for(m = member.members.first; m; m = m.next)
{
static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
{
- char fileName[MAX_LOCATION];
- char string[1024];
Method method;
Property prop;
- DataMember member;
- Type param;
DataRow row;
DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
row = parentRow.AddRow();
row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
- row.tag = (int)cl;
+ row.tag = (int64)cl;
row.collapsed = true;
row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
{
if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { $"Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
- mRow.tag = (int)method;
+ mRow.tag = (int64)method;
}
else
{
if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { $"Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
- mRow.tag = (int)method;
+ mRow.tag = (int64)method;
}
}
else
{
if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { $"Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
- mRow.tag = (int)method;
+ mRow.tag = (int64)method;
}
}
}
DataRow mRow;
if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { $"Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
- mRow.tag = (int)prop;
+ mRow.tag = (int64)prop;
}
else
{
for(prop = cl.conversions.first; prop; prop = prop.next)
{
DataRow mRow;
- char * name;
+ const char * name;
if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { $"Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
if(name) name += 2; else name = prop.name;
mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
- mRow.tag = (int)prop;
+ mRow.tag = (int64)prop;
}
}
if(cl.type == enumClass)
DataRow mRow;
if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
- mRow.tag = (int)item;
+ mRow.tag = (int64)item;
+ }
+ }
+}
+
+class AddressBar : Window
+{
+ background = activeBorder;
+ tabCycle = true;
+ Button open
+ {
+ this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, bitmap = { ":actions/docOpen.png" };
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ MainForm mainForm = (MainForm)parent;
+ FileDialog fileDialog = mainForm.fileDialog;
+ if(fileDialog.Modal() == ok)
+ mainForm.OpenModule(fileDialog.filePath);
+ return true;
+ }
+ };
+ Button back
+ {
+ this, bevelOver = true, inactive = true, anchor = Anchor { left = 28, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
+ disabled = true;
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ ((MainForm)parent).Back();
+ return true;
+ }
+ };
+ Button forward
+ {
+ this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
+ disabled = true;
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ ((MainForm)parent).Forward();
+ return true;
+ }
+ };
+ Button home
+ {
+ this, bevelOver = true, inactive = true, anchor = Anchor { left = 80, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
+
+ bool NotifyClicked(Button button, int x, int y, Modifiers mods)
+ {
+ ((MainForm)parent).Home();
+ return true;
+ }
+ };
+ /* TODO: Search (#143/#441)
+ When there's something in the search box, list matching sections, the exact match first,instead of the Hierarchy in the ListBox.
+ Update this in the NotifyUpdate. Enter goes to the exact match.
+
+ Label { this, anchor = Anchor { left = (124+12) }, labeledWindow = search };
+
+ EditBox search
+ {
+ this, text = "Search:", anchor = Anchor { left = (16+48+124), right = 60, top = 0, bottom = 0 }, hotKey = altD;
+
+ bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
+ {
+ if(!disabled && (SmartKey)key == enter)
+ ((MainForm)parent).Go(editBox.contents);
+ return true;
+ }
+
+ void NotifyUpdate(EditBox editBox)
+ {
+ String location = ((MainForm)parent).view.location;
+ disabled = !strcmp(location ? location : "", editBox.contents);
}
+ };
+ */
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ if(key == escape)
+ ((MainForm)parent).view.MakeActive();
+ return true;
}
}
borderStyle = sizable;
hasMaximize = true;
hasMinimize = true;
- nativeDecorations = true;
icon = { ":documentorIcon.png" };
text = $"API Documentation Browser";
bool NotifySelect(MenuItem selection, Modifiers mods)
{
- SettingsDialog { master = this }.Modal(); // Open the settings dialog to allow the user to change the directory for the eCdoc files
+ if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
+ {
+ // Refresh docs
+ view.edit = false;
+ view.Destroy(0);
+ view.Create();
+ }
return true;
}
};
MenuDivider { fileMenu };
MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
- void OpenModule(char * filePath)
+ void OpenModule(const char * filePath)
{
+ char moduleName[MAX_LOCATION];
char extension[MAX_EXTENSION];
Module module = null;
static char symbolsDir[MAX_LOCATION];
+ history.size = 0;
+ modulesAdded.RemoveAll();
+
FreeContext(globalContext);
FreeExcludedSymbols(excludedSymbols);
::defines.Free(FreeModuleDefine);
imports.Free(FreeModuleImport);
-
+
FreeGlobalData(globalData);
- FreeTypeData(componentsApp);
FreeIncludeFiles();
- delete componentsApp;
+ if(componentsApp)
+ {
+ FreeTypeData(componentsApp);
+ delete componentsApp;
+ }
- SetGlobalContext(globalContext);
componentsApp = __ecere_COM_Initialize(false, 1, null);
SetPrivateModule(componentsApp);
ImportModule(filePath, normalImport, publicAccess, false);
- if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll"))
+ if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
componentsApp.name = CopyString(filePath);
-
+
for(module = componentsApp.allModules.first; module; module = module.next)
{
if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
AddComponents(componentsApp, false);
+ GetLastDirectory(filePath, moduleName);
+ // Extension, path and lib prefix get removed in Module::name
+ if(extension[0])
+ {
+ StripExtension(moduleName);
+ if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
+ {
+ int len = strlen(moduleName) - 3;
+ memmove(moduleName, moduleName + 3, len);
+ moduleName[len] = 0;
+ }
+ }
+
for(module = componentsApp.allModules.first; module; module = module.next)
{
- if(module.name && (!strcmp(module.name, filePath)))
+ if(module.name && (!strcmp(module.name, moduleName)))
break;
}
if(!module) module = componentsApp;
- mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int)module));
+ homeModule = module;
+ mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
SetSymbolsDir(null);
}
+ AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
ListBox browser
{
- this, anchor = { left = 0, top = 0, bottom = 0 }, borderStyle = 0, background = aliceBlue;
+ this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
hotKey = alt0;
{
Window activeChild = this.activeChild;
- view.Destroy(0);
- if(page)
- view.Create();
- activeChild.Activate();
+ // Back / Forward Support
+ if(row && !dontRecordHistory)
+ {
+ if(history.count > historyPos+1)
+ history.count = historyPos+1;
+ historyPos = history.count-1;
+ addressBar.back.disabled = (historyPos == 0);
+ addressBar.forward.disabled = (historyPos >= history.count-1);
+
+ history.Add((Instance)(uint64)row.tag);
+ historyPos = history.count-1;
+
+ addressBar.back.disabled = (historyPos == 0);
+ addressBar.forward.disabled = (historyPos >= history.count-1);
+ }
+
+ view.Destroy(0);
+ if(page)
+ view.Create();
+ activeChild.Activate();
}
else if(!view.created)
view.Create();
-
+
{
page = row.GetData(null);
if(page && page.page)
default:
{
char hex[20];
- sprintf(hex, "%p", row.tag);
+ sprintf(hex, "%p", (void *)(uintptr)row.tag);
view.GoToAnchor(hex);
}
}
};
HelpView view
{
- this, anchor = { top = 0, bottom = 0, right = 0 };
+ this, anchor = { top = 26, bottom = 0, right = 0 };
hotKey = escape;
};
PaneSplitter slider
{
- this, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
+ this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
};
bool OnClose(bool parentClosing)
}
return true;
}
+
+ Array<Instance> history { };
+ int historyPos;
+ bool dontRecordHistory;
+ Module homeModule;
+
+ bool OnKeyHit(Key key, unichar ch)
+ {
+ switch(key)
+ {
+ case altLeft: Back(); return false;
+ case altRight: Forward(); return false;
+ }
+ return true;
+ }
+
+ bool Forward()
+ {
+ if(historyPos < history.count-1)
+ {
+ char location[64];
+ historyPos++;
+ addressBar.back.disabled = (historyPos == 0);
+ addressBar.forward.disabled = (historyPos >= history.count-1);
+ sprintf(location, "api://%p", history[historyPos]);
+ dontRecordHistory = true;
+ view.OnOpen(location);
+ dontRecordHistory = false;
+ return true;
+ }
+ return false;
+ }
+
+ bool Back()
+ {
+ if(historyPos > 0)
+ {
+ char location[64];
+ historyPos--;
+ addressBar.back.disabled = (historyPos == 0);
+ addressBar.forward.disabled = (historyPos >= history.count-1);
+ sprintf(location, "api://%p", history[historyPos]);
+ dontRecordHistory = true;
+ view.OnOpen(location);
+ dontRecordHistory = false;
+ return true;
+ }
+ return false;
+ }
+
+ void Home()
+ {
+ mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
+ }
};
class EditDialog : Window
bool OnCreate()
{
TempFile f { };
+
page = mainForm.browser.currentRow.GetData(null);
if(page)
{
+ // Writability test
+ {
+ char docDir[MAX_LOCATION];
+ readOnly = true;
+ strcpy(docDir, ideSettings.docDir);
+ if(FileExists(docDir).isDirectory)
+ {
+ PathCatSlash(docDir, "___docWriteTest");
+ if(FileExists(docDir).isDirectory)
+ {
+ RemoveDir(docDir);
+ if(!FileExists(docDir))
+ readOnly = false;
+ }
+ else
+ {
+ MakeDir(docDir);
+ if(FileExists(docDir).isDirectory)
+ {
+ readOnly = false;
+ RemoveDir(docDir);
+ }
+ }
+ }
+ }
+
page.Generate(f);
f.Seek(0, start);
OpenFile(f, null);
void SaveEdit()
{
- char archiveFile[MAX_LOCATION];
- char fileName[MAX_FILENAME];
- char directory[MAX_LOCATION];
- char * location;
- Archive archive;
- SplitArchivePath(editString, archiveFile, &location);
- GetLastDirectory(location, fileName);
- StripLastDirectory(location, directory);
- archive = ArchiveOpen(archiveFile, { true } );
- if(archive)
- {
- TempFile f { };
- ArchiveDir dir = archive.OpenDirectory(directory, null, replace);
- Block block;
- bool empty = true;
+ Block block;
+ bool empty = true;
+ String contents = null;
+ uint len;
+ TempFile f { };
+ for(block = textBlock.parent.subBlocks.first; block; block = block.next)
+ {
+ if(block.type == TEXT && block.textLen)
+ {
+ empty = false;
+ break;
+ }
+ }
+ if(!empty)
+ {
for(block = textBlock.parent.subBlocks.first; block; block = block.next)
{
- if(block.type == TEXT && block.textLen)
+ if(block.type == BR)
+ f.Puts("<br>");
+ else if(block.type == TEXT)
+ f.Write(block.text, 1, block.textLen);
+ }
+ }
+ f.Seek(0, start);
+ if((len = f.GetSize()))
+ {
+ contents = new char[len+1];
+ f.Read(contents, 1, len);
+ contents[len] = '\0';
+ }
+
+ {
+ char docPath[MAX_LOCATION];
+ char temp[MAX_LOCATION];
+ char part[MAX_FILENAME];
+ Module module;
+ void * object;
+ void * data;
+ DocumentationType type;
+ DocumentationItem item;
+ ItemDoc doc;
+ NamespaceDoc nsDoc = null;
+ ClassDoc clDoc = null;
+ FunctionDoc fnDoc = null;
+ MethodDoc mdDoc = null;
+ Class cl = null;
+ Method method = null;
+ GlobalFunction function = null;
+
+ strcpy(temp, editString);
+ SplitDirectory(temp, part, temp);
+ module = (Module)strtoull(part, null, 16);
+ SplitDirectory(temp, part, temp);
+ object = (void *)strtoull(part, null, 16);
+ SplitDirectory(temp, part, temp);
+ data = (void *)strtoull(part, null, 16);
+ SplitDirectory(temp, part, temp);
+ if(!strcmp(part, "namespace"))
+ type = nameSpaceDoc;
+ else if(!strcmp(part, "function"))
+ type = functionDoc;
+ else if(!strcmp(part, "class"))
+ type = classDoc;
+ else if(!strcmp(part, "method"))
+ type = methodDoc;
+ SplitDirectory(temp, part, temp);
+ if(!strcmp(part, "description"))
+ item = description;
+ else if(!strcmp(part, "usage"))
+ item = usage;
+ else if(!strcmp(part, "remarks"))
+ item = remarks;
+ else if(!strcmp(part, "example"))
+ item = example;
+ else if(!strcmp(part, "seeAlso"))
+ item = seeAlso;
+ else if(!strcmp(part, "enumerationValue"))
+ item = enumerationValue;
+ else if(!strcmp(part, "definition"))
+ item = definition;
+ else if(!strcmp(part, "conversion"))
+ item = conversion;
+ else if(!strcmp(part, "memberDescription"))
+ item = memberDescription;
+ else if(!strcmp(part, "propertyDescription"))
+ item = propertyDescription;
+ else if(!strcmp(part, "parameter"))
+ item = parameter;
+ else if(!strcmp(part, "returnValue"))
+ item = returnValue;
+
+ doc = getDoc(docPath, module, type, object, item, data, !empty && contents);
+
+ /* Why invalidate this entry here?
+ {
+ MapIterator<const String, DocCacheEntry> it { map = docCache };
+ if(it.Index(docPath, false))
{
- empty = false;
- break;
+ delete it.data;
+ it.Remove();
}
+ }*/
+
+ switch(type)
+ {
+ case classDoc: cl = (Class)object; break;
+ case functionDoc: function = object; break;
+ case methodDoc: method = object; cl = method._class; break;
}
- if(!empty)
+
+ if(doc)
{
- for(block = textBlock.parent.subBlocks.first; block; block = block.next)
+ if(eClass_IsDerived(doc._class, class(ClassDoc)))
{
- if(block.type == BR)
- f.Puts("<br>");
- else if(block.type == TEXT)
- f.Write(block.text, 1, block.textLen);
+ clDoc = (ClassDoc)doc;
+ }
+ else if(eClass_IsDerived(doc._class, class(NamespaceDoc)))
+ {
+ nsDoc = (NamespaceDoc)doc;
}
}
- f.Seek(0, start);
- dir.AddFromFile(fileName, f, null, replace, 0, null, null);
- delete dir;
- delete archive;
- delete f;
- if(empty)
+
+ if(clDoc || nsDoc)
{
- Block parent = textBlock.parent;
- while((block = parent.subBlocks.first))
+ if(type == functionDoc)
+ {
+ const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
+ if(name) name += 2; else name = function.name;
+ fnDoc = nsDoc.functions ? nsDoc.functions[name] : null;
+ if(!empty && !fnDoc)
+ {
+ if(!nsDoc.functions) nsDoc.functions = { };
+ nsDoc.functions[name] = fnDoc = { };
+ }
+ }
+ else if(type == methodDoc)
{
- parent.subBlocks.Remove(block);
- delete block;
+ mdDoc = clDoc.methods ? clDoc.methods[method.name] : null;
+ if(!empty && !mdDoc)
+ {
+ if(!clDoc.methods && !empty) clDoc.methods = { };
+ clDoc.methods[method.name] = mdDoc = { };
+ }
+ }
+
+ if(!empty || mdDoc || fnDoc || (type == classDoc && clDoc) || (type == nameSpaceDoc && nsDoc))
+ {
+ switch(item)
+ {
+ case description:
+ if(type == methodDoc) { mdDoc.description = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.description = contents; contents = null; }
+ else if(type == classDoc) { clDoc.description = contents; contents = null; }
+ else { nsDoc.description = contents; contents = null; }
+ break;
+ case usage:
+ if(type == methodDoc) { mdDoc.usage = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.usage = contents; contents = null; }
+ else if(type == classDoc) { clDoc.usage = contents; contents = null; }
+ break;
+ case remarks:
+ if(type == methodDoc) { mdDoc.remarks = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.remarks = contents; contents = null; }
+ else if(type == classDoc) { clDoc.remarks = contents; contents = null; }
+ break;
+ case example:
+ if(type == methodDoc) { mdDoc.example = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.example = contents; contents = null; }
+ else if(type == classDoc) { clDoc.example = contents; contents = null; }
+ break;
+ case seeAlso:
+ if(type == methodDoc) { mdDoc.also = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.also = contents; contents = null; }
+ else if(type == classDoc) { clDoc.also = contents; contents = null; }
+ break;
+ case returnValue:
+ if(type == methodDoc) { mdDoc.returnValue = contents; contents = null; }
+ else if(type == functionDoc) { fnDoc.returnValue = contents; contents = null; }
+ break;
+ case enumerationValue:
+ {
+ ValueDoc itDoc = clDoc.values ? clDoc.values[((NamedLink)data).name] : null;
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!clDoc.values) clDoc.values = { };
+ clDoc.values[((NamedLink)data).name] = itDoc = { };
+ }
+ itDoc.description = contents; contents = null;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, ValueDoc> it { map = clDoc.values };
+ if(it.Index(((NamedLink)data).name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ break;
+ }
+ case definition:
+ {
+ DefineDoc itDoc = nsDoc.defines ? nsDoc.defines[((Definition)data).name] : null;
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!nsDoc.defines) nsDoc.defines = { };
+ nsDoc.defines[((Definition)data).name] = itDoc = { };
+ }
+ itDoc.description = contents; contents = null;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, DefineDoc> it { map = nsDoc.defines };
+ if(it.Index(((Definition)data).name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ break;
+ }
+ case conversion:
+ {
+ ConversionDoc itDoc;
+ const char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
+ if(name) name += 2; else name = ((Property)data).name;
+ itDoc = clDoc.conversions ? clDoc.conversions[name] : null;
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!clDoc.conversions) clDoc.conversions = { };
+ clDoc.conversions[name] = itDoc = { };
+ }
+ itDoc.description = contents; contents = null;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, ConversionDoc> it { map = clDoc.conversions };
+ if(it.Index(name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ break;
+ }
+ case memberDescription:
+ {
+ FieldDoc itDoc = clDoc.fields ? clDoc.fields[((DataMember)data).name] : null;
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!clDoc.fields) clDoc.fields = { };
+ clDoc.fields[((DataMember)data).name] = itDoc = { };
+ }
+ itDoc.description = contents; contents = null;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, FieldDoc> it { map = clDoc.fields };
+ if(it.Index(((DataMember)data).name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ break;
+ }
+ case propertyDescription:
+ {
+ PropertyDoc itDoc = clDoc.properties ? clDoc.properties[((Property)data).name] : null;
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!clDoc.properties) clDoc.properties = { };
+ clDoc.properties[((Property)data).name] = itDoc = { };
+ }
+ itDoc.description = contents, contents = null;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, PropertyDoc> it { map = clDoc.properties };
+ if(it.Index(((Property)data).name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ break;
+ }
+ case parameter:
+ {
+ if(type == functionDoc || type == methodDoc)
+ {
+ Map<String, ParameterDoc> * parameters = (type == functionDoc) ? &fnDoc.parameters : &mdDoc.parameters;
+ char * name = ((Type)data).name;
+ ParameterDoc itDoc = *parameters ? (*parameters)[name] : null;
+ int position = 0;
+ Type prev = data;
+ while(prev) position++, prev = prev.prev;
+
+ if(!empty || itDoc)
+ {
+ if(!empty && !itDoc)
+ {
+ if(!*parameters) *parameters = { };
+ (*parameters)[name] = itDoc = { };
+ }
+ itDoc.description = contents; contents = null;
+ itDoc.position = position;
+ if(itDoc.isEmpty)
+ {
+ MapIterator<String, ParameterDoc> it { map = *parameters };
+ if(it.Index(((Type)data).name, false))
+ it.Remove();
+ delete itDoc;
+ }
+ }
+ }
+ break;
+ }
+ }
}
- textBlock = Block { type = TEXT, parent = parent, font = parent.font };
- textBlock.text = CopyString($"[Add Text]");
- textBlock.textLen = strlen(textBlock.text);
- parent.subBlocks.Add(textBlock);
}
- edit = false;
- if(created)
+ if(type == functionDoc && fnDoc && fnDoc.isEmpty)
{
- ComputeMinSizes();
- ComputeSizes();
- PositionCaret(true);
- Update(null);
+ MapIterator<String, FunctionDoc> it { map = nsDoc.functions };
+ const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
+ if(name) name += 2; else name = function.name;
+ if(it.Index(name, false))
+ it.Remove();
+ delete fnDoc;
+ }
+ else if(type == methodDoc && mdDoc && mdDoc.isEmpty)
+ {
+ MapIterator<String, MethodDoc> it { map = clDoc.methods };
+ if(it.Index(method.name, false))
+ it.Remove();
+ delete mdDoc;
+ }
+ if(nsDoc)
+ {
+ if(nsDoc.functions && !nsDoc.functions.count) delete nsDoc.functions;
+ if(nsDoc.defines && !nsDoc.defines.count) delete nsDoc.defines;
+ }
+ if(clDoc)
+ {
+ if(clDoc && clDoc.conversions && !clDoc.conversions.count) delete clDoc.conversions;
+ if(clDoc && clDoc.properties && !clDoc.properties.count) delete clDoc.properties;
+ if(clDoc && clDoc.fields && !clDoc.fields.count) delete clDoc.fields;
+ if(clDoc && clDoc.methods && !clDoc.methods.count) delete clDoc.methods;
+ if(clDoc && clDoc.values && !clDoc.values.count) delete clDoc.values;
+ }
+
+ if(clDoc || nsDoc)
+ {
+ char dirPath[MAX_LOCATION];
+ StripLastDirectory(docPath, dirPath);
+ if(FileExists(docPath))
+ DeleteFile(docPath);
+ if(cl ? (clDoc && !clDoc.isEmpty) : (nsDoc && !nsDoc.isEmpty))
+ {
+ File f;
+ if(!FileExists(dirPath))
+ MakeDir(dirPath);
+ if((f = FileOpen(docPath, write)))
+ {
+ WriteECONObject(f, cl ? class(ClassDoc) : class(NamespaceDoc), doc, 0);
+ delete f;
+ }
+ else
+ PrintLn("error: writeClassDocFile -- problem opening file: ", docPath);
+ }
}
+ delete doc;
+ delete contents;
+ }
+
+ if(empty)
+ {
+ Block parent = textBlock.parent;
+ while((block = parent.subBlocks.first))
+ {
+ parent.subBlocks.Remove(block);
+ delete block;
+ }
+ textBlock = Block { type = TEXT, parent = parent, font = parent.font };
+ textBlock.text = CopyString($"[Add Text]");
+ textBlock.textLen = strlen(textBlock.text);
+ parent.subBlocks.Add(textBlock);
+ }
+
+ edit = false;
+ if(created)
+ {
+ ComputeMinSizes();
+ ComputeSizes();
+ PositionCaret(true);
+ Update(null);
}
}
if(edit && (!textBlock || overLink != textBlock.parent))
{
- SaveEdit();
+ if(!readOnly)
+ SaveEdit();
HTMLView::OnLeftButtonDown(x, y, mods);
selPosition = curPosition = 0;
selBlock = textBlock;
{
if(!strncmp(href, "api://", 6))
{
- int tag = (uint)strtoul(href + 6, null, 16);
+ int64 tag = (int64)strtoull(href + 6, null, 16);
DataRow row = mainForm.browser.FindSubRow(tag);
if(row)
{
if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
{
Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
- int tw = 0, th = 0;
+ int th = 0;
display.FontExtent(block.font.font, " ", 1, null, &th);
if(!block.prev)
{
// dialog.Create();
edit = true;
// PositionCaret(true);
+
+ // TOCHECK: Adding this here seemed to fixed caret positioning bugs
+ ComputeSizes();
}
return true;
}
}
{
- int tw = 0, th = 0;
+ int th = 0;
int textPos = 0;
int sx = textBlock.startX, sy = textBlock.startY;
char * text = textBlock.text;
len = (nextSpace - (text + textPos)) + 1;
else
len = textBlock.textLen - textPos;
-
+
display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
if(x + width + w > maxW && x > 0)
case Key { down, shift = true }:
case down:
{
- int tw = 0, th = 0;
+ int th = 0;
int textPos = 0;
int sx = textBlock.startX, sy = textBlock.startY;
char * text = textBlock.text;
len = (nextSpace - (text + textPos)) + 1;
else
len = textBlock.textLen - textPos;
-
+
display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
if(x + width + w > maxW && x > 0)
Update(null);
PositionCaret(false);
return false;
- }
+ }
else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
{
startPos = 0;
sx = textBlock.startX;
}
}
-
+
/*if(textBlock.next && textBlock.next.next)
{
textBlock = textBlock.next.next;
break;
}
}
- // No next word found,
+ // No next word found,
if(!found && (c != curPosition || line != textBlock))
{
found = true;
}
}
}
- // No next word found,
+ // No next word found,
if(!found && curPosition > 0)
{
foundAlpha = true;
}
break;
case backSpace:
+ if(readOnly) break;
if(textBlock == selBlock && curPosition == selPosition)
{
if(curPosition)
DeleteSelection();
break;
case del:
+ if(readOnly) break;
if(textBlock != selBlock || curPosition != selPosition)
DeleteSelection();
else if(textBlock.textLen > curPosition)
break;
case enter:
{
- int tw = 0, th = 0;
+ int th = 0;
Block block;
Block newBlock;
int startY, startX;
+ if(readOnly) break;
DeleteSelection();
block = { type = BR, parent = textBlock.parent, font = textBlock.font };
}
case ctrlX:
case Key { del, shift = true }:
+ if(readOnly) break;
// Cut
CopySelection();
DeleteSelection();
break;
case shiftInsert:
case ctrlV:
- {
- ClipBoard clipBoard { };
- if(clipBoard.Load())
- {
- int c;
- char * text = clipBoard.memory;
- char ch;
- int start = 0;
- Block parent;
- FontEntry font;
+ if(!readOnly)
+ {
+ ClipBoard clipBoard { };
+ if(clipBoard.Load())
+ {
+ int c;
+ char * text = clipBoard.memory;
+ char ch;
+ int start = 0;
+ Block parent;
+ FontEntry font;
- DeleteSelection();
+ DeleteSelection();
- parent = textBlock.parent;
- font = textBlock.font;
+ parent = textBlock.parent;
+ font = textBlock.font;
- for(c = 0; ; c++)
- {
- ch = text[c];
- if(ch == '\n' || ch == '\r' || !ch)
+ for(c = 0; ; c++)
{
- int len = c - start;
- textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
- memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
- memcpy(textBlock.text + curPosition, text + start, len);
- textBlock.textLen += len;
- curPosition += len;
- selPosition = curPosition;
- selBlock = textBlock;
- if(!ch) break;
+ ch = text[c];
+ if(ch == '\n' || ch == '\r' || !ch)
{
- Block block { type = BR, parent = parent, font = font };
- Block newBlock { type = TEXT, parent = parent, font = font };
- int startY = textBlock.startY, startX = textBlock.startX;
- int tw = 0, th = 0;
-
- display.FontExtent(textBlock.font.font, " ", 1, null, &th);
- textBlock.parent.subBlocks.Insert(textBlock, block);
- textBlock.parent.subBlocks.Insert(block, newBlock);
-
- startY += th;
-
- newBlock.textLen = textBlock.textLen - curPosition;
- newBlock.text = new char[newBlock.textLen+1];
- memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
- textBlock.textLen = curPosition;
- textBlock.text[curPosition] = 0;
-
- newBlock.startY = startY;
- newBlock.startX = startX;
- selPosition = curPosition = 0;
+ int len = c - start;
+ textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
+ memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
+ memcpy(textBlock.text + curPosition, text + start, len);
+ textBlock.textLen += len;
+ curPosition += len;
+ selPosition = curPosition;
selBlock = textBlock;
- textBlock = newBlock;
+ if(!ch) break;
+ {
+ Block block { type = BR, parent = parent, font = font };
+ Block newBlock { type = TEXT, parent = parent, font = font };
+ int startY = textBlock.startY, startX = textBlock.startX;
+ int th = 0;
+
+ display.FontExtent(textBlock.font.font, " ", 1, null, &th);
+ textBlock.parent.subBlocks.Insert(textBlock, block);
+ textBlock.parent.subBlocks.Insert(block, newBlock);
+
+ startY += th;
+
+ newBlock.textLen = textBlock.textLen - curPosition;
+ newBlock.text = new char[newBlock.textLen+1];
+ memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
+ textBlock.textLen = curPosition;
+ textBlock.text[curPosition] = 0;
+
+ newBlock.startY = startY;
+ newBlock.startX = startX;
+ selPosition = curPosition = 0;
+ selBlock = textBlock;
+ textBlock = newBlock;
+ }
+ if(ch == '\r' && text[c+1] == '\n') c++;
+ start = c + 1;
}
- if(ch == '\r' && text[c+1] == '\n') c++;
- start = c + 1;
}
+ ComputeMinSizes();
+ ComputeSizes();
+ PositionCaret(true);
+ Update(null);
}
- ComputeMinSizes();
- ComputeSizes();
- PositionCaret(true);
- Update(null);
+ delete clipBoard;
}
- delete clipBoard;
break;
- }
default:
{
// eC BUG HERE: (Should be fixed)
- if(!key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
+ if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
{
char string[5];
int len = UTF32toUTF8Len(&ch, 1, string, 5);
textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
-
+
for(c = 0; c<len; c++)
{
textBlock.text[curPosition] = string[c];
}
selPosition = curPosition;
selBlock = textBlock;
-
+
{
//Clear(html.block);
//CreateForms(html.block);
char * text = textBlock.text;
int maxW;
Block block = textBlock;
+ int xOffset = 0;
while(block && block.type != TD) block = block.parent;
if(block)
{
}
else
maxW = clientSize.w - 10 - sx;
-
+
display.FontExtent(textBlock.font.font, " ", 1, null, &th);
+ // Work around to re-align with first line having different indentation because of before <A> of current block
+ {
+ Block parent = textBlock.parent;
+ while(parent && parent.type == ANCHOR) parent = parent.parent;
+ if(parent && parent.subBlocks.first && ((Block)parent.subBlocks.first).type == TEXT)
+ xOffset = sx - ((Block)parent.subBlocks.first).startX;
+ }
+
while(textPos < textBlock.textLen)
{
int startPos = textPos;
int width = 0;
- int x = 0;
+ int x = xOffset;
bool lineComplete = false;
for(; textPos<textBlock.textLen && !lineComplete;)
len = (nextSpace - (text + textPos)) + 1;
else
len = textBlock.textLen - textPos;
-
+
display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
if(x + width + w > maxW && x > 0)
break;
}
sy += th;
- sx = textBlock.startX;
+ sx = textBlock.startX - xOffset;
}
if(setCaretX)
caretX = sx;
caretY = sy;
- SetCaret(sx, sy, th);
+ SetCaret(sx-1, sy, th);
{
Point scrollPos = scroll;
bool doScroll = false;
int maxW;
Block b = textBlock;
int space;
+ int xOffset = 0;
if(textBlock.type != TEXT) continue;
}
else
maxW = clientSize.w - 10 - sx;
-
+
+ // Work around to re-align with first line having different indentation because of before <A> of current block
+ {
+ Block parent = textBlock.parent;
+ while(parent && parent.type == ANCHOR) parent = parent.parent;
+ if(parent && parent.subBlocks.first && ((Block)parent.subBlocks.first).type == TEXT)
+ xOffset = sx - ((Block)parent.subBlocks.first).startX;
+ }
+
display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
//space = space/2+2;
space = 2;
while(textPos < textBlock.textLen)
{
- int startPos = textPos;
int width = 0;
- int x = 0;
+ int x = xOffset;
bool lineComplete = false;
for(; textPos<textBlock.textLen && !lineComplete;)
len = (nextSpace - (text + textPos)) + 1;
else
len = textBlock.textLen - textPos;
-
+
display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
- sx = x + textBlock.startX;
+ sx = x + textBlock.startX - xOffset;
if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
{
int c, numBytes;
{
bool Init()
{
- Platform os = GetRuntimePlatform();
- componentsApp = __ecere_COM_Initialize(false, 1, null);
- SetPrivateModule(componentsApp);
+ Platform os = __runtimePlatform;
SetGlobalContext(globalContext);
SetExcludedSymbols(&excludedSymbols);
SetDefines(&::defines);
SetImports(&imports);
-
+ SetInDocumentor(true);
+
SetGlobalData(globalData);
- settingsContainer.dataOwner = &settings;
+ settingsContainer.dataOwner = &ideSettings;
settingsContainer.Load();
- if(!settings.docDir || !settings.docDir[0] )
+ if(!ideSettings.docDir || !ideSettings.docDir[0] )
{
if(os == win32) // if Windows OS then
{
char programFilesDir[MAX_LOCATION];
- char appData[MAX_LOCATION];
+ char appData[MAX_LOCATION];
char homeDrive[MAX_LOCATION];
char winDir[MAX_LOCATION];
GetEnvironment("APPDATA", appData, sizeof(appData));
if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
{
PathCat(programFilesDir, "ECERE SDK\\doc");
- settings.docDir = programFilesDir;
+ ideSettings.docDir = programFilesDir;
}
- else if(homeDrive && homeDrive[0])
+ else if(homeDrive[0])
{
PathCat(homeDrive, "ECERE SDK\\doc");
- settings.docDir = homeDrive;
+ ideSettings.docDir = homeDrive;
}
- else if(winDir && winDir[0])
+ else if(winDir[0])
{
PathCat(winDir, "..\\ECERE SDK\\doc");
- settings.docDir = winDir;
+ ideSettings.docDir = winDir;
}
else
- settings.docDir = "C:\\ECERE SDK\\doc";
+ ideSettings.docDir = "C:\\ECERE SDK\\doc";
}
else // if Os is Linux, or Mac OSX or something else
- settings.docDir = "/usr/share/ecere/doc/";
+ ideSettings.docDir = "/usr/share/ecere/doc/";
settingsContainer.Save();
}
Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
DataRow row;
AddComponents(module, true);
- mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int)module);
- // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int)eSystem_FindClass(componentsApp, "Window"));
+ mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
+ // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
while((row = row.parent))
row.collapsed = false;
#endif
}
+
+ commandThread.Create();
+ return true;
+ }
+
+ bool Cycle(bool idle)
+ {
+ if(quit)
+ mainForm.Destroy(0);
return true;
}
void Terminate()
{
+ PrintLn("Exited");
+ console.Flush();
+ quit = true;
+ if(commandThread.created)
+ {
+ console.CloseInput();
+ console.CloseOutput();
+ app.Unlock();
+ commandThread.Wait();
+ app.Lock();
+ }
+
FreeContext(globalContext);
FreeExcludedSymbols(excludedSymbols);
::defines.Free(FreeModuleDefine);
}
}
+ConsoleFile console { };
MainForm mainForm { };
+bool quit;
+
+Thread commandThread
+{
+ unsigned int Main()
+ {
+ while(!quit)
+ {
+ char command[1024];
+ console.GetLine(command, sizeof(command));
+ if(!quit && command[0])
+ {
+ app.Lock();
+ if(!strcmpi(command, "Activate"))
+ mainForm.Activate();
+ else if(!strcmpi(command, "Quit"))
+ quit = true;
+ app.Unlock();
+ }
+ }
+ return 0;
+ }
+};
+#endif // !defined(EAR_TO_ECON_ECDOC)
+
+class ItemDoc
+{
+public:
+ property String name { get { return this ? name : null; } set { delete name; name = CopyString(value); } isset { return name && *name; } }
+ property String description { get { return this ? description : null; } set { delete description; description = CopyString(value); } isset { return description && *description; } }
+private:
+ char * name;
+ char * description;
+ property bool isEmpty
+ {
+ get
+ {
+ return !(
+ (name && *name) ||
+ (description && *description));
+ }
+ }
+ ~ItemDoc()
+ {
+ delete name;
+ delete description;
+ }
+}
+
+class MoreDoc : ItemDoc
+{
+public:
+ property String usage { get { return this ? usage : null; } set { delete usage; usage = CopyString(value); } isset { return usage && *usage; } }
+ property String example { get { return this ? example : null; } set { delete example; example = CopyString(value); } isset { return example && *example; } }
+ property String remarks { get { return this ? remarks : null; } set { delete remarks; remarks = CopyString(value); } isset { return remarks && *remarks; } }
+ property String also { get { return this ? also : null; } set { delete also; also = CopyString(value); } isset { return also && *also; } }
+private:
+ char * usage;
+ char * example;
+ char * remarks;
+ char * also;
+ property bool isEmpty
+ {
+ get
+ {
+ return !(
+ (usage && *usage) ||
+ (example && *example) ||
+ (remarks && *remarks) ||
+ (also && *also) ||
+ !ItemDoc::isEmpty);
+ }
+ }
+ ~MoreDoc()
+ {
+ delete usage;
+ delete example;
+ delete remarks;
+ delete also;
+ }
+}
+
+class NamespaceDoc : ItemDoc
+{
+public:
+ Map<String, DefineDoc> defines;
+ Map<String, FunctionDoc> functions;
+private:
+ property bool isEmpty
+ {
+ get
+ {
+ return !(
+ (defines && defines.count) ||
+ (functions && functions.count) ||
+ !ItemDoc::isEmpty);
+ }
+ }
+ ~NamespaceDoc()
+ {
+ delete defines;
+ delete functions;
+ }
+}
+
+class DefineDoc : ItemDoc { }
+
+class FunctionDoc : MoreDoc
+{
+public:
+ Map<String, ParameterDoc> parameters;
+ property String returnValue { get { return this ? returnValue : null; } set { delete returnValue; returnValue = CopyString(value); } isset { return returnValue && *returnValue; } }
+private:
+ char * returnValue;
+ property bool isEmpty
+ {
+ get
+ {
+ return !(
+ (parameters && parameters.count) ||
+ (returnValue && *returnValue) ||
+ !MoreDoc::isEmpty);
+ }
+ }
+ ~FunctionDoc()
+ {
+ delete parameters;
+ delete returnValue;
+ }
+}
+
+class ParameterDoc : ItemDoc
+{
+public:
+ uint position;
+}
+
+class ClassDoc : MoreDoc
+{
+public:
+ Map<String, ValueDoc> values;
+ Map<String, FieldDoc> fields;
+ Map<String, PropertyDoc> properties;
+ Map<String, ConversionDoc> conversions;
+ Map<String, MethodDoc> methods;
+private:
+ property bool isEmpty
+ {
+ get
+ {
+ return !(
+ (values && values.count) ||
+ (fields && fields.count) ||
+ (properties && properties.count) ||
+ (conversions && conversions.count) ||
+ (methods && methods.count) ||
+ !MoreDoc::isEmpty);
+ }
+ }
+ ~ClassDoc()
+ {
+ delete values;
+ delete fields;
+ delete properties;
+ delete conversions;
+ delete methods;
+ }
+}
+
+class ValueDoc : ItemDoc { }
+
+class FieldDoc : ItemDoc { }
+
+class PropertyDoc : ItemDoc { }
+
+class ConversionDoc : ItemDoc { }
+
+class MethodDoc : FunctionDoc { }
+
+char * getDocFileNameFromTypeName(const char * typeName)
+{
+ char * docFileName = new char[MAX_FILENAME];
+ const char * swap = "pointer";
+ const char * s = typeName;
+ char * d = docFileName;
+ const char * end = s + strlen(typeName);
+ int swapLen = strlen(swap);
+ for(; s < end; s++)
+ {
+ if(*s == ' ')
+ *d = '-';
+ else if(*s == '*')
+ {
+ strcpy(d, swap);
+ d += swapLen;
+ }
+ else
+ *d = *s;
+ d++;
+ }
+ *d = '\0';
+ return docFileName;
+}
+
+class DocCacheEntry //: struct // TOCHECK: Why does this causes an error: 'struct __ecereNameSpace__ecere__com__MapIterator' has no member named 'data'
+{
+public:
+ Time timeStamp; // Should this be last accessed, or last retrieved?
+ ItemDoc doc;
+
+ ~DocCacheEntry()
+ {
+ delete doc;
+ }
+}
+
+Map<String, DocCacheEntry> docCache { };