You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
527 lines
17 KiB
527 lines
17 KiB
// A Qt to C# binding generator.
|
|
//
|
|
// Copyright (C) 2002 Adam Treat (manyoso@yahoo.com)
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
using System;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Collections;
|
|
|
|
namespace QtCSharp {
|
|
|
|
public class Printer {
|
|
|
|
QType qtype;
|
|
string tab, directory;
|
|
|
|
public Printer (QType qtype, string directory)
|
|
{
|
|
this.qtype = qtype;
|
|
this.directory = directory;
|
|
tab = "\t";
|
|
if (qtype.IsInterface)
|
|
PrintInterface ();
|
|
else
|
|
Print ();
|
|
}
|
|
|
|
public void Print ()
|
|
{
|
|
StreamWriter writer = new StreamWriter(directory + Path.DirectorySeparatorChar +
|
|
qtype.Name + ".cs", false, new ASCIIEncoding());
|
|
writer.Write(Header);
|
|
writer.Write(StartClass(qtype.Name, qtype.Access, new ArrayList(qtype.QAncestors)));
|
|
|
|
foreach (QEnum qenum in qtype.QEnums) {
|
|
writer.Write(StartEnum(qenum.Name, qenum.Access, qenum.Type));
|
|
writer.Write(Items(qenum.QItems));
|
|
writer.Write(EndMember);
|
|
}
|
|
|
|
foreach (QCtor qctor in qtype.QCtors) {
|
|
if (qctor.Throttle) {
|
|
} else if (qctor.Inherited) {
|
|
writer.Write (WriteInherited (qctor.Name, qctor.Access));
|
|
} else if (qctor.Dummy) {
|
|
writer.Write (WriteDummy (qctor.Name, qctor.Access));
|
|
} else if (qctor.Boxer) {
|
|
writer.Write (WriteBoxer (qctor.Name, qctor.Access));
|
|
} else if (!qctor.Overload) {
|
|
writer.Write (ImportAttrib);
|
|
writer.Write (ImportCtorCall (qctor.Name, qctor.Id, qctor.PinvokeParams));
|
|
writer.Write (StartCtor (qctor.Name, qctor.Access, qctor.CSharpParams));
|
|
writer.Write (RawObject (qctor.Name, qctor.Id, qctor.PinvokeCallParams));
|
|
writer.Write (CheckParent (qctor.Parent));
|
|
writer.Write (Register);
|
|
writer.Write (DefaultConnections ());
|
|
writer.Write (EndMember);
|
|
} else {
|
|
writer.Write (OverLoadCtor(qctor.Name, qctor.Access, qctor.CSharpParams, qctor.OverloadParams));
|
|
}
|
|
}
|
|
|
|
writer.Write (StartDCtor (qtype.Name));
|
|
writer.Write (DCtorCall);
|
|
writer.Write (EndMember);
|
|
|
|
//writer.Write (DisposePublic ());
|
|
|
|
foreach (QDCtor qdctor in qtype.QDCtors) {
|
|
writer.Write (ImportAttrib);
|
|
writer.Write (ImportDCtorCall (qdctor.Name));
|
|
}
|
|
|
|
//writer.Write (DisposeProtected ());
|
|
writer.Write (Delete ());
|
|
|
|
foreach (QMethod qmethod in qtype.QMethods) {
|
|
if (qmethod.Throttle) {
|
|
} else if (!qmethod.Overload) {
|
|
writer.Write(ImportAttrib);
|
|
if (qmethod.Access == "public" || qmethod.Access == "protected" || qmethod.Access == "internal") {
|
|
writer.Write(ImportMethodCall(qtype.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
|
|
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
|
|
writer.Write(MethodCall(qmethod.QStringReturn, qmethod.Boxer, qtype.Name, qmethod.Name, "rawObject", qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
|
|
} else {
|
|
writer.Write(StaticImportMethodCall(qtype.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
|
|
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
|
|
writer.Write(StaticMethodCall(qmethod.QStringReturn, qmethod.Boxer, qtype.Name, qmethod.Name, qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
|
|
}
|
|
writer.Write(EndMember);
|
|
} else {
|
|
writer.Write(OverLoadMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams, qmethod.OverloadParams));
|
|
}
|
|
}
|
|
|
|
foreach (QAncestor qancestor in qtype.QAncestors) {
|
|
writer.Write("\n\n"+tab+tab+"// Begin interface methods.\n");
|
|
if (qancestor.IsInterface) {
|
|
Printer printer = new Printer (qancestor, directory);
|
|
foreach (QMethod qmethod in qancestor.QMethods) {
|
|
if (qmethod.Throttle) {
|
|
} else if (!qmethod.Overload) {
|
|
writer.Write(ImportAttrib);
|
|
if (qmethod.Access == "public" || qmethod.Access == "protected") {
|
|
writer.Write(ImportMethodCall(qancestor.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
|
|
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
|
|
writer.Write(MethodCall(qmethod.QStringReturn, qmethod.Boxer, qancestor.Name, qmethod.Name, qancestor.Name+" ()", qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
|
|
} else {
|
|
writer.Write(StaticImportMethodCall(qancestor.Name, qmethod.Name, qmethod.Id, qmethod.PinvokeReturn, qmethod.PinvokeParams));
|
|
writer.Write(StartMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams));
|
|
writer.Write(StaticMethodCall(qmethod.QStringReturn, qmethod.Boxer, qancestor.Name, qmethod.Name, qmethod.Id, qmethod.Return, qmethod.PinvokeCallParams));
|
|
}
|
|
writer.Write(EndMember);
|
|
} else {
|
|
writer.Write(OverLoadMethod(qmethod.PascalName, qmethod.Access, qmethod.Return, qmethod.CSharpParams, qmethod.OverloadParams));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
writer.Write(EndClass);
|
|
writer.Write(Footer);
|
|
writer.Close();
|
|
}
|
|
|
|
public void PrintInterface ()
|
|
{
|
|
StreamWriter writer = new StreamWriter(directory + Path.DirectorySeparatorChar +
|
|
qtype.IName + ".cs", false, new ASCIIEncoding());
|
|
writer.Write(Header);
|
|
writer.Write(StartClass(qtype.IName, "public", qtype.QAncestors));
|
|
|
|
foreach (QMethod qmethod in qtype.QMethods) {
|
|
if (qmethod.Throttle || qmethod.Access == "public static" || qmethod.Access == "protected") {
|
|
} else {
|
|
writer.Write(IMethod(qmethod.PascalName, qmethod.Return, qmethod.CSharpParams));
|
|
}
|
|
}
|
|
writer.Write("\n"+tab+tab+" IntPtr "+qtype.Name+" ();");
|
|
writer.Write(EndClass);
|
|
writer.Write(Footer);
|
|
writer.Close();
|
|
}
|
|
|
|
public string StartClass (string name, string access, ArrayList qancestors)
|
|
{
|
|
StringBuilder sb = new StringBuilder ();
|
|
|
|
if (qtype.IsInterface) {
|
|
sb.Append(tab+access+" interface "+name+" {");
|
|
return sb.ToString ();
|
|
}
|
|
|
|
sb.Append(tab+access+" class "+name+" : ");
|
|
if (qancestors.Count == 0) sb.Append ("QtSupport");
|
|
foreach (QAncestor qancestor in qancestors) {
|
|
if (!qancestor.IsInterface) {
|
|
if (qancestor.Name == "Qt") {
|
|
sb.Append ("QtSupport");
|
|
break;
|
|
} else {
|
|
sb.Append (qancestor.Name);
|
|
qancestors.Remove (qancestor);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
foreach (QAncestor qancestor in qancestors) {
|
|
if (qancestor.IsInterface) {
|
|
sb.Append (", "+qancestor.IName);
|
|
}
|
|
}
|
|
|
|
sb.Append (", IDisposable {");
|
|
return sb.ToString ();
|
|
}
|
|
|
|
public string EndClass
|
|
{
|
|
get {return "\n"+tab+"}";}
|
|
}
|
|
|
|
public string StartEnum (string name, string access, string type)
|
|
{
|
|
if (type != null)
|
|
return "\n\n"+tab+tab+access+" enum "+name+" : "+type+" {";
|
|
else
|
|
return "\n\n"+tab+tab+access+" enum "+name+" {";
|
|
}
|
|
|
|
public string WriteInherited (string name, string access)
|
|
{
|
|
return "\n\n"+tab+tab+access+" "+name+" () : this (QNull.Instance) {}";
|
|
}
|
|
|
|
public string WriteDummy (string name, string access)
|
|
{
|
|
return "\n\n"+tab+tab+access+" "+name+" (QNull dummy) : base (QNull.Instance) {}";
|
|
}
|
|
|
|
public string WriteBoxer (string name, string access)
|
|
{
|
|
return "\n\n" +
|
|
tab+tab+access+" "+name+" (IntPtr ptr) : this (QNull.Instance)\n"+tab+tab+"{\n" +
|
|
tab+tab+tab+"rawObject = ptr;\n" +
|
|
tab+tab+tab+"RegisterObject(this);\n" +
|
|
tab+tab+"}";
|
|
}
|
|
|
|
public string CheckParent (bool check)
|
|
{
|
|
if (check)
|
|
return "\n\n\t\t\tif ((qparent = parent) != null)\n" +
|
|
"\t\t\t\parent.AddChild (this);\n";
|
|
else
|
|
return "";
|
|
}
|
|
|
|
public string StartCtor (string name, string access, ArrayList csharpparams)
|
|
{
|
|
return "\n"+tab+tab+access+" "+name+" ("+Params(csharpparams)+") : this (QNull.Instance)\n"+tab+tab+"{\n";
|
|
}
|
|
|
|
public string StartDCtor (string name)
|
|
{
|
|
return "\n\n"+tab+tab+"~"+name+" ()\n"+tab+tab+"{\n";
|
|
}
|
|
|
|
public string StartMethod (string name, string access, string returntype, ArrayList csharpparams)
|
|
{
|
|
string str = "\n"+tab+tab+access+" "+returntype+" "+name+" ("+Params(csharpparams)+")\n"+tab+tab+"{\n";
|
|
|
|
// QEvents should never be disposed inside C#
|
|
if (access.IndexOf ("static") <= 0)
|
|
str += "\t\t\tif (disposed)\n\t\t\t\tthrow new ObjectDisposedException (this+\": Attempted use of disposed object\");\n\n";
|
|
|
|
return str;
|
|
}
|
|
|
|
public string IMethod (string name, string returntype, ArrayList csharpparams)
|
|
{
|
|
return "\n"+tab+tab+" "+returntype+" "+name+" ("+Params(csharpparams)+");";
|
|
}
|
|
|
|
public string EndMember
|
|
{
|
|
get {return "\n"+tab+tab+"}";}
|
|
}
|
|
|
|
public string OverLoadCtor (string name, string access, ArrayList csharpparams, ArrayList overloadparams)
|
|
{
|
|
return "\n\n"+tab+tab+access+" "+name+" ("+Params(csharpparams)+") : this ("+Params(overloadparams)+") {}";
|
|
}
|
|
|
|
public string OverLoadMethod (string name, string access, string returntype, ArrayList csharpparams, ArrayList overloadparams)
|
|
{
|
|
string str;
|
|
|
|
if (returntype == "void")
|
|
str = name + "(" + Params(overloadparams) + ");\n" + tab + tab;
|
|
else
|
|
str = "return "+name+"("+Params(overloadparams)+");\n" + tab+tab;
|
|
|
|
return "\n\n"+tab+tab+access+" "+returntype+" "+name +
|
|
" ("+Params(csharpparams)+")\n" + tab+tab+"{\n" + tab+tab+tab+ str + "}";
|
|
}
|
|
|
|
public string Items (ArrayList qitems)
|
|
{
|
|
int count = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach (QItem qitem in qitems) {
|
|
count++;
|
|
sb.Append("\n"+tab+tab+tab+qitem.Name+" = "+qitem.Value);
|
|
if (count != qitems.Count)
|
|
sb.Append(",");
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string Params (ArrayList qparams)
|
|
{
|
|
int count = 0;
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach (QParam qparam in qparams) {
|
|
count++;
|
|
if (qparam.Type != "")
|
|
sb.Append(qparam.Type+" "+qparam.Name);
|
|
else
|
|
sb.Append(qparam.Name);
|
|
|
|
if (count != qparams.Count)
|
|
sb.Append(", ");
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public string ImportCtorCall (string name, string id, ArrayList qparams)
|
|
{
|
|
if (id != "0")
|
|
return "\n"+tab+tab+"private static extern IntPtr qt_new_"+name+id+" ("+Params(qparams)+");";
|
|
else
|
|
return "\n"+tab+tab+"private static extern IntPtr qt_new_"+name+" ("+Params(qparams)+");";
|
|
}
|
|
|
|
public string ImportDCtorCall (string name)
|
|
{
|
|
return "\n"+tab+tab+"private static extern void qt_del_"+name+" (IntPtr raw);";
|
|
}
|
|
|
|
public string ImportMethodCall (string type, string name, string id, string returntype, ArrayList qparams)
|
|
{
|
|
if (name.StartsWith ("Q_"))
|
|
name = name.Replace ("Q_", "");
|
|
string comma = "";
|
|
if (qparams.Count != 0) comma = ", ";
|
|
if (id != "0")
|
|
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+id+" (IntPtr raw"+comma+Params(qparams)+");";
|
|
else
|
|
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+" (IntPtr raw"+comma+Params(qparams)+");";
|
|
}
|
|
|
|
public string StaticImportMethodCall (string type, string name, string id, string returntype, ArrayList qparams)
|
|
{
|
|
if (name.StartsWith ("Q_"))
|
|
name = name.Replace ("Q_", "");
|
|
if (id != "0")
|
|
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+id+" ("+Params(qparams)+");";
|
|
else
|
|
return "\n"+tab+tab+"private static extern "+returntype+" qt_"+type+"_"+name+" ("+Params(qparams)+");";
|
|
}
|
|
|
|
public string RawObject (string name, string id, ArrayList qparams)
|
|
{
|
|
if (qtype.IsQObject) {
|
|
ArrayList newparams = new ArrayList ();
|
|
|
|
foreach (QParam parm in qparams) {
|
|
//Console.WriteLine ("--> {0}", parm.Name);
|
|
if (parm.Name == "parent.RawObject") {
|
|
QParam newparm = parm.Clone() as QParam;
|
|
newparm.Name = "parent != null ? parent.RawObject : IntPtr.Zero";
|
|
newparams.Add (newparm);
|
|
}
|
|
else
|
|
newparams.Add (parm);
|
|
}
|
|
|
|
if (id != "0")
|
|
return tab+tab+tab+"rawObject = qt_new_"+name+id+" ("+Params(newparams)+");";
|
|
else
|
|
return tab+tab+tab+"rawObject = qt_new_"+name+" ("+Params(newparams)+");";
|
|
}
|
|
else {
|
|
if (id != "0")
|
|
return tab+tab+tab+"rawObject = qt_new_"+name+id+" ("+Params(qparams)+");";
|
|
else
|
|
return tab+tab+tab+"rawObject = qt_new_"+name+" ("+Params(qparams)+");";
|
|
}
|
|
}
|
|
|
|
public string DCtorCall {
|
|
get {
|
|
return tab+tab+tab+"Dispose (false);";
|
|
}
|
|
}
|
|
|
|
public string MethodCall (bool qstring, bool boxer, string type, string name, string instPtr, string id, string ReturnType, ArrayList qparams)
|
|
{
|
|
if (name.StartsWith ("Q_"))
|
|
name = name.Replace ("Q_", "");
|
|
|
|
string ret = "";
|
|
string comma = qparams.Count == 0 ? "" : ", ";
|
|
string newid = id == "0" ? "" : id;
|
|
|
|
if (boxer && qstring) {
|
|
ret = "\t\t\treturn new TQString (qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+"));\n";
|
|
}
|
|
else if (boxer) {
|
|
ret = "\t\t\treturn LookupObject (qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+"), typeof ("+ReturnType+")) as "+ReturnType+";";
|
|
}
|
|
else {
|
|
ret = "qt_"+type+"_"+name+newid+" ("+instPtr+comma+Params (qparams)+");";
|
|
|
|
if (ReturnType != "void")
|
|
ret = "return " + ret;
|
|
|
|
ret = "\t\t\t" + ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public string StaticMethodCall (bool qstring, bool boxer, string type, string name, string id, string ReturnType, ArrayList qparams)
|
|
{
|
|
if (name.StartsWith ("Q_"))
|
|
name = name.Replace ("Q_", "");
|
|
|
|
string ret;
|
|
string newid = id == "0" ? "" : id;
|
|
|
|
if (boxer && qstring) {
|
|
ret = "\t\t\treturn new TQString (qt_"+type+"_"+name+newid+" ("+Params (qparams)+"));\n";
|
|
}
|
|
else if (boxer) {
|
|
ret = "\t\t\treturn LookupObject (qt_"+type+"_"+name+newid+" ("+Params (qparams)+"), typeof ("+ReturnType+")) as "+ReturnType+";\n";
|
|
}
|
|
else {
|
|
ret = "qt_"+type+"_"+name+newid+" ("+Params (qparams)+");";
|
|
|
|
if (ReturnType != "void")
|
|
ret = "return " + ret;
|
|
|
|
ret = "\t\t\t" + ret;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public string ImportAttrib
|
|
{
|
|
get {return "\n\n"+tab+tab+"[DllImport(\"libqtc\", CharSet=CharSet.Ansi)]";}
|
|
}
|
|
|
|
public string Import () {
|
|
if (!qtype.IsInterface) {
|
|
return tab + "using System.Runtime.InteropServices;\n\n";
|
|
} else {
|
|
return "\n";
|
|
}
|
|
}
|
|
|
|
public string Header
|
|
{
|
|
get {
|
|
return "// "+qtype.Name+".cs - A Qt to C# binding.\n" +
|
|
"//\n" +
|
|
"// Copyright (C) 2002 Adam Treat (manyoso@yahoo.com)\n" +
|
|
"//\n" +
|
|
"// This program is free software; you can redistribute it and/or\n" +
|
|
"// modify it under the terms of the GNU General Public License\n" +
|
|
"// as published by the Free Software Foundation; either version 2\n" +
|
|
"// of the License, or (at your option) any later version.\n" +
|
|
"//\n" +
|
|
"// This program is distributed in the hope that it will be useful,\n" +
|
|
"// but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +
|
|
"// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +
|
|
"// GNU General Public License for more details.\n" +
|
|
"//\n" +
|
|
"// You should have received a copy of the GNU General Public License\n" +
|
|
"// along with this program; if not, write to the Free Software\n" +
|
|
"// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\n" +
|
|
"//\n" +
|
|
"// Generated File. Do Not Modify.\n" +
|
|
"\n" +
|
|
"namespace Qt {\n" +
|
|
"\n" +
|
|
tab + "using Qt;\n" +
|
|
tab + "using System;\n" + Import ();
|
|
}
|
|
}
|
|
|
|
public string Footer
|
|
{
|
|
get {return "\n}";}
|
|
}
|
|
|
|
public string Register
|
|
{
|
|
get
|
|
{
|
|
return "\n"+tab+tab+tab+"RegisterObject (this);";
|
|
}
|
|
}
|
|
|
|
public string Delete ()
|
|
{
|
|
|
|
string ret = "\n" +
|
|
"\t\tinternal override void Delete ()\n" +
|
|
"\t\t{\n";
|
|
|
|
// Let Qt manage QEvents
|
|
if (! (qtype.Name.StartsWith ("Q") && qtype.Name.EndsWith ("Event")))
|
|
{
|
|
ret += "\t\t\tif (deleted) return;\n\n";
|
|
|
|
if (qtype.QDCtors.Count > 0)
|
|
ret += "\t\t\tqt_del_"+qtype.Name+" (rawObject);\n";
|
|
else
|
|
ret = "\n" + ret + "\t\t\t// libqtc lacks a qt_del_"+qtype.Name+" function\n";
|
|
|
|
ret += "\t\t\tdeleted = true;\n";
|
|
}
|
|
|
|
ret += "\t\t}";
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
public string DefaultConnections ()
|
|
{
|
|
if (qtype.IsQObject)
|
|
return "\n\t\t\tConnect (this, TQT_SIGNAL (\"destroyed ()\"), TQT_SLOT (\"NativeDestroyed ()\"));";
|
|
else
|
|
return "";
|
|
}
|
|
}
|
|
}
|