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/XAccessibleTextMarkup.hpp>
44 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
45 #include <com/sun/star/accessibility/XAccessibleValue.hpp>
46 #include <com/sun/star/accessibility/XAccessibleAction.hpp>
47 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
48 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
49 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
50 #include <com/sun/star/accessibility/XAccessibleMultiLineText.hpp>
51 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
52 #include <com/sun/star/accessibility/XAccessibleRelationSet.hpp>
53 #include <com/sun/star/accessibility/XAccessibleTable.hpp>
54 #include <com/sun/star/accessibility/XAccessibleEditableText.hpp>
55 #include <com/sun/star/accessibility/XAccessibleImage.hpp>
56 #include <com/sun/star/accessibility/XAccessibleHyperlink.hpp>
57 #include <com/sun/star/accessibility/XAccessibleHypertext.hpp>
58 #include <com/sun/star/accessibility/XAccessibleSelection.hpp>
59 #include <com/sun/star/awt/XExtendedToolkit.hpp>
60 #include <com/sun/star/awt/XTopWindow.hpp>
61 #include <com/sun/star/awt/XTopWindowListener.hpp>
62 #include <com/sun/star/awt/XWindow.hpp>
63 #include <com/sun/star/lang/XComponent.hpp>
64 #include <com/sun/star/lang/XServiceInfo.hpp>
65 #include <com/sun/star/lang/XInitialization.hpp>
66 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
67 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
68 #include <com/sun/star/beans/Property.hpp>
70 #include <rtl/ref.hxx>
71 #include <cppuhelper/factory.hxx>
72 #include <cppuhelper/queryinterface.hxx>
74 #include "atkwrapper.hxx"
75 #include "atkregistry.hxx"
76 #include "atklistener.hxx"
84 using namespace ::com::sun::star
;
86 static GObjectClass
*parent_class
= NULL
;
88 static AtkRelationType
mapRelationType( sal_Int16 nRelation
)
90 AtkRelationType type
= ATK_RELATION_NULL
;
94 case accessibility::AccessibleRelationType::CONTENT_FLOWS_FROM
:
95 type
= ATK_RELATION_FLOWS_FROM
;
98 case accessibility::AccessibleRelationType::CONTENT_FLOWS_TO
:
99 type
= ATK_RELATION_FLOWS_TO
;
102 case accessibility::AccessibleRelationType::CONTROLLED_BY
:
103 type
= ATK_RELATION_CONTROLLED_BY
;
106 case accessibility::AccessibleRelationType::CONTROLLER_FOR
:
107 type
= ATK_RELATION_CONTROLLER_FOR
;
110 case accessibility::AccessibleRelationType::LABEL_FOR
:
111 type
= ATK_RELATION_LABEL_FOR
;
114 case accessibility::AccessibleRelationType::LABELED_BY
:
115 type
= ATK_RELATION_LABELLED_BY
;
118 case accessibility::AccessibleRelationType::MEMBER_OF
:
119 type
= ATK_RELATION_MEMBER_OF
;
122 case accessibility::AccessibleRelationType::SUB_WINDOW_OF
:
123 type
= ATK_RELATION_SUBWINDOW_OF
;
126 case accessibility::AccessibleRelationType::NODE_CHILD_OF
:
127 type
= ATK_RELATION_NODE_CHILD_OF
;
134 ATK_RELATION_NODE_CHILD_OF
,
136 ATK_RELATION_EMBEDDED_BY
,
137 ATK_RELATION_POPUP_FOR
,
143 AtkStateType
mapAtkState( sal_Int16 nState
)
145 AtkStateType type
= ATK_STATE_INVALID
;
147 // A perfect / complete mapping ...
150 #define MAP_DIRECT( a ) \
151 case accessibility::AccessibleStateType::a: \
152 type = ATK_STATE_##a; break
154 MAP_DIRECT( INVALID
);
155 MAP_DIRECT( ACTIVE
);
158 MAP_DIRECT( CHECKED
);
159 MAP_DIRECT( EDITABLE
);
160 MAP_DIRECT( ENABLED
);
161 MAP_DIRECT( EXPANDABLE
);
162 MAP_DIRECT( EXPANDED
);
163 MAP_DIRECT( FOCUSABLE
);
164 MAP_DIRECT( FOCUSED
);
165 MAP_DIRECT( HORIZONTAL
);
166 MAP_DIRECT( ICONIFIED
);
167 MAP_DIRECT( INDETERMINATE
);
168 MAP_DIRECT( MANAGES_DESCENDANTS
);
170 MAP_DIRECT( MULTI_LINE
);
171 MAP_DIRECT( OPAQUE
);
172 MAP_DIRECT( PRESSED
);
173 MAP_DIRECT( RESIZABLE
);
174 MAP_DIRECT( SELECTABLE
);
175 MAP_DIRECT( SELECTED
);
176 MAP_DIRECT( SENSITIVE
);
177 MAP_DIRECT( SHOWING
);
178 MAP_DIRECT( SINGLE_LINE
);
180 MAP_DIRECT( TRANSIENT
);
181 MAP_DIRECT( VERTICAL
);
182 MAP_DIRECT( VISIBLE
);
183 // a spelling error ...
184 case accessibility::AccessibleStateType::DEFUNC
:
185 type
= ATK_STATE_DEFUNCT
; break;
186 case accessibility::AccessibleStateType::MULTI_SELECTABLE
:
187 type
= ATK_STATE_MULTISELECTABLE
; break;
195 static inline AtkRole
registerRole( const gchar
* name
)
197 AtkRole ret
= atk_role_for_name( name
);
198 if( ATK_ROLE_INVALID
== ret
)
199 ret
= atk_role_register( name
);
204 static AtkRole
mapToAtkRole( sal_Int16 nRole
)
206 AtkRole role
= ATK_ROLE_UNKNOWN
;
208 static AtkRole roleMap
[] = {
211 ATK_ROLE_COLUMN_HEADER
,
214 ATK_ROLE_CHECK_MENU_ITEM
,
215 ATK_ROLE_COLOR_CHOOSER
,
217 ATK_ROLE_DATE_EDITOR
,
218 ATK_ROLE_DESKTOP_ICON
,
219 ATK_ROLE_DESKTOP_FRAME
, // ? pane
220 ATK_ROLE_DIRECTORY_PANE
,
222 ATK_ROLE_UNKNOWN
, // DOCUMENT - registered below
223 ATK_ROLE_UNKNOWN
, // EMBEDDED_OBJECT - registered below
224 ATK_ROLE_UNKNOWN
, // END_NOTE - registered below
225 ATK_ROLE_FILE_CHOOSER
,
227 ATK_ROLE_FONT_CHOOSER
,
229 ATK_ROLE_TEXT
, // FOOTNOTE - registered below
232 ATK_ROLE_IMAGE
, // GRAPHIC
233 ATK_ROLE_UNKNOWN
, // GROUP_BOX - registered below
235 ATK_ROLE_PARAGRAPH
, // HEADING - registered below
236 ATK_ROLE_TEXT
, // HYPER_LINK - registered below
238 ATK_ROLE_INTERNAL_FRAME
,
240 ATK_ROLE_LAYERED_PANE
,
246 ATK_ROLE_OPTION_PANE
,
248 ATK_ROLE_PAGE_TAB_LIST
,
251 ATK_ROLE_PASSWORD_TEXT
,
253 ATK_ROLE_PUSH_BUTTON
,
254 ATK_ROLE_PROGRESS_BAR
,
255 ATK_ROLE_RADIO_BUTTON
,
256 ATK_ROLE_RADIO_MENU_ITEM
,
260 ATK_ROLE_SCROLL_PANE
,
261 ATK_ROLE_UNKNOWN
, // SHAPE - registered below
264 ATK_ROLE_SPIN_BUTTON
, // SPIN_BOX ?
270 ATK_ROLE_INTERNAL_FRAME
, // TEXT_FRAME - registered below
271 ATK_ROLE_TOGGLE_BUTTON
,
277 ATK_ROLE_PUSH_BUTTON
, // BUTTON_DROPDOWN
278 ATK_ROLE_PUSH_BUTTON
, // BUTTON_MENU
279 ATK_ROLE_UNKNOWN
, // CAPTION - registered below
280 ATK_ROLE_UNKNOWN
, // CHART - registered below
281 ATK_ROLE_UNKNOWN
, // EDIT_BAR - registered below
282 ATK_ROLE_UNKNOWN
, // FORM - registered below
283 ATK_ROLE_UNKNOWN
, // IMAGE_MAP - registered below
284 ATK_ROLE_UNKNOWN
, // NOTE - registered below
285 ATK_ROLE_UNKNOWN
, // PAGE - registered below
287 ATK_ROLE_UNKNOWN
, // SECTION - registered below
288 ATK_ROLE_UNKNOWN
, // TREE_ITEM - registered below
292 static bool initialized
= false;
296 // re-use strings from ATK library
297 roleMap
[accessibility::AccessibleRole::EDIT_BAR
] = registerRole("edit bar");
298 roleMap
[accessibility::AccessibleRole::EMBEDDED_OBJECT
] = registerRole("embedded component");
299 roleMap
[accessibility::AccessibleRole::CHART
] = registerRole("chart");
300 roleMap
[accessibility::AccessibleRole::CAPTION
] = registerRole("caption");
301 roleMap
[accessibility::AccessibleRole::DOCUMENT
] = registerRole("document frame");
302 roleMap
[accessibility::AccessibleRole::HEADING
] = registerRole("heading");
303 roleMap
[accessibility::AccessibleRole::PAGE
] = registerRole("page");
304 roleMap
[accessibility::AccessibleRole::SECTION
] = registerRole("section");
305 roleMap
[accessibility::AccessibleRole::FORM
] = registerRole("form");
307 // these don't exist in ATK yet
308 roleMap
[accessibility::AccessibleRole::END_NOTE
] = registerRole("end note");
309 roleMap
[accessibility::AccessibleRole::FOOTNOTE
] = registerRole("foot note");
310 roleMap
[accessibility::AccessibleRole::GROUP_BOX
] = registerRole("group box");
311 roleMap
[accessibility::AccessibleRole::HYPER_LINK
] = registerRole("hyper link");
312 roleMap
[accessibility::AccessibleRole::SHAPE
] = registerRole("shape");
313 roleMap
[accessibility::AccessibleRole::TEXT_FRAME
] = registerRole("text frame");
314 roleMap
[accessibility::AccessibleRole::IMAGE_MAP
] = registerRole("image map");
315 roleMap
[accessibility::AccessibleRole::NOTE
] = registerRole("note");
316 roleMap
[accessibility::AccessibleRole::TREE_ITEM
] = registerRole("tree item");
321 static const sal_Int32 nMapSize
= sizeof(roleMap
)/sizeof(sal_Int16
);
322 if( 0 <= nRole
&& nMapSize
> nRole
)
323 role
= roleMap
[nRole
];
329 /*****************************************************************************/
333 /*****************************************************************************/
335 static G_CONST_RETURN gchar
*
336 wrapper_get_name( AtkObject
*atk_obj
)
338 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
344 rtl::OUStringToOString(
345 obj
->mpContext
->getAccessibleName(),
346 RTL_TEXTENCODING_UTF8
);
348 int nCmp
= atk_obj
->name
? rtl_str_compare( atk_obj
->name
, aName
.getStr() ) : -1;
352 g_free(atk_obj
->name
);
353 atk_obj
->name
= g_strdup(aName
.getStr());
356 catch(const uno::Exception
& e
) {
357 g_warning( "Exception in getAccessibleName()" );
361 return ATK_OBJECT_CLASS (parent_class
)->get_name(atk_obj
);
364 /*****************************************************************************/
366 static G_CONST_RETURN gchar
*
367 wrapper_get_description( AtkObject
*atk_obj
)
369 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
374 rtl::OString aDescription
=
375 rtl::OUStringToOString(
376 obj
->mpContext
->getAccessibleDescription(),
377 RTL_TEXTENCODING_UTF8
);
379 g_free(atk_obj
->description
);
380 atk_obj
->description
= g_strdup(aDescription
.getStr());
382 catch(const uno::Exception
& e
) {
383 g_warning( "Exception in getAccessibleDescription()" );
387 return ATK_OBJECT_CLASS (parent_class
)->get_description(atk_obj
);
391 /*****************************************************************************/
394 wrapper_get_n_children( AtkObject
*atk_obj
)
396 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
402 n
= obj
->mpContext
->getAccessibleChildCount();
404 catch(const uno::Exception
& e
) {
405 OSL_ENSURE(0, "Exception in getAccessibleChildCount()" );
412 /*****************************************************************************/
415 wrapper_ref_child( AtkObject
*atk_obj
,
418 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
419 AtkObject
* child
= NULL
;
421 // see comments above atk_object_wrapper_remove_child
422 if( -1 < i
&& obj
->index_of_child_about_to_be_removed
== i
)
424 g_object_ref( obj
->child_about_to_be_removed
);
425 return obj
->child_about_to_be_removed
;
431 uno::Reference
< accessibility::XAccessible
> xAccessible
=
432 obj
->mpContext
->getAccessibleChild( i
);
434 child
= atk_object_wrapper_ref( xAccessible
);
436 catch(const uno::Exception
& e
) {
437 OSL_ENSURE(0, "Exception in getAccessibleChild");
444 /*****************************************************************************/
447 wrapper_get_index_in_parent( AtkObject
*atk_obj
)
449 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
455 i
= obj
->mpContext
->getAccessibleIndexInParent();
457 #ifdef ENABLE_TRACING
458 fprintf(stderr
, "%p->getAccessibleIndexInParent() returned: %u\n",
459 obj
->mpAccessible
, i
);
462 catch(const uno::Exception
& e
) {
463 g_warning( "Exception in getAccessibleIndexInParent()" );
469 /*****************************************************************************/
471 static AtkRelationSet
*
472 wrapper_ref_relation_set( AtkObject
*atk_obj
)
474 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
475 AtkRelationSet
*pSet
= atk_relation_set_new();
480 uno::Reference
< accessibility::XAccessibleRelationSet
> xRelationSet(
481 obj
->mpContext
->getAccessibleRelationSet()
484 sal_Int32 nRelations
= xRelationSet
.is() ? xRelationSet
->getRelationCount() : 0;
485 for( sal_Int32 n
= 0; n
< nRelations
; n
++ )
487 accessibility::AccessibleRelation aRelation
= xRelationSet
->getRelation( n
);
488 sal_uInt32 nTargetCount
= aRelation
.TargetSet
.getLength();
489 AtkObject
**pTargets
= (AtkObject
**) alloca( nTargetCount
* sizeof(AtkObject
*) );
491 for( sal_uInt32 i
= 0; i
< nTargetCount
; i
++ )
493 uno::Reference
< accessibility::XAccessible
> xAccessible(
494 aRelation
.TargetSet
[i
], uno::UNO_QUERY
);
495 pTargets
[i
] = atk_object_wrapper_ref( xAccessible
);
500 pTargets
, nTargetCount
,
501 mapRelationType( aRelation
.RelationType
)
503 atk_relation_set_add( pSet
, pRel
);
504 g_object_unref( G_OBJECT( pRel
) );
507 catch(const uno::Exception
&e
) {
508 g_object_unref( G_OBJECT( pSet
) );
516 /*****************************************************************************/
521 const sal_Char
* name
;
522 } aStateTypeTable
[] = {
523 { accessibility::AccessibleStateType::INVALID
, "INVALID" },
524 { accessibility::AccessibleStateType::ACTIVE
, "ACTIVE" },
525 { accessibility::AccessibleStateType::ARMED
, "ARMED" },
526 { accessibility::AccessibleStateType::BUSY
, "BUSY" },
527 { accessibility::AccessibleStateType::CHECKED
, "CHECKED" },
528 { accessibility::AccessibleStateType::DEFUNC
, "DEFUNC" },
529 { accessibility::AccessibleStateType::EDITABLE
, "EDITABLE" },
530 { accessibility::AccessibleStateType::ENABLED
, "ENABLED" },
531 { accessibility::AccessibleStateType::EXPANDABLE
, "EXPANDABLE" },
532 { accessibility::AccessibleStateType::EXPANDED
, "EXPANDED" },
533 { accessibility::AccessibleStateType::FOCUSABLE
, "FOCUSABLE" },
534 { accessibility::AccessibleStateType::FOCUSED
, "FOCUSED" },
535 { accessibility::AccessibleStateType::HORIZONTAL
, "HORIZONTAL" },
536 { accessibility::AccessibleStateType::ICONIFIED
, "ICONIFIED" },
537 { accessibility::AccessibleStateType::INDETERMINATE
, "INDETERMINATE" },
538 { accessibility::AccessibleStateType::MANAGES_DESCENDANTS
, "MANAGES_DESCENDANTS" },
539 { accessibility::AccessibleStateType::MODAL
, "MODAL" },
540 { accessibility::AccessibleStateType::MULTI_LINE
, "MULTI_LINE" },
541 { accessibility::AccessibleStateType::MULTI_SELECTABLE
, "MULTI_SELECTABLE" },
542 { accessibility::AccessibleStateType::OPAQUE
, "OPAQUE" },
543 { accessibility::AccessibleStateType::PRESSED
, "PRESSED" },
544 { accessibility::AccessibleStateType::RESIZABLE
, "RESIZABLE" },
545 { accessibility::AccessibleStateType::SELECTABLE
, "SELECTABLE" },
546 { accessibility::AccessibleStateType::SELECTED
, "SELECTED" },
547 { accessibility::AccessibleStateType::SENSITIVE
, "SENSITIVE" },
548 { accessibility::AccessibleStateType::SHOWING
, "SHOWING" },
549 { accessibility::AccessibleStateType::SINGLE_LINE
, "SINGLE_LINE" },
550 { accessibility::AccessibleStateType::STALE
, "STALE" },
551 { accessibility::AccessibleStateType::TRANSIENT
, "TRANSIENT" },
552 { accessibility::AccessibleStateType::VERTICAL
, "VERTICAL" },
553 { accessibility::AccessibleStateType::VISIBLE
, "VISIBLE" }
556 static void printStates(const uno::Sequence
<sal_Int16
>& rStates
)
558 sal_Int32 n
= rStates
.getLength();
559 size_t nTypes
= sizeof(aStateTypeTable
)/sizeof(aStateTypeTable
[0]);
560 for (sal_Int32 i
= 0; i
< n
; ++i
)
562 for (size_t j
= 0; j
< nTypes
; ++j
)
564 if (aStateTypeTable
[j
].value
== rStates
[i
])
565 printf("%s ", aStateTypeTable
[j
].name
);
573 wrapper_ref_state_set( AtkObject
*atk_obj
)
575 AtkObjectWrapper
*obj
= ATK_OBJECT_WRAPPER (atk_obj
);
576 AtkStateSet
*pSet
= atk_state_set_new();
581 uno::Reference
< accessibility::XAccessibleStateSet
> xStateSet(
582 obj
->mpContext
->getAccessibleStateSet());
586 uno::Sequence
< sal_Int16
> aStates
= xStateSet
->getStates();
588 for( sal_Int32 n
= 0; n
< aStates
.getLength(); n
++ )
589 atk_state_set_add_state( pSet
, mapAtkState( aStates
[n
] ) );
591 // We need to emulate FOCUS state for menus, menu-items etc.
592 if( atk_obj
== atk_get_focus_object() )
593 atk_state_set_add_state( pSet
, ATK_STATE_FOCUSED
);
594 /* FIXME - should we do this ?
596 atk_state_set_remove_state( pSet, ATK_STATE_FOCUSED );
601 catch(const uno::Exception
&e
) {
602 g_warning( "Exception in wrapper_ref_state_set" );
603 atk_state_set_add_state( pSet
, ATK_STATE_DEFUNCT
);
607 atk_state_set_add_state( pSet
, ATK_STATE_DEFUNCT
);
612 /*****************************************************************************/
616 atk_object_wrapper_finalize (GObject
*obj
)
618 AtkObjectWrapper
*pWrap
= ATK_OBJECT_WRAPPER (obj
);
620 if( pWrap
->mpAccessible
)
622 ooo_wrapper_registry_remove( pWrap
->mpAccessible
);
623 pWrap
->mpAccessible
->release();
624 pWrap
->mpAccessible
= NULL
;
627 atk_object_wrapper_dispose( pWrap
);
629 parent_class
->finalize( obj
);
633 atk_object_wrapper_class_init (AtkObjectWrapperClass
*klass
)
635 GObjectClass
*gobject_class
= G_OBJECT_CLASS( klass
);
636 AtkObjectClass
*atk_class
= ATK_OBJECT_CLASS( klass
);
638 parent_class
= (GObjectClass
*) g_type_class_peek_parent (klass
);
641 gobject_class
->finalize
= atk_object_wrapper_finalize
;
644 atk_class
->get_name
= wrapper_get_name
;
645 atk_class
->get_description
= wrapper_get_description
;
646 atk_class
->get_n_children
= wrapper_get_n_children
;
647 atk_class
->ref_child
= wrapper_ref_child
;
648 atk_class
->get_index_in_parent
= wrapper_get_index_in_parent
;
649 atk_class
->ref_relation_set
= wrapper_ref_relation_set
;
650 atk_class
->ref_state_set
= wrapper_ref_state_set
;
654 atk_object_wrapper_init (AtkObjectWrapper
*wrapper
,
655 AtkObjectWrapperClass
)
657 wrapper
->mpAction
= NULL
;
658 wrapper
->mpComponent
= NULL
;
659 wrapper
->mpEditableText
= NULL
;
660 wrapper
->mpHypertext
= NULL
;
661 wrapper
->mpImage
= NULL
;
662 wrapper
->mpSelection
= NULL
;
663 wrapper
->mpTable
= NULL
;
664 wrapper
->mpText
= NULL
;
665 wrapper
->mpValue
= NULL
;
671 atk_object_wrapper_get_type (void)
673 static GType type
= 0;
677 static const GTypeInfo typeInfo
=
679 sizeof (AtkObjectWrapperClass
),
680 (GBaseInitFunc
) NULL
,
681 (GBaseFinalizeFunc
) NULL
,
682 (GClassInitFunc
) atk_object_wrapper_class_init
,
683 (GClassFinalizeFunc
) NULL
,
685 sizeof (AtkObjectWrapper
),
687 (GInstanceInitFunc
) atk_object_wrapper_init
,
690 type
= g_type_register_static (ATK_TYPE_OBJECT
,
692 &typeInfo
, (GTypeFlags
)0) ;
698 isOfType( uno::XInterface
*pInterface
, const uno::Type
& rType
)
700 g_return_val_if_fail( pInterface
!= NULL
, false );
704 uno::Any aRet
= pInterface
->queryInterface( rType
);
706 bIs
= ( ( typelib_TypeClass_INTERFACE
== aRet
.pType
->eTypeClass
) &&
707 ( aRet
.pReserved
!= NULL
) );
708 } catch( const uno::Exception
&e
) { }
714 typedef GType (* GetGIfaceType
) (void);
718 GInterfaceInitFunc aInit
;
719 GetGIfaceType aGetGIfaceType
;
720 const uno::Type
& (*aGetUnoType
) (void *);
722 // re-location heaven:
724 "Comp", (GInterfaceInitFunc
) componentIfaceInit
,
725 atk_component_get_type
,
726 accessibility::XAccessibleComponent::static_type
729 "Act", (GInterfaceInitFunc
) actionIfaceInit
,
731 accessibility::XAccessibleAction::static_type
734 "Txt", (GInterfaceInitFunc
) textIfaceInit
,
736 accessibility::XAccessibleText::static_type
739 "Val", (GInterfaceInitFunc
) valueIfaceInit
,
741 accessibility::XAccessibleValue::static_type
744 "Tab", (GInterfaceInitFunc
) tableIfaceInit
,
746 accessibility::XAccessibleTable::static_type
749 "Edt", (GInterfaceInitFunc
) editableTextIfaceInit
,
750 atk_editable_text_get_type
,
751 accessibility::XAccessibleEditableText::static_type
754 "Img", (GInterfaceInitFunc
) imageIfaceInit
,
756 accessibility::XAccessibleImage::static_type
759 "Hyp", (GInterfaceInitFunc
) hypertextIfaceInit
,
760 atk_hypertext_get_type
,
761 accessibility::XAccessibleHypertext::static_type
764 "Sel", (GInterfaceInitFunc
) selectionIfaceInit
,
765 atk_selection_get_type
,
766 accessibility::XAccessibleSelection::static_type
768 // AtkDocument is a nastily broken interface (so far)
769 // we could impl. get_document_type perhaps though.
772 const int aTypeTableSize
= G_N_ELEMENTS( aTypeTable
);
775 ensureTypeFor( uno::XInterface
*pAccessible
)
778 int bTypes
[ aTypeTableSize
] = { 0, };
779 rtl::OString
aTypeName( "OOoAtkObj" );
781 for( i
= 0; i
< aTypeTableSize
; i
++ )
783 if( isOfType( pAccessible
, aTypeTable
[i
].aGetUnoType(0) ) )
785 aTypeName
+= aTypeTable
[i
].name
;
788 // g_message( "Accessible %p has type '%s' (%d)",
789 // pAccessible, aTypeTable[i].name, bTypes[i] );
792 GType nType
= g_type_from_name( aTypeName
);
793 if( nType
== G_TYPE_INVALID
)
795 GTypeInfo aTypeInfo
= {
796 sizeof( AtkObjectWrapperClass
),
797 NULL
, NULL
, NULL
, NULL
, NULL
,
798 sizeof( AtkObjectWrapper
),
801 nType
= g_type_register_static( ATK_TYPE_OBJECT_WRAPPER
,
802 aTypeName
, &aTypeInfo
, (GTypeFlags
)0 ) ;
804 for( int j
= 0; j
< aTypeTableSize
; j
++ )
807 GInterfaceInfo aIfaceInfo
= { NULL
, NULL
, NULL
};
808 aIfaceInfo
.interface_init
= aTypeTable
[j
].aInit
;
809 g_type_add_interface_static (nType
, aTypeTable
[j
].aGetGIfaceType(),
817 atk_object_wrapper_ref( const uno::Reference
< accessibility::XAccessible
> &rxAccessible
, bool create
)
819 g_return_val_if_fail( rxAccessible
.get() != NULL
, NULL
);
821 AtkObject
*obj
= ooo_wrapper_registry_get(rxAccessible
);
829 return atk_object_wrapper_new( rxAccessible
);
836 atk_object_wrapper_new( const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& rxAccessible
,
839 g_return_val_if_fail( rxAccessible
.get() != NULL
, NULL
);
841 AtkObjectWrapper
*pWrap
= NULL
;
844 uno::Reference
< accessibility::XAccessibleContext
> xContext(rxAccessible
->getAccessibleContext());
846 g_return_val_if_fail( xContext
.get() != NULL
, NULL
);
848 GType nType
= ensureTypeFor( xContext
.get() );
849 gpointer obj
= g_object_new( nType
, NULL
);
851 pWrap
= ATK_OBJECT_WRAPPER( obj
);
852 pWrap
->mpAccessible
= rxAccessible
.get();
853 rxAccessible
->acquire();
855 pWrap
->index_of_child_about_to_be_removed
= -1;
856 pWrap
->child_about_to_be_removed
= NULL
;
859 pWrap
->mpContext
= xContext
.get();
861 AtkObject
* atk_obj
= ATK_OBJECT(pWrap
);
862 atk_obj
->role
= mapToAtkRole( xContext
->getAccessibleRole() );
863 atk_obj
->accessible_parent
= parent
;
865 ooo_wrapper_registry_add( rxAccessible
, atk_obj
);
868 g_object_ref( atk_obj
->accessible_parent
);
871 /* gail_focus_tracker remembers the focused object at the first
872 * parent in the hierachy that is a Gtk+ widget, but at the time the
873 * event gets processed (at idle), it may be too late to create the
874 * hierachy, so doing it now ..
876 uno::Reference
< accessibility::XAccessible
> xParent( xContext
->getAccessibleParent() );
878 /* The top-level objects should never be of this class */
879 OSL_ASSERT( xParent
.is() );
882 atk_obj
->accessible_parent
= atk_object_wrapper_ref( xParent
);
885 // Attach a listener to the UNO object if it's not TRANSIENT
886 uno::Reference
< accessibility::XAccessibleStateSet
> xStateSet( xContext
->getAccessibleStateSet() );
887 if( xStateSet
.is() && ! xStateSet
->contains( accessibility::AccessibleStateType::TRANSIENT
) )
889 uno::Reference
< accessibility::XAccessibleEventBroadcaster
> xBroadcaster(xContext
, uno::UNO_QUERY
);
890 if( xBroadcaster
.is() )
891 xBroadcaster
->addEventListener( static_cast< accessibility::XAccessibleEventListener
* > ( new AtkListener(pWrap
) ) );
896 return ATK_OBJECT( pWrap
);
898 catch (const uno::Exception
&e
)
901 g_object_unref( pWrap
);
908 /*****************************************************************************/
910 void atk_object_wrapper_add_child(AtkObjectWrapper
* wrapper
, AtkObject
*child
, gint index
)
912 AtkObject
*atk_obj
= ATK_OBJECT( wrapper
);
914 atk_object_set_parent( child
, atk_obj
);
915 g_signal_emit_by_name( atk_obj
, "children_changed::add", index
, child
, NULL
);
918 /*****************************************************************************/
920 void atk_object_wrapper_remove_child(AtkObjectWrapper
* wrapper
, AtkObject
*child
, gint index
)
923 * the atk-bridge GTK+ module get's back to the event source to ref the child just
924 * vanishing, so we keep this reference because the semantic on OOo side is different.
926 wrapper
->child_about_to_be_removed
= child
;
927 wrapper
->index_of_child_about_to_be_removed
= index
;
929 g_signal_emit_by_name( ATK_OBJECT( wrapper
), "children_changed::remove", index
, child
, NULL
);
931 wrapper
->index_of_child_about_to_be_removed
= -1;
932 wrapper
->child_about_to_be_removed
= NULL
;
935 /*****************************************************************************/
937 #define RELEASE(i) if( i ) { i->release(); i = NULL; }
939 void atk_object_wrapper_dispose(AtkObjectWrapper
* wrapper
)
941 RELEASE( wrapper
->mpContext
)
942 RELEASE( wrapper
->mpAction
)
943 RELEASE( wrapper
->mpComponent
)
944 RELEASE( wrapper
->mpEditableText
)
945 RELEASE( wrapper
->mpHypertext
)
946 RELEASE( wrapper
->mpImage
)
947 RELEASE( wrapper
->mpSelection
)
948 RELEASE( wrapper
->mpMultiLineText
)
949 RELEASE( wrapper
->mpTable
)
950 RELEASE( wrapper
->mpText
)
951 RELEASE( wrapper
->mpTextMarkup
)
952 RELEASE( wrapper
->mpTextAttributes
)
953 RELEASE( wrapper
->mpValue
)