// $Id: WriterBase.cc,v 1.75 2004/06/14 10:38:30 christof Exp $ /* glade--: C++ frontend for glade (Gtk+ User Interface Builder) * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "WriterBase.hh" #include "window.hh" safemap Writer; void WriterBase::GHInclude(const Widget &w, CxxFile &f) const { // if we see CXX_SEPERATE_CLASS _we_ need it for inheritance if (w.getProperty("cxx_visibility","private")=="private" && CanBeManaged(w) && !w.getBoolProperty(CXX_SEPERATE_CLASS)) return; // only a local ctor variable needed Pkg_Version help=Configuration.gtkmm_version; bool need_special=TwoFourDifferent(w); if (f.ElementAlreadyThere(CxxFile::element_t( CxxFile::v_IncludeBracket,IncludeName(w)))) { if (!GTKMM24 || !need_special) return; Configuration.gtkmm_version=Pkg_Version(2,2,0); bool ret=f.ElementAlreadyThere(CxxFile::element_t( CxxFile::v_IncludeBracket,IncludeName(w))); Configuration.gtkmm_version=help; if (ret) return; } if (need_special) { If24(f); f.Include(IncludeName(w)); f.CppElse(); Configuration.gtkmm_version=Pkg_Version(2,2,0); } f.Include(IncludeName(w)); if (need_special) { Configuration.gtkmm_version=help; f.EndIf(); } } void WriterBase::GCInclude(const Widget &w, CxxFile &f) const { if (w.getProperty("cxx_visibility","private")!="private" || !CanBeManaged(w) || w.getBoolProperty(CXX_SEPERATE_CLASS)) return; // only a local ctor variable needed Pkg_Version help=Configuration.gtkmm_version; bool need_special=TwoFourDifferent(w); if (f.ElementAlreadyThere(CxxFile::element_t( CxxFile::v_IncludeBracket,IncludeName(w)))) { if (!GTKMM24 || !need_special) return; Configuration.gtkmm_version=Pkg_Version(2,2,0); bool ret=f.ElementAlreadyThere(CxxFile::element_t( CxxFile::v_IncludeBracket,IncludeName(w))); Configuration.gtkmm_version=help; if (ret) return; } if (need_special) { If24(f); f.Include(IncludeName(w)); f.CppElse(); Configuration.gtkmm_version=Pkg_Version(2,2,0); } f.Include(IncludeName(w)); if (need_special) { Configuration.gtkmm_version=help; f.EndIf(); } } void /*WriterBase::*/Visibility(CxxFile &f, const std::string &visibility) { if (visibility=="private") f.Private(); else if (visibility=="protected") f.Protected(); else if (visibility=="public") f.Public(); } void WriterBase::MemberVariable(CxxFile &f, const std::string &visibility, const std::string &type, const std::string &name) { Visibility(f,visibility); f.Declaration() << type << ' ' << name; f.EndLine(); } void WriterBase::GHDeclaration(const Widget &w, CxxFile &f) const { const std::string visibility(w.getProperty("cxx_visibility","private")); if (visibility=="private" && CanBeManaged(w)) return; // only a local ctor variable needed bool need_special=TwoFourDifferent(w); Pkg_Version help=Configuration.gtkmm_version; if (need_special) { Visibility(f,visibility); If24(f); MemberVariable(f,visibility,"class "+TypeName(w)+" *",Configuration.InstanceName(w.Name())); f.CppElse(); Configuration.gtkmm_version=Pkg_Version(2,2,0); } MemberVariable(f,visibility,"class "+TypeName(w)+" *",Configuration.InstanceName(w.Name())); if (need_special) { Configuration.gtkmm_version=help; f.EndIf(); } } void WriterBase::Configure(Widget const &, CxxFile &, const std::string &instance) const { //#warning WriterBase::Configure } void WriterBase::ConstructionArgs(Widget const &w, CxxFile &f) const { f.FunctionArg(); } const WriterBase &LookupWriter(const std::string &type,bool seperate_entity) { safemap::iterator i; if (seperate_entity) i=Writer.find("Class"); else i=Writer.find(type); if (i!=Writer.end()) return *(i->second); const WriterBase *deflt=Writer[""]; if (!deflt) { std::cerr << "Writer map crazy\n"; for (i=Writer.begin();i!=Writer.end();++i) std::cerr << i->first << ':'; std::cerr << '\n'; abort(); } std::cerr << "glade--: unknown Widget type "<(this)) { w.setProperty("cxx_visibility","public"); } if (Configuration.only_private_widgets && w.getProperty("cxx_visibility","private")!="private") Configuration.only_private_widgets=false; // separate files need separate classes if (seperate_file && !seperate_class) { std::cerr << w.Name() << ": widgets in a separate file need their own class, marked\n"; w.setProperty(CXX_SEPERATE_CLASS,"true"); seperate_class=true; } // append a node for marking whether it is managed w.setProperty(CXX_IS_MANAGED,"false"); } const std::string WriterBase::Instance(const Widget &parent,const Widget &w2, Subwidget sw) const { // std::cerr << "Instance " << parent.Name() << ':' << w2.Name() << ',' << sw << '\n'; if (sw==SW_Unknown) sw=IsSubwidget(parent,w2); if (sw==is_Subwidget_only || sw==is_Subwidget_all || sw==is_Subwidget) { std::string ii(InternalInstance(parent,w2)); // std::cerr << "II("<2 && *(instance.end()-1)=='>' && *(instance.end()-2)=='-'); return "*"+std::string(instance.begin(),instance.end()-2); } // returns true if matching bool WriterBase::isInternalMethod(const Widget &w,std::string &method,const std::string &args,std::string &scope,bool &is_signal) const { std::string rettype("void"); std::string scope2; // =scope; const std::string sargs(SignalHandlerArgs(w,method,rettype,scope2)); if (!scope2.empty()) { is_signal=true; scope=scope2; return true; } return false; } // by default I prefer the old style: set_title() over property_title().set_value void WriterBase::WriteTranslatableProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, bool only_new) { if (w.hasProperty(property)) { f.Statement() << instance; if (only_new && GTKMM2) f << "property_" << property << "().set_value(" << Configuration.Translatable(w.getProperty(property)) << ')'; else f << "set_" << property << '(' << Configuration.Translatable(w.getProperty(property)) << ')'; } } void WriterBase::WriteEnumPropertyNS(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, bool only_new) { if (w.hasProperty(property)) { f.Statement() << instance; std::string val=Gtkmm2Namespace(w.getProperty(property)); if (only_new && GTKMM2) f << "property_" << property << "().set_value(" << val << ')'; else f << "set_" << property << '(' << val << ')'; } } void WriterBase::WriteBoolProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, bool only_new, std::string functname) { if (functname.empty()) functname=property; if (w.hasProperty(property)) { f.Statement() << instance; if (only_new && GTKMM2) f << "property_" << property << "().set_value(" << PRINT_BOOL(w.getBoolProperty(property)) << ')'; else f << "set_" << functname << '(' << PRINT_BOOL(w.getBoolProperty(property)) << ')'; } } void WriterBase::WriteBoolProp_2Fun(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, const std::string &off, const std::string &on) { if (w.hasProperty(property)) { f.Statement() << instance; if (w.getBoolProperty(property)) f << on; else f << off; } } void WriterBase::WriteIntProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, bool only_new, std::string functname) { if (functname.empty()) functname=property; if (w.hasProperty(property)) { f.Statement() << instance; if (only_new && GTKMM2) f << "property_" << property << "().set_value(" << w.getIntProperty(property) << ')'; else f << "set_" << functname << '(' << w.getIntProperty(property) << ')'; } } void WriterBase::WriteIntIntProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &prop1, const std::string &prop2, const std::string &property, bool only_new, int def) { if (only_new && GTKMM2) { WriteIntProperty(w,f,instance, prop1, true); WriteIntProperty(w,f,instance, prop2, true); } else if (w.hasProperty(prop1) || w.hasProperty(prop2)) { f.Statement() << instance << "set_" << property << '(' << w.getIntProperty(prop1,def) << ',' << w.getIntProperty(prop2,def) << ')'; } } void WriterBase::WriteFloatFloatProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &prop1, const std::string &prop2, const std::string &property, bool only_new, float def) { if (only_new && GTKMM2) { WriteFloatProperty(w,f,instance, prop1, true); WriteFloatProperty(w,f,instance, prop2, true); } else if (w.hasProperty(prop1) || w.hasProperty(prop2)) { f.Statement() << instance << "set_" << property << '(' << w.getFloatProperty(prop1,def) << ',' << w.getFloatProperty(prop2,def) << ')'; } } void WriterBase::WriteFloatProperty(const Widget &w, CxxFile &f, const std::string &instance, const std::string &property, bool only_new) { if (w.hasProperty(property)) { f.Statement() << instance; if (only_new && GTKMM2) f << "property_" << property << "().set_value(" << w.getFloatProperty(property) << ')'; else f << "set_" << property << '(' << w.getFloatProperty(property) << ')'; } } // Remove some unwanted text from strings. *** Is there a standard // function/method that will erase all occurences of a substring? void WriterBase::replace_all(std::string &s,const std::string &from, const std::string &to) { std::string::size_type rm,from_sz=from.size(); for(rm=s.find(from); rm!=std::string::npos; rm=s.find(from)) s.replace(rm, from_sz, to); } void WriterBase::erase_all(std::string &s,const std::string &from) { std::string::size_type rm,from_sz=from.size(); for(rm=s.find(from); rm!=std::string::npos; rm=s.find(from)) s.erase(rm, from_sz); } std::string WriterBase::Gtkmm2Namespace(const std::string &s) { if (GTKMM1) return s; std::string res=s; replace_all(res,"GTK_","Gtk::"); replace_all(res,"GDK_","Gdk::"); return res; } Tag WriterBase::createWidgetTag(const std::string &cls, const std::string &name) { Tag res("widget"); if (Configuration.glade2) { res.setAttr("class",cls); res.setAttr("id",name); } else { res.push_back(Tag("class",cls)); res.push_back(Tag("name",name)); } return res; } #if 0 void WriterBase::setTagProperty(Tag &t, const std::string &name, const std::string &value) { Tag &p=t.push_back(Tag("property")); p.setAttr("name",name); p.Value(value); } #endif const std::string WriterBase::GtkPrefix() { if (Configuration.gtkmm_version>=Pkg_Version(1,1,5)) return "Gtk::"; return "Gtk_"; } const std::string WriterBase::GnomePrefix() { if (GNOME2) return "Gnome::"; // FIXME: Surely we should test gnomemm, not gtkmm, here. // I don't know which gnomemm version corresponds to gtkmm 1.1.5 // but does anybody still care about that old versions if (Configuration.gtkmm_version>=Pkg_Version(1,1,5)) return "Gnome::"; return "Gnome_"; } const std::string WriterBase::GnomeUIPrefix() { if (GNOME2) return "Gnome::UI::"; return GnomePrefix(); } const std::string WriterBase::BonoboPrefix() { if (GNOME2) return "Gnome::Bonobo::"; return "Bonobo::"; } const std::string WriterBase::BonoboUIPrefix() { if (GNOME2) return "Gnome::Bonobo::"; return "Bonobo::"; } // strange things ... do we really need these any longer ? const std::string WriterBase::instance(const Widget &w) { // if (w.getBoolProperty(CXX_SEPERATE_CLASS)) return ""; /* this->"; */ return Configuration.InstanceName(w.Name())+"->"; } const std::string WriterBase::instance_pointer(const Widget &w) { // if (w.getBoolProperty(CXX_SEPERATE_CLASS)) return "this"; return Pointer(w); } const std::string WriterBase::instance_reference(const Widget &w) { // if (w.getBoolProperty(CXX_SEPERATE_CLASS)) return "(*this)"; return Reference(w); } const std::string WriterBase::gtk_object_pointer() { if (Configuration.gtkmm_version >= Pkg_Version(1,3,0)) return "gobj()"; return "gtkobj()"; } const std::string WriterBase::gtk_wrapper() { if (Configuration.gtkmm_version >= Pkg_Version(1,3,0)) return "Glib::wrap"; return "Gtk::wrap"; } const std::string WriterBase::GTKMM_22_24(const std::string &a,const std::string &b) { if (Configuration.gtkmm_version >= Pkg_Version(2,4,0)) return "GMM_GTKMM_22_24("+a+","+b+")"; else return a; } CxxFile &WriterBase::If24(CxxFile &f) { f.CppIf() << "GTKMM_MAJOR_VERSION==2 && GTKMM_MINOR_VERSION>2"; return f; }