// 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 { TQType qtype; string tab, directory; public Printer (TQType 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.TQAncestors))); foreach (TQEnum qenum in qtype.TQEnums) { writer.Write(StartEnum(qenum.Name, qenum.Access, qenum.Type)); writer.Write(Items(qenum.TQItems)); writer.Write(EndMember); } foreach (TQCtor qctor in qtype.TQCtors) { 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 (TQDCtor qdctor in qtype.TQDCtors) { writer.Write (ImportAttrib); writer.Write (ImportDCtorCall (qdctor.Name)); } //writer.Write (DisposeProtected ()); writer.Write (Delete ()); foreach (TQMethod qmethod in qtype.TQMethods) { 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.TQStringReturn, 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.TQStringReturn, 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 (TQAncestor qancestor in qtype.TQAncestors) { writer.Write("\n\n"+tab+tab+"// Begin interface methods.\n"); if (qancestor.IsInterface) { Printer printer = new Printer (qancestor, directory); foreach (TQMethod qmethod in qancestor.TQMethods) { 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.TQStringReturn, 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.TQStringReturn, 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.TQAncestors)); foreach (TQMethod qmethod in qtype.TQMethods) { 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 (TQAncestor qancestor in qancestors) { if (!qancestor.IsInterface) { if (qancestor.Name == "Qt") { sb.Append ("QtSupport"); break; } else { sb.Append (qancestor.Name); qancestors.Remove (qancestor); break; } } } foreach (TQAncestor 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 (TQNull.Instance) {}"; } public string WriteDummy (string name, string access) { return "\n\n"+tab+tab+access+" "+name+" (TQNull dummy) : base (TQNull.Instance) {}"; } public string WriteBoxer (string name, string access) { return "\n\n" + tab+tab+access+" "+name+" (IntPtr ptr) : this (TQNull.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\tparent.AddChild (this);\n"; else return ""; } public string StartCtor (string name, string access, ArrayList csharpparams) { return "\n"+tab+tab+access+" "+name+" ("+Params(csharpparams)+") : this (TQNull.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"; // TQEvents 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 (TQItem 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 (TQParam 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.IsTQObject) { ArrayList newparams = new ArrayList (); foreach (TQParam parm in qparams) { //Console.WriteLine ("--> {0}", parm.Name); if (parm.Name == "parent.RawObject") { TQParam newparm = parm.Clone() as TQParam; 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(\"libtqtc\", 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 TQEvents if (! (qtype.Name.StartsWith ("Q") && qtype.Name.EndsWith ("Event"))) { ret += "\t\t\tif (deleted) return;\n\n"; if (qtype.TQDCtors.Count > 0) ret += "\t\t\tqt_del_"+qtype.Name+" (rawObject);\n"; else ret = "\n" + ret + "\t\t\t// libtqtc lacks a qt_del_"+qtype.Name+" function\n"; ret += "\t\t\tdeleted = true;\n"; } ret += "\t\t}"; return ret; } public string DefaultConnections () { if (qtype.IsTQObject) return "\n\t\t\tConnect (this, TQ_SIGNAL (\"destroyed ()\"), TQ_SLOT (\"NativeDestroyed ()\"));"; else return ""; } } }