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