1 /************************************************************************/
2 /* */
3 /* Gtk specific document configuration. */
4 /* */
5 /* Thanks to Andrea Frome who contributed the original code. */
6 /* */
7 /************************************************************************/
8
9 # include "appFrameConfig.h"
10
11 # include <stddef.h>
12 # include <stdio.h>
13
14 # include "appFrame.h"
15 # include "guiWidgetDrawingSurface.h"
16 # include "guiDrawingWidget.h"
17
18 # include <appDebugon.h>
19
20 # ifdef USE_GTK
21
22 /************************************************************************/
23 /* */
24 /* Thanks to Andrea Frome who contributed the original code. */
25 /* */
26 /************************************************************************/
27
28 /************************************************************************/
29 /* */
30 /* Event handler to keep track of resize events for the document. */
31 /* Both resize events of the shel widget and the document widget are */
32 /* handeled to keep track of the difference in size. */
33 /* */
34 /* The difference in size is used to set the maximum size of the */
35 /* shell widget in the window manager. */
36 /* */
37 /************************************************************************/
38
APP_EVENT_HANDLER_H(appDocTopConfigure,w,voided,event)39 static APP_EVENT_HANDLER_H( appDocTopConfigure, w, voided, event )
40 {
41 EditDocument * ed= (EditDocument *)voided;
42
43 if ( event->type == GDK_MAP )
44 {
45 ed->edMapped= 1;
46 }
47
48 return;
49 }
50
51 /************************************************************************/
52 /* */
53 /* Make a document window. */
54 /* */
55 /* 1) Allocate a document. */
56 /* 3) Make a shell to contain everything. */
57 /* 4) Make the window pane. */
58 /* */
59 /************************************************************************/
60
appDocMakeMainWindow(EditDocument * ed)61 static int appDocMakeMainWindow( EditDocument * ed )
62 {
63 int rval= 0;
64 EditApplication * ea= ed->edApplication;
65
66 APP_BITMAP_IMAGE pixmap= (APP_BITMAP_IMAGE)0;
67 APP_BITMAP_MASK mask= (APP_BITMAP_MASK)0;
68
69 const int spacing= 0;
70
71 MemoryBuffer fullTitle;
72 MemoryBuffer iconName;
73
74 utilInitMemoryBuffer( &fullTitle );
75 utilInitMemoryBuffer( &iconName );
76
77 if ( ea->eaMainIcon &&
78 appGetImagePixmap( ea, ea->eaMainIcon, &pixmap, &mask ) )
79 { SDEB(ea->eaMainIcon); rval= -1; goto ready; }
80
81 if ( appFormatDocumentTitle( &fullTitle, &iconName, ea, &(ed->edTitle) ) )
82 { LDEB(1); rval= -1; goto ready; }
83
84 ed->edToplevel.atTopWidget= gtk_window_new( GTK_WINDOW_TOPLEVEL );
85
86 gtk_window_set_title( GTK_WINDOW( ed->edToplevel.atTopWidget ),
87 utilMemoryBufferGetString( &fullTitle ) );
88
89 gtk_window_set_position( GTK_WINDOW( ed->edToplevel.atTopWidget ),
90 GTK_WIN_POS_CENTER );
91 gtk_window_set_policy( GTK_WINDOW( ed->edToplevel.atTopWidget ),
92 TRUE, TRUE, FALSE );
93
94 gtk_widget_realize( ed->edToplevel.atTopWidget );
95
96 gdk_window_set_icon( ed->edToplevel.atTopWidget->window,
97 ed->edToplevel.atTopWidget->window,
98 pixmap, mask );
99 gdk_window_set_icon_name( ed->edToplevel.atTopWidget->window,
100 utilMemoryBufferGetString( &iconName ) );
101
102 appSetCloseCallback( ed->edToplevel.atTopWidget, ea,
103 appDocFileCloseCallback, (void *)ed );
104
105 appSetDestroyCallback( ed->edToplevel.atTopWidget,
106 appDestroyEditDocument, (void *)ed );
107
108 ed->edMainWindow= gtk_vbox_new( FALSE, spacing );
109 gtk_container_add( GTK_CONTAINER( ed->edToplevel.atTopWidget ),
110 ed->edMainWindow );
111 gtk_widget_show( ed->edMainWindow );
112
113 ed->edToplevel.atAccelGroup= gtk_accel_group_new();
114
115 # if GTK_MAJOR_VERSION < 2
116 gtk_accel_group_attach( ed->edToplevel.atAccelGroup,
117 GTK_OBJECT( ed->edToplevel.atTopWidget ) );
118 # else
119 gtk_window_add_accel_group( GTK_WINDOW( ed->edToplevel.atTopWidget ),
120 ed->edToplevel.atAccelGroup );
121 # endif
122
123 ed->edMenuBar= gtk_menu_bar_new();
124 gtk_widget_show( ed->edMenuBar );
125 gtk_box_pack_start( GTK_BOX( ed->edMainWindow ),
126 ed->edMenuBar, FALSE, TRUE, 0 );
127
128 appDocFillMenu( ed );
129
130 ready:
131
132 utilCleanMemoryBuffer( &fullTitle );
133 utilCleanMemoryBuffer( &iconName );
134
135 return rval;
136 }
137
appDocMakeScrolledWindow(EditDocument * ed)138 static int appDocMakeScrolledWindow( EditDocument * ed )
139 {
140 ed->edScrolledWindow= gtk_table_new( 2, 2, FALSE );
141
142 gtk_widget_show( ed->edScrolledWindow );
143 gtk_box_pack_start( GTK_BOX( ed->edMainWindow ),
144 ed->edScrolledWindow, TRUE, TRUE, 0 );
145
146 /*****/
147
148 ed->edVerticalScrollbar= gtk_vscrollbar_new( NULL );
149 ed->edVerticalAdjustment=
150 gtk_range_get_adjustment( GTK_RANGE( ed->edVerticalScrollbar ) );
151
152 gtk_table_attach( GTK_TABLE( ed->edScrolledWindow ),
153 ed->edVerticalScrollbar,
154 1, 2,
155 0, 1,
156 GTK_FILL,
157 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
158 0, 0 );
159
160 gtk_widget_show( ed->edVerticalScrollbar );
161
162 /*****/
163
164 ed->edHorizontalScrollbar= gtk_hscrollbar_new( NULL );
165 ed->edHorizontalAdjustment=
166 gtk_range_get_adjustment( GTK_RANGE( ed->edHorizontalScrollbar ) );
167
168 gtk_table_attach( GTK_TABLE( ed->edScrolledWindow ),
169 ed->edHorizontalScrollbar,
170 0, 1,
171 1, 2,
172 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
173 GTK_FILL,
174 0, 0 );
175
176 gtk_widget_show( ed->edHorizontalScrollbar );
177
178 return 0;
179 }
180
appMakeDocumentWidget(EditApplication * ea,EditDocument * ed)181 int appMakeDocumentWidget( EditApplication * ea,
182 EditDocument * ed )
183 {
184 appDocumentRulerWidth( ea, ed );
185
186 /* 2 */
187 ed->edWorkWidget= gtk_table_new( 3, 3, FALSE );
188
189 gtk_table_attach( GTK_TABLE( ed->edScrolledWindow ),
190 ed->edWorkWidget,
191 0, 1,
192 0, 1,
193 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
194 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
195 0, 0 );
196
197 gtk_widget_show( ed->edWorkWidget );
198
199 ed->edTopRulerWidget= gtk_drawing_area_new();
200
201 gtk_table_attach( GTK_TABLE( ed->edWorkWidget ),
202 ed->edTopRulerWidget,
203 0, 3,
204 0, 1,
205 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
206 GTK_FILL,
207 0, 0 );
208
209 gtk_widget_show( ed->edTopRulerWidget );
210
211 ed->edBottomRulerWidget= gtk_drawing_area_new();
212
213 gtk_table_attach( GTK_TABLE( ed->edWorkWidget ),
214 ed->edBottomRulerWidget,
215 0, 3,
216 2, 3,
217 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
218 GTK_FILL,
219 0, 0 );
220
221 gtk_widget_show( ed->edBottomRulerWidget );
222
223 ed->edLeftRulerWidget= gtk_drawing_area_new();
224
225 gtk_table_attach( GTK_TABLE( ed->edWorkWidget ),
226 ed->edLeftRulerWidget,
227 0, 1,
228 1, 2,
229 GTK_FILL,
230 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
231 0, 0 );
232
233 gtk_widget_show( ed->edLeftRulerWidget );
234
235 ed->edRightRulerWidget= gtk_drawing_area_new();
236
237 gtk_table_attach( GTK_TABLE( ed->edWorkWidget ),
238 ed->edRightRulerWidget,
239 2, 3,
240 1, 2,
241 GTK_FILL,
242 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
243 0, 0 );
244
245 gtk_widget_show( ed->edRightRulerWidget );
246
247 ed->edDocumentWidget.dwWidget= gtk_drawing_area_new();
248
249 gtk_table_attach( GTK_TABLE( ed->edWorkWidget ),
250 ed->edDocumentWidget.dwWidget,
251 1, 2,
252 1, 2,
253 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
254 GTK_FILL | GTK_EXPAND | GTK_SHRINK,
255 0, 0 );
256
257 gtk_widget_show( ed->edDocumentWidget.dwWidget );
258
259 GTK_WIDGET_SET_FLAGS( ed->edDocumentWidget.dwWidget, GTK_CAN_FOCUS );
260 gtk_window_set_focus( GTK_WINDOW( ed->edToplevel.atTopWidget ),
261 ed->edDocumentWidget.dwWidget );
262
263 return 0;
264 }
265
appDocMakeToolbar(EditDocument * ed)266 static int appDocMakeToolbar( EditDocument * ed )
267 {
268 # if 0
269 EditApplication * ea= ed->edApplication;
270 Arg al[20];
271 int ac= 0;
272
273 Display * display= ea->eaDisplay;
274 int screen= DefaultScreen( ea->eaDisplay );
275
276 int verPixPerCM;
277
278 verPixPerCM= ( 10* DisplayHeight( display, screen ) )/
279 DisplayHeightMM( display, screen );
280 XtSetArg( al[ac], XmNleftAttachment, XmATTACH_FORM ); ac++;
281 XtSetArg( al[ac], XmNtopAttachment, XmATTACH_FORM ); ac++;
282 XtSetArg( al[ac], XmNrightAttachment, XmATTACH_FORM ); ac++;
283 XtSetArg( al[ac], XmNheight, verPixPerCM ); ac++;
284
285 ed->edToolbar= XmCreateForm( ed->edMainWindow, WIDGET_NAME, al, ac );
286
287 # endif
288 return 0;
289 }
290
appFinishDocumentWindow(EditDocument * ed)291 int appFinishDocumentWindow( EditDocument * ed )
292 {
293 EditApplication * ea= ed->edApplication;
294 DocumentWidget * dw= &(ed->edDocumentWidget);
295
296 /* 3 */
297 if ( appDocMakeMainWindow( ed ) ||
298 appDocMakeToolbar( ed ) ||
299 appDocMakeScrolledWindow( ed ) ||
300 (*ea->eaMakeDocumentWidget)( ea, ed ) )
301 { LDEB(1); return -1; }
302
303 gtk_signal_connect( GTK_OBJECT( dw->dwWidget ),
304 "configure_event",
305 (GtkSignalFunc)appDocConfigure,
306 (void *)ed );
307
308 gtk_signal_connect( GTK_OBJECT( ed->edToplevel.atTopWidget ),
309 "map_event",
310 (GtkSignalFunc)appDocTopConfigure,
311 (void *)ed );
312
313 gtk_signal_connect( GTK_OBJECT( dw->dwWidget ),
314 "selection_clear_event",
315 (GtkSignalFunc)appDocCopyPasteHandler,
316 (void *)ed );
317
318 gtk_signal_connect( GTK_OBJECT( dw->dwWidget ),
319 "selection_received",
320 (GtkSignalFunc)appDocGotPasteReplyGtk,
321 (void *)ed );
322
323 gtk_signal_connect( GTK_OBJECT( dw->dwWidget ),
324 "selection_get",
325 (GtkSignalFunc)appDocReplyToCopyRequest,
326 (void *)ed );
327
328 return 0;
329 }
330
331 /************************************************************************/
332 /* */
333 /* Finish the setup of a document window. */
334 /* */
335 /* 2) The drawing area does not deliver focus out events so install */
336 /* the focus event handler on the top level widget. */
337 /* */
338 /************************************************************************/
339
appFinishDocumentSetup(EditDocument * ed)340 int appFinishDocumentSetup( EditDocument * ed )
341 {
342 EditApplication * ea= ed->edApplication;
343 DocumentWidget * dw= &(ed->edDocumentWidget);
344
345 guiDrawSetRedrawHandler( dw->dwWidget, appDocExposeHandler, (void *)ed );
346
347 if ( ea->eaObserveFocus )
348 {
349 /* 2 */
350 # if 1
351 appGuiSetFocusChangeHandler( ed->edToplevel.atTopWidget,
352 ea->eaObserveFocus, (void *)ed );
353 # else
354 appGuiSetFocusChangeHandler( dw->dwWidget,
355 ea->eaObserveFocus, (void *)ed );
356 # endif
357 }
358
359 if ( ea->eaDocumentMouseHandler )
360 {
361 guiDrawSetButtonPressHandler( dw->dwWidget,
362 ea->eaDocumentMouseHandler, (void *)ed );
363
364 gtk_widget_add_events( dw->dwWidget, GDK_POINTER_MOTION_MASK );
365 }
366
367 if ( ea->eaDocumentScrollHandler )
368 {
369 guiDrawSetScrollHandler( dw->dwWidget,
370 ea->eaDocumentScrollHandler, (void *)ed );
371 }
372
373 dw->dwOwner= (void *)ed;
374 dw->dwGotString= ea->eaDocGotString;
375 dw->dwGotKey= ea->eaDocGotKey;
376
377 gtk_signal_connect( GTK_OBJECT( ed->edVerticalAdjustment ),
378 "value_changed",
379 (GtkSignalFunc)appDocVerticalScrollbarCallback,
380 (void *)ed );
381
382 gtk_signal_connect( GTK_OBJECT( ed->edHorizontalAdjustment ),
383 "value_changed",
384 (GtkSignalFunc)appDocHorizontalScrollbarCallback,
385 (void *)ed );
386
387 appDocumentSetInputContext( ea->eaInputMethod, dw );
388
389 return 0;
390 }
391
392 /************************************************************************/
393 /* */
394 /* Management of the 'Windows' menu options. */
395 /* */
396 /************************************************************************/
397
appSetWindowsItemState(APP_WIDGET menu,EditDocument * ed,int changed)398 void appSetWindowsItemState( APP_WIDGET menu,
399 EditDocument * ed,
400 int changed )
401 {
402 GList * glf;
403 GList * gl;
404
405 gl= glf= gtk_container_children( GTK_CONTAINER( menu ) );
406
407 while( gl )
408 {
409 GtkWidget * child= (GtkWidget *)gl->data;
410 void * voided;
411
412 voided= gtk_object_get_user_data( GTK_OBJECT( child ) );
413
414 if ( voided == (void *)ed )
415 { appGuiSetToggleItemState( child, changed ); }
416
417 gl= gl->next;
418 }
419
420 if ( glf )
421 { g_list_free( glf ); }
422
423 return;
424 }
425
appRemoveWindowsOption(APP_WIDGET menu,EditDocument * oldEd)426 void appRemoveWindowsOption( APP_WIDGET menu,
427 EditDocument * oldEd )
428 {
429 GList * glf;
430 GList * gl;
431
432 gl= glf= gtk_container_children( GTK_CONTAINER( menu ) );
433
434 while( gl )
435 {
436 GtkWidget * child= (GtkWidget *)gl->data;
437 void * voided;
438
439 voided= gtk_object_get_user_data( GTK_OBJECT( child ) );
440
441 if ( voided == (void *)oldEd )
442 { gtk_widget_destroy( child ); }
443
444 gl= gl->next;
445 }
446
447 if ( glf )
448 { g_list_free( glf ); }
449
450 return;
451 }
452
appRenameWindowsOption(APP_WIDGET menu,EditDocument * ed,const MemoryBuffer * title)453 void appRenameWindowsOption( APP_WIDGET menu,
454 EditDocument * ed,
455 const MemoryBuffer * title )
456 {
457 GList * glf;
458 GList * gl;
459
460 gl= glf= gtk_container_children( GTK_CONTAINER( menu ) );
461
462 while( gl )
463 {
464 GtkWidget * child= (GtkWidget *)gl->data;
465 void * voided;
466
467 voided= gtk_object_get_user_data( GTK_OBJECT( child ) );
468
469 if ( voided == (void *)ed )
470 {
471 appGuiSetToggleItemLabel( child,
472 utilMemoryBufferGetString( title ) );
473 }
474
475 gl= gl->next;
476 }
477
478 if ( glf )
479 { g_list_free( glf ); }
480
481 return;
482 }
483
484 # endif
485