// $Id: widget.cc,v 1.66 2004/06/22 15:25:23 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 "widget.hh" const std::string Gtk_Widget::TypeName(const Widget &w) const { return GtkPrefix()+"Widget"; } const std::string Gtk_Widget::IncludeName(const Widget &w) const { return Configuration.GtkmmIncludePath()+"widget.h"; } const std::string Gtk_Widget::SignalHandlerArgs(const Widget &w,const std::string &signal,std::string &rettype,std::string &scope) const { std::string bool_sig_ret="gint"; if (GTKMM2) bool_sig_ret="bool"; scope=Gtk_Widget::TypeName(w); if (signal=="draw") return "GdkRectangle *rect"; if (signal=="size_request") return "GtkRequisition *req"; if (signal=="size_allocate") return "GtkAllocation *all"; if (signal=="state_changed") return "unsigned int state"; if (signal=="event") { rettype=bool_sig_ret; return "GdkEvent *ev"; } if (signal=="button_press_event" || signal=="button_release_event") { rettype=bool_sig_ret; return "GdkEventButton *ev"; } if (signal=="motion_notify_event") { rettype=bool_sig_ret; return "GdkEventMotion *ev"; } if (signal=="delete_event" || signal=="map_event" || signal=="unmap_event") { rettype=bool_sig_ret; return "GdkEventAny *ev"; } if (signal=="expose_event") { rettype=bool_sig_ret; return "GdkEventExpose *ev"; } if (signal=="key_press_event" || signal=="key_release_event") { rettype=bool_sig_ret; return "GdkEventKey *ev"; } if (signal=="enter_notify_event" || signal=="leave_notify_event") { rettype=bool_sig_ret; return "GdkEventCrossing *ev"; } if (signal=="configure_event") { rettype=bool_sig_ret; return "GdkEventConfigure *ev"; } if (signal=="focus_in_event" || signal=="focus_out_event") { rettype=bool_sig_ret; return "GdkEventFocus *ev"; } if (signal=="property_notify_event") { rettype=bool_sig_ret; return "GdkEventProperty *ev"; } if (signal=="selection_clear_event" || signal=="selection_request_event" || signal=="selection_notify_event") { rettype=bool_sig_ret; return "GdkEventSelection *ev"; } if (signal=="proximity_in_event" || signal=="proximity_out_event") { rettype=bool_sig_ret; return "GdkEventProximity *ev"; } if (signal=="drag_begin_event") { rettype=bool_sig_ret; return "GdkEventDragBegin *ev"; } if (signal=="drag_request_event") { rettype=bool_sig_ret; return "GdkEventDragRequest *ev"; } const std::string drag_context= GTKMM2 ? "const Glib::RefPtr& context" : "GdkDragContext *context"; const std::string selection_data = GTKMM24 ? "Gtk::SelectionData &selection_data" : "GtkSelectionData *selection_data"; if (signal=="drag_begin" || signal=="drag_end" || signal=="drag_data_delete") return drag_context; if (signal=="drag_data_get") return drag_context+","+selection_data+",guint info,guint time"; if (signal=="drag_leave") return drag_context+",guint time"; if (signal=="drag_motion" || signal=="drag_drop") return drag_context+",gint x,gint y,guint time"; if (signal=="drag_data_received") return drag_context+",gint x,gint y,"+selection_data+",guint info,guint time"; if (signal=="drop_enter_event") { rettype=bool_sig_ret; return "GdkEventDropEnter *ev"; } if (signal=="drop_leave_event") { rettype=bool_sig_ret; return "GdkEventDropLeave *ev"; } if (signal=="drop_data_available_event") { rettype=bool_sig_ret; return "GdkEventDropDataAvailable *ev"; } if (signal=="other_event") { rettype=bool_sig_ret; return "GdkEventOther *ev"; } if (signal=="selection_received") return selection_data+",guint time"; if (signal=="selection_get") return selection_data+",guint info,guint time"; if (signal=="client_event") { rettype=bool_sig_ret; return "GdkEventClient *ev"; } if (signal=="no_expose_event") { rettype=bool_sig_ret; return "GdkEventAny *ev"; } if (signal=="show" || signal=="grab_focus" || signal=="hide" || signal=="destroy" || signal=="map" || signal=="unmap" || signal=="realize" || signal=="unrealize") return ""; if (signal=="popup_menu") { rettype="bool"; return ""; } if (signal=="visibility_notify_event") { rettype=bool_sig_ret; return "GdkEventVisibility *ev"; } scope=""; return ""; } // define this to allow widgets of this type //static Gtk_Widget Gtk_Widget; void Gtk_Widget::Configure(const Widget &w, CxxFile &f,const std::string &instance) const { /* Note: Below code causes trouble for menu items, as objects are created _after_ this method is called. Also, most of it doesn't apply anyway; the bits that do have been copied to appropriate locations. */ if(TypeName(w).find("MenuItem")!=std::string::npos) return; // glade 0.x / 1.1.0 WriteIntIntProperty(w,f,instance, "width", "height", GTKMM2?"size_request":"usize"); // glade 1.1.2+ WriteIntIntProperty(w,f,instance, "width_request", "height_request", GTKMM2?"size_request":"usize"); WriteEnumPropertyNS(w,f,instance, "events"); // uposition // style std::string name=w.Name(); if (!name.empty() && Configuration.widget_names) { f.Statement() << instance << "set_name(" << Configuration.CString_WithQuotes(name) << ')'; } WriteBoolProperty(w,f,instance, "sensitive"); if (GTKMM1) WriteBoolProp_2Fun(w,f,instance, "can_focus", "unset_flags(GTK_CAN_FOCUS)", "set_flags(GTK_CAN_FOCUS)"); else { WriteBoolProp_2Fun(w,f,instance, "can_focus", "unset_flags(Gtk::CAN_FOCUS)", "set_flags(Gtk::CAN_FOCUS)"); WriteBoolProp_2Fun(w,f,instance, "can_default", "unset_flags(Gtk::CAN_DEFAULT)", "set_flags(Gtk::CAN_DEFAULT)"); } if (w.getBoolProperty("has_focus",false)) { f.Statement() << instance << "grab_focus()"; } if (w.hasProperty("tooltip") && (!w.isSeperateClass() || instance.empty())) { std::string tooltip(w.getProperty("tooltip")); f.Statement() << "_tooltips.set_tip(" << Reference(instance) << ", " << Configuration.Translatable(tooltip) << ", \"\")"; } // this will fail for internal widgets !! will it ? CP if (Configuration.has_accelerators) { for (Widget::const_iterator i=w.get_Accels();i!=w.end();++i) { std::string modifiers=i->getGladeAttr("modifiers"); std::string key=i->getGladeAttr("key"); const std::string signal=i->getGladeAttr("signal"); if (modifiers.empty() || key.empty() || signal.empty()) std::cerr << w.Name() << ": accel is missing param (" << modifiers << ',' << key << ',' << signal << ")\n"; else { if (key.substr(0,4)!="GDK_") key="GDK_"+key; f.Statement() << instance << "add_accelerator(" << Configuration.CString_WithQuotes(signal) << ", " << (GTKMM2 ? "" : "*") << "gmm_data->getAccelGroup(), " << key << ", "; if (GTKMM1) f << "(GdkModifierType )" << modifiers << ", GTK_ACCEL_VISIBLE)"; else // gtkmm2 { replace_all(modifiers,"GDK_","Gdk::"); if (modifiers=="0") f << "Gdk::ModifierType(0)"; else f << modifiers; f << ", Gtk::ACCEL_VISIBLE)"; } } } } } void Gtk_Widget::Configure_show(const Widget &w, CxxFile &f,const std::string &instance) const { if (w.getBoolProperty("visible",!Configuration.glade2)) { f.Statement() << instance << "show()"; } } void Gtk_Widget::ApplyPreferences(Tag &t) const { if (!Configuration.has_accelerators && t.hasTag("accelerator")) Configuration.has_accelerators=true; Parent::ApplyPreferences(t); } bool Gtk_Widget::isInternalMethod(const Widget &w,std::string &method,const std::string &args,std::string &scope,bool &is_signal) const { const char prefix[]="gtk_widget_"; const int plen(sizeof(prefix)-1); if (method.substr(0,plen)==prefix) method=method.substr(plen); if ((method=="set_usize" && matches("gint\\ \\_,gint\\ \\_",args)) || ((method=="set_flags" || method=="unset_flags") && (matches("gint\\ \\_",args)||matches("int\\ \\_",args)))) { scope=Gtk_Widget::TypeName(w); is_signal=false; return true; } if ((method=="grab_focus" && args.empty() && GTKMM2) || (method=="grab_default" && args.empty()) || (method=="set_usize" && matches("gint\\ \\_,gint\\ \\_",args)) || ((method=="set_flags" || method=="unset_flags") && (matches("gint\\ \\_",args)||matches("int\\ \\_",args)))) { scope=Gtk_Widget::TypeName(w); is_signal=false; return true; } return Parent::isInternalMethod(w,method,args,scope,is_signal); } bool Gtk_Widget::isProxySignal(const Widget &w,std::string &method,bool after)const { if (after && method.size()>6 && method.substr(method.size()-6)=="_event") { std::string rettype,scope; SignalHandlerArgs(w,method,rettype,scope); if (scope==Gtk_Widget::TypeName(w)) std::cerr << "You really should connect with '!after' to " << w.Name() << "'s " << method << '\n'; } return Parent::isProxySignal(w,method,after); }