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