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: atkwrapper.cxx,v $
10 * $Revision: 1.11.52.1 $
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 <com/sun/star/uno/Any.hxx>
35 #include <com/sun/star/uno/Type.hxx>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/AccessibleRelation.hpp>
39 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
40 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 #include <com/sun/star/accessibility/XAccessible.hpp>
42 #include <com/sun/star/accessibility/XAccessibleText.hpp>
43 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
44 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
45 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
46 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
47 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
48 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
49 #include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
50 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
51 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
52 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
53 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
54 #include <com/sun/star/accessibility/XAccessibleImage.hpp>
55 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
56 #include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
57 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
58 #include <com/sun/star/awt/XExtendedToolkit.hpp>
59 #include <com/sun/star/awt/XTopWindow.hpp>
60 #include <com/sun/star/awt/XTopWindowListener.hpp>
61 #include <com/sun/star/awt/XWindow.hpp>
62 #include <com/sun/star/lang/XComponent.hpp>
63 #include <com/sun/star/lang/XServiceInfo.hpp>
64 #include <com/sun/star/lang/XInitialization.hpp>
65 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
66 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
67 #include <com/sun/star/beans/Property.hpp>
69 #include <rtl/ref.hxx>
70 #include <cppuhelper/factory.hxx>
71 #include <cppuhelper/queryinterface.hxx>
73 #include "atkwrapper.hxx"
74 #include "atkregistry.hxx"
75 #include "atklistener.hxx"
83 using namespace ::com::sun::star
;
85 static GObjectClass
*parent_class
= NULL
;
87 static AtkRelationType
mapRelationType( sal_Int16 nRelation
)
89 AtkRelationType type
= ATK_RELATION_NULL
;
93 case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM
:
94 type
= ATK_RELATION_FLOWS_FROM
;
97 case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO
:
98 type
= ATK_RELATION_FLOWS_TO
;
101 case accessibility::AccessibleRelationType::CONTROLLED_BY
:
102 type
= ATK_RELATION_CONTROLLED_BY
;
105 case accessibility::AccessibleRelationType::CONTROLLER_FOR
:
106 type
= ATK_RELATION_CONTROLLER_FOR
;
109 case accessibility::AccessibleRelationType::LABEL_FOR
:
110 type
= ATK_RELATION_LABEL_FOR
;
113 case accessibility::AccessibleRelationType::LABELED_BY
:
114 type
= ATK_RELATION_LABELLED_BY
;
117 case accessibility::AccessibleRelationType::MEMBER_OF
:
118 type
= ATK_RELATION_MEMBER_OF
;
121 case accessibility::AccessibleRelationType::SUB_WINDOW_OF
:
122 type
= ATK_RELATION_SUBWINDOW_OF
;
125 case accessibility::AccessibleRelationType::NODE_CHILD_OF
:
126 type
= ATK_RELATION_NODE_CHILD_OF
;
133 ATK_RELATION_NODE_CHILD_OF
,
135 ATK_RELATION_EMBEDDED_BY
,
136 ATK_RELATION_POPUP_FOR
,
142 AtkStateType
mapAtkState( sal_Int16 nState
)
144 AtkStateType type
= ATK_STATE_INVALID
;
146 // A perfect / complete mapping ...
149 #define MAP_DIRECT( a ) \
150 case accessibility::AccessibleStateType::a: \
151 type = ATK_STATE_##a; break
153 MAP_DIRECT( INVALID
);
154 MAP_DIRECT( ACTIVE
);
157 MAP_DIRECT( CHECKED
);
158 MAP_DIRECT( EDITABLE
);
159 MAP_DIRECT( ENABLED
);
160 MAP_DIRECT( EXPANDABLE
);
161 MAP_DIRECT( EXPANDED
);
162 MAP_DIRECT( FOCUSABLE
);
163 MAP_DIRECT( FOCUSED
);
164 MAP_DIRECT( HORIZONTAL
);
165 MAP_DIRECT( ICONIFIED
);
166 MAP_DIRECT( INDETERMINATE
);
167 MAP_DIRECT( MANAGES_DESCENDANTS
);
169 MAP_DIRECT( MULTI_LINE
);
170 MAP_DIRECT( OPAQUE
);
171 MAP_DIRECT( PRESSED
);
172 MAP_DIRECT( RESIZABLE
);
173 MAP_DIRECT( SELECTABLE
);
174 MAP_DIRECT( SELECTED
);
175 MAP_DIRECT( SENSITIVE
);
176 MAP_DIRECT( SHOWING
);
177 MAP_DIRECT( SINGLE_LINE
);
179 MAP_DIRECT( TRANSIENT
);
180 MAP_DIRECT( VERTICAL
);
181 MAP_DIRECT( VISIBLE
);
182 // a spelling error ...
183 case accessibility::AccessibleStateType::DEFUNC
:
184 type
= ATK_STATE_DEFUNCT
; break;
185 case accessibility::AccessibleStateType::MULTI_SELECTABLE
:
186 type
= ATK_STATE_MULTISELECTABLE
; break;
194 static inline AtkRole
registerRole( const gchar
* name
)
196 AtkRole ret
= atk_role_for_name( name
);
197 if( ATK_ROLE_INVALID
== ret
)
198 ret
= atk_role_register( name
);
203 static AtkRole
mapToAtkRole( sal_Int16 nRole
)
205 AtkRole role
= ATK_ROLE_UNKNOWN
;
207 static AtkRole roleMap
[] = {
210 ATK_ROLE_COLUMN_HEADER
,
213 ATK_ROLE_CHECK_MENU_ITEM
,
214 ATK_ROLE_COLOR_CHOOSER
,
216 ATK_ROLE_DATE_EDITOR
,
217 ATK_ROLE_DESKTOP_ICON
,
218 ATK_ROLE_DESKTOP_FRAME
, // ? pane
219 ATK_ROLE_DIRECTORY_PANE
,
221 ATK_ROLE_UNKNOWN
, // DOCUMENT - registered below
222 ATK_ROLE_UNKNOWN
, // EMBEDDED_OBJECT - registered below
223 ATK_ROLE_UNKNOWN
, // END_NOTE - registered below
224 ATK_ROLE_FILE_CHOOSER
,
226 ATK_ROLE_FONT_CHOOSER
,
228 ATK_ROLE_TEXT
, // FOOTNOTE - registered below
231 ATK_ROLE_IMAGE
, // GRAPHIC
232 ATK_ROLE_UNKNOWN
, // GROUP_BOX - registered below
234 ATK_ROLE_PARAGRAPH
, // HEADING - registered below
235 ATK_ROLE_TEXT
, // HYPER_LINK - registered below
237 ATK_ROLE_INTERNAL_FRAME
,
239 ATK_ROLE_LAYERED_PANE
,
245 ATK_ROLE_OPTION_PANE
,
247 ATK_ROLE_PAGE_TAB_LIST
,
250 ATK_ROLE_PASSWORD_TEXT
,
252 ATK_ROLE_PUSH_BUTTON
,
253 ATK_ROLE_PROGRESS_BAR
,
254 ATK_ROLE_RADIO_BUTTON
,
255 ATK_ROLE_RADIO_MENU_ITEM
,
259 ATK_ROLE_SCROLL_PANE
,
260 ATK_ROLE_UNKNOWN
, // SHAPE - registered below
263 ATK_ROLE_SPIN_BUTTON
, // SPIN_BOX ?
269 ATK_ROLE_INTERNAL_FRAME
, // TEXT_FRAME - registered below
270 ATK_ROLE_TOGGLE_BUTTON
,
276 ATK_ROLE_PUSH_BUTTON
, // BUTTON_DROPDOWN
277 ATK_ROLE_PUSH_BUTTON
, // BUTTON_MENU
278 ATK_ROLE_UNKNOWN
, // CAPTION - registered below
279 ATK_ROLE_UNKNOWN
, // CHART - registered below
280 ATK_ROLE_UNKNOWN
, // EDIT_BAR - registered below
281 ATK_ROLE_UNKNOWN
, // FORM - registered below
282 ATK_ROLE_UNKNOWN
, // IMAGE_MAP - registered below
283 ATK_ROLE_UNKNOWN
, // NOTE - registered below
284 ATK_ROLE_UNKNOWN
, // PAGE - registered below
286 ATK_ROLE_UNKNOWN
, // SECTION - registered below
287 ATK_ROLE_UNKNOWN
, // TREE_ITEM - registered below
291 static bool initialized
= false;
295 // re-use strings from ATK library
296 roleMap
[accessibility::AccessibleRole::EDIT_BAR
] = registerRole("edit bar");
297 roleMap
[accessibility::AccessibleRole::EMBEDDED_OBJECT
] = registerRole("embedded component");
298 roleMap
[accessibility::AccessibleRole::CHART
] = registerRole("chart");
299 roleMap
[accessibility::AccessibleRole::CAPTION
] = registerRole("caption");
300 roleMap
[accessibility::AccessibleRole::DOCUMENT
] = registerRole("document frame");
301 roleMap
[accessibility::AccessibleRole::HEADING
] = registerRole("heading");
302 roleMap
[accessibility::AccessibleRole::PAGE
] = registerRole("page");
303 roleMap
[accessibility::AccessibleRole::SECTION
] = registerRole("section");
304 roleMap
[accessibility::AccessibleRole::FORM
] = registerRole("form");
306 // these don't exist in ATK yet
307 roleMap
[accessibility::AccessibleRole::END_NOTE
] = registerRole("end note");
308 roleMap
[accessibility::AccessibleRole::FOOTNOTE
] = registerRole("foot note");
309 roleMap
[accessibility::AccessibleRole::GROUP_BOX
] = registerRole("group box");
310 roleMap
[accessibility::AccessibleRole::HYPER_LINK
] = registerRole("hyper link");
311 roleMap
[accessibility::AccessibleRole::SHAPE
] = registerRole("shape");
312 roleMap
[accessibility::AccessibleRole::TEXT_FRAME
] = registerRole("text frame");
313 roleMap
[accessibility::AccessibleRole::IMAGE_MAP
] = registerRole("image map");
314 roleMap
[accessibility::AccessibleRole::NOTE
] = registerRole("note");
315 roleMap
[accessibility::AccessibleRole::TREE_ITEM
] = registerRole("tree item");
320 static const sal_Int32 nMapSize
= sizeof(roleMap
)/sizeof(sal_Int16
);
321 if( 0 <= nRole
&& nMapSize
> nRole
)
322 role
= roleMap
[nRole
];
328 /*****************************************************************************/
332 /*****************************************************************************/
334 static G_CONST_RETURN gchar
*
335 wrapper_get_name( AtkObject
*atk_obj
)
337 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
343 rtl::OUStringToOString(
344 obj
->mpContext
->getAccessibleName(),
345 RTL_TEXTENCODING_UTF8
);
347 int nCmp
= atk_obj
->name
? rtl_str_compare( atk_obj
->name
, aName
.getStr() ) : -1;
351 g_free(atk_obj
->name
);
352 atk_obj
->name
= g_strdup(aName
.getStr());
355 catch(const uno::Exception
& e
) {
356 g_warning( "Exception in getAccessibleName()" );
360 return ATK_OBJECT_CLASS (parent_class
)->get_name(atk_obj
);
363 /*****************************************************************************/
365 static G_CONST_RETURN gchar
*
366 wrapper_get_description( AtkObject
*atk_obj
)
368 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
373 rtl::OString aDescription
=
374 rtl::OUStringToOString(
375 obj
->mpContext
->getAccessibleDescription(),
376 RTL_TEXTENCODING_UTF8
);
378 g_free(atk_obj
->description
);
379 atk_obj
->description
= g_strdup(aDescription
.getStr());
381 catch(const uno::Exception
& e
) {
382 g_warning( "Exception in getAccessibleDescription()" );
386 return ATK_OBJECT_CLASS (parent_class
)->get_description(atk_obj
);
390 /*****************************************************************************/
393 wrapper_get_n_children( AtkObject
*atk_obj
)
395 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
401 n
= obj
->mpContext
->getAccessibleChildCount();
403 catch(const uno::Exception
& e
) {
404 OSL_ENSURE(0, "Exception in getAccessibleChildCount()" );
411 /*****************************************************************************/
414 wrapper_ref_child( AtkObject
*atk_obj
,
417 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
418 AtkObject
* child
= NULL
;
420 // see comments above atk_object_wrapper_remove_child
421 if( -1 < i
&& obj
->index_of_child_about_to_be_removed
== i
)
423 g_object_ref( obj
->child_about_to_be_removed
);
424 return obj
->child_about_to_be_removed
;
430 uno::Reference
< accessibility::XAccessible
> xAccessible
=
431 obj
->mpContext
->getAccessibleChild( i
);
433 child
= atk_object_wrapper_ref( xAccessible
);
435 catch(const uno::Exception
& e
) {
436 OSL_ENSURE(0, "Exception in getAccessibleChild");
443 /*****************************************************************************/
446 wrapper_get_index_in_parent( AtkObject
*atk_obj
)
448 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
454 i
= obj
->mpContext
->getAccessibleIndexInParent();
456 #ifdef ENABLE_TRACING
457 fprintf(stderr
, "%p->getAccessibleIndexInParent() returned: %u\n",
458 obj
->mpAccessible
, i
);
461 catch(const uno::Exception
& e
) {
462 g_warning( "Exception in getAccessibleIndexInParent()" );
468 /*****************************************************************************/
470 static AtkRelationSet
*
471 wrapper_ref_relation_set( AtkObject
*atk_obj
)
473 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
474 AtkRelationSet
*pSet
= atk_relation_set_new();
479 uno::Reference
< accessibility::XAccessibleRelationSet
> xRelationSet(
480 obj
->mpContext
->getAccessibleRelationSet()
483 sal_Int32 nRelations
= xRelationSet
.is() ? xRelationSet
->getRelationCount() : 0;
484 for( sal_Int32 n
= 0; n
< nRelations
; n
++ )
486 accessibility::AccessibleRelation aRelation
= xRelationSet
->getRelation( n
);
487 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
488 AtkObject
**pTargets
= (AtkObject
**) alloca( nTargetCount
* sizeof(AtkObject
*) );
490 for( sal_uInt32 i
= 0; i
< nTargetCount
; i
++ )
492 uno::Reference
< accessibility::XAccessible
> xAccessible(
493 aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
494 pTargets
[i
] = atk_object_wrapper_ref( xAccessible
);
499 pTargets
, nTargetCount
,
500 mapRelationType( aRelation
.RelationType
)
502 atk_relation_set_add( pSet
, pRel
);
503 g_object_unref( G_OBJECT( pRel
) );
506 catch(const uno::Exception
&e
) {
507 g_object_unref( G_OBJECT( pSet
) );
515 /*****************************************************************************/
520 const sal_Char
* name
;
521 } aStateTypeTable
[] = {
522 { accessibility::AccessibleStateType::INVALID
, "INVALID" },
523 { accessibility::AccessibleStateType::ACTIVE
, "ACTIVE" },
524 { accessibility::AccessibleStateType::ARMED
, "ARMED" },
525 { accessibility::AccessibleStateType::BUSY
, "BUSY" },
526 { accessibility::AccessibleStateType::CHECKED
, "CHECKED" },
527 { accessibility::AccessibleStateType::DEFUNC
, "DEFUNC" },
528 { accessibility::AccessibleStateType::EDITABLE
, "EDITABLE" },
529 { accessibility::AccessibleStateType::ENABLED
, "ENABLED" },
530 { accessibility::AccessibleStateType::EXPANDABLE
, "EXPANDABLE" },
531 { accessibility::AccessibleStateType::EXPANDED
, "EXPANDED" },
532 { accessibility::AccessibleStateType::FOCUSABLE
, "FOCUSABLE" },
533 { accessibility::AccessibleStateType::FOCUSED
, "FOCUSED" },
534 { accessibility::AccessibleStateType::HORIZONTAL
, "HORIZONTAL" },
535 { accessibility::AccessibleStateType::ICONIFIED
, "ICONIFIED" },
536 { accessibility::AccessibleStateType::INDETERMINATE
, "INDETERMINATE" },
537 { accessibility::AccessibleStateType::MANAGES_DESCENDANTS
, "MANAGES_DESCENDANTS" },
538 { accessibility::AccessibleStateType::MODAL
, "MODAL" },
539 { accessibility::AccessibleStateType::MULTI_LINE
, "MULTI_LINE" },
540 { accessibility::AccessibleStateType::MULTI_SELECTABLE
, "MULTI_SELECTABLE" },
541 { accessibility::AccessibleStateType::OPAQUE
, "OPAQUE" },
542 { accessibility::AccessibleStateType::PRESSED
, "PRESSED" },
543 { accessibility::AccessibleStateType::RESIZABLE
, "RESIZABLE" },
544 { accessibility::AccessibleStateType::SELECTABLE
, "SELECTABLE" },
545 { accessibility::AccessibleStateType::SELECTED
, "SELECTED" },
546 { accessibility::AccessibleStateType::SENSITIVE
, "SENSITIVE" },
547 { accessibility::AccessibleStateType::SHOWING
, "SHOWING" },
548 { accessibility::AccessibleStateType::SINGLE_LINE
, "SINGLE_LINE" },
549 { accessibility::AccessibleStateType::STALE
, "STALE" },
550 { accessibility::AccessibleStateType::TRANSIENT
, "TRANSIENT" },
551 { accessibility::AccessibleStateType::VERTICAL
, "VERTICAL" },
552 { accessibility::AccessibleStateType::VISIBLE
, "VISIBLE" }
555 static void printStates(const uno::Sequence
<sal_Int16
>& rStates
)
557 sal_Int32 n
= rStates
.getLength();
558 size_t nTypes
= sizeof(aStateTypeTable
)/sizeof(aStateTypeTable
[0]);
559 for (sal_Int32 i
= 0; i
< n
; ++i
)
561 for (size_t j
= 0; j
< nTypes
; ++j
)
563 if (aStateTypeTable
[j
].value
== rStates
[i
])
564 printf("%s ", aStateTypeTable
[j
].name
);
572 wrapper_ref_state_set( AtkObject
*atk_obj
)
574 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
575 AtkStateSet
*pSet
= atk_state_set_new();
580 uno::Reference
< accessibility::XAccessibleStateSet
> xStateSet(
581 obj
->mpContext
->getAccessibleStateSet());
585 uno::Sequence
< sal_Int16
> aStates
= xStateSet
->getStates();
587 for( sal_Int32 n
= 0; n
< aStates
.getLength(); n
++ )
588 atk_state_set_add_state( pSet
, mapAtkState( aStates
[n
] ) );
590 // We need to emulate FOCUS state for menus, menu-items etc.
591 if( atk_obj
== atk_get_focus_object() )
592 atk_state_set_add_state( pSet
, ATK_STATE_FOCUSED
);
593 /* FIXME - should we do this ?
595 atk_state_set_remove_state( pSet, ATK_STATE_FOCUSED );
600 catch(const uno::Exception
&e
) {
601 g_warning( "Exception in wrapper_ref_state_set" );
602 atk_state_set_add_state( pSet
, ATK_STATE_DEFUNCT
);
606 atk_state_set_add_state( pSet
, ATK_STATE_DEFUNCT
);
611 /*****************************************************************************/
615 atk_object_wrapper_finalize (GObject
*obj
)
617 AtkObjectWrapper
*pWrap
= ATK_OBJECT_WRAPPER (obj
);
619 if( pWrap
->mpAccessible
)
621 ooo_wrapper_registry_remove( pWrap
->mpAccessible
);
622 pWrap
->mpAccessible
->release();
623 pWrap
->mpAccessible
= NULL
;
626 atk_object_wrapper_dispose( pWrap
);
628 parent_class
->finalize( obj
);
632 atk_object_wrapper_class_init (AtkObjectWrapperClass
*klass
)
634 GObjectClass
*gobject_class
= G_OBJECT_CLASS( klass
);
635 AtkObjectClass
*atk_class
= ATK_OBJECT_CLASS( klass
);
637 parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
640 gobject_class
->finalize
= atk_object_wrapper_finalize
;
643 atk_class
->get_name
= wrapper_get_name
;
644 atk_class
->get_description
= wrapper_get_description
;
645 atk_class
->get_n_children
= wrapper_get_n_children
;
646 atk_class
->ref_child
= wrapper_ref_child
;
647 atk_class
->get_index_in_parent
= wrapper_get_index_in_parent
;
648 atk_class
->ref_relation_set
= wrapper_ref_relation_set
;
649 atk_class
->ref_state_set
= wrapper_ref_state_set
;
653 atk_object_wrapper_init (AtkObjectWrapper
*wrapper
,
654 AtkObjectWrapperClass
)
656 wrapper
->mpAction
= NULL
;
657 wrapper
->mpComponent
= NULL
;
658 wrapper
->mpEditableText
= NULL
;
659 wrapper
->mpHypertext
= NULL
;
660 wrapper
->mpImage
= NULL
;
661 wrapper
->mpSelection
= NULL
;
662 wrapper
->mpTable
= NULL
;
663 wrapper
->mpText
= NULL
;
664 wrapper
->mpValue
= NULL
;
670 atk_object_wrapper_get_type (void)
672 static GType type
= 0;
676 static const GTypeInfo typeInfo
=
678 sizeof (AtkObjectWrapperClass
),
679 (GBaseInitFunc
) NULL
,
680 (GBaseFinalizeFunc
) NULL
,
681 (GClassInitFunc
) atk_object_wrapper_class_init
,
682 (GClassFinalizeFunc
) NULL
,
684 sizeof (AtkObjectWrapper
),
686 (GInstanceInitFunc
) atk_object_wrapper_init
,
689 type
= g_type_register_static (ATK_TYPE_OBJECT
,
691 &typeInfo
, (GTypeFlags
)0) ;
697 isOfType( uno::XInterface
*pInterface
, const uno::Type
& rType
)
699 g_return_val_if_fail( pInterface
!= NULL
, false );
703 uno::Any aRet
= pInterface
->queryInterface( rType
);
705 bIs
= ( ( typelib_TypeClass_INTERFACE
== aRet
.pType
->eTypeClass
) &&
706 ( aRet
.pReserved
!= NULL
) );
707 } catch( const uno::Exception
&e
) { }
713 typedef GType (* GetGIfaceType
) (void);
717 GInterfaceInitFunc aInit
;
718 GetGIfaceType aGetGIfaceType
;
719 const uno::Type
& (*aGetUnoType
) (void *);
721 // re-location heaven:
723 "Comp", (GInterfaceInitFunc
) componentIfaceInit
,
724 atk_component_get_type
,
725 accessibility::XAccessibleComponent::static_type
728 "Act", (GInterfaceInitFunc
) actionIfaceInit
,
730 accessibility::XAccessibleAction::static_type
733 "Txt", (GInterfaceInitFunc
) textIfaceInit
,
735 accessibility::XAccessibleText::static_type
738 "Val", (GInterfaceInitFunc
) valueIfaceInit
,
740 accessibility::XAccessibleValue::static_type
743 "Tab", (GInterfaceInitFunc
) tableIfaceInit
,
745 accessibility::XAccessibleTable::static_type
748 "Edt", (GInterfaceInitFunc
) editableTextIfaceInit
,
749 atk_editable_text_get_type
,
750 accessibility::XAccessibleEditableText::static_type
753 "Img", (GInterfaceInitFunc
) imageIfaceInit
,
755 accessibility::XAccessibleImage::static_type
758 "Hyp", (GInterfaceInitFunc
) hypertextIfaceInit
,
759 atk_hypertext_get_type
,
760 accessibility::XAccessibleHypertext::static_type
763 "Sel", (GInterfaceInitFunc
) selectionIfaceInit
,
764 atk_selection_get_type
,
765 accessibility::XAccessibleSelection::static_type
767 // AtkDocument is a nastily broken interface (so far)
768 // we could impl. get_document_type perhaps though.
771 const int aTypeTableSize
= G_N_ELEMENTS( aTypeTable
);
774 ensureTypeFor( uno::XInterface
*pAccessible
)
777 int bTypes
[ aTypeTableSize
] = { 0, };
778 rtl::OString
aTypeName( "OOoAtkObj" );
780 for( i
= 0; i
< aTypeTableSize
; i
++ )
782 if( isOfType( pAccessible
, aTypeTable
[i
].aGetUnoType(0) ) )
784 aTypeName
+= aTypeTable
[i
].name
;
787 // g_message( "Accessible %p has type '%s' (%d)",
788 // pAccessible, aTypeTable[i].name, bTypes[i] );
791 GType nType
= g_type_from_name( aTypeName
);
792 if( nType
== G_TYPE_INVALID
)
794 GTypeInfo aTypeInfo
= {
795 sizeof( AtkObjectWrapperClass
),
796 NULL
, NULL
, NULL
, NULL
, NULL
,
797 sizeof( AtkObjectWrapper
),
800 nType
= g_type_register_static( ATK_TYPE_OBJECT_WRAPPER
,
801 aTypeName
, &aTypeInfo
, (GTypeFlags
)0 ) ;
803 for( int j
= 0; j
< aTypeTableSize
; j
++ )
806 GInterfaceInfo aIfaceInfo
= { NULL
, NULL
, NULL
};
807 aIfaceInfo
.interface_init
= aTypeTable
[j
].aInit
;
808 g_type_add_interface_static (nType
, aTypeTable
[j
].aGetGIfaceType(),
816 atk_object_wrapper_ref( const uno::Reference
< accessibility::XAccessible
> &rxAccessible
, bool create
)
818 g_return_val_if_fail( rxAccessible
.get() != NULL
, NULL
);
820 AtkObject
*obj
= ooo_wrapper_registry_get(rxAccessible
);
828 return atk_object_wrapper_new( rxAccessible
);
835 atk_object_wrapper_new( const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& rxAccessible
,
838 g_return_val_if_fail( rxAccessible
.get() != NULL
, NULL
);
840 AtkObjectWrapper
*pWrap
= NULL
;
843 uno::Reference
< accessibility::XAccessibleContext
> xContext(rxAccessible
->getAccessibleContext());
845 g_return_val_if_fail( xContext
.get() != NULL
, NULL
);
847 GType nType
= ensureTypeFor( xContext
.get() );
848 gpointer obj
= g_object_new( nType
, NULL
);
850 pWrap
= ATK_OBJECT_WRAPPER( obj
);
851 pWrap
->mpAccessible
= rxAccessible
.get();
852 rxAccessible
->acquire();
854 pWrap
->index_of_child_about_to_be_removed
= -1;
855 pWrap
->child_about_to_be_removed
= NULL
;
858 pWrap
->mpContext
= xContext
.get();
860 AtkObject
* atk_obj
= ATK_OBJECT(pWrap
);
861 atk_obj
->role
= mapToAtkRole( xContext
->getAccessibleRole() );
862 atk_obj
->accessible_parent
= parent
;
864 ooo_wrapper_registry_add( rxAccessible
, atk_obj
);
867 g_object_ref( atk_obj
->accessible_parent
);
870 /* gail_focus_tracker remembers the focused object at the first
871 * parent in the hierachy that is a Gtk+ widget, but at the time the
872 * event gets processed (at idle), it may be too late to create the
873 * hierachy, so doing it now ..
875 uno::Reference
< accessibility::XAccessible
> xParent( xContext
->getAccessibleParent() );
877 /* The top-level objects should never be of this class */
878 OSL_ASSERT( xParent
.is() );
881 atk_obj
->accessible_parent
= atk_object_wrapper_ref( xParent
);
884 // Attach a listener to the UNO object if it's not TRANSIENT
885 uno::Reference
< accessibility::XAccessibleStateSet
> xStateSet( xContext
->getAccessibleStateSet() );
886 if( xStateSet
.is() && ! xStateSet
->contains( accessibility::AccessibleStateType::TRANSIENT
) )
888 uno::Reference
< accessibility::XAccessibleEventBroadcaster
> xBroadcaster(xContext
, uno::UNO_QUERY
);
889 if( xBroadcaster
.is() )
890 xBroadcaster
->addEventListener( static_cast< accessibility::XAccessibleEventListener
* > ( new AtkListener(pWrap
) ) );
895 return ATK_OBJECT( pWrap
);
897 catch (const uno::Exception
&e
)
900 g_object_unref( pWrap
);
907 /*****************************************************************************/
909 void atk_object_wrapper_add_child(AtkObjectWrapper
* wrapper
, AtkObject
*child
, gint index
)
911 AtkObject
*atk_obj
= ATK_OBJECT( wrapper
);
913 atk_object_set_parent( child
, atk_obj
);
914 g_signal_emit_by_name( atk_obj
, "children_changed::add", index
, child
, NULL
);
917 /*****************************************************************************/
919 void atk_object_wrapper_remove_child(AtkObjectWrapper
* wrapper
, AtkObject
*child
, gint index
)
922 * the atk-bridge GTK+ module get's back to the event source to ref the child just
923 * vanishing, so we keep this reference because the semantic on OOo side is different.
925 wrapper
->child_about_to_be_removed
= child
;
926 wrapper
->index_of_child_about_to_be_removed
= index
;
928 g_signal_emit_by_name( ATK_OBJECT( wrapper
), "children_changed::remove", index
, child
, NULL
);
930 wrapper
->index_of_child_about_to_be_removed
= -1;
931 wrapper
->child_about_to_be_removed
= NULL
;
934 /*****************************************************************************/
936 #define RELEASE(i) if( i ) { i->release(); i = NULL; }
938 void atk_object_wrapper_dispose(AtkObjectWrapper
* wrapper
)
940 RELEASE( wrapper
->mpContext
)
941 RELEASE( wrapper
->mpAction
)
942 RELEASE( wrapper
->mpComponent
)
943 RELEASE( wrapper
->mpEditableText
)
944 RELEASE( wrapper
->mpHypertext
)
945 RELEASE( wrapper
->mpImage
)
946 RELEASE( wrapper
->mpSelection
)
947 RELEASE( wrapper
->mpMultiLineText
)
948 RELEASE( wrapper
->mpTable
)
949 RELEASE( wrapper
->mpText
)
950 RELEASE( wrapper
->mpTextAttributes
)
951 RELEASE( wrapper
->mpValue
)