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 * AccEditableText.cpp : Implementation of CUAccCOMApp and DLL registration.
24 */
25 #include "stdafx.h"
26 #include "UAccCOM2.h"
27 #include "AccEditableText.h"
28 #include <com/sun/star/accessibility/XAccessible.hpp>
29 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
30 #include <com/sun/star/accessibility/XAccessibleText.hpp>
31 #include <com/sun/star/awt/FontSlant.hpp>
32 #include <com/sun/star/beans/PropertyValue.hpp>
33 #include <com/sun/star/style/LineSpacing.hpp>
34 #include <com/sun/star/style/TabStop.hpp>
35 #include <vector>
36
37 using namespace com::sun::star::accessibility;
38 using namespace com::sun::star::uno;
39 using namespace com::sun::star::awt;
40 using namespace com::sun::star::beans;
41 using namespace std;
42
43 /**
44 * Copys a range of text to the clipboard.
45 *
46 * @param startOffset the start offset of copying.
47 * @param endOffset the end offset of copying.
48 * @param success the boolean result to be returned.
49 */
copyText(long startOffset,long endOffset)50 STDMETHODIMP CAccEditableText::copyText(long startOffset, long endOffset)
51 {
52
53 CHECK_ENABLE_INF
54
55 ENTER_PROTECTED_BLOCK
56
57 // #CHECK XInterface#
58 if(!pRXEdtTxt.is())
59 {
60 return E_FAIL;
61 }
62
63 if ( GetXInterface()->copyText( startOffset, endOffset ) )
64 return S_OK;
65
66 return E_FAIL;
67
68 LEAVE_PROTECTED_BLOCK
69 }
70
71 /**
72 * Deletes a range of text.
73 *
74 * @param startOffset the start offset of deleting.
75 * @param endOffset the end offset of deleting.
76 * @param success the boolean result to be returned.
77 */
deleteText(long startOffset,long endOffset)78 STDMETHODIMP CAccEditableText::deleteText(long startOffset, long endOffset)
79 {
80
81 CHECK_ENABLE_INF
82
83 ENTER_PROTECTED_BLOCK
84
85 if( !pRXEdtTxt.is() )
86 return E_FAIL;
87
88 if( GetXInterface()->deleteText( startOffset, endOffset ) )
89 return S_OK;
90
91 return E_FAIL;
92
93 LEAVE_PROTECTED_BLOCK
94 }
95
96 /**
97 * Inserts text at a specified offset.
98 *
99 * @param offset the offset of inserting.
100 * @param text the text to be inserted.
101 * @param success the boolean result to be returned.
102 */
insertText(long offset,BSTR * text)103 STDMETHODIMP CAccEditableText::insertText(long offset, BSTR * text)
104 {
105
106 CHECK_ENABLE_INF
107
108 ENTER_PROTECTED_BLOCK
109
110 if (text == NULL)
111 return E_INVALIDARG;
112
113 if( !pRXEdtTxt.is() )
114 return E_FAIL;
115
116 ::rtl::OUString ouStr(*text);
117
118 if( GetXInterface()->insertText( ouStr, offset ) )
119 return S_OK;
120
121 return E_FAIL;
122
123 LEAVE_PROTECTED_BLOCK
124 }
125
126 /**
127 * Cuts a range of text to the clipboard.
128 *
129 * @param startOffset the start offset of cuting.
130 * @param endOffset the end offset of cuting.
131 * @param success the boolean result to be returned.
132 */
cutText(long startOffset,long endOffset)133 STDMETHODIMP CAccEditableText::cutText(long startOffset, long endOffset)
134 {
135
136 CHECK_ENABLE_INF
137
138 ENTER_PROTECTED_BLOCK
139
140 if( !pRXEdtTxt.is() )
141 return E_FAIL;
142
143 if( GetXInterface()->cutText( startOffset, endOffset ) )
144 return S_OK;
145
146 return E_FAIL;
147
148 LEAVE_PROTECTED_BLOCK
149 }
150
151 /**
152 * Pastes text from clipboard at specified offset.
153 *
154 * @param offset the offset of pasting.
155 * @param success the boolean result to be returned.
156 */
pasteText(long offset)157 STDMETHODIMP CAccEditableText::pasteText(long offset)
158 {
159
160 CHECK_ENABLE_INF
161
162 ENTER_PROTECTED_BLOCK
163
164 if( !pRXEdtTxt.is() )
165 return E_FAIL;
166
167 if( GetXInterface()->pasteText( offset ) )
168 return S_OK;
169
170 return E_FAIL;
171
172 LEAVE_PROTECTED_BLOCK
173 }
174
175 /**
176 * Replaces range of text with new text.
177 *
178 * @param startOffset the start offset of replacing.
179 * @param endOffset the end offset of replacing.
180 * @param text the replacing text.
181 * @param success the boolean result to be returned.
182 */
replaceText(long startOffset,long endOffset,BSTR * text)183 STDMETHODIMP CAccEditableText::replaceText(long startOffset, long endOffset, BSTR * text)
184 {
185
186 CHECK_ENABLE_INF
187
188 ENTER_PROTECTED_BLOCK
189
190 // #CHECK#
191 if (text == NULL)
192 return E_INVALIDARG;
193 if( !pRXEdtTxt.is() )
194 return E_FAIL;
195
196 ::rtl::OUString ouStr(*text);
197
198 if( GetXInterface()->replaceText( startOffset,endOffset, ouStr) )
199 return S_OK;
200 return E_FAIL;
201
202 LEAVE_PROTECTED_BLOCK
203 }
204
205 /**
206 * Sets attributes of range of text.
207 *
208 * @param startOffset the start offset.
209 * @param endOffset the end offset.
210 * @param attributes the attribute text.
211 * @param success the boolean result to be returned.
212 */
setAttributes(long startOffset,long endOffset,BSTR * attributes)213 STDMETHODIMP CAccEditableText::setAttributes(long startOffset, long endOffset, BSTR * attributes)
214 {
215
216 CHECK_ENABLE_INF
217
218 ENTER_PROTECTED_BLOCK
219
220 // #CHECK#
221 if (attributes == NULL)
222 return E_INVALIDARG;
223 if( !pRXEdtTxt.is() )
224 return E_FAIL;
225
226 ::rtl::OUString ouStr(*attributes);
227
228 sal_Int32 nIndex = 0;
229 sal_Unicode cTok = ';';
230 vector< ::rtl::OUString > vecAttr;
231 do
232 {
233 ::rtl::OUString ouToken = ouStr.getToken(0, cTok, nIndex);
234 vecAttr.push_back(ouToken);
235 }
236 while(nIndex >= 0);
237
238 Sequence< PropertyValue > beanSeq(vecAttr.size());
239 for(unsigned int i = 0; i < vecAttr.size(); i ++)
240 {
241 ::rtl::OUString attr = vecAttr[i];
242 sal_Int32 nPos = attr.indexOf(':');
243 if(nPos > -1)
244 {
245 ::rtl::OUString attrName = attr.copy(0, nPos);
246 ::rtl::OUString attrValue = attr.copy(nPos + 1, attr.getLength() - nPos - 1);
247 beanSeq[i].Name = attrName;
248 get_AnyFromOLECHAR(attrName, attrValue, beanSeq[i].Value);
249 }
250 }
251
252 if( GetXInterface()->setAttributes( startOffset,endOffset, beanSeq) )
253 return S_OK;
254
255 return E_FAIL;
256
257 LEAVE_PROTECTED_BLOCK
258 }
259
260 /**
261 * Convert attributes string to Any type.
262 * Reference to infra\accessibility\bridge\org\openoffice\java\accessibility\AccessibleTextImpl.java
263 *
264 * @param ouName the string of attribute name.
265 * @param ouValue the string of attribute value.
266 * @param rAny the Any object to be returned.
267 */
get_AnyFromOLECHAR(const::rtl::OUString & ouName,const::rtl::OUString & ouValue,Any & rAny)268 void CAccEditableText::get_AnyFromOLECHAR(const ::rtl::OUString &ouName, const ::rtl::OUString &ouValue, Any &rAny)
269 {
270 if(ouName.compareTo(L"CharBackColor") == 0 ||
271 ouName.compareTo(L"CharColor") == 0 ||
272 ouName.compareTo(L"ParaAdjust") == 0 ||
273 ouName.compareTo(L"ParaFirstLineIndent") == 0 ||
274 ouName.compareTo(L"ParaLeftMargin") == 0 ||
275 ouName.compareTo(L"ParaRightMargin") == 0 ||
276 ouName.compareTo(L"ParaTopMargin") == 0 ||
277 ouName.compareTo(L"ParaBottomMargin") == 0 ||
278 ouName.compareTo(L"CharFontPitch") == 0)
279 {
280 // Convert to int.
281 // NOTE: CharFontPitch is not implemented in java file.
282 sal_Int32 nValue = ouValue.toInt32();
283 rAny.setValue(&nValue, getCppuType((sal_Int32 *)0));
284 }
285 else if(ouName.compareTo(L"CharShadowed") == 0 ||
286 ouName.compareTo(L"CharContoured") == 0)
287 {
288 // Convert to boolean.
289 boolean nValue = (boolean)ouValue.toBoolean();
290 rAny.setValue(&nValue, getCppuType((sal_Bool *)sal_False));
291 }
292 else if(ouName.compareTo(L"CharEscapement") == 0 ||
293 ouName.compareTo(L"CharStrikeout") == 0 ||
294 ouName.compareTo(L"CharUnderline") == 0 ||
295 ouName.compareTo(L"CharFontPitch") == 0)
296 {
297 // Convert to short.
298 short nValue = (short)ouValue.toInt32();
299 rAny.setValue(&nValue, getCppuType((short *)0));
300 }
301 else if(ouName.compareTo(L"CharHeight") == 0 ||
302 ouName.compareTo(L"CharWeight") == 0)
303 {
304 // Convert to float.
305 float fValue = ouValue.toFloat();
306 rAny.setValue(&fValue, getCppuType((float *)0));
307 }
308 else if(ouName.compareTo(L"CharFontName") == 0)
309 {
310 // Convert to string.
311 rAny.setValue(&ouValue, getCppuType((::rtl::OUString *)0));
312 }
313 else if(ouName.compareTo(L"CharPosture") == 0)
314 {
315 // Convert to FontSlant.
316 ::com::sun::star::awt::FontSlant fontSlant = (::com::sun::star::awt::FontSlant)ouValue.toInt32();
317 rAny.setValue(&fontSlant, getCppuType((::com::sun::star::awt::FontSlant*)0));
318 }
319 else if(ouName.compareTo(L"ParaTabStops") == 0)
320 {
321 //
322 // Convert to the Sequence with TabStop element.
323 vector< ::com::sun::star::style::TabStop > vecTabStop;
324 ::com::sun::star::style::TabStop tabStop;
325 ::rtl::OUString ouSubValue;
326 sal_Int32 nIndex = 0;
327 sal_Int32 pos = 0, posComma = 0;
328
329 do
330 {
331 // Position.
332 pos = ouValue.indexOf(L"Position=", pos);
333 if(pos != -1)
334 {
335 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "Position=".
336 if(posComma != -1)
337 {
338 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
339 tabStop.Position = ouSubValue.toInt32();
340 pos = posComma + 1;
341
342 // TabAlign.
343 pos = ouValue.indexOf(L"TabAlign=", pos);
344 if(pos != -1)
345 {
346 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=".
347 if(posComma != -1)
348 {
349 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
350 tabStop.Alignment = (::com::sun::star::style::TabAlign)ouSubValue.toInt32();
351 pos = posComma + 1;
352
353 // DecimalChar.
354 pos = ouValue.indexOf(L"DecimalChar=", pos);
355 if(pos != -1)
356 {
357 posComma = ouValue.indexOf(',', pos + 11); // 11 = length of "TabAlign=".
358 if(posComma != -1)
359 {
360 ouSubValue = ouValue.copy(pos + 11, posComma - pos - 11);
361 tabStop.DecimalChar = (sal_Unicode)ouSubValue.toChar();
362 pos = posComma + 1;
363
364 // FillChar.
365 pos = ouValue.indexOf(L"FillChar=", pos);
366 if(pos != -1)
367 {
368 posComma = ouValue.indexOf(',', pos + 9); // 9 = length of "TabAlign=".
369 if(posComma != -1)
370 {
371 ouSubValue = ouValue.copy(pos + 9, posComma - pos - 9);
372 tabStop.DecimalChar = (sal_Unicode)ouSubValue.toChar();
373 pos = posComma + 1;
374
375 // Complete TabStop element.
376 vecTabStop.push_back(tabStop);
377 }
378 else
379 break; // No match comma.
380 }
381 else
382 break; // No match FillChar.
383 }
384 else
385 break; // No match comma.
386 }
387 else
388 break; // No match DecimalChar.
389 }
390 else
391 break; // No match comma.
392 }
393 else
394 break; // No match TabAlign.
395 }
396 else
397 break; // No match comma.
398 }
399 else
400 break; // No match Position.
401 }
402 while(pos < ouValue.getLength());
403
404 //
405 // Dump into Sequence.
406 int iSeqLen = (vecTabStop.size() == 0) ? 1 : vecTabStop.size();
407 Sequence< ::com::sun::star::style::TabStop > seqTabStop(iSeqLen);
408
409 if(vecTabStop.size() != 0)
410 {
411 // Dump every element.
412 for(int i = 0; i < iSeqLen; i ++)
413 {
414 seqTabStop[i] = vecTabStop[i];
415 }
416 }
417 else
418 {
419 // Create default value.
420 seqTabStop[0].Position = 0;
421 seqTabStop[0].Alignment = ::com::sun::star::style::TabAlign_DEFAULT;
422 seqTabStop[0].DecimalChar = '.';
423 seqTabStop[0].FillChar = ' ';
424 }
425
426 // Assign to Any object.
427 rAny.setValue(&seqTabStop, getCppuType((Sequence< ::com::sun::star::style::TabStop >*)0));
428 }
429 else if(ouName.compareTo(L"ParaLineSpacing") == 0)
430 {
431 // Parse value string.
432 ::com::sun::star::style::LineSpacing lineSpacing;
433 ::rtl::OUString ouSubValue;
434 sal_Int32 pos = 0, posComma = 0;
435
436 pos = ouValue.indexOf(L"Mode=", pos);
437 if(pos != -1)
438 {
439 posComma = ouValue.indexOf(',', pos + 5); // 5 = length of "Mode=".
440 if(posComma != -1)
441 {
442 ouSubValue = ouValue.copy(pos + 5, posComma - pos - 5);
443 lineSpacing.Mode = (sal_Int16)ouSubValue.toInt32();
444 pos = posComma + 1;
445
446 pos = ouValue.indexOf(L"Height=", pos);
447 if(pos != -1)
448 {
449 ouSubValue = ouValue.copy(pos + 7, ouValue.getLength() - pos - 7);
450 lineSpacing.Height = (sal_Int16)ouSubValue.toInt32();
451 }
452 else
453 {
454 lineSpacing.Height = (sal_Int16)100; // Default height.
455 }
456 }
457 else
458 {
459 lineSpacing.Height = (sal_Int16)100; // Default height.
460 }
461 }
462 else
463 {
464 // Default Mode and Height.
465 lineSpacing.Mode = (sal_Int16)0;
466 lineSpacing.Height = (sal_Int16)100; // Default height.
467 }
468
469 // Convert to Any object.
470 rAny.setValue(&lineSpacing, getCppuType((::com::sun::star::style::LineSpacing* )0));
471 }
472 else
473 {
474 // Do nothing.
475 sal_Int32 nDefault = 0;
476 rAny.setValue(&nDefault, getCppuType((sal_Int32 *)0));
477 }
478 }
479
480 /**
481 * Overide of IUNOXWrapper.
482 *
483 * @param pXInterface the pointer of UNO interface.
484 */
put_XInterface(long pXInterface)485 STDMETHODIMP CAccEditableText::put_XInterface(long pXInterface)
486 {
487
488
489 ENTER_PROTECTED_BLOCK
490
491 CUNOXWrapper::put_XInterface(pXInterface);
492 //special query.
493 if(pUNOInterface == NULL)
494 return E_FAIL;
495 Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
496 if( !pRContext.is() )
497 {
498 return E_FAIL;
499 }
500 Reference<XAccessibleEditableText> pRXI(pRContext,UNO_QUERY);
501 if( !pRXI.is() )
502 pRXEdtTxt = NULL;
503 else
504 pRXEdtTxt = pRXI.get();
505 return S_OK;
506
507 LEAVE_PROTECTED_BLOCK
508 }
509