1 /* base class for models of heap classes
2 */
3
4 /*
5
6 Copyright (C) 1991-2003 The National Gallery
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
22 */
23
24 /*
25
26 These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
27
28 */
29
30 /*
31 #define DEBUG
32 */
33
34 #include "ip.h"
35
36 static ModelClass *parent_class = NULL;
37
38 void *
heapmodel_new_heap(Heapmodel * heapmodel,PElement * root)39 heapmodel_new_heap( Heapmodel *heapmodel, PElement *root )
40 {
41 HeapmodelClass *heapmodel_class = HEAPMODEL_GET_CLASS( heapmodel );
42
43 if( heapmodel_class->new_heap ) {
44 void *res;
45
46 res = heapmodel_class->new_heap( heapmodel, root );
47
48 return( res );
49 }
50
51 return( NULL );
52 }
53
54 void *
heapmodel_update_model(Heapmodel * heapmodel)55 heapmodel_update_model( Heapmodel *heapmodel )
56 {
57 HeapmodelClass *heapmodel_class = HEAPMODEL_GET_CLASS( heapmodel );
58
59 #ifdef DEBUG
60 printf( "heapmodel_update_model: %s ",
61 G_OBJECT_TYPE_NAME( heapmodel ) );
62 row_name_print( heapmodel->row );
63 printf( " modified = %d\n", heapmodel->modified );
64 #endif /*DEBUG*/
65
66 if( heapmodel_class->update_model && !heapmodel->modified ) {
67 void *res;
68
69 res = heapmodel_class->update_model( heapmodel );
70
71 return( res );
72 }
73
74 return( NULL );
75 }
76
77 void *
heapmodel_update_heap(Heapmodel * heapmodel)78 heapmodel_update_heap( Heapmodel *heapmodel )
79 {
80 HeapmodelClass *heapmodel_class = HEAPMODEL_GET_CLASS( heapmodel );
81
82 if( heapmodel_class->update_heap && heapmodel->modified ) {
83 void *res;
84
85 res = heapmodel_class->update_heap( heapmodel );
86
87 return( res );
88 }
89
90 return( NULL );
91 }
92
93 void *
heapmodel_clear_edited(Heapmodel * heapmodel)94 heapmodel_clear_edited( Heapmodel *heapmodel )
95 {
96 HeapmodelClass *heapmodel_class = HEAPMODEL_GET_CLASS( heapmodel );
97
98 if( heapmodel_class->clear_edited )
99 return( heapmodel_class->clear_edited( heapmodel ) );
100
101 return( NULL );
102 }
103
104 static Rhs *
heapmodel_get_rhs(Heapmodel * heapmodel)105 heapmodel_get_rhs( Heapmodel *heapmodel )
106 {
107 iContainer *p;
108
109 /* Search for the enclosing RHS ... may not be one if (eg.) this is a
110 * top-level row.
111 */
112 for( p = ICONTAINER( heapmodel )->parent; p; p = p->parent )
113 if( IS_RHS( p ) )
114 return( RHS( p ) );
115
116 return( NULL );
117 }
118
119 static Row *
heapmodel_get_row(Heapmodel * heapmodel)120 heapmodel_get_row( Heapmodel *heapmodel )
121 {
122 Rhs *rhs;
123
124 if( IS_RHS( heapmodel ) )
125 return( ROW( ICONTAINER( heapmodel )->parent ) );
126 else if( (rhs = heapmodel_get_rhs( heapmodel )) )
127 return( HEAPMODEL( rhs )->row );
128 else
129 return( NULL );
130 }
131
132 static void
heapmodel_parent_add(iContainer * child)133 heapmodel_parent_add( iContainer *child )
134 {
135 Heapmodel *heapmodel = HEAPMODEL( child );
136
137 g_assert( IS_HEAPMODEL( child->parent ) ||
138 IS_FILEMODEL( child->parent ) );
139
140 ICONTAINER_CLASS( parent_class )->parent_add( child );
141
142 /* Update our context.
143 */
144 heapmodel->rhs = heapmodel_get_rhs( heapmodel );
145 heapmodel->row = heapmodel_get_row( heapmodel );
146 }
147
148 static void *
heapmodel_real_new_heap(Heapmodel * heapmodel,PElement * root)149 heapmodel_real_new_heap( Heapmodel *heapmodel, PElement *root )
150 {
151 iobject_changed( IOBJECT( heapmodel ) );
152
153 return( NULL );
154 }
155
156 static void *
heapmodel_real_update_model(Heapmodel * heapmodel)157 heapmodel_real_update_model( Heapmodel *heapmodel )
158 {
159 iobject_changed( IOBJECT( heapmodel ) );
160
161 return( NULL );
162 }
163
164 static void *
heapmodel_real_update_heap(Heapmodel * heapmodel)165 heapmodel_real_update_heap( Heapmodel *heapmodel )
166 {
167 g_assert( heapmodel->modified );
168
169 heapmodel_set_modified( heapmodel, FALSE );
170
171 return( NULL );
172 }
173
174 static void *
heapmodel_real_clear_edited(Heapmodel * heapmodel)175 heapmodel_real_clear_edited( Heapmodel *heapmodel )
176 {
177 return( NULL );
178 }
179
180 static void
heapmodel_class_init(HeapmodelClass * class)181 heapmodel_class_init( HeapmodelClass *class )
182 {
183 HeapmodelClass *heapmodel_class = (HeapmodelClass *) class;
184 iContainerClass *icontainer_class = (iContainerClass *) class;
185
186 parent_class = g_type_class_peek_parent( class );
187
188 /* Init methods.
189 */
190 icontainer_class->parent_add = heapmodel_parent_add;
191
192 heapmodel_class->new_heap = heapmodel_real_new_heap;
193 heapmodel_class->update_heap = heapmodel_real_update_heap;
194 heapmodel_class->update_model = heapmodel_real_update_model;
195 heapmodel_class->clear_edited = heapmodel_real_clear_edited;
196 }
197
198 static void
heapmodel_init(Heapmodel * heapmodel)199 heapmodel_init( Heapmodel *heapmodel )
200 {
201 heapmodel->row = NULL;
202 heapmodel->rhs = NULL;
203
204 heapmodel->modified = FALSE;
205 }
206
207 GType
heapmodel_get_type(void)208 heapmodel_get_type( void )
209 {
210 static GType heapmodel_type = 0;
211
212 if( !heapmodel_type ) {
213 static const GTypeInfo info = {
214 sizeof( HeapmodelClass ),
215 NULL, /* base_init */
216 NULL, /* base_finalize */
217 (GClassInitFunc) heapmodel_class_init,
218 NULL, /* class_finalize */
219 NULL, /* class_data */
220 sizeof( Heapmodel ),
221 32, /* n_preallocs */
222 (GInstanceInitFunc) heapmodel_init,
223 };
224
225 heapmodel_type = g_type_register_static( TYPE_MODEL,
226 "Heapmodel", &info, 0 );
227 }
228
229 return( heapmodel_type );
230 }
231
232 void
heapmodel_set_modified(Heapmodel * heapmodel,gboolean modified)233 heapmodel_set_modified( Heapmodel *heapmodel, gboolean modified )
234 {
235 if( heapmodel->modified != modified ) {
236 #ifdef DEBUG
237 {
238 HeapmodelClass *heapmodel_class =
239 HEAPMODEL_GET_CLASS( heapmodel );
240
241 printf( "heapmodel_set_modified: %s::",
242 G_OBJECT_CLASS_NAME( heapmodel_class ) );
243 row_name_print( heapmodel->row );
244 printf( " %s\n", bool_to_char( modified ) );
245 }
246 #endif /*DEBUG*/
247
248 heapmodel->modified = modified;
249 iobject_changed( IOBJECT( heapmodel ) );
250 }
251 }
252
253 /* Generate a descriptive name for a heapmodel. Used for captions.
254 */
255 gboolean
heapmodel_name(Heapmodel * heapmodel,VipsBuf * buf)256 heapmodel_name( Heapmodel *heapmodel, VipsBuf *buf )
257 {
258 Row *row = heapmodel->row;
259 Expr *expr;
260 Symbol *sym;
261 Toolitem *toolitem;
262
263 if( !row || !(expr = row->expr) || !PEISCLASS( &expr->root ) )
264 return( FALSE );
265 sym = PEGETCLASSCOMPILE( &expr->root )->sym;
266
267 /* If this is an action member we should be able to look up
268 * it's sym and get a descriptive label.
269 */
270 if( (toolitem = toolitem_lookup( row->ws->kitg, sym )) )
271 vips_buf_appends( buf, toolitem->name );
272 else
273 symbol_qualified_name_relative( row->ws->sym, sym, buf );
274
275 return( TRUE );
276 }
277
278 /* Print the value member to a buf.
279 */
280 gboolean
heapmodel_value(Heapmodel * heapmodel,VipsBuf * buf)281 heapmodel_value( Heapmodel *heapmodel, VipsBuf *buf )
282 {
283 Expr *expr;
284 PElement value;
285
286 if( !heapmodel->row ||
287 !(expr = heapmodel->row->expr) ||
288 expr->err ||
289 expr->sym->dirty ||
290 !class_get_member( &expr->root, MEMBER_VALUE, NULL, &value ) )
291 return( FALSE );
292
293 itext_value( reduce_context, buf, &value );
294
295 return( TRUE );
296 }
297
298