/* $Id: xml.hg,v 1.17.2.1 2004/03/12 11:24:03 murrayc Exp $ */ /* Copyright (C) 2002 The libglademm Development Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include _DEFS(libglademm,libglade) _PINCLUDE(glibmm/private/object_p.h) namespace Gnome { namespace Glade { class XmlError : public Glib::Exception { public: explicit XmlError(const Glib::ustring& message); virtual ~XmlError() throw(); XmlError(const XmlError& other); XmlError& operator=(const XmlError& other); virtual Glib::ustring what() const; private: Glib::ustring message_; }; class Xml : public Glib::Object { _CLASS_GOBJECT(Xml, GladeXML, GLADE_XML, Glib::Object, GObject) _IGNORE(glade_xml_construct, glade_xml_new_from_buffer) _IGNORE(glade_xml_build_widget, glade_xml_set_value_from_string, glade_xml_set_toplevel, glade_xml_ensure_accel, glade_xml_handle_widget_prop, glade_xml_set_common_params, glade_xml_handle_internal_child, glade_xml_set_packing_property) //Ignore private glade_xml functions. protected: /** Loads a glade XML file. * @throw XmlError */ Xml(const std::string& filename, const Glib::ustring& root, const Glib::ustring& domain); /** Reads glade XML data from memory. * @throw XmlError */ Xml(const char* buffer, int size, const Glib::ustring& root, const Glib::ustring& domain); Gtk::Widget* get_widget_checked(const Glib::ustring& name, GType type); GtkWidget* get_cwidget(const Glib::ustring& name); public: typedef Gnome::Glade::XmlError Error; /** Loads a glade XML file. * @throw XmlError */ static Glib::RefPtr create(const std::string& filename, const Glib::ustring& root = Glib::ustring(), const Glib::ustring& domain = Glib::ustring()); /** Reads glade XML data from memory. * @throw XmlError */ static Glib::RefPtr create_from_buffer(const char* buffer, int size, const Glib::ustring& root = Glib::ustring(), const Glib::ustring& domain = Glib::ustring()); _MEMBER_GET(filename, filename, std::string, const char*) //void glade_xml_signal_connect (GladeXML *self, // const char *handlername, // GCallback func); //void glade_xml_signal_connect_data (GladeXML *self, // const char *handlername, // GCallback func, // gpointer user_data); // //void glade_xml_signal_autoconnect (GladeXML *self); // // //typedef void (*GladeXMLConnectFunc) (const gchar *handler_name, // GObject *object, // const gchar *signal_name, // const gchar *signal_data, // GObject *connect_object, // gboolean after, // gpointer user_data); // // //void glade_xml_signal_connect_full (GladeXML *self, // const gchar *handler_name, // GladeXMLConnectFunc func, // gpointer user_data); // //void glade_xml_signal_autoconnect_full (GladeXML *self, // GladeXMLConnectFunc func, // gpointer user_data); // // /** Get a widget from the glade file. * For instance: * @code * Gtk::Table* pTable = dynamic_cast(refXml->get_widget("mytable")); * @endcode * @param name The name of the widget. * @return A pointer to the widget, or 0 on failure. */ _WRAP_METHOD(Gtk::Widget* get_widget(const Glib::ustring& name), glade_xml_get_widget) /** This is for convenience. * It allows for a shorter syntax with less repetition. For instance: * @code * Gtk::Table* pTable = 0; * refXml->get_widget("mytable", pTable); * @endcode * This method prints a warning message to the console if the widget * doesn't exist or has the wrong type, so you don't need to check that * manually. * @param name The name of the widget. * @retval widget A pointer to the widget, or 0 on failure. * @return The value of @a widget. */ template inline T_Widget* get_widget(const Glib::ustring& name, T_Widget*& widget) { // The dynamic_cast<> should never fail if get_widget_checked() succeeded. widget = dynamic_cast(this->get_widget_checked(name, T_Widget::get_base_type())); if(!widget) g_critical("Gnome::Glade::Xml::get_widget(): dynamic_cast<> failed."); return widget; } /** This provides a pointer to a widget whose details are specified in the Glade file, but which is implemented * by your own derived class. Your class must have a constructor like so: * @code * DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr& refGlade) * : Gtk::Dialog(cobject) //Calls the base class constructor * @endcode * * For instance: * @code * Gtk::DerivedBox* pBox = 0; * refXml->get_widget_derived("mybox", pBox); * @endcode * * @param name The name of the widget. * @retval widget A pointer to the widget, or 0 on failure. * @return The value of @a widget. */ template inline T_Widget* get_widget_derived(const Glib::ustring& name, T_Widget*& widget) { // initialize input parameter widget = 0; // Get the widget from the glade file. typedef typename T_Widget::BaseObjectType cwidget_type; cwidget_type* pCWidget = (cwidget_type*)get_cwidget(name); //Check whether there is already a C++ wrapper instance associated with this C instance: Glib::ObjectBase* pObjectBase = ObjectBase::_get_current_wrapper((GObject*)pCWidget); //If there is already a C++ instance, then return it again: if(pObjectBase) { widget = dynamic_cast( Glib::wrap(pCWidget) ); //The dynamic cast checks that it is of the correct type. //Somebody might be trying to call get_widget_derived() after already calling get_widget(), //or after already calling get_widget_derived() with a different derived C++ type. if(!widget) g_critical("Gnome::Glade::Xml::get_widget_derived(): dynamic_cast<> failed. An existing C++ instance, of a different type, seems to exist."); } else { //Create a new C++ instance to wrap the existing C instance: //Set the output variable. We needed to do this because we can not template the return type. Glib::RefPtr refThis(this); refThis->reference(); //take a copy. widget = new T_Widget(pCWidget, refThis); } //We return it as well (we need the parameter as well, because C++ can not just template the return type.) return widget; } _WRAP_METHOD(Glib::ListHandle get_widget_prefix(const Glib::ustring& name), glade_xml_get_widget_prefix) ///Take the widget from the glade-generated container and put it in another container. void reparent_widget(const Glib::ustring& name, Gtk::Container& container); _WRAP_METHOD(std::string relative_file(const std::string& filename) const, glade_xml_relative_file) _WRAP_METHOD(static Glib::ustring get_widget_name(Gtk::Widget& widget), glade_get_widget_name) _WRAP_METHOD(static Glib::RefPtr get_widget_tree(Gtk::Widget& widget), glade_get_widget_tree, refreturn) ///* interface for changing the custom widget handling */ //typedef GtkWidget *(* GladeXMLCustomWidgetHandler) (GladeXML *xml, // gchar *func_name, // gchar *name, // gchar *string1, // gchar *string2, // gint int1, // gint int2, // gpointer user_data); //void glade_set_custom_handler(GladeXMLCustomWidgetHandler handler, // gpointer user_data); protected: #m4begin dnl Custom-coded vfunc: dnl _PUSH(SECTION_PCC_CLASS_INIT_VFUNCS) klass->lookup_type = &lookup_type_vfunc_callback; _SECTION(SECTION_PH_VFUNCS) static GType lookup_type_vfunc_callback(GladeXML* self, const char* classname); _POP() #m4end virtual GType lookup_type_vfunc(const Glib::ustring& classname); }; } // namespace Glade } // namespace Gnome