Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "nsIWidget.h"
8 : #include "nsPoint.h"
9 : #include "nsQueryContentEventResult.h"
10 : #include "mozilla/Move.h"
11 : #include "mozilla/TextEvents.h"
12 :
13 : using namespace mozilla;
14 :
15 : /******************************************************************************
16 : * Is*PropertyAvailable() methods which check if the property is available
17 : * (valid) with the event message.
18 : ******************************************************************************/
19 :
20 0 : static bool IsNotFoundPropertyAvailable(EventMessage aEventMessage)
21 : {
22 0 : return aEventMessage == eQuerySelectedText ||
23 0 : aEventMessage == eQueryCharacterAtPoint;
24 : }
25 :
26 0 : static bool IsOffsetPropertyAvailable(EventMessage aEventMessage)
27 : {
28 0 : return aEventMessage == eQueryTextContent ||
29 0 : aEventMessage == eQueryTextRect ||
30 0 : aEventMessage == eQueryCaretRect ||
31 0 : IsNotFoundPropertyAvailable(aEventMessage);
32 : }
33 :
34 0 : static bool IsRectRelatedPropertyAvailable(EventMessage aEventMessage)
35 : {
36 0 : return aEventMessage == eQueryCaretRect ||
37 0 : aEventMessage == eQueryTextRect ||
38 0 : aEventMessage == eQueryEditorRect ||
39 0 : aEventMessage == eQueryCharacterAtPoint;
40 : }
41 :
42 : /******************************************************************************
43 : * nsQueryContentEventResult
44 : ******************************************************************************/
45 :
46 0 : NS_INTERFACE_MAP_BEGIN(nsQueryContentEventResult)
47 0 : NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIQueryContentEventResult)
48 0 : NS_INTERFACE_MAP_ENTRY(nsIQueryContentEventResult)
49 0 : NS_INTERFACE_MAP_END
50 :
51 0 : NS_IMPL_ADDREF(nsQueryContentEventResult)
52 0 : NS_IMPL_RELEASE(nsQueryContentEventResult)
53 :
54 0 : nsQueryContentEventResult::nsQueryContentEventResult()
55 : : mEventMessage(eVoidEvent)
56 0 : , mSucceeded(false)
57 : {
58 0 : }
59 :
60 0 : nsQueryContentEventResult::~nsQueryContentEventResult()
61 : {
62 0 : }
63 :
64 : NS_IMETHODIMP
65 0 : nsQueryContentEventResult::GetOffset(uint32_t* aOffset)
66 : {
67 0 : if (NS_WARN_IF(!mSucceeded)) {
68 0 : return NS_ERROR_NOT_AVAILABLE;
69 : }
70 :
71 0 : if (NS_WARN_IF(!IsOffsetPropertyAvailable(mEventMessage))) {
72 0 : return NS_ERROR_NOT_AVAILABLE;
73 : }
74 :
75 : // With some event message, both offset and notFound properties are available.
76 : // In that case, offset value may mean "not found". If so, this method
77 : // shouldn't return mOffset as the result because it's a special value for
78 : // "not found".
79 0 : if (IsNotFoundPropertyAvailable(mEventMessage)) {
80 : bool notFound;
81 0 : nsresult rv = GetNotFound(¬Found);
82 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
83 0 : return rv; // Just an unexpected case...
84 : }
85 : // As said above, if mOffset means "not found", offset property shouldn't
86 : // return its value without any errors.
87 0 : if (NS_WARN_IF(notFound)) {
88 0 : return NS_ERROR_NOT_AVAILABLE;
89 : }
90 : }
91 :
92 0 : *aOffset = mOffset;
93 0 : return NS_OK;
94 : }
95 :
96 : NS_IMETHODIMP
97 0 : nsQueryContentEventResult::GetTentativeCaretOffset(uint32_t* aOffset)
98 : {
99 : bool notFound;
100 0 : nsresult rv = GetTentativeCaretOffsetNotFound(¬Found);
101 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
102 0 : return rv;
103 : }
104 0 : if (NS_WARN_IF(notFound)) {
105 0 : return NS_ERROR_NOT_AVAILABLE;
106 : }
107 0 : *aOffset = mTentativeCaretOffset;
108 0 : return NS_OK;
109 : }
110 :
111 : NS_IMETHODIMP
112 0 : nsQueryContentEventResult::GetReversed(bool *aReversed)
113 : {
114 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
115 0 : NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText, NS_ERROR_NOT_AVAILABLE);
116 0 : *aReversed = mReversed;
117 0 : return NS_OK;
118 : }
119 :
120 : NS_IMETHODIMP
121 0 : nsQueryContentEventResult::GetLeft(int32_t *aLeft)
122 : {
123 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
124 0 : NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage),
125 : NS_ERROR_NOT_AVAILABLE);
126 0 : *aLeft = mRect.x;
127 0 : return NS_OK;
128 : }
129 :
130 : NS_IMETHODIMP
131 0 : nsQueryContentEventResult::GetWidth(int32_t *aWidth)
132 : {
133 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
134 0 : NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage),
135 : NS_ERROR_NOT_AVAILABLE);
136 0 : *aWidth = mRect.width;
137 0 : return NS_OK;
138 : }
139 :
140 : NS_IMETHODIMP
141 0 : nsQueryContentEventResult::GetTop(int32_t *aTop)
142 : {
143 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
144 0 : NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage),
145 : NS_ERROR_NOT_AVAILABLE);
146 0 : *aTop = mRect.y;
147 0 : return NS_OK;
148 : }
149 :
150 : NS_IMETHODIMP
151 0 : nsQueryContentEventResult::GetHeight(int32_t *aHeight)
152 : {
153 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
154 0 : NS_ENSURE_TRUE(IsRectRelatedPropertyAvailable(mEventMessage),
155 : NS_ERROR_NOT_AVAILABLE);
156 0 : *aHeight = mRect.height;
157 0 : return NS_OK;
158 : }
159 :
160 : NS_IMETHODIMP
161 0 : nsQueryContentEventResult::GetText(nsAString &aText)
162 : {
163 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
164 0 : NS_ENSURE_TRUE(mEventMessage == eQuerySelectedText ||
165 : mEventMessage == eQueryTextContent ||
166 : mEventMessage == eQueryTextRect,
167 : NS_ERROR_NOT_AVAILABLE);
168 0 : aText = mString;
169 0 : return NS_OK;
170 : }
171 :
172 : NS_IMETHODIMP
173 0 : nsQueryContentEventResult::GetSucceeded(bool *aSucceeded)
174 : {
175 0 : NS_ENSURE_TRUE(mEventMessage != eVoidEvent, NS_ERROR_NOT_INITIALIZED);
176 0 : *aSucceeded = mSucceeded;
177 0 : return NS_OK;
178 : }
179 :
180 : NS_IMETHODIMP
181 0 : nsQueryContentEventResult::GetNotFound(bool* aNotFound)
182 : {
183 0 : if (NS_WARN_IF(!mSucceeded) ||
184 0 : NS_WARN_IF(!IsNotFoundPropertyAvailable(mEventMessage))) {
185 0 : return NS_ERROR_NOT_AVAILABLE;
186 : }
187 0 : *aNotFound = (mOffset == WidgetQueryContentEvent::NOT_FOUND);
188 0 : return NS_OK;
189 : }
190 :
191 : NS_IMETHODIMP
192 0 : nsQueryContentEventResult::GetTentativeCaretOffsetNotFound(bool* aNotFound)
193 : {
194 0 : if (NS_WARN_IF(!mSucceeded)) {
195 0 : return NS_ERROR_NOT_AVAILABLE;
196 : }
197 0 : if (NS_WARN_IF(mEventMessage != eQueryCharacterAtPoint)) {
198 0 : return NS_ERROR_NOT_AVAILABLE;
199 : }
200 0 : *aNotFound = (mTentativeCaretOffset == WidgetQueryContentEvent::NOT_FOUND);
201 0 : return NS_OK;
202 : }
203 :
204 : NS_IMETHODIMP
205 0 : nsQueryContentEventResult::GetCharacterRect(int32_t aOffset,
206 : int32_t* aLeft, int32_t* aTop,
207 : int32_t* aWidth, int32_t* aHeight)
208 : {
209 0 : NS_ENSURE_TRUE(mSucceeded, NS_ERROR_NOT_AVAILABLE);
210 0 : NS_ENSURE_TRUE(mEventMessage == eQueryTextRectArray,
211 : NS_ERROR_NOT_AVAILABLE);
212 :
213 0 : if (NS_WARN_IF(mRectArray.Length() <= static_cast<uint32_t>(aOffset))) {
214 0 : return NS_ERROR_FAILURE;
215 : }
216 :
217 0 : *aLeft = mRectArray[aOffset].x;
218 0 : *aTop = mRectArray[aOffset].y;
219 0 : *aWidth = mRectArray[aOffset].width;
220 0 : *aHeight = mRectArray[aOffset].height;
221 :
222 0 : return NS_OK;
223 : }
224 :
225 : void
226 0 : nsQueryContentEventResult::SetEventResult(nsIWidget* aWidget,
227 : WidgetQueryContentEvent &aEvent)
228 : {
229 0 : mEventMessage = aEvent.mMessage;
230 0 : mSucceeded = aEvent.mSucceeded;
231 0 : mReversed = aEvent.mReply.mReversed;
232 0 : mRect = aEvent.mReply.mRect;
233 0 : mOffset = aEvent.mReply.mOffset;
234 0 : mTentativeCaretOffset = aEvent.mReply.mTentativeCaretOffset;
235 0 : mString = aEvent.mReply.mString;
236 0 : mRectArray = mozilla::Move(aEvent.mReply.mRectArray);
237 : // Mark as result that is longer used.
238 0 : aEvent.mSucceeded = false;
239 :
240 0 : if (!IsRectRelatedPropertyAvailable(mEventMessage) ||
241 0 : !aWidget || !mSucceeded) {
242 0 : return;
243 : }
244 :
245 0 : nsIWidget* topWidget = aWidget->GetTopLevelWidget();
246 0 : if (!topWidget || topWidget == aWidget) {
247 0 : return;
248 : }
249 :
250 : // Convert the top widget related coordinates to the given widget's.
251 : LayoutDeviceIntPoint offset =
252 0 : aWidget->WidgetToScreenOffset() - topWidget->WidgetToScreenOffset();
253 0 : mRect.MoveBy(-offset);
254 0 : for (size_t i = 0; i < mRectArray.Length(); i++) {
255 0 : mRectArray[i].MoveBy(-offset);
256 : }
257 : }
|