/accessible/src/windows/ia2/ia2AccessibleText.cpp

https://bitbucket.org/avikpal/mozilla-central · C++ · 537 lines · 398 code · 128 blank · 11 comment · 57 complexity · aae08639615093dce374da4eb55d1f77 MD5 · raw file

  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* vim:expandtab:shiftwidth=2:tabstop=2:
  3. */
  4. /* This Source Code Form is subject to the terms of the Mozilla Public
  5. * License, v. 2.0. If a copy of the MPL was not distributed with this
  6. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  7. #include "ia2AccessibleText.h"
  8. #include "Accessible2.h"
  9. #include "AccessibleText_i.c"
  10. #include "HyperTextAccessibleWrap.h"
  11. #include "nsIPersistentProperties2.h"
  12. using namespace mozilla::a11y;
  13. // IAccessibleText
  14. STDMETHODIMP
  15. ia2AccessibleText::addSelection(long aStartOffset, long aEndOffset)
  16. {
  17. A11Y_TRYBLOCK_BEGIN
  18. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  19. if (textAcc->IsDefunct())
  20. return CO_E_OBJNOTCONNECTED;
  21. nsresult rv = textAcc->AddSelection(aStartOffset, aEndOffset);
  22. return GetHRESULT(rv);
  23. A11Y_TRYBLOCK_END
  24. }
  25. STDMETHODIMP
  26. ia2AccessibleText::get_attributes(long aOffset, long *aStartOffset,
  27. long *aEndOffset, BSTR *aTextAttributes)
  28. {
  29. A11Y_TRYBLOCK_BEGIN
  30. if (!aStartOffset || !aEndOffset || !aTextAttributes)
  31. return E_INVALIDARG;
  32. *aStartOffset = 0;
  33. *aEndOffset = 0;
  34. *aTextAttributes = nullptr;
  35. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  36. if (textAcc->IsDefunct())
  37. return CO_E_OBJNOTCONNECTED;
  38. int32_t startOffset = 0, endOffset = 0;
  39. nsCOMPtr<nsIPersistentProperties> attributes;
  40. nsresult rv = textAcc->GetTextAttributes(true, aOffset,
  41. &startOffset, &endOffset,
  42. getter_AddRefs(attributes));
  43. if (NS_FAILED(rv))
  44. return GetHRESULT(rv);
  45. HRESULT hr = AccessibleWrap::ConvertToIA2Attributes(attributes,
  46. aTextAttributes);
  47. if (FAILED(hr))
  48. return hr;
  49. *aStartOffset = startOffset;
  50. *aEndOffset = endOffset;
  51. return S_OK;
  52. A11Y_TRYBLOCK_END
  53. }
  54. STDMETHODIMP
  55. ia2AccessibleText::get_caretOffset(long *aOffset)
  56. {
  57. A11Y_TRYBLOCK_BEGIN
  58. *aOffset = -1;
  59. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  60. if (textAcc->IsDefunct())
  61. return CO_E_OBJNOTCONNECTED;
  62. int32_t offset = 0;
  63. nsresult rv = textAcc->GetCaretOffset(&offset);
  64. if (NS_FAILED(rv))
  65. return GetHRESULT(rv);
  66. *aOffset = offset;
  67. return offset != -1 ? S_OK : S_FALSE;
  68. A11Y_TRYBLOCK_END
  69. }
  70. STDMETHODIMP
  71. ia2AccessibleText::get_characterExtents(long aOffset,
  72. enum IA2CoordinateType aCoordType,
  73. long *aX, long *aY,
  74. long *aWidth, long *aHeight)
  75. {
  76. A11Y_TRYBLOCK_BEGIN
  77. *aX = 0;
  78. *aY = 0;
  79. *aWidth = 0;
  80. *aHeight = 0;
  81. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  82. if (textAcc->IsDefunct())
  83. return CO_E_OBJNOTCONNECTED;
  84. uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
  85. nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
  86. nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
  87. int32_t x = 0, y =0, width = 0, height = 0;
  88. nsresult rv = textAcc->GetCharacterExtents (aOffset, &x, &y, &width, &height,
  89. geckoCoordType);
  90. if (NS_FAILED(rv))
  91. return GetHRESULT(rv);
  92. *aX = x;
  93. *aY = y;
  94. *aWidth = width;
  95. *aHeight = height;
  96. return S_OK;
  97. A11Y_TRYBLOCK_END
  98. }
  99. STDMETHODIMP
  100. ia2AccessibleText::get_nSelections(long *aNSelections)
  101. {
  102. A11Y_TRYBLOCK_BEGIN
  103. *aNSelections = 0;
  104. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  105. if (textAcc->IsDefunct())
  106. return CO_E_OBJNOTCONNECTED;
  107. int32_t selCount = 0;
  108. nsresult rv = textAcc->GetSelectionCount(&selCount);
  109. if (NS_FAILED(rv))
  110. return GetHRESULT(rv);
  111. *aNSelections = selCount;
  112. return S_OK;
  113. A11Y_TRYBLOCK_END
  114. }
  115. STDMETHODIMP
  116. ia2AccessibleText::get_offsetAtPoint(long aX, long aY,
  117. enum IA2CoordinateType aCoordType,
  118. long *aOffset)
  119. {
  120. A11Y_TRYBLOCK_BEGIN
  121. *aOffset = 0;
  122. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  123. if (textAcc->IsDefunct())
  124. return CO_E_OBJNOTCONNECTED;
  125. uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
  126. nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
  127. nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
  128. int32_t offset = 0;
  129. nsresult rv = textAcc->GetOffsetAtPoint(aX, aY, geckoCoordType, &offset);
  130. if (NS_FAILED(rv))
  131. return GetHRESULT(rv);
  132. *aOffset = offset;
  133. return S_OK;
  134. A11Y_TRYBLOCK_END
  135. }
  136. STDMETHODIMP
  137. ia2AccessibleText::get_selection(long aSelectionIndex, long *aStartOffset,
  138. long *aEndOffset)
  139. {
  140. A11Y_TRYBLOCK_BEGIN
  141. *aStartOffset = 0;
  142. *aEndOffset = 0;
  143. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  144. if (textAcc->IsDefunct())
  145. return CO_E_OBJNOTCONNECTED;
  146. int32_t startOffset = 0, endOffset = 0;
  147. nsresult rv = textAcc->GetSelectionBounds(aSelectionIndex,
  148. &startOffset, &endOffset);
  149. if (NS_FAILED(rv))
  150. return GetHRESULT(rv);
  151. *aStartOffset = startOffset;
  152. *aEndOffset = endOffset;
  153. return S_OK;
  154. A11Y_TRYBLOCK_END
  155. }
  156. STDMETHODIMP
  157. ia2AccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
  158. {
  159. A11Y_TRYBLOCK_BEGIN
  160. *aText = nullptr;
  161. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  162. if (textAcc->IsDefunct())
  163. return CO_E_OBJNOTCONNECTED;
  164. nsAutoString text;
  165. nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text);
  166. if (NS_FAILED(rv))
  167. return GetHRESULT(rv);
  168. if (text.IsEmpty())
  169. return S_FALSE;
  170. *aText = ::SysAllocStringLen(text.get(), text.Length());
  171. return *aText ? S_OK : E_OUTOFMEMORY;
  172. A11Y_TRYBLOCK_END
  173. }
  174. STDMETHODIMP
  175. ia2AccessibleText::get_textBeforeOffset(long aOffset,
  176. enum IA2TextBoundaryType aBoundaryType,
  177. long *aStartOffset, long *aEndOffset,
  178. BSTR *aText)
  179. {
  180. A11Y_TRYBLOCK_BEGIN
  181. *aStartOffset = 0;
  182. *aEndOffset = 0;
  183. *aText = nullptr;
  184. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  185. if (textAcc->IsDefunct())
  186. return CO_E_OBJNOTCONNECTED;
  187. nsresult rv = NS_OK;
  188. nsAutoString text;
  189. int32_t startOffset = 0, endOffset = 0;
  190. if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
  191. startOffset = 0;
  192. endOffset = textAcc->CharacterCount();
  193. rv = textAcc->GetText(startOffset, endOffset, text);
  194. } else {
  195. AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
  196. if (boundaryType == -1)
  197. return S_FALSE;
  198. rv = textAcc->GetTextBeforeOffset(aOffset, boundaryType,
  199. &startOffset, &endOffset, text);
  200. }
  201. if (NS_FAILED(rv))
  202. return GetHRESULT(rv);
  203. *aStartOffset = startOffset;
  204. *aEndOffset = endOffset;
  205. if (text.IsEmpty())
  206. return S_FALSE;
  207. *aText = ::SysAllocStringLen(text.get(), text.Length());
  208. return *aText ? S_OK : E_OUTOFMEMORY;
  209. A11Y_TRYBLOCK_END
  210. }
  211. STDMETHODIMP
  212. ia2AccessibleText::get_textAfterOffset(long aOffset,
  213. enum IA2TextBoundaryType aBoundaryType,
  214. long *aStartOffset, long *aEndOffset,
  215. BSTR *aText)
  216. {
  217. A11Y_TRYBLOCK_BEGIN
  218. *aStartOffset = 0;
  219. *aEndOffset = 0;
  220. *aText = nullptr;
  221. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  222. if (textAcc->IsDefunct())
  223. return CO_E_OBJNOTCONNECTED;
  224. nsresult rv = NS_OK;
  225. nsAutoString text;
  226. int32_t startOffset = 0, endOffset = 0;
  227. if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
  228. startOffset = 0;
  229. endOffset = textAcc->CharacterCount();
  230. rv = textAcc->GetText(startOffset, endOffset, text);
  231. } else {
  232. AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
  233. if (boundaryType == -1)
  234. return S_FALSE;
  235. rv = textAcc->GetTextAfterOffset(aOffset, boundaryType,
  236. &startOffset, &endOffset, text);
  237. }
  238. if (NS_FAILED(rv))
  239. return GetHRESULT(rv);
  240. *aStartOffset = startOffset;
  241. *aEndOffset = endOffset;
  242. if (text.IsEmpty())
  243. return S_FALSE;
  244. *aText = ::SysAllocStringLen(text.get(), text.Length());
  245. return *aText ? S_OK : E_OUTOFMEMORY;
  246. A11Y_TRYBLOCK_END
  247. }
  248. STDMETHODIMP
  249. ia2AccessibleText::get_textAtOffset(long aOffset,
  250. enum IA2TextBoundaryType aBoundaryType,
  251. long *aStartOffset, long *aEndOffset,
  252. BSTR *aText)
  253. {
  254. A11Y_TRYBLOCK_BEGIN
  255. *aStartOffset = 0;
  256. *aEndOffset = 0;
  257. *aText = nullptr;
  258. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  259. if (textAcc->IsDefunct())
  260. return CO_E_OBJNOTCONNECTED;
  261. nsresult rv = NS_OK;
  262. nsAutoString text;
  263. int32_t startOffset = 0, endOffset = 0;
  264. if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
  265. startOffset = 0;
  266. endOffset = textAcc->CharacterCount();
  267. rv = textAcc->GetText(startOffset, endOffset, text);
  268. } else {
  269. AccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
  270. if (boundaryType == -1)
  271. return S_FALSE;
  272. rv = textAcc->GetTextAtOffset(aOffset, boundaryType,
  273. &startOffset, &endOffset, text);
  274. }
  275. if (NS_FAILED(rv))
  276. return GetHRESULT(rv);
  277. *aStartOffset = startOffset;
  278. *aEndOffset = endOffset;
  279. if (text.IsEmpty())
  280. return S_FALSE;
  281. *aText = ::SysAllocStringLen(text.get(), text.Length());
  282. return *aText ? S_OK : E_OUTOFMEMORY;
  283. A11Y_TRYBLOCK_END
  284. }
  285. STDMETHODIMP
  286. ia2AccessibleText::removeSelection(long aSelectionIndex)
  287. {
  288. A11Y_TRYBLOCK_BEGIN
  289. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  290. if (textAcc->IsDefunct())
  291. return CO_E_OBJNOTCONNECTED;
  292. nsresult rv = textAcc->RemoveSelection(aSelectionIndex);
  293. return GetHRESULT(rv);
  294. A11Y_TRYBLOCK_END
  295. }
  296. STDMETHODIMP
  297. ia2AccessibleText::setCaretOffset(long aOffset)
  298. {
  299. A11Y_TRYBLOCK_BEGIN
  300. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  301. if (textAcc->IsDefunct())
  302. return CO_E_OBJNOTCONNECTED;
  303. nsresult rv = textAcc->SetCaretOffset(aOffset);
  304. return GetHRESULT(rv);
  305. A11Y_TRYBLOCK_END
  306. }
  307. STDMETHODIMP
  308. ia2AccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
  309. long aEndOffset)
  310. {
  311. A11Y_TRYBLOCK_BEGIN
  312. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  313. if (textAcc->IsDefunct())
  314. return CO_E_OBJNOTCONNECTED;
  315. nsresult rv = textAcc->SetSelectionBounds(aSelectionIndex,
  316. aStartOffset, aEndOffset);
  317. return GetHRESULT(rv);
  318. A11Y_TRYBLOCK_END
  319. }
  320. STDMETHODIMP
  321. ia2AccessibleText::get_nCharacters(long *aNCharacters)
  322. {
  323. A11Y_TRYBLOCK_BEGIN
  324. *aNCharacters = 0;
  325. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  326. if (textAcc->IsDefunct())
  327. return CO_E_OBJNOTCONNECTED;
  328. *aNCharacters = textAcc->CharacterCount();
  329. return S_OK;
  330. A11Y_TRYBLOCK_END
  331. }
  332. STDMETHODIMP
  333. ia2AccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
  334. enum IA2ScrollType aScrollType)
  335. {
  336. A11Y_TRYBLOCK_BEGIN
  337. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  338. if (textAcc->IsDefunct())
  339. return CO_E_OBJNOTCONNECTED;
  340. nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
  341. return GetHRESULT(rv);
  342. A11Y_TRYBLOCK_END
  343. }
  344. STDMETHODIMP
  345. ia2AccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
  346. enum IA2CoordinateType aCoordType,
  347. long aX, long aY)
  348. {
  349. A11Y_TRYBLOCK_BEGIN
  350. HyperTextAccessible* textAcc = static_cast<HyperTextAccessibleWrap*>(this);
  351. if (textAcc->IsDefunct())
  352. return CO_E_OBJNOTCONNECTED;
  353. uint32_t geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
  354. nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
  355. nsIAccessibleCoordinateType::COORDTYPE_PARENT_RELATIVE;
  356. nsresult rv = textAcc->ScrollSubstringToPoint(aStartIndex, aEndIndex,
  357. geckoCoordType, aX, aY);
  358. return GetHRESULT(rv);
  359. A11Y_TRYBLOCK_END
  360. }
  361. STDMETHODIMP
  362. ia2AccessibleText::get_newText(IA2TextSegment *aNewText)
  363. {
  364. A11Y_TRYBLOCK_BEGIN
  365. return GetModifiedText(true, aNewText);
  366. A11Y_TRYBLOCK_END
  367. }
  368. STDMETHODIMP
  369. ia2AccessibleText::get_oldText(IA2TextSegment *aOldText)
  370. {
  371. A11Y_TRYBLOCK_BEGIN
  372. return GetModifiedText(false, aOldText);
  373. A11Y_TRYBLOCK_END
  374. }
  375. // ia2AccessibleText
  376. HRESULT
  377. ia2AccessibleText::GetModifiedText(bool aGetInsertedText,
  378. IA2TextSegment *aText)
  379. {
  380. uint32_t startOffset = 0, endOffset = 0;
  381. nsAutoString text;
  382. nsresult rv = GetModifiedText(aGetInsertedText, text,
  383. &startOffset, &endOffset);
  384. if (NS_FAILED(rv))
  385. return GetHRESULT(rv);
  386. aText->start = startOffset;
  387. aText->end = endOffset;
  388. if (text.IsEmpty())
  389. return S_FALSE;
  390. aText->text = ::SysAllocStringLen(text.get(), text.Length());
  391. return aText->text ? S_OK : E_OUTOFMEMORY;
  392. }
  393. AccessibleTextBoundary
  394. ia2AccessibleText::GetGeckoTextBoundary(enum IA2TextBoundaryType aBoundaryType)
  395. {
  396. switch (aBoundaryType) {
  397. case IA2_TEXT_BOUNDARY_CHAR:
  398. return nsIAccessibleText::BOUNDARY_CHAR;
  399. case IA2_TEXT_BOUNDARY_WORD:
  400. return nsIAccessibleText::BOUNDARY_WORD_START;
  401. case IA2_TEXT_BOUNDARY_LINE:
  402. return nsIAccessibleText::BOUNDARY_LINE_START;
  403. //case IA2_TEXT_BOUNDARY_SENTENCE:
  404. //case IA2_TEXT_BOUNDARY_PARAGRAPH:
  405. // XXX: not implemented
  406. default:
  407. return -1;
  408. }
  409. }