1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package org.openoffice.java.accessibility;
25 
26 import javax.accessibility.AccessibleContext;
27 import javax.accessibility.AccessibleText;
28 
29 import com.sun.star.uno.*;
30 import com.sun.star.accessibility.*;
31 
32 /**
33  */
34 public class Paragraph extends Container implements javax.accessibility.Accessible {
35 
Paragraph(XAccessible xAccessible, XAccessibleContext xAccessibleContext)36     protected Paragraph(XAccessible xAccessible, XAccessibleContext xAccessibleContext) {
37         super(javax.accessibility.AccessibleRole.TEXT, xAccessible, xAccessibleContext);
38     }
39 
40     protected class AccessibleParagraphListener extends AccessibleContainerListener {
41 
AccessibleParagraphListener()42         protected AccessibleParagraphListener() {
43             super();
44         }
45 
setComponentState(short state, boolean enable)46         protected void setComponentState(short state, boolean enable) {
47             switch (state) {
48                 case AccessibleStateType.EDITABLE:
49                     fireStatePropertyChange(javax.accessibility.AccessibleState.EDITABLE, enable);
50                     break;
51                 case AccessibleStateType.MULTI_LINE:
52                     fireStatePropertyChange(javax.accessibility.AccessibleState.MULTI_LINE, enable);
53                     break;
54                 case AccessibleStateType.SINGLE_LINE:
55                     break;
56                 default:
57                     super.setComponentState(state, enable);
58                     break;
59             }
60         }
61 
62 
handleVisibleDataChanged()63         protected void handleVisibleDataChanged() {
64             if (Paragraph.this.isFocusOwner()) {
65                 AccessibleContext ac = accessibleContext;
66                 if (ac != null) {
67                     AccessibleText at = ac.getAccessibleText();
68                     if (at != null) {
69                         int pos = at.getCaretPosition();
70                         // Simulating a caret event here should help at tools
71                         // that re not aware of the paragraph approach of OOo.
72                         firePropertyChange(ac.ACCESSIBLE_CARET_PROPERTY,
73                             new Integer(-1), new Integer(pos));
74                     }
75                 }
76             }
77         }
78 
79         /** Called by OpenOffice process to notify property changes */
notifyEvent(AccessibleEventObject event)80         public void notifyEvent(AccessibleEventObject event) {
81             switch (event.EventId) {
82                 case AccessibleEventId.CARET_CHANGED:
83                     firePropertyChange(accessibleContext.ACCESSIBLE_CARET_PROPERTY,
84                         Component.toNumber(event.OldValue),
85                         Component.toNumber(event.NewValue));
86                     break;
87                 case AccessibleEventId.VISIBLE_DATA_CHANGED:
88                 case AccessibleEventId.BOUNDRECT_CHANGED:
89                     // Whenever a paragraph gets inserted above the currently
90                     // focused one, this is the only event that will occur for.
91                     handleVisibleDataChanged();
92                 default:
93                     super.notifyEvent(event);
94                 break;
95             }
96         }
97     }
98 
createEventListener()99     protected XAccessibleEventListener createEventListener() {
100         return new AccessibleParagraphListener();
101     }
102 
103     /** Creates the AccessibleContext associated with this object */
createAccessibleContext()104     public javax.accessibility.AccessibleContext createAccessibleContext() {
105         return new AccessibleParagraph();
106     }
107 
108     protected class AccessibleParagraph extends AccessibleContainer {
109 
AccessibleParagraph()110         protected AccessibleParagraph() {
111             // Don't do the queryInterface on XAccessibleText already ..
112             super(false);
113             /* Since getAccessibleText() is heavily used by the java access
114              * bridge for gnome and the gnome at-tools, we do a query interface
115              * here and remember the result.
116              */
117             accessibleText = AccessibleHypertextImpl.get(unoAccessibleContext);
118         }
119 
120         /*
121         * AccessibleContext
122         */
123 
124         /** Gets the role of this object */
getAccessibleRole()125         public javax.accessibility.AccessibleRole getAccessibleRole() {
126             return javax.accessibility.AccessibleRole.TEXT;
127         }
128 
129         /** Gets the AccessibleEditableText associated with this object presenting text on the display */
getAccessibleEditableText()130         public javax.accessibility.AccessibleEditableText getAccessibleEditableText() {
131 
132             if (disposed)
133                 return null;
134 
135             try {
136                 XAccessibleEditableText unoAccessibleText = (XAccessibleEditableText)
137                     UnoRuntime.queryInterface(XAccessibleEditableText.class,
138                     unoAccessibleComponent);
139                 if (unoAccessibleText != null) {
140                     return new AccessibleEditableTextImpl(unoAccessibleText);
141                 } else {
142                     return null;
143                 }
144             } catch (com.sun.star.uno.RuntimeException e) {
145                 return null;
146             }
147         }
148 
149         /** Gets the AccessibleAction associated with this object that has a graphical representation */
getAccessibleAction()150         public javax.accessibility.AccessibleAction getAccessibleAction() {
151             try {
152                 XAccessibleAction unoAccessibleAction = (XAccessibleAction)
153                     UnoRuntime.queryInterface(XAccessibleAction.class, unoAccessibleComponent);
154                 return (unoAccessibleAction != null) ?
155                     new AccessibleActionImpl(unoAccessibleAction) : null;
156             } catch (com.sun.star.uno.RuntimeException e) {
157                 return null;
158             }
159         }
160 
161         /** Returns the relation set of this object */
getAccessibleRelationSet()162         public javax.accessibility.AccessibleRelationSet getAccessibleRelationSet() {
163             try {
164                 XAccessibleRelationSet unoAccessibleRelationSet =
165                     unoAccessible.getAccessibleContext().getAccessibleRelationSet();
166                 if (unoAccessibleRelationSet == null) {
167                     return super.getAccessibleRelationSet();
168                 }
169 
170                 javax.accessibility.AccessibleRelationSet relationSet = new javax.accessibility.AccessibleRelationSet();
171                 int count = unoAccessibleRelationSet.getRelationCount();
172                 for (int i = 0; i < count; i++) {
173                     AccessibleRelation unoAccessibleRelation = unoAccessibleRelationSet.getRelation(i);
174                     switch (unoAccessibleRelation.RelationType) {
175                         case AccessibleRelationType.CONTROLLED_BY:
176                             relationSet.add(new javax.accessibility.AccessibleRelation(
177                                 javax.accessibility.AccessibleRelation.CONTROLLED_BY,
178                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
179                             break;
180                         case AccessibleRelationType.CONTROLLER_FOR:
181                             relationSet.add(new javax.accessibility.AccessibleRelation(
182                                 javax.accessibility.AccessibleRelation.CONTROLLER_FOR,
183                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
184                             break;
185                         case AccessibleRelationType.LABELED_BY:
186                             relationSet.add(new javax.accessibility.AccessibleRelation(
187                                 javax.accessibility.AccessibleRelation.LABELED_BY,
188                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
189                             break;
190                         case AccessibleRelationType.MEMBER_OF:
191                             relationSet.add(new javax.accessibility.AccessibleRelation(
192                                 javax.accessibility.AccessibleRelation.MEMBER_OF,
193                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
194                             break;
195                         case AccessibleRelationType.CONTENT_FLOWS_TO:
196                             relationSet.add(new javax.accessibility.AccessibleRelation(
197                                 "flowsTo",
198                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
199                             break;
200                         case AccessibleRelationType.CONTENT_FLOWS_FROM:
201                             relationSet.add(new javax.accessibility.AccessibleRelation(
202                                 "flowsFrom",
203                                 getAccessibleComponents(unoAccessibleRelation.TargetSet)));
204                             break;
205                         default:
206                             break;
207                     }
208                 }
209                 return relationSet;
210             } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
211                 return super.getAccessibleRelationSet();
212             } catch (com.sun.star.uno.RuntimeException e) {
213                 return super.getAccessibleRelationSet();
214             }
215         }
216     }
217 }
218 
219