1 /* AbiWord
2  *
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU General Public License
5  * as published by the Free Software Foundation; either version 2
6  * of the License, or (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16  * 02110-1301 USA.
17  */
18 
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 
23 #include <gtk/gtk.h>
24 #include "ap_UnixFrameImpl.h"
25 #include "ap_UnixApp.h"
26 #include "ev_UnixToolbar.h"
27 #include "ap_FrameData.h"
28 #include "ap_UnixTopRuler.h"
29 #include "ap_UnixLeftRuler.h"
30 #include "xap_UnixApp.h"
31 #include "xap_UnixDialogHelper.h"
32 #include "xap_Gtk2Compat.h"
33 #include "ap_UnixStatusBar.h"
34 #include "ut_debugmsg.h"
35 #include "ev_UnixMenuBar.h"
36 
37 
AP_UnixFrameImpl(AP_UnixFrame * pUnixFrame)38 AP_UnixFrameImpl::AP_UnixFrameImpl(AP_UnixFrame *pUnixFrame) :
39 	XAP_UnixFrameImpl(static_cast<XAP_Frame *>(pUnixFrame)),
40 	m_dArea(NULL),
41 	m_pVadj(NULL),
42 	m_pHadj(NULL),
43 	m_hScroll(NULL),
44 	m_vScroll(NULL),
45 	m_topRuler(NULL),
46 	m_leftRuler(NULL),
47 	m_grid(NULL),
48 	m_innergrid(NULL),
49 	m_wSunkenBox(NULL),
50 	m_iHScrollSignal(0),
51 	m_iVScrollSignal(0)
52 {
53 	UT_DEBUGMSG(("Created AP_UnixFrameImpl %p \n",this));
54 }
55 
createInstance(XAP_Frame * pFrame)56 XAP_FrameImpl * AP_UnixFrameImpl::createInstance(XAP_Frame *pFrame)
57 {
58 	XAP_FrameImpl *pFrameImpl = new AP_UnixFrameImpl(static_cast<AP_UnixFrame *>(pFrame));
59 
60 	return pFrameImpl;
61 }
62 
_bindToolbars(AV_View * pView)63 void AP_UnixFrameImpl::_bindToolbars(AV_View * pView)
64 {
65 	int nrToolbars = m_vecToolbarLayoutNames.getItemCount();
66 	for (int k = 0; k < nrToolbars; k++)
67 	{
68 		// TODO Toolbars are a frame-level item, but a view-listener is
69 		// TODO a view-level item.  I've bound the toolbar-view-listeners
70 		// TODO to the current view within this frame and have code in the
71 		// TODO toolbar to allow the view-listener to be rebound to a different
72 		// TODO view.  in the future, when we have support for multiple views
73 		// TODO in the frame (think splitter windows), we will need to have
74 		// TODO a loop like this to help change the focus when the current
75 		// TODO view changes.
76 		EV_UnixToolbar * pUnixToolbar = reinterpret_cast<EV_UnixToolbar *>(m_vecToolbars.getNthItem(k));
77 		pUnixToolbar->bindListenerToView(pView);
78 	}
79 }
80 
81 // Does the initial show/hide of toolbars (based on the user prefs).
82 // This is needed because toggleBar is called only when the user
83 // (un)checks the show {Stantandard,Format,Extra} toolbar checkbox,
84 // and thus we have to manually call this function at startup.
_showOrHideToolbars()85 void AP_UnixFrameImpl::_showOrHideToolbars()
86 {
87 	XAP_Frame* pFrame = getFrame();
88 	bool *bShowBar = static_cast<AP_FrameData*>(pFrame->getFrameData())->m_bShowBar;
89 	UT_uint32 cnt = m_vecToolbarLayoutNames.getItemCount();
90 
91 	for (UT_uint32 i = 0; i < cnt; i++)
92 	{
93 		// TODO: The two next lines are here to bind the EV_Toolbar to the
94 		// AP_FrameData, but their correct place are next to the toolbar creation (JCA)
95 		EV_UnixToolbar * pUnixToolbar = static_cast<EV_UnixToolbar *> (m_vecToolbars.getNthItem(i));
96 		static_cast<AP_FrameData*> (pFrame->getFrameData())->m_pToolbar[i] = pUnixToolbar;
97 		static_cast<AP_UnixFrame *>(pFrame)->toggleBar(i, bShowBar[i]);
98 	}
99 }
100 
101 /*!
102  * Refills the framedata class with pointers to the current toolbars. We
103  * need to do this after a toolbar icon and been dragged and dropped.
104  */
_refillToolbarsInFrameData()105 void AP_UnixFrameImpl::_refillToolbarsInFrameData()
106 {
107 	UT_uint32 cnt = m_vecToolbarLayoutNames.getItemCount();
108 
109 	for (UT_uint32 i = 0; i < cnt; i++)
110 	{
111 		EV_UnixToolbar * pUnixToolbar = static_cast<EV_UnixToolbar *> (m_vecToolbars.getNthItem(i));
112 		static_cast<AP_FrameData*>(getFrame()->getFrameData())->m_pToolbar[i] = pUnixToolbar;
113 	}
114 }
115 
116 // Does the initial show/hide of statusbar (based on the user prefs).
117 // Idem.
_showOrHideStatusbar()118 void AP_UnixFrameImpl::_showOrHideStatusbar()
119 {
120 #ifdef ENABLE_STATUSBAR
121 	XAP_Frame* pFrame = getFrame();
122 	bool bShowStatusBar = static_cast<AP_FrameData*> (pFrame->getFrameData())->m_bShowStatusBar;
123 	static_cast<AP_UnixFrame *>(pFrame)->toggleStatusBar(bShowStatusBar);
124 #endif
125 }
126 
127 
ap_focus_in_event(GtkWidget * drawing_area,GdkEventCrossing *,AP_UnixFrameImpl *)128 gboolean AP_UnixFrameImpl::ap_focus_in_event (GtkWidget * drawing_area, GdkEventCrossing * /*event*/, AP_UnixFrameImpl * /*me*/)
129 {
130   gtk_widget_grab_focus (drawing_area);
131   return TRUE;
132 }
133 
ap_focus_out_event(GtkWidget *,GdkEventCrossing *,AP_UnixFrameImpl *)134 gboolean AP_UnixFrameImpl::ap_focus_out_event (GtkWidget * /*drawing_area*/, GdkEventCrossing * /*event*/, AP_UnixFrameImpl * /*me*/)
135 {
136   return TRUE;
137 }
138 
_createDocumentWindow()139 GtkWidget * AP_UnixFrameImpl::_createDocumentWindow()
140 {
141 	XAP_Frame* pFrame = getFrame();
142 	bool bShowRulers = static_cast<AP_FrameData*>(pFrame->getFrameData())->m_bShowRuler;
143 
144 	// create the rulers
145 	AP_UnixTopRuler * pUnixTopRuler = NULL;
146 	AP_UnixLeftRuler * pUnixLeftRuler = NULL;
147 
148 	if ( bShowRulers )
149 	{
150 		pUnixTopRuler = new AP_UnixTopRuler(pFrame);
151 		UT_ASSERT(pUnixTopRuler);
152 		m_topRuler = pUnixTopRuler->createWidget();
153 
154 		if (static_cast<AP_FrameData*>(pFrame->getFrameData())->m_pViewMode == VIEW_PRINT)
155 		  {
156 		    pUnixLeftRuler = new AP_UnixLeftRuler(pFrame);
157 		    UT_ASSERT(pUnixLeftRuler);
158 		    m_leftRuler = pUnixLeftRuler->createWidget();
159 
160 		    // get the width from the left ruler and stuff it into the top ruler.
161 		    //pUnixTopRuler->setOffsetLeftRuler(pUnixLeftRuler->getWidth());
162 		  }
163 		else
164 		  {
165 		    m_leftRuler = NULL;
166 		    //pUnixTopRuler->setOffsetLeftRuler(0);
167 		  }
168 	}
169 	else
170 	{
171 		m_topRuler = NULL;
172 		m_leftRuler = NULL;
173 	}
174 
175 	static_cast<AP_FrameData*>(pFrame->getFrameData())->m_pTopRuler = pUnixTopRuler;
176 	static_cast<AP_FrameData*>(pFrame->getFrameData())->m_pLeftRuler = pUnixLeftRuler;
177 
178 	// set up for scroll bars.
179 	m_pHadj = reinterpret_cast<GtkAdjustment *>(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
180 	m_hScroll = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, m_pHadj);
181 	g_object_set_data(G_OBJECT(m_pHadj), "user_data", this);
182 	g_object_set_data(G_OBJECT(m_hScroll), "user_data", this);
183 #if GTK_CHECK_VERSION(3,0,0)
184 	gtk_widget_set_hexpand(m_hScroll, TRUE);
185 #endif
186 
187 	m_iHScrollSignal = g_signal_connect(G_OBJECT(m_pHadj), "value_changed", G_CALLBACK(XAP_UnixFrameImpl::_fe::hScrollChanged), NULL);
188 
189 	m_pVadj = reinterpret_cast<GtkAdjustment *>(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
190 	m_vScroll = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, m_pVadj);
191 	g_object_set_data(G_OBJECT(m_pVadj), "user_data", this);
192 	g_object_set_data(G_OBJECT(m_vScroll), "user_data", this);
193 #if GTK_CHECK_VERSION(3,0,0)
194 	gtk_widget_set_vexpand(m_vScroll, TRUE);
195 #endif
196 
197 	m_iVScrollSignal = g_signal_connect(G_OBJECT(m_pVadj), "value_changed", G_CALLBACK(XAP_UnixFrameImpl::_fe::vScrollChanged), NULL);
198 
199 	// we don't want either scrollbar grabbing events from us
200 	gtk_widget_set_can_focus(m_hScroll, false);
201 	gtk_widget_set_can_focus(m_vScroll, false);
202 
203 	// create a drawing area in the for our document window.
204 	m_dArea = ap_DocView_new();
205 #if GTK_CHECK_VERSION(3,0,0)
206 	g_object_set(G_OBJECT(m_dArea), "expand", TRUE, NULL);
207 #endif
208 	g_object_set_data(G_OBJECT(m_dArea), "user_data", this);
209 	UT_DEBUGMSG(("!!! drawing area m_dArea created! %p for %p \n",m_dArea,this));
210 	gtk_widget_set_can_focus(m_dArea, true);	// allow it to be focussed
211 
212 	gtk_widget_set_events(GTK_WIDGET(m_dArea), (GDK_EXPOSURE_MASK |
213 						    GDK_BUTTON_PRESS_MASK |
214 						    GDK_POINTER_MOTION_MASK |
215 						    GDK_BUTTON_RELEASE_MASK |
216 						    GDK_KEY_PRESS_MASK |
217 						    GDK_KEY_RELEASE_MASK |
218 						    GDK_ENTER_NOTIFY_MASK |
219 						    GDK_FOCUS_CHANGE_MASK |
220 						    GDK_LEAVE_NOTIFY_MASK |
221 						    GDK_SCROLL_MASK
222 #if GTK_CHECK_VERSION(3,0,0)
223 						    | GDK_SMOOTH_SCROLL_MASK
224 #endif
225 						    ));
226 #if GTK_CHECK_VERSION(3,0,0)
227 	g_signal_connect(G_OBJECT(m_dArea), "draw",
228 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::draw), NULL);
229 #else
230         // We disable double buffering on Gtk3 because it doesn't work.
231 	gtk_widget_set_double_buffered(GTK_WIDGET(m_dArea), FALSE);
232 	g_signal_connect(G_OBJECT(m_dArea), "expose_event",
233 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::expose), NULL);
234 #endif
235 
236 	g_signal_connect(G_OBJECT(m_dArea), "key_press_event",
237 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::key_press_event), NULL);
238 
239 	g_signal_connect(G_OBJECT(m_dArea), "key_release_event",
240 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::key_release_event), NULL);
241 
242 	g_signal_connect(G_OBJECT(m_dArea), "button_press_event",
243 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::button_press_event), NULL);
244 
245 	g_signal_connect(G_OBJECT(m_dArea), "button_release_event",
246 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::button_release_event), NULL);
247 
248 	g_signal_connect(G_OBJECT(m_dArea), "motion_notify_event",
249 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::motion_notify_event), NULL);
250 
251 	g_signal_connect(G_OBJECT(m_dArea), "scroll_event",
252 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::scroll_notify_event), NULL);
253 
254 	g_signal_connect(G_OBJECT(m_dArea), "configure_event",
255 					   G_CALLBACK(XAP_UnixFrameImpl::_fe::configure_event), NULL);
256 
257 	// focus and XIM related
258 	g_signal_connect(G_OBJECT(m_dArea), "enter_notify_event", G_CALLBACK(ap_focus_in_event), this);
259 	g_signal_connect(G_OBJECT(m_dArea), "leave_notify_event", G_CALLBACK(ap_focus_out_event), this);
260 
261 	//
262 	// Need this to fix screen flicker for abiwidget on focus in/out
263 	//
264 	g_signal_connect(G_OBJECT(m_dArea), "focus_in_event", G_CALLBACK(XAP_UnixFrameImpl::_fe::focus_in_event), this);
265 	g_signal_connect(G_OBJECT(m_dArea), "focus_out_event", G_CALLBACK(XAP_UnixFrameImpl::_fe::focus_out_event), this);
266 
267 
268 	// create a table for scroll bars, rulers, and drawing area
269 
270 #if GTK_CHECK_VERSION(3,0,0)
271 	m_grid = gtk_grid_new();
272 	g_object_set(G_OBJECT(m_grid), "expand", TRUE, NULL);
273 #else
274 	m_grid = gtk_table_new(2, 1, FALSE); //was 1,1
275 #endif
276 	g_object_set_data(G_OBJECT(m_grid),"user_data", this);
277 
278 	// NOTE:  in order to display w/ and w/o rulers, gtk needs two tables to
279 	// work with.  The 2 2x2 tables, (i)nner and (o)uter divide up the 3x3
280 	// table as follows.  The inner table is at the 1,1 table.
281 	//	+-----+---+
282 	//	| i i | o |
283 	//	| i i |   |
284 	//	+-----+---+
285 	//	|  o  | o |
286 	//	+-----+---+
287 
288 	// scroll bars
289 
290 #if GTK_CHECK_VERSION(3,0,0)
291 	gtk_grid_attach(GTK_GRID(m_grid), m_hScroll, 0, 1, 1, 1);
292 
293 	gtk_grid_attach(GTK_GRID(m_grid), m_vScroll, 1, 0, 1, 1);
294 
295 
296 	// arrange the widgets within our inner table.
297 	m_innergrid = gtk_grid_new();
298 	g_object_set(G_OBJECT(m_innergrid), "expand", TRUE, NULL);
299 	gtk_grid_attach(GTK_GRID(m_grid), m_innergrid, 0, 0, 1, 1);
300 
301 	if ( bShowRulers )
302 	{
303 		gtk_grid_attach(GTK_GRID(m_innergrid), m_topRuler, 0, 0, 2, 1);
304 
305 		if (m_leftRuler)
306 			gtk_grid_attach(GTK_GRID(m_innergrid), m_leftRuler, 0, 1, 1, 1);
307 
308 		gtk_grid_attach(GTK_GRID(m_innergrid), m_dArea,   1, 1, 1, 1);
309 	}
310 	else	// no rulers
311 	{
312 		gtk_grid_attach(GTK_GRID(m_innergrid), m_dArea,   1, 1, 1, 1);
313 	}
314 #else
315 	gtk_table_attach(GTK_TABLE(m_grid), m_hScroll, 0, 1, 1, 2,
316 					 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
317 					 (GtkAttachOptions) (GTK_FILL), // was just GTK_FILL
318 					 0, 0);
319 
320 	gtk_table_attach(GTK_TABLE(m_grid), m_vScroll, 1, 2, 0, 1,
321 					 (GtkAttachOptions) (GTK_FILL), // was just GTK_FILL
322 					 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
323 					 0, 0);
324 
325 
326  	// arrange the widgets within our inner table.
327 	m_innergrid = gtk_table_new(2,2,FALSE);
328 	gtk_table_attach( GTK_TABLE(m_grid), m_innergrid, 0, 1, 0, 1,
329 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
330 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
331 						 0, 0);
332 	if ( bShowRulers )
333 	{
334 		gtk_table_attach(GTK_TABLE(m_innergrid), m_topRuler, 0, 2, 0, 1,
335 						 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
336 						 (GtkAttachOptions)(GTK_FILL),
337 						 0, 0);
338 		if (m_leftRuler)
339 			gtk_table_attach(GTK_TABLE(m_innergrid), m_leftRuler, 0, 1, 1, 2,
340 							 (GtkAttachOptions)(GTK_FILL),
341 							 (GtkAttachOptions)(GTK_EXPAND | GTK_FILL),
342 							 0, 0);
343 
344 		gtk_table_attach(GTK_TABLE(m_innergrid), m_dArea,   1, 2, 1, 2,
345 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
346 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
347 						 0, 0);
348 	}
349 	else	// no rulers
350 	{
351 		gtk_table_attach(GTK_TABLE(m_innergrid), m_dArea,   1, 2, 1, 2,
352 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
353 						 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
354 						 0, 0);
355 	}
356 #endif
357 	// create a 3d box and put the table in it, so that we
358 	// get a sunken in look.
359 	m_wSunkenBox = gtk_frame_new(NULL);
360 	gtk_frame_set_shadow_type(GTK_FRAME(m_wSunkenBox), GTK_SHADOW_IN);
361 	gtk_container_add(GTK_CONTAINER(m_wSunkenBox), m_grid);
362 
363 	// (scrollbars are shown, only if needed, by _setScrollRange)
364 	gtk_widget_show(m_dArea);
365 	gtk_widget_show(m_innergrid);
366 	gtk_widget_show(m_grid);
367 
368 	return m_wSunkenBox;
369 }
370 
_hideMenuScroll(bool bHideMenuScroll)371 void AP_UnixFrameImpl::_hideMenuScroll(bool bHideMenuScroll)
372 {
373   if(bHideMenuScroll)
374   {
375     UT_DEBUGMSG(("Hiding Menu \n"));
376     gtk_widget_hide(m_pUnixMenu->getMenuBar());
377     UT_DEBUGMSG(("Hiding scrollbar \n"));
378     gtk_widget_hide(m_vScroll);
379   }
380   else
381   {
382     gtk_widget_show_all(m_pUnixMenu->getMenuBar());
383     gtk_widget_show_all(m_vScroll);
384   }
385 }
_setWindowIcon()386 void AP_UnixFrameImpl::_setWindowIcon()
387 {
388 	// attach program icon to window
389 	GtkWidget * window = getTopLevelWindow();
390 	GdkPixbuf* icon = NULL;
391 
392 #if 0 // we don't need to use the theme.
393 	GtkIconTheme * theme = gtk_icon_theme_get_default();
394 	icon = gtk_icon_theme_load_icon(theme, "abiword", 48, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
395 	if (icon)
396 	{
397 		gtk_window_set_icon (GTK_WINDOW (window), icon);
398 		g_object_unref (G_OBJECT(icon));
399 		return;
400 	}
401 #endif
402 	// Hmm, we can't load the icon from the theme. This happens when we are
403 	// are installed in a custom prefix, so let's try to load the icon manually.
404 	GError* error = NULL;
405 	static const char* s_icon_sizes[] = {
406 		"16x16",
407 		"22x22",
408 		"32x32",
409 		"48x48",
410 		"256x256",
411 		NULL
412 	};
413 
414 	const char** currentSize = s_icon_sizes;
415 	GList* iconList = NULL;
416 	while(*currentSize)
417 	{
418 		std::string icon_path = std::string(ICONDIR) + "/hicolor/"
419 			+ *currentSize + "/apps/abiword.png";
420 		icon = gdk_pixbuf_new_from_file(icon_path.c_str(), &error);
421 		if (icon)
422 		{
423 			iconList = g_list_append(iconList, icon);
424 		}
425 		else
426 		{
427 			g_warning("Unable to load AbiWord icon %s: %s\n",
428 				  icon_path.c_str(),
429 				  error ? error->message : "(null)");
430 			if (error)
431 			{
432 				g_error_free(error);
433 			}
434 		}
435 		currentSize++;
436 	}
437 	if (iconList)
438 	{
439 		gtk_window_set_icon_list(GTK_WINDOW(window), iconList);
440 		g_list_free_full(iconList, &g_object_unref);
441 	}
442 }
443 
_createWindow()444 void AP_UnixFrameImpl::_createWindow()
445 {
446 	_createTopLevelWindow();
447 
448 	gtk_widget_show(getTopLevelWindow());
449 
450 	if(getFrame()->getFrameMode() == XAP_NormalFrame)
451 	{
452 		// needs to be shown so that the following functions work
453 		// TODO: get rid of cursed flicker caused by initially
454 		// TODO: showing these and then hiding them (esp.
455 		// TODO: noticable in the gnome build with a toolbar disabled)
456 		_showOrHideToolbars();
457 		_showOrHideStatusbar();
458 	}
459 	if(getFrame()->isMenuScrollHidden())
460 	{
461 	    _hideMenuScroll(true);
462 	}
463 }
464 
_createStatusBarWindow()465 GtkWidget * AP_UnixFrameImpl::_createStatusBarWindow()
466 {
467 #ifdef ENABLE_STATUSBAR
468 	XAP_Frame* pFrame = getFrame();
469 	AP_UnixStatusBar * pUnixStatusBar = new AP_UnixStatusBar(pFrame);
470 	UT_ASSERT(pUnixStatusBar);
471 
472 	static_cast<AP_FrameData *>(pFrame->getFrameData())->m_pStatusBar = pUnixStatusBar;
473 
474 	return pUnixStatusBar->createWidget();
475 #else
476 	return NULL;
477 #endif
478 }
479 
_setScrollRange(apufi_ScrollType scrollType,int iValue,gfloat fUpperLimit,gfloat fSize)480 void AP_UnixFrameImpl::_setScrollRange(apufi_ScrollType scrollType, int iValue, gfloat fUpperLimit, gfloat fSize)
481 {
482 	GtkAdjustment *pScrollAdjustment = (scrollType == apufi_scrollX) ? m_pHadj : m_pVadj;
483 	GtkWidget *wScrollWidget = (scrollType == apufi_scrollX) ? m_hScroll : m_vScroll;
484 	xxx_UT_DEBUGMSG(("Scroll Adjustment set to %d upper %f size %f\n",iValue, fUpperLimit, fSize));
485 	GR_Graphics * pGr = getFrame()->getCurrentView()->getGraphics ();
486 	XAP_Frame::tZoomType tZoom = getFrame()->getZoomType();
487 	if(pScrollAdjustment) //this isn't guaranteed in AbiCommand
488 	{
489 		gtk_adjustment_configure(pScrollAdjustment, iValue, 0.0, fUpperLimit,
490                                  pGr->tluD(20.0), fSize, fSize);
491 	}
492 
493 	// hide the horizontal scrollbar if the scroll range is such that the window can contain it all
494 	// show it otherwise
495 // Hide the horizontal scrollbar if we've set to page width or fit to page.
496 // This stops a resizing race condition.
497 //
498  	if ((m_hScroll == wScrollWidget) && ((fUpperLimit <= fSize) ||(  tZoom == XAP_Frame::z_PAGEWIDTH) || (tZoom == XAP_Frame::z_WHOLEPAGE)))
499 	{
500  		gtk_widget_hide(wScrollWidget);
501 	}
502  	else if((wScrollWidget != m_vScroll) || !getFrame()->isMenuScrollHidden())
503 	{
504  		gtk_widget_show(wScrollWidget);
505 	}
506 }
507 
508 #define COLOR_MIX 0.67   //COLOR_MIX should be between 0 and 1
509 
getColorSelBackground() const510 UT_RGBColor AP_UnixFrameImpl::getColorSelBackground () const
511 {
512     if( XAP_App::getApp()->getNoGUI() )
513         return(UT_RGBColor(0,0,0));
514 
515     UT_return_val_if_fail(m_dArea, UT_RGBColor(0,0,0));
516 
517 #if GTK_CHECK_VERSION(3,0,0)
518     // Bug 13762 guess colours for the selection.
519     // Code copied from gr_UnixCairoGraphics.
520 
521     // guess colours
522     // WHITE
523     GdkRGBA rgba2;
524     rgba2.red = 1.;
525     rgba2.green = 1.;
526     rgba2.blue = 1.;
527     rgba2.alpha = 1;
528     // guess colours.
529     // BLACK
530     GdkRGBA rgba1;
531     rgba1.red = 0.;
532     rgba1.green = 0.;
533     rgba1.blue = 0.;
534     rgba1.alpha = 1;
535 
536     GdkRGBA rgba_;
537     rgba_.red = rgba1.red*(1.-COLOR_MIX) + rgba2.red*COLOR_MIX;
538     rgba_.green = rgba1.green*(1.-COLOR_MIX) + rgba2.green*COLOR_MIX;
539     rgba_.blue = rgba1.blue*(1.-COLOR_MIX) + rgba2.blue*COLOR_MIX;
540 
541     return UT_RGBColor(rgba_.red * 255, rgba_.green * 255, rgba_.blue * 255);
542 #else
543     GdkColor clr = m_dArea->style->base[GTK_STATE_SELECTED];
544     return UT_RGBColor (clr.red >> 8, clr.green >> 8, clr.blue >> 8);
545 #endif
546 }
547 
getColorSelForeground() const548 UT_RGBColor AP_UnixFrameImpl::getColorSelForeground () const
549 {
550 #if GTK_CHECK_VERSION(3,0,0)
551   return UT_RGBColor(0,0,0);
552 #else
553   gint state;
554 
555   // our text widget has focus
556   if (GTK_WIDGET_HAS_FOCUS(m_dArea))
557     state = GTK_STATE_SELECTED;
558   else
559     state = GTK_STATE_ACTIVE;
560 
561   GdkColor clr = m_dArea->style->text[state];
562   return UT_RGBColor (clr.red >> 8, clr.green >> 8, clr.blue >> 8);
563 #endif
564 }
565