1 /* Workspace-local defs.
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
workspacedefs_text_changed(GtkTextBuffer * buffer,Workspacedefs * workspacedefs)39 workspacedefs_text_changed( GtkTextBuffer *buffer,
40 Workspacedefs *workspacedefs )
41 {
42 #ifdef DEBUG
43 printf( "workspacedefs_text_changed\n" );
44 #endif /*DEBUG*/
45
46 if( !workspacedefs->changed ) {
47 workspacedefs->changed = TRUE;
48
49 #ifdef DEBUG
50 printf( "\t(changed = TRUE)\n" );
51 #endif /*DEBUG*/
52
53 /* The workspace hasn't changed, but this will queue a refresh
54 * on us.
55 */
56 iobject_changed( IOBJECT( workspacedefs->ws ) );
57 }
58 }
59
60 static void
workspacedefs_refresh(vObject * vobject)61 workspacedefs_refresh( vObject *vobject )
62 {
63 Workspacedefs *workspacedefs = WORKSPACEDEFS( vobject );
64 Workspace *ws = workspacedefs->ws;
65 char txt[256];
66 VipsBuf buf = VIPS_BUF_STATIC( txt );
67
68 #ifdef DEBUG
69 printf( "workspacedefs_refresh:\n" );
70 #endif /*DEBUG*/
71
72 if( !workspacedefs->changed ) {
73 guint text_hash = g_str_hash( ws->local_defs );
74
75 if( text_hash != workspacedefs->text_hash ) {
76 g_signal_handlers_block_by_func(
77 gtk_text_view_get_buffer(
78 GTK_TEXT_VIEW( workspacedefs->text ) ),
79 workspacedefs_text_changed, workspacedefs );
80 text_view_set_text(
81 GTK_TEXT_VIEW( workspacedefs->text ),
82 ws->local_defs, TRUE );
83 g_signal_handlers_unblock_by_func(
84 gtk_text_view_get_buffer(
85 GTK_TEXT_VIEW( workspacedefs->text ) ),
86 workspacedefs_text_changed, workspacedefs );
87
88 workspacedefs->text_hash = text_hash;
89 }
90 }
91
92 if( ws->local_kit ) {
93 int n = icontainer_get_n_children( ICONTAINER(
94 ws->local_kit ) );
95
96 vips_buf_appendf( &buf, ngettext( "%d definition",
97 "%d definitions", n ), n );
98 }
99 if( workspacedefs->errors ) {
100 if( !vips_buf_is_empty( &buf ) )
101 vips_buf_appendf( &buf, ", " );
102 vips_buf_appendf( &buf, _( "errors" ) );
103 }
104 if( workspacedefs->changed ) {
105 if( !vips_buf_is_empty( &buf ) )
106 vips_buf_appendf( &buf, ", " );
107 vips_buf_appendf( &buf, _( "modified" ) );
108 }
109 set_glabel( workspacedefs->status, "%s", vips_buf_all( &buf ) );
110
111 VOBJECT_CLASS( parent_class )->refresh( vobject );
112 }
113
114 static void
workspacedefs_link(vObject * vobject,iObject * iobject)115 workspacedefs_link( vObject *vobject, iObject *iobject )
116 {
117 Workspacedefs *workspacedefs = WORKSPACEDEFS( vobject );
118 Workspace *ws = WORKSPACE( iobject );
119
120 g_assert( !workspacedefs->ws );
121
122 workspacedefs->ws = ws;
123
124 VOBJECT_CLASS( parent_class )->link( vobject, iobject );
125 }
126
127 static void
workspacedefs_class_init(WorkspacedefsClass * class)128 workspacedefs_class_init( WorkspacedefsClass *class )
129 {
130 vObjectClass *vobject_class = (vObjectClass *) class;
131
132 parent_class = g_type_class_peek_parent( class );
133
134 vobject_class->refresh = workspacedefs_refresh;
135 vobject_class->link = workspacedefs_link;
136 }
137
138 static gboolean
workspacedefs_set_text_from_file(Workspacedefs * workspacedefs,const char * fname)139 workspacedefs_set_text_from_file( Workspacedefs *workspacedefs,
140 const char *fname )
141 {
142 Workspace *ws = workspacedefs->ws;
143
144 workspacedefs->changed = FALSE;
145 workspacedefs->errors = FALSE;
146 if( !workspace_local_set_from_file( ws, fname ) ) {
147 text_view_select_text( GTK_TEXT_VIEW( workspacedefs->text ),
148 input_state.charpos - yyleng, input_state.charpos );
149 workspacedefs->errors = TRUE;
150
151 return( FALSE );
152 }
153
154 symbol_recalculate_all();
155
156 return( TRUE );
157 }
158
159 /* Callback from load browser.
160 */
161 static void
workspacedefs_load_file_cb(iWindow * iwnd,void * client,iWindowNotifyFn nfn,void * sys)162 workspacedefs_load_file_cb( iWindow *iwnd,
163 void *client, iWindowNotifyFn nfn, void *sys )
164 {
165 Filesel *filesel = FILESEL( iwnd );
166 Workspacedefs *workspacedefs = WORKSPACEDEFS( client );
167 char *fname;
168
169 if( !(fname = filesel_get_filename( filesel )) ) {
170 nfn( sys, IWINDOW_ERROR );
171 return;
172 }
173
174 if( !workspacedefs_set_text_from_file( workspacedefs, fname ) ) {
175 g_free( fname );
176 nfn( sys, IWINDOW_ERROR );
177 return;
178 }
179
180 g_free( fname );
181
182 nfn( sys, IWINDOW_YES );
183 }
184
185 static void
workspacedefs_replace_cb(GtkWidget * wid,Workspacedefs * workspacedefs)186 workspacedefs_replace_cb( GtkWidget *wid, Workspacedefs *workspacedefs )
187 {
188 GtkWidget *filesel;
189
190 filesel = filesel_new();
191 iwindow_set_title( IWINDOW( filesel ),
192 _( "Replace Definition From File" ) );
193 filesel_set_flags( FILESEL( filesel ), FALSE, FALSE );
194 filesel_set_filetype( FILESEL( filesel ), filesel_type_definition, 0 );
195 iwindow_set_parent( IWINDOW( filesel ), GTK_WIDGET( wid ) );
196 filesel_set_done( FILESEL( filesel ),
197 workspacedefs_load_file_cb, workspacedefs );
198 iwindow_build( IWINDOW( filesel ) );
199
200 gtk_widget_show( GTK_WIDGET( filesel ) );
201 }
202
203 static void
workspacedefs_save_as_cb(GtkWidget * wid,Workspacedefs * workspacedefs)204 workspacedefs_save_as_cb( GtkWidget *wid, Workspacedefs *workspacedefs )
205 {
206 Workspace *ws = workspacedefs->ws;
207
208 if( ws->local_kit )
209 filemodel_inter_saveas( IWINDOW( wid ),
210 FILEMODEL( ws->local_kit ) );
211 }
212
213 static gboolean
workspacedefs_set_text(Workspacedefs * workspacedefs,const char * txt)214 workspacedefs_set_text( Workspacedefs *workspacedefs, const char *txt )
215 {
216 Workspace *ws = workspacedefs->ws;
217
218 workspacedefs->changed = FALSE;
219 workspacedefs->errors = FALSE;
220 workspacedefs->text_hash = g_str_hash( txt );
221 if( !workspace_local_set( ws, txt ) ) {
222 text_view_select_text( GTK_TEXT_VIEW( workspacedefs->text ),
223 input_state.charpos - yyleng, input_state.charpos );
224 workspacedefs->errors = TRUE;
225
226 return( FALSE );
227 }
228
229 symbol_recalculate_all();
230
231 return( TRUE );
232 }
233
234 /* "Process" in defs area.
235 */
236 static void
workspacedefs_process_cb(GtkWidget * wid,Workspacedefs * workspacedefs)237 workspacedefs_process_cb( GtkWidget *wid, Workspacedefs *workspacedefs )
238 {
239 char *txt;
240
241 #ifdef DEBUG
242 printf( "workspacedefs_process_cb:\n" );
243 printf( "\tchanged = FALSE\n" );
244 #endif /*DEBUG*/
245
246 txt = text_view_get_text( GTK_TEXT_VIEW( workspacedefs->text ) );
247 if( !workspacedefs_set_text( workspacedefs, txt ) )
248 iwindow_alert( wid, GTK_MESSAGE_ERROR );
249 g_free( txt );
250 }
251
252 static void
workspacedefs_init(Workspacedefs * workspacedefs)253 workspacedefs_init( Workspacedefs *workspacedefs )
254 {
255 GtkWidget *pane;
256 Popupbutton *popupbutton;
257 GtkWidget *swin;
258 GtkWidget *hbox;
259 GtkWidget *but;
260
261 #ifdef DEBUG
262 printf( "workspacedefs_init:\n" );
263 #endif /*DEBUG*/
264
265 workspacedefs->changed = FALSE;
266 workspacedefs->errors = FALSE;
267 workspacedefs->text_hash = 0;
268
269 pane = menu_build( _( "Workspace definitions" ) );
270 menu_add_but( pane, _( "Replace From _File" ),
271 GTK_SIGNAL_FUNC( workspacedefs_replace_cb ), workspacedefs );
272 menu_add_but( pane, GTK_STOCK_SAVE_AS,
273 GTK_SIGNAL_FUNC( workspacedefs_save_as_cb ), workspacedefs );
274
275 hbox = gtk_hbox_new( FALSE, 7 );
276 gtk_box_pack_start( GTK_BOX( workspacedefs ), hbox, FALSE, FALSE, 0 );
277 gtk_widget_show( hbox );
278
279 popupbutton = popupbutton_new();
280 popupbutton_set_menu( popupbutton, pane );
281 gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( popupbutton ),
282 FALSE, FALSE, 0 );
283 gtk_widget_show( GTK_WIDGET( popupbutton ) );
284
285 but = gtk_button_new_with_label( _( "Process" ) );
286 g_signal_connect( G_OBJECT( but ), "clicked",
287 G_CALLBACK( workspacedefs_process_cb ), workspacedefs );
288 gtk_box_pack_start( GTK_BOX( hbox ), but, FALSE, FALSE, 0 );
289 gtk_widget_show( but );
290 workspacedefs->status = gtk_label_new( NULL );
291 gtk_misc_set_alignment( GTK_MISC( workspacedefs->status ), 0, 0.5 );
292 gtk_box_pack_start( GTK_BOX( hbox ),
293 workspacedefs->status, TRUE, TRUE, 0 );
294 gtk_widget_show( workspacedefs->status );
295
296 swin = gtk_scrolled_window_new( NULL, NULL );
297 gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW( swin ),
298 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
299 gtk_box_pack_end( GTK_BOX( workspacedefs ), swin, TRUE, TRUE, 0 );
300 gtk_widget_show( swin );
301 workspacedefs->text = program_text_new();
302 g_signal_connect( gtk_text_view_get_buffer(
303 GTK_TEXT_VIEW( workspacedefs->text ) ), "changed",
304 G_CALLBACK( workspacedefs_text_changed ), workspacedefs );
305 gtk_container_add( GTK_CONTAINER( swin ), workspacedefs->text );
306 gtk_widget_show( workspacedefs->text );
307 }
308
309 GtkType
workspacedefs_get_type(void)310 workspacedefs_get_type( void )
311 {
312 static GtkType type = 0;
313
314 if( !type ) {
315 static const GtkTypeInfo info = {
316 "Workspacedefs",
317 sizeof( Workspacedefs ),
318 sizeof( WorkspacedefsClass ),
319 (GtkClassInitFunc) workspacedefs_class_init,
320 (GtkObjectInitFunc) workspacedefs_init,
321 /* reserved_1 */ NULL,
322 /* reserved_2 */ NULL,
323 (GtkClassInitFunc) NULL,
324 };
325
326 type = gtk_type_unique( TYPE_VOBJECT, &info );
327 }
328
329 return( type );
330 }
331
332 Workspacedefs *
workspacedefs_new(void)333 workspacedefs_new( void )
334 {
335 Workspacedefs *workspacedefs = gtk_type_new( TYPE_WORKSPACEDEFS );
336
337 return( workspacedefs );
338 }
339
340