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 AOO.
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