1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: atkwindow.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <plugins/gtk/gtkframe.hxx>
35 #include <vcl/window.hxx>
36 #include "vcl/popupmenuwindow.hxx"
38 #include "atkwindow.hxx"
39 #include "atkwrapper.hxx"
40 #include "atkregistry.hxx"
42 #include <com/sun/star/accessibility/AccessibleRole.hpp>
44 using namespace ::com::sun::star::accessibility
;
45 using namespace ::com::sun::star::uno
;
49 static void (* window_real_initialize
) (AtkObject
*obj
, gpointer data
) = NULL
;
50 static void (* window_real_finalize
) (GObject
*obj
) = NULL
;
53 init_from_window( AtkObject
*accessible
, Window
*pWindow
)
55 static AtkRole aDefaultRole
= ATK_ROLE_INVALID
;
57 // Special role for sub-menu and combo-box popups that are exposed directly
58 // by their parents already.
59 if( aDefaultRole
== ATK_ROLE_INVALID
)
60 aDefaultRole
= atk_role_register( "redundant object" );
62 AtkRole role
= aDefaultRole
;
64 // Determine the appropriate role for the GtkWindow
65 switch( pWindow
->GetAccessibleRole() )
67 case AccessibleRole::ALERT
:
68 role
= ATK_ROLE_ALERT
;
71 case AccessibleRole::DIALOG
:
72 role
= ATK_ROLE_DIALOG
;
75 case AccessibleRole::FRAME
:
76 role
= ATK_ROLE_FRAME
;
79 /* Ignore window objects for sub-menus, combo- and list boxes,
80 * which are exposed as children of their parents.
82 case AccessibleRole::WINDOW
:
84 USHORT type
= WINDOW_WINDOW
;
85 bool parentIsMenuFloatingWindow
= false;
87 Window
*pParent
= pWindow
->GetParent();
89 type
= pParent
->GetType();
90 parentIsMenuFloatingWindow
= ( TRUE
== pParent
->IsMenuFloatingWindow() );
93 if( (WINDOW_LISTBOX
!= type
) && (WINDOW_COMBOBOX
!= type
) &&
94 (WINDOW_MENUBARWINDOW
!= type
) && ! parentIsMenuFloatingWindow
)
96 role
= ATK_ROLE_WINDOW
;
103 Window
*pChild
= pWindow
->GetChild( 0 );
106 if( WINDOW_HELPTEXTWINDOW
== pChild
->GetType() )
108 role
= ATK_ROLE_TOOL_TIP
;
109 pChild
->SetAccessibleRole( AccessibleRole::LABEL
);
110 accessible
->name
= g_strdup( rtl::OUStringToOString( pChild
->GetText(), RTL_TEXTENCODING_UTF8
).getStr() );
112 else if ( pWindow
->GetType() == WINDOW_BORDERWINDOW
&& pChild
->GetType() == WINDOW_FLOATINGWINDOW
)
114 PopupMenuFloatingWindow
* p
= dynamic_cast<PopupMenuFloatingWindow
*>(pChild
);
115 if (p
&& p
->IsPopupMenu() && p
->GetMenuStackLevel() == 0)
117 // This is a top-level menu popup. Register it.
118 role
= ATK_ROLE_POPUP_MENU
;
119 pChild
->SetAccessibleRole( AccessibleRole::POPUP_MENU
);
120 accessible
->name
= g_strdup( rtl::OUStringToOString( pChild
->GetText(), RTL_TEXTENCODING_UTF8
).getStr() );
128 accessible
->role
= role
;
131 /*****************************************************************************/
134 ooo_window_wrapper_clear_focus(gpointer
)
136 atk_focus_tracker_notify( NULL
);
140 /*****************************************************************************/
143 ooo_window_wrapper_real_focus_gtk (GtkWidget
*, GdkEventFocus
*)
145 g_idle_add( ooo_window_wrapper_clear_focus
, NULL
);
149 /*****************************************************************************/
152 isChildPopupMenu(Window
* pWindow
)
154 Window
* pChild
= pWindow
->GetAccessibleChildWindow(0);
158 if (WINDOW_FLOATINGWINDOW
!= pChild
->GetType())
161 PopupMenuFloatingWindow
* p
= dynamic_cast<PopupMenuFloatingWindow
*>(pChild
);
165 return p
->IsPopupMenu();
169 ooo_window_wrapper_real_initialize(AtkObject
*obj
, gpointer data
)
171 window_real_initialize(obj
, data
);
173 GtkSalFrame
*pFrame
= GtkSalFrame::getFromWindow( GTK_WINDOW( data
) );
176 Window
*pWindow
= pFrame
->GetWindow();
179 init_from_window( obj
, pWindow
);
181 Reference
< XAccessible
> xAccessible( pWindow
->GetAccessible(true) );
183 /* We need the wrapper object for the top-level XAccessible to be
184 * in the wrapper registry when atk traverses the hierachy up on
187 if( WINDOW_BORDERWINDOW
== pWindow
->GetType() )
189 if ( isChildPopupMenu(pWindow
) )
191 AtkObject
*child
= atk_object_wrapper_new( xAccessible
, obj
);
192 ooo_wrapper_registry_add( xAccessible
, child
);
196 ooo_wrapper_registry_add( xAccessible
, obj
);
197 g_object_set_data( G_OBJECT(obj
), "ooo:atk-wrapper-key", xAccessible
.get() );
202 AtkObject
*child
= atk_object_wrapper_new( xAccessible
, obj
);
203 child
->role
= ATK_ROLE_FILLER
;
204 if( (ATK_ROLE_DIALOG
== obj
->role
) || (ATK_ROLE_ALERT
== obj
->role
) )
205 child
->role
= ATK_ROLE_OPTION_PANE
;
206 ooo_wrapper_registry_add( xAccessible
, child
);
211 g_signal_connect_after( GTK_WIDGET( data
), "focus-out-event",
212 G_CALLBACK (ooo_window_wrapper_real_focus_gtk
),
216 /*****************************************************************************/
219 ooo_window_wrapper_real_finalize (GObject
*obj
)
221 ooo_wrapper_registry_remove( (XAccessible
*) g_object_get_data( obj
, "ooo:atk-wrapper-key" ));
222 window_real_finalize( obj
);
225 /*****************************************************************************/
228 ooo_window_wrapper_class_init (AtkObjectClass
*klass
, gpointer
)
230 AtkObjectClass
*atk_class
;
231 GObjectClass
*gobject_class
;
235 * Patch the gobject vtable of GailWindow to refer to our instance of
239 data
= g_type_class_peek_parent( klass
);
240 atk_class
= ATK_OBJECT_CLASS (data
);
242 window_real_initialize
= atk_class
->initialize
;
243 atk_class
->initialize
= ooo_window_wrapper_real_initialize
;
245 gobject_class
= G_OBJECT_CLASS (data
);
247 window_real_finalize
= gobject_class
->finalize
;
248 gobject_class
->finalize
= ooo_window_wrapper_real_finalize
;
253 /*****************************************************************************/
256 ooo_window_wrapper_get_type (void)
258 static GType type
= 0;
262 GType parent_type
= g_type_from_name( "GailWindow" );
266 g_warning( "Unknown type: GailWindow" );
267 parent_type
= ATK_TYPE_OBJECT
;
270 GTypeQuery type_query
;
271 g_type_query( parent_type
, &type_query
);
273 static const GTypeInfo typeInfo
=
275 type_query
.class_size
,
276 (GBaseInitFunc
) NULL
,
277 (GBaseFinalizeFunc
) NULL
,
278 (GClassInitFunc
) ooo_window_wrapper_class_init
,
279 (GClassFinalizeFunc
) NULL
,
281 type_query
.instance_size
,
283 (GInstanceInitFunc
) NULL
,
287 type
= g_type_register_static (parent_type
, "OOoWindowAtkObject", &typeInfo
, (GTypeFlags
)0) ;
293 void restore_gail_window_vtable (void)
295 AtkObjectClass
*atk_class
;
298 GType type
= g_type_from_name( "GailWindow" );
300 if( type
== G_TYPE_INVALID
)
303 data
= g_type_class_peek( type
);
304 atk_class
= ATK_OBJECT_CLASS (data
);
306 atk_class
->initialize
= window_real_initialize
;