1 /* a view of a text thingy
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 ViewClass *parent_class = NULL;
37 
38 static void
itextview_refresh(vObject * vobject)39 itextview_refresh( vObject *vobject )
40 {
41 	iTextview *itextview = ITEXTVIEW( vobject );
42 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
43 	Row *row = HEAPMODEL( itext )->row;
44 
45 	const char *display;
46 
47 #ifdef DEBUG
48 	printf( "itextview_refresh: " );
49 	row_name_print( row );
50 	printf( " (%p)\n", vobject );
51 #endif /*DEBUG*/
52 
53 	/* Only reset edit mode if the text hasn't been changed. We
54 	 * don't want the user to lose work.
55 	 */
56 	if( !itextview->formula->changed )
57 		switch( row->ws->mode ) {
58 		case WORKSPACE_MODE_REGULAR:
59 			formula_set_edit( itextview->formula, FALSE );
60 			formula_set_sensitive( itextview->formula, TRUE );
61 			break;
62 
63 		case WORKSPACE_MODE_FORMULA:
64 			formula_set_edit( itextview->formula, TRUE );
65 			formula_set_sensitive( itextview->formula, TRUE );
66 			break;
67 
68 		case WORKSPACE_MODE_NOEDIT:
69 			formula_set_edit( itextview->formula, FALSE );
70 			formula_set_sensitive( itextview->formula, FALSE );
71 			break;
72 
73 		default:
74 			g_assert_not_reached();
75 		}
76 
77 	/* We display the formula if this is a class ... we assume the members
78 	 * and/or the graphic will represent the value.
79 	 */
80 	if( row->is_class )
81 		display = itext->formula;
82 	else
83 		display = vips_buf_all( &itext->value );
84 
85 	if( itextview->formula && itext->value.base )
86 		formula_set_value_expr( itextview->formula,
87 			display, itext->formula );
88 
89 	VOBJECT_CLASS( parent_class )->refresh( vobject );
90 }
91 
92 static void
itextview_link(View * view,Model * model,View * parent)93 itextview_link( View *view, Model *model, View *parent )
94 {
95 	iTextview *itextview = ITEXTVIEW( view );
96 	iText *itext = ITEXT( model );
97 	Row *row = HEAPMODEL( itext )->row;
98 
99 #ifdef DEBUG
100 	printf( "itextview_link: " );
101 	row_name_print( row );
102 	printf( "\n" );
103 #endif /*DEBUG*/
104 
105 	VIEW_CLASS( parent_class )->link( view, model, parent );
106 
107 	/* Edit mode defaults to edit mode for workspace.
108 	 */
109         formula_set_edit( itextview->formula,
110 		row->ws->mode == WORKSPACE_MODE_FORMULA );
111 }
112 
113 /* Reset edit mode ... go back to whatever is set for this ws.
114  */
115 static void
itextview_reset(View * view)116 itextview_reset( View *view )
117 {
118 	iTextview *itextview = ITEXTVIEW( view );
119 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
120 	Row *row = HEAPMODEL( itext )->row;
121 
122 #ifdef DEBUG
123 	printf( "itextview_reset: " );
124 	row_name_print( row );
125 	printf( "\n" );
126 #endif /*DEBUG*/
127 
128 	formula_set_edit( ITEXTVIEW( view )->formula,
129 		row->ws->mode == WORKSPACE_MODE_FORMULA );
130 
131 	VIEW_CLASS( parent_class )->reset( view );
132 }
133 
134 /* Re-read the text in a tally entry.
135  */
136 static void *
itextview_scan(View * view)137 itextview_scan( View *view )
138 {
139 	iTextview *itextview = ITEXTVIEW( view );
140 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
141 
142 #ifdef DEBUG
143 	Row *row = HEAPMODEL( itext )->row;
144 
145 	printf( "itextview_scan: " );
146 	row_name_print( row );
147 	printf( "\n" );
148 #endif /*DEBUG*/
149 
150 	if( formula_scan( itextview->formula ) &&
151 		itext_set_formula( itext, itextview->formula->expr ) )
152 		itext_set_edited( itext, TRUE );
153 
154 	return( VIEW_CLASS( parent_class )->scan( view ) );
155 }
156 
157 static void
itextview_class_init(iTextviewClass * class)158 itextview_class_init( iTextviewClass *class )
159 {
160 	vObjectClass *vobject_class = (vObjectClass *) class;
161 	ViewClass *view_class = (ViewClass *) class;
162 
163 	parent_class = g_type_class_peek_parent( class );
164 
165 	/* Create signals.
166 	 */
167 
168 	/* Init methods.
169 	 */
170 	vobject_class->refresh = itextview_refresh;
171 
172 	view_class->link = itextview_link;
173 	view_class->reset = itextview_reset;
174 	view_class->scan = itextview_scan;
175 }
176 
177 void
itextview_edit_cb(Formula * formula,iTextview * itextview)178 itextview_edit_cb( Formula *formula, iTextview *itextview )
179 {
180 	view_resettable_register( VIEW( itextview ) );
181 }
182 
183 void
itextview_activate_cb(Formula * formula,iTextview * itextview)184 itextview_activate_cb( Formula *formula, iTextview *itextview )
185 {
186 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
187 	Row *row = HEAPMODEL( itext )->row;
188 
189 	/* Reset edits on this row and all children. Our (potentially) next
190 	 * text will invlidate all of them.
191 	 */
192 	(void) icontainer_map_all( ICONTAINER( row ),
193 		(icontainer_map_fn) heapmodel_clear_edited, NULL );
194 
195 	/* Make sure we scan this text, even if it's not been edited.
196 	 */
197 	view_scannable_register( VIEW( itextview ) );
198 
199 	workspace_set_modified( row->ws, TRUE );
200 
201 	symbol_recalculate_all();
202 }
203 
204 static void
itextview_enter_cb(Formula * formula,iTextview * itextview)205 itextview_enter_cb( Formula *formula, iTextview *itextview )
206 {
207 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
208 	Row *row = HEAPMODEL( itext )->row;
209 
210 	row_set_status( row );
211 	row_show_dependents( row );
212 }
213 
214 static void
itextview_leave_cb(Formula * formula,iTextview * itextview)215 itextview_leave_cb( Formula *formula, iTextview *itextview )
216 {
217 	iText *itext = ITEXT( VOBJECT( itextview )->iobject );
218 	Row *row = HEAPMODEL( itext )->row;
219 
220 	row_hide_dependents( row );
221 }
222 
223 static void
itextview_init(iTextview * itextview)224 itextview_init( iTextview *itextview )
225 {
226 	itextview->formula = formula_new();
227 
228         gtk_signal_connect( GTK_OBJECT( itextview->formula ), "edit",
229 		GTK_SIGNAL_FUNC( itextview_edit_cb ), itextview );
230         gtk_signal_connect_object( GTK_OBJECT( itextview->formula ), "changed",
231 		GTK_SIGNAL_FUNC( view_changed_cb ), itextview );
232         gtk_signal_connect( GTK_OBJECT( itextview->formula ), "activate",
233                 GTK_SIGNAL_FUNC( itextview_activate_cb ), itextview );
234         gtk_signal_connect( GTK_OBJECT( itextview->formula ), "enter",
235 		GTK_SIGNAL_FUNC( itextview_enter_cb ), itextview );
236         gtk_signal_connect( GTK_OBJECT( itextview->formula ), "leave",
237 		GTK_SIGNAL_FUNC( itextview_leave_cb ), itextview );
238 
239         gtk_box_pack_start( GTK_BOX( itextview ),
240 		GTK_WIDGET( itextview->formula ), TRUE, FALSE, 0 );
241         gtk_widget_show( GTK_WIDGET( itextview->formula ) );
242 }
243 
244 GtkType
itextview_get_type(void)245 itextview_get_type( void )
246 {
247 	static GtkType itextview_type = 0;
248 
249 	if( !itextview_type ) {
250 		static const GtkTypeInfo itextview_info = {
251 			"iTextview",
252 			sizeof( iTextview ),
253 			sizeof( iTextviewClass ),
254 			(GtkClassInitFunc) itextview_class_init,
255 			(GtkObjectInitFunc) itextview_init,
256 			/* reserved_1 */ NULL,
257 			/* reserved_2 */ NULL,
258 			(GtkClassInitFunc) NULL,
259 		};
260 
261 		itextview_type = gtk_type_unique( TYPE_VIEW, &itextview_info );
262 	}
263 
264 	return( itextview_type );
265 }
266 
267 View *
itextview_new(void)268 itextview_new( void )
269 {
270 	iTextview *itextview = gtk_type_new( TYPE_ITEXTVIEW );
271 
272 	return( VIEW( itextview ) );
273 }
274