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