1 // $Id: widget.cc,v 1.66 2004/06/22 15:25:23 christof Exp $
2 /* glade--: C++ frontend for glade (Gtk+ User Interface Builder)
3 * Copyright (C) 1999-2000 Adolf Petig GmbH & Co. KG, written by Christof Petig
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19
20 #include "widget.hh"
21
TypeName(const Widget & w) const22 const std::string Gtk_Widget::TypeName(const Widget &w) const
23 { return GtkPrefix()+"Widget";
24 }
25
IncludeName(const Widget & w) const26 const std::string Gtk_Widget::IncludeName(const Widget &w) const
27 { return Configuration.GtkmmIncludePath()+"widget.h";
28 }
29
SignalHandlerArgs(const Widget & w,const std::string & signal,std::string & rettype,std::string & scope) const30 const std::string Gtk_Widget::SignalHandlerArgs(const Widget &w,const std::string &signal,std::string &rettype,std::string &scope) const
31 { std::string bool_sig_ret="gint";
32 if (GTKMM2) bool_sig_ret="bool";
33 scope=Gtk_Widget::TypeName(w);
34 if (signal=="draw") return "GdkRectangle *rect";
35 if (signal=="size_request") return "GtkRequisition *req";
36 if (signal=="size_allocate") return "GtkAllocation *all";
37 if (signal=="state_changed") return "unsigned int state";
38 if (signal=="event") { rettype=bool_sig_ret; return "GdkEvent *ev"; }
39 if (signal=="button_press_event" || signal=="button_release_event")
40 { rettype=bool_sig_ret; return "GdkEventButton *ev"; }
41 if (signal=="motion_notify_event") { rettype=bool_sig_ret; return "GdkEventMotion *ev"; }
42 if (signal=="delete_event" || signal=="map_event" || signal=="unmap_event")
43 { rettype=bool_sig_ret; return "GdkEventAny *ev"; }
44 if (signal=="expose_event") { rettype=bool_sig_ret; return "GdkEventExpose *ev"; }
45 if (signal=="key_press_event" || signal=="key_release_event")
46 { rettype=bool_sig_ret; return "GdkEventKey *ev"; }
47 if (signal=="enter_notify_event" || signal=="leave_notify_event")
48 { rettype=bool_sig_ret; return "GdkEventCrossing *ev"; }
49 if (signal=="configure_event") { rettype=bool_sig_ret; return "GdkEventConfigure *ev"; }
50 if (signal=="focus_in_event" || signal=="focus_out_event")
51 { rettype=bool_sig_ret; return "GdkEventFocus *ev"; }
52 if (signal=="property_notify_event") { rettype=bool_sig_ret; return "GdkEventProperty *ev"; }
53 if (signal=="selection_clear_event" || signal=="selection_request_event" || signal=="selection_notify_event")
54 { rettype=bool_sig_ret; return "GdkEventSelection *ev"; }
55 if (signal=="proximity_in_event" || signal=="proximity_out_event")
56 { rettype=bool_sig_ret; return "GdkEventProximity *ev"; }
57 if (signal=="drag_begin_event") { rettype=bool_sig_ret; return "GdkEventDragBegin *ev"; }
58 if (signal=="drag_request_event") { rettype=bool_sig_ret; return "GdkEventDragRequest *ev"; }
59 const std::string drag_context= GTKMM2
60 ? "const Glib::RefPtr<Gdk::DragContext>& context"
61 : "GdkDragContext *context";
62 const std::string selection_data = GTKMM24
63 ? "Gtk::SelectionData &selection_data"
64 : "GtkSelectionData *selection_data";
65 if (signal=="drag_begin" || signal=="drag_end" || signal=="drag_data_delete")
66 return drag_context;
67 if (signal=="drag_data_get") return drag_context+","+selection_data+",guint info,guint time";
68 if (signal=="drag_leave") return drag_context+",guint time";
69 if (signal=="drag_motion" || signal=="drag_drop")
70 return drag_context+",gint x,gint y,guint time";
71 if (signal=="drag_data_received")
72 return drag_context+",gint x,gint y,"+selection_data+",guint info,guint time";
73 if (signal=="drop_enter_event") { rettype=bool_sig_ret; return "GdkEventDropEnter *ev"; }
74 if (signal=="drop_leave_event") { rettype=bool_sig_ret; return "GdkEventDropLeave *ev"; }
75 if (signal=="drop_data_available_event") { rettype=bool_sig_ret; return "GdkEventDropDataAvailable *ev"; }
76 if (signal=="other_event") { rettype=bool_sig_ret; return "GdkEventOther *ev"; }
77 if (signal=="selection_received") return selection_data+",guint time";
78 if (signal=="selection_get") return selection_data+",guint info,guint time";
79 if (signal=="client_event") { rettype=bool_sig_ret; return "GdkEventClient *ev"; }
80 if (signal=="no_expose_event") { rettype=bool_sig_ret; return "GdkEventAny *ev"; }
81 if (signal=="show" || signal=="grab_focus" || signal=="hide"
82 || signal=="destroy" || signal=="map" || signal=="unmap"
83 || signal=="realize" || signal=="unrealize") return "";
84 if (signal=="popup_menu") { rettype="bool"; return ""; }
85 if (signal=="visibility_notify_event") { rettype=bool_sig_ret; return "GdkEventVisibility *ev"; }
86 scope="";
87 return "";
88 }
89
90 // define this to allow widgets of this type
91 //static Gtk_Widget Gtk_Widget;
92
Configure(const Widget & w,CxxFile & f,const std::string & instance) const93 void Gtk_Widget::Configure(const Widget &w, CxxFile &f,const std::string &instance) const
94 {
95 /* Note: Below code causes trouble for menu items, as objects are created
96 _after_ this method is called. Also, most of it doesn't apply anyway;
97 the bits that do have been copied to appropriate locations. */
98 if(TypeName(w).find("MenuItem")!=std::string::npos)
99 return;
100
101 // glade 0.x / 1.1.0
102 WriteIntIntProperty(w,f,instance, "width", "height",
103 GTKMM2?"size_request":"usize");
104 // glade 1.1.2+
105 WriteIntIntProperty(w,f,instance, "width_request", "height_request",
106 GTKMM2?"size_request":"usize");
107
108 WriteEnumPropertyNS(w,f,instance, "events");
109
110 // uposition
111 // style
112
113 std::string name=w.Name();
114 if (!name.empty() && Configuration.widget_names)
115 { f.Statement() << instance << "set_name(" << Configuration.CString_WithQuotes(name) << ')';
116 }
117
118 WriteBoolProperty(w,f,instance, "sensitive");
119
120 if (GTKMM1) WriteBoolProp_2Fun(w,f,instance, "can_focus",
121 "unset_flags(GTK_CAN_FOCUS)", "set_flags(GTK_CAN_FOCUS)");
122 else
123 { WriteBoolProp_2Fun(w,f,instance, "can_focus",
124 "unset_flags(Gtk::CAN_FOCUS)", "set_flags(Gtk::CAN_FOCUS)");
125 WriteBoolProp_2Fun(w,f,instance, "can_default",
126 "unset_flags(Gtk::CAN_DEFAULT)", "set_flags(Gtk::CAN_DEFAULT)");
127 }
128
129 if (w.getBoolProperty("has_focus",false))
130 { f.Statement() << instance << "grab_focus()";
131 }
132
133 if (w.hasProperty("tooltip") && (!w.isSeperateClass() || instance.empty()))
134 { std::string tooltip(w.getProperty("tooltip"));
135 f.Statement() << "_tooltips.set_tip(" << Reference(instance)
136 << ", " << Configuration.Translatable(tooltip) << ", \"\")";
137 }
138 // this will fail for internal widgets !! will it ? CP
139 if (Configuration.has_accelerators)
140 { for (Widget::const_iterator i=w.get_Accels();i!=w.end();++i)
141 { std::string modifiers=i->getGladeAttr("modifiers");
142 std::string key=i->getGladeAttr("key");
143 const std::string signal=i->getGladeAttr("signal");
144
145 if (modifiers.empty() || key.empty() || signal.empty())
146 std::cerr << w.Name() << ": accel is missing param ("
147 << modifiers << ',' << key << ',' << signal << ")\n";
148 else
149 { if (key.substr(0,4)!="GDK_") key="GDK_"+key;
150 f.Statement() << instance
151 << "add_accelerator("
152 << Configuration.CString_WithQuotes(signal)
153 << ", " << (GTKMM2 ? "" : "*")
154 << "gmm_data->getAccelGroup(), " << key << ", ";
155 if (GTKMM1)
156 f << "(GdkModifierType )" << modifiers << ", GTK_ACCEL_VISIBLE)";
157 else // gtkmm2
158 { replace_all(modifiers,"GDK_","Gdk::");
159 if (modifiers=="0") f << "Gdk::ModifierType(0)";
160 else f << modifiers;
161 f << ", Gtk::ACCEL_VISIBLE)";
162 }
163 }
164 }
165 }
166 }
167
Configure_show(const Widget & w,CxxFile & f,const std::string & instance) const168 void Gtk_Widget::Configure_show(const Widget &w, CxxFile &f,const std::string &instance) const
169 { if (w.getBoolProperty("visible",!Configuration.glade2))
170 { f.Statement() << instance << "show()";
171 }
172 }
173
ApplyPreferences(Tag & t) const174 void Gtk_Widget::ApplyPreferences(Tag &t) const
175 { if (!Configuration.has_accelerators && t.hasTag("accelerator"))
176 Configuration.has_accelerators=true;
177 Parent::ApplyPreferences(t);
178 }
179
isInternalMethod(const Widget & w,std::string & method,const std::string & args,std::string & scope,bool & is_signal) const180 bool Gtk_Widget::isInternalMethod(const Widget &w,std::string &method,const std::string &args,std::string &scope,bool &is_signal) const
181 { const char prefix[]="gtk_widget_";
182 const int plen(sizeof(prefix)-1);
183 if (method.substr(0,plen)==prefix) method=method.substr(plen);
184 if ((method=="set_usize" && matches("gint\\ \\_,gint\\ \\_",args))
185 || ((method=="set_flags" || method=="unset_flags")
186 && (matches("gint\\ \\_",args)||matches("int\\ \\_",args))))
187 { scope=Gtk_Widget::TypeName(w);
188 is_signal=false;
189 return true;
190 }
191 if ((method=="grab_focus" && args.empty() && GTKMM2)
192 || (method=="grab_default" && args.empty())
193 || (method=="set_usize" && matches("gint\\ \\_,gint\\ \\_",args))
194 || ((method=="set_flags" || method=="unset_flags")
195 && (matches("gint\\ \\_",args)||matches("int\\ \\_",args))))
196 { scope=Gtk_Widget::TypeName(w);
197 is_signal=false;
198 return true;
199 }
200 return Parent::isInternalMethod(w,method,args,scope,is_signal);
201 }
202
isProxySignal(const Widget & w,std::string & method,bool after) const203 bool Gtk_Widget::isProxySignal(const Widget &w,std::string &method,bool after)const
204 { if (after && method.size()>6 && method.substr(method.size()-6)=="_event")
205 { std::string rettype,scope;
206 SignalHandlerArgs(w,method,rettype,scope);
207 if (scope==Gtk_Widget::TypeName(w))
208 std::cerr << "You really should connect with '!after' to " << w.Name()
209 << "'s " << method << '\n';
210 }
211 return Parent::isProxySignal(w,method,after);
212 }
213