1 // $Id: Widget.hh,v 1.46 2003/05/19 07:00:53 christof Exp $
2 /*  glade--: C++ frontend for glade (Gtk+ User Interface Builder)
3  *  Copyright (C) 1998  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 #ifndef WIDGET_HH
21 #define WIDGET_HH
22 #include <config.h>
23 #include "Enums.hh"
24 #include "GladeTag.hh"
25 #include <iterator>
26 #include <list>
27 #include "Widget_type.hh"
28 #include "ChildParamList.hh"
29 #include <iostream>
30 #include <stdexcept>
31 #include <cassert>
32 
33 // Widget is a Tag handle class with convenience additions for widget
34 // handling. Constructing a Widget from an Tag is very fast, so remembering
35 // only Tag* has no penalty (up to now).
36 
37 // Due to C++'s limits we can't include a widget in one of its iterators ...
38 // so we use Tag*                       [or Tag& - do we?]
39 
40 // we protect tag against modification if passed by a const
41 // constructor.
42 
43 // WARNING: Tag's lifetime must exceed its derived Widget's !!!!
44 // and of course a containers lifetime should exceed it's iterators' lifetime
45 // WARNING2: since we use 'ti=Widget(parent).begin();'
46 //  Widget's iterators must not rely on Widget's existance
47 // => Tags must live longer than Widget's iterators
48 
49 // I hate this nonsense, perhaps another reorganization should address this
50 
51 class Widget
52 {  	Tag *tag,*childtag;
53 	mutable std::string name;
54 	bool is_const;
55 
test4validity()56 	void test4validity()
57 	{  if (tag->Type()=="child" && tag->begin()!=tag->end() && !childtag)
58 	   {  childtag=tag; tag=&*(tag->begin());
59 	   }
60 	   assert(tag->Type()=="widget" || tag->Type()=="placeholder");
61 	}
obselete(const char * x)62 	void obselete(const char *x)
63 	{
64 	   std::cout << "Widget: obselete member function "<<x<<" called\n";
65 	}
66 public:
67 	// internal use
Widget(Tag * t,Tag * c=0)68 	Widget(Tag *t,Tag *c=0) throw() : tag(t), childtag(c), name(""), is_const(false)
69 	{ test4validity(); }
70 	// be careful to not pass a temporary
Widget(const Tag & t,Tag * c=0)71 	Widget(const Tag &t,Tag *c=0) throw()
72 	: tag((Tag*)&t), childtag(c), name(""), is_const(true)
73 	{ test4validity(); }
74 	// be careful to not pass a temporary
Widget(const Tag & t,const std::string & _name,Tag * c=0)75 	Widget(const Tag &t,const std::string &_name,Tag *c=0) throw()
76 		: tag((Tag*)&t), childtag(c), name(_name), is_const(true)
77 	{ test4validity(); }
Widget(const Widget & w,const std::string & _name)78 	Widget(const Widget &w,const std::string &_name) throw()
79 		: tag(w.tag), childtag(w.childtag), name(_name), is_const(w.is_const)
80 	{ test4validity(); }
81 
getTagPtr() const82 	const Tag *getTagPtr() const { return tag; }
getTag() const83 	const Tag &getTag() const { return *tag; }
operator ==(const Widget & w) const84 	bool operator==(const Widget &w) const { return tag==w.tag; }
85 	const std::string Class() const throw();
86 	const std::string ChildName() const throw();
87 	Widget getParent() const throw(std::out_of_range);
88 
89 	// wrapper for unification of glade-1+2
90 	bool hasProperty(const std::string &name) const;
91 	const std::string getProperty(const std::string &name, const std::string &_default="") const;
getIntProperty(const std::string & name,int _default=0) const92 	int getIntProperty(const std::string &name, int _default=0) const
93 	{  return Tag::parse_value_def<int>(getProperty(name),_default); }
getBoolProperty(const std::string & name,bool _default=false) const94 	bool getBoolProperty(const std::string &name, bool _default=false) const
95 	{  return Tag::parse_value_def<bool>(getProperty(name),_default); }
getFloatProperty(const std::string & name,float _default=0) const96 	float getFloatProperty(const std::string &name, float _default=0) const
97 	{  return Tag::parse_value_def<float>(getProperty(name),_default); }
98 
99 	void setProperty(const std::string &name, const std::string &value="true");
100 
101 	// const is not always true
102 	const std::string Name() const throw();
103 	Subwidget subwidgettype(const Widget &w) const throw();
104 
105 	std::vector<std::string> Dependancies() const throw();
106 #if 0
107 	bool hasTag(const std::string &t) const throw()
108 	{  return tag->hasTag(t); }
109 #endif
110 	bool hasChildren() const throw();
debug() const111 	void debug() const throw()
112 	{  tag->debug(); }
113 
mark(const std::string & tg)114 	void mark(const std::string &tg) throw()
115 	{  assert(!is_const);
116 	   setProperty(tg,"true"); }
mark(const std::string & tg,const std::string & value)117 	void mark(const std::string &tg,const std::string &value) throw()
118 	{  assert(!is_const);
119 	   setProperty(tg,value); }
120 
isSeperateClass() const121 	bool isSeperateClass() const throw()
122 	{  return getBoolProperty(CXX_SEPERATE_CLASS); }
wasWrapped() const123 	bool wasWrapped() const throw()
124 	{  return getBoolProperty(CXX_IS_MANAGED,false); }
markManaged() const125 	void markManaged() const throw()
126 		// this is not const ... but I don't want to rewrite the
127 		// writers yet
128 	{  const_cast<Widget*>(this)->setProperty(CXX_IS_MANAGED,"true"); }
129 
130 	const ChildParamList get_Child_params() const throw();
131 
132 #if 0
133 	const std::string getString(const std::string &t,const std::string &def="") const throw()
134 	{  return tag->getString(t,def); }
135 	bool getBool(const std::string &t,const bool def=false) const throw()
136 	{  return tag->getBool(t,def); }
137 	int getInt(const std::string &t,const int def=-1) const throw()
138 	{  return tag->getInt(t,def); }
139 	float getFloat(const std::string &t,const float def=0) const throw()
140 	{  return tag->getFloat(t,def); }
141 #endif
142 
143 	// new functions:
144 	// - find internal subwidget by name
145 
146         // to get this class more compact
147 #include "Widget_iterators.hh"
148 
149 	const_iterator begin() const;
end() const150 	const_iterator end() const
151 	{  return const_iterator(tag->end(),tag->end(),""); }
152 	iterator begin();
end()153 	iterator end()
154 	{  assert(!is_const); // too hard?
155 	   return iterator(tag->end(),tag->end(),""); }
156 
get_Signals() const157 	const_iterator get_Signals() const throw()
158 	{
159 	   return const_iterator(find(tag->begin(),tag->end(),"signal"),tag->end(),"signal");
160 	}
161 
162 	const_iterator get_Accels() const throw();
163 	// replace this by getGladeAttr
164 //	static const std::string getAccelProperty(const_iterator it, const string &name, const string &_default="");
165 
166 	const_contained_iterator begin_contained(InternalSelection _internal=NoInternal,bool debug=false) const;
end_contained() const167 	const_contained_iterator end_contained() const
168 	{  return const_contained_iterator(tag->end(),tag,NoInternal);
169 	}
170 };
171 
172 #endif
173