/* $Id: xml.ccg,v 1.12 2003/08/23 17:21:07 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 namespace Gnome { namespace Glade { XmlError::XmlError(const Glib::ustring& message) : message_ (message) {} XmlError::~XmlError() throw() {} XmlError::XmlError(const XmlError& other) : Glib::Exception (other), message_ (other.message_) {} XmlError& XmlError::operator=(const XmlError& other) { message_ = other.message_; return *this; } Glib::ustring XmlError::what() const { return message_; } Xml::Xml(const std::string& filename, const Glib::ustring& root, const Glib::ustring& domain) : _CONSTRUCT() { if(!glade_xml_construct(gobj(), filename.c_str(), root.empty() ? 0 : root.c_str(), domain.empty() ? 0 : domain.c_str())) { throw XmlError("Failed to load glade file `" + Glib::filename_to_utf8(filename) + '\''); } } // TODO: we need glade_xml_construct_from_buffer() Xml::Xml(const char* buffer, int size, const Glib::ustring& root, const Glib::ustring& domain) : Glib::ObjectBase(0), Glib::Object((GObject*) glade_xml_new_from_buffer( buffer, size, root.empty() ? 0 : root.c_str(), domain.empty() ? 0 : domain.c_str())) { if(!gobj()) throw XmlError("Failed to read glade input buffer"); } // static Glib::RefPtr Xml::create(const std::string& filename, const Glib::ustring& root, const Glib::ustring& domain) { return Glib::RefPtr(new Xml(filename, root, domain)); } // static Glib::RefPtr Xml::create_from_buffer(const char* buffer, int size, const Glib::ustring& root, const Glib::ustring& domain) { return Glib::RefPtr(new Xml(buffer, size, root, domain)); } void Xml::reparent_widget(const Glib::ustring& name, Gtk::Container& container) { Gtk::Widget* pWidget = 0; get_widget(name, pWidget); g_return_if_fail(pWidget != 0); pWidget->reparent(container); } Gtk::Widget* Xml::get_widget_checked(const Glib::ustring& name, GType type) { // Get the widget from the glade file. Gtk::Widget *const pWidget = get_widget(name); if(!pWidget) { g_critical("widget `%s' not found in glade file `%s'", name.c_str(), gobj()->filename); return 0; } // Check if it has the correct type. if(!g_type_is_a(G_OBJECT_TYPE(pWidget->gobj()), type)) { g_critical("widget `%s' (in glade file `%s') is of type `%s' but `%s' was expected", name.c_str(), gobj()->filename, G_OBJECT_TYPE_NAME(pWidget->gobj()), g_type_name(type)); return 0; } return pWidget; } GtkWidget* Xml::get_cwidget(const Glib::ustring& name) { GtkWidget* pCWidget = glade_xml_get_widget(gobj(), name.c_str()); if(!pCWidget) g_critical("Glade::Xml::get_cwidget(): glade_xml_get_widget() failed."); return pCWidget; } // Custom coded so that we can custom-code the vfunc in the Xml class. // This is marginally better than modifying gtkmmproc to allow this. // GType Xml_Class::lookup_type_vfunc_callback(GladeXML* self, const char* classname) { CppObjectType *const obj = dynamic_cast( Glib::ObjectBase::_get_current_wrapper((GObject*) self)); if(obj) { try { return obj->lookup_type_vfunc(Glib::convert_const_gchar_ptr_to_ustring(classname)); } catch(...) { Glib::exception_handlers_invoke(); } } else { BaseClassType *const base = static_cast( g_type_class_peek_parent(G_OBJECT_GET_CLASS(self)) // Get the parent class of the object class. ); if(base && base->lookup_type) return (*base->lookup_type)(self, classname); } return 0; } GType Xml::lookup_type_vfunc(const Glib::ustring& classname) { // See if there is a gtkmm version of the gclass: Glib::ustring classname_prefixed ("gtkmm__"); // gtkmm uses a prefix classname_prefixed += classname; GType gtype = g_type_from_name(classname_prefixed.c_str()); if(gtype == G_TYPE_INVALID) // if it's not a registered typename { // There's no gtkmm derived type, so just use the normal one. gtype = g_type_from_name(classname.c_str()); } return gtype; } } // namespace Glade } // namespace Gnome