1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #include "nsAutoCompleteSimpleResult.h"
6 
7 #define CHECK_MATCH_INDEX(_index, _insert)                                   \
8   if (_index < 0 ||                                                          \
9       static_cast<MatchesArray::size_type>(_index) > mMatches.Length() ||    \
10       (!_insert &&                                                           \
11        static_cast<MatchesArray::size_type>(_index) == mMatches.Length())) { \
12     MOZ_ASSERT(false, "Trying to use an invalid index on mMatches");         \
13     return NS_ERROR_ILLEGAL_VALUE;                                           \
14   }
15 
16 NS_IMPL_ISUPPORTS(nsAutoCompleteSimpleResult, nsIAutoCompleteResult,
17                   nsIAutoCompleteSimpleResult)
18 
19 struct AutoCompleteSimpleResultMatch {
AutoCompleteSimpleResultMatchAutoCompleteSimpleResultMatch20   AutoCompleteSimpleResultMatch(const nsAString& aValue,
21                                 const nsAString& aComment,
22                                 const nsAString& aImage,
23                                 const nsAString& aStyle,
24                                 const nsAString& aFinalCompleteValue,
25                                 const nsAString& aLabel)
26       : mValue(aValue),
27         mComment(aComment),
28         mImage(aImage),
29         mStyle(aStyle),
30         mFinalCompleteValue(aFinalCompleteValue),
31         mLabel(aLabel) {}
32 
33   nsString mValue;
34   nsString mComment;
35   nsString mImage;
36   nsString mStyle;
37   nsString mFinalCompleteValue;
38   nsString mLabel;
39 };
40 
nsAutoCompleteSimpleResult()41 nsAutoCompleteSimpleResult::nsAutoCompleteSimpleResult()
42     : mDefaultIndex(-1), mSearchResult(RESULT_NOMATCH) {}
43 
AppendResult(nsIAutoCompleteResult * aResult)44 nsresult nsAutoCompleteSimpleResult::AppendResult(
45     nsIAutoCompleteResult* aResult) {
46   nsAutoString searchString;
47   nsresult rv = aResult->GetSearchString(searchString);
48   NS_ENSURE_SUCCESS(rv, rv);
49   mSearchString = searchString;
50 
51   uint16_t searchResult;
52   rv = aResult->GetSearchResult(&searchResult);
53   NS_ENSURE_SUCCESS(rv, rv);
54   mSearchResult = searchResult;
55 
56   nsAutoString errorDescription;
57   if (NS_SUCCEEDED(aResult->GetErrorDescription(errorDescription)) &&
58       !errorDescription.IsEmpty()) {
59     mErrorDescription = errorDescription;
60   }
61 
62   int32_t defaultIndex = -1;
63   if (NS_SUCCEEDED(aResult->GetDefaultIndex(&defaultIndex)) &&
64       defaultIndex >= 0) {
65     mDefaultIndex = defaultIndex;
66   }
67 
68   nsCOMPtr<nsIAutoCompleteSimpleResult> simpleResult =
69       do_QueryInterface(aResult);
70   if (simpleResult) {
71     nsCOMPtr<nsIAutoCompleteSimpleResultListener> listener;
72     if (NS_SUCCEEDED(simpleResult->GetListener(getter_AddRefs(listener))) &&
73         listener) {
74       listener.swap(mListener);
75     }
76   }
77 
78   // Copy matches.
79   uint32_t matchCount = 0;
80   rv = aResult->GetMatchCount(&matchCount);
81   NS_ENSURE_SUCCESS(rv, rv);
82   for (size_t i = 0; i < matchCount; ++i) {
83     nsAutoString value, comment, image, style, finalCompleteValue, label;
84 
85     rv = aResult->GetValueAt(i, value);
86     NS_ENSURE_SUCCESS(rv, rv);
87     rv = aResult->GetCommentAt(i, comment);
88     NS_ENSURE_SUCCESS(rv, rv);
89     rv = aResult->GetImageAt(i, image);
90     NS_ENSURE_SUCCESS(rv, rv);
91     rv = aResult->GetStyleAt(i, style);
92     NS_ENSURE_SUCCESS(rv, rv);
93     rv = aResult->GetFinalCompleteValueAt(i, finalCompleteValue);
94     NS_ENSURE_SUCCESS(rv, rv);
95     rv = aResult->GetLabelAt(i, label);
96     NS_ENSURE_SUCCESS(rv, rv);
97 
98     rv = AppendMatch(value, comment, image, style, finalCompleteValue, label);
99     NS_ENSURE_SUCCESS(rv, rv);
100   }
101 
102   return NS_OK;
103 }
104 
105 // searchString
106 NS_IMETHODIMP
GetSearchString(nsAString & aSearchString)107 nsAutoCompleteSimpleResult::GetSearchString(nsAString& aSearchString) {
108   aSearchString = mSearchString;
109   return NS_OK;
110 }
111 NS_IMETHODIMP
SetSearchString(const nsAString & aSearchString)112 nsAutoCompleteSimpleResult::SetSearchString(const nsAString& aSearchString) {
113   mSearchString.Assign(aSearchString);
114   return NS_OK;
115 }
116 
117 // searchResult
118 NS_IMETHODIMP
GetSearchResult(uint16_t * aSearchResult)119 nsAutoCompleteSimpleResult::GetSearchResult(uint16_t* aSearchResult) {
120   *aSearchResult = mSearchResult;
121   return NS_OK;
122 }
123 NS_IMETHODIMP
SetSearchResult(uint16_t aSearchResult)124 nsAutoCompleteSimpleResult::SetSearchResult(uint16_t aSearchResult) {
125   mSearchResult = aSearchResult;
126   return NS_OK;
127 }
128 
129 // defaultIndex
130 NS_IMETHODIMP
GetDefaultIndex(int32_t * aDefaultIndex)131 nsAutoCompleteSimpleResult::GetDefaultIndex(int32_t* aDefaultIndex) {
132   *aDefaultIndex = mDefaultIndex;
133   return NS_OK;
134 }
135 NS_IMETHODIMP
SetDefaultIndex(int32_t aDefaultIndex)136 nsAutoCompleteSimpleResult::SetDefaultIndex(int32_t aDefaultIndex) {
137   mDefaultIndex = aDefaultIndex;
138   return NS_OK;
139 }
140 
141 // errorDescription
142 NS_IMETHODIMP
GetErrorDescription(nsAString & aErrorDescription)143 nsAutoCompleteSimpleResult::GetErrorDescription(nsAString& aErrorDescription) {
144   aErrorDescription = mErrorDescription;
145   return NS_OK;
146 }
147 NS_IMETHODIMP
SetErrorDescription(const nsAString & aErrorDescription)148 nsAutoCompleteSimpleResult::SetErrorDescription(
149     const nsAString& aErrorDescription) {
150   mErrorDescription.Assign(aErrorDescription);
151   return NS_OK;
152 }
153 
154 NS_IMETHODIMP
InsertMatchAt(int32_t aIndex,const nsAString & aValue,const nsAString & aComment,const nsAString & aImage,const nsAString & aStyle,const nsAString & aFinalCompleteValue,const nsAString & aLabel)155 nsAutoCompleteSimpleResult::InsertMatchAt(
156     int32_t aIndex, const nsAString& aValue, const nsAString& aComment,
157     const nsAString& aImage, const nsAString& aStyle,
158     const nsAString& aFinalCompleteValue, const nsAString& aLabel) {
159   CHECK_MATCH_INDEX(aIndex, true);
160 
161   AutoCompleteSimpleResultMatch match(aValue, aComment, aImage, aStyle,
162                                       aFinalCompleteValue, aLabel);
163 
164   if (!mMatches.InsertElementAt(aIndex, match)) {
165     return NS_ERROR_OUT_OF_MEMORY;
166   }
167 
168   return NS_OK;
169 }
170 
171 NS_IMETHODIMP
AppendMatch(const nsAString & aValue,const nsAString & aComment,const nsAString & aImage,const nsAString & aStyle,const nsAString & aFinalCompleteValue,const nsAString & aLabel)172 nsAutoCompleteSimpleResult::AppendMatch(const nsAString& aValue,
173                                         const nsAString& aComment,
174                                         const nsAString& aImage,
175                                         const nsAString& aStyle,
176                                         const nsAString& aFinalCompleteValue,
177                                         const nsAString& aLabel) {
178   return InsertMatchAt(mMatches.Length(), aValue, aComment, aImage, aStyle,
179                        aFinalCompleteValue, aLabel);
180 }
181 
182 NS_IMETHODIMP
RemoveMatchAt(int32_t aIndex)183 nsAutoCompleteSimpleResult::RemoveMatchAt(int32_t aIndex) {
184   CHECK_MATCH_INDEX(aIndex, false);
185 
186   mMatches.RemoveElementAt(aIndex);
187   return NS_OK;
188 }
189 
190 NS_IMETHODIMP
GetMatchCount(uint32_t * aMatchCount)191 nsAutoCompleteSimpleResult::GetMatchCount(uint32_t* aMatchCount) {
192   *aMatchCount = mMatches.Length();
193   return NS_OK;
194 }
195 
196 NS_IMETHODIMP
GetValueAt(int32_t aIndex,nsAString & _retval)197 nsAutoCompleteSimpleResult::GetValueAt(int32_t aIndex, nsAString& _retval) {
198   CHECK_MATCH_INDEX(aIndex, false);
199   _retval = mMatches[aIndex].mValue;
200   return NS_OK;
201 }
202 
203 NS_IMETHODIMP
GetLabelAt(int32_t aIndex,nsAString & _retval)204 nsAutoCompleteSimpleResult::GetLabelAt(int32_t aIndex, nsAString& _retval) {
205   CHECK_MATCH_INDEX(aIndex, false);
206   _retval = mMatches[aIndex].mLabel;
207   if (_retval.IsEmpty()) {
208     _retval = mMatches[aIndex].mValue;
209   }
210   return NS_OK;
211 }
212 
213 NS_IMETHODIMP
GetCommentAt(int32_t aIndex,nsAString & _retval)214 nsAutoCompleteSimpleResult::GetCommentAt(int32_t aIndex, nsAString& _retval) {
215   CHECK_MATCH_INDEX(aIndex, false);
216   _retval = mMatches[aIndex].mComment;
217   return NS_OK;
218 }
219 
220 NS_IMETHODIMP
GetImageAt(int32_t aIndex,nsAString & _retval)221 nsAutoCompleteSimpleResult::GetImageAt(int32_t aIndex, nsAString& _retval) {
222   CHECK_MATCH_INDEX(aIndex, false);
223   _retval = mMatches[aIndex].mImage;
224   return NS_OK;
225 }
226 
227 NS_IMETHODIMP
GetStyleAt(int32_t aIndex,nsAString & _retval)228 nsAutoCompleteSimpleResult::GetStyleAt(int32_t aIndex, nsAString& _retval) {
229   CHECK_MATCH_INDEX(aIndex, false);
230   _retval = mMatches[aIndex].mStyle;
231   return NS_OK;
232 }
233 
234 NS_IMETHODIMP
GetFinalCompleteValueAt(int32_t aIndex,nsAString & _retval)235 nsAutoCompleteSimpleResult::GetFinalCompleteValueAt(int32_t aIndex,
236                                                     nsAString& _retval) {
237   CHECK_MATCH_INDEX(aIndex, false);
238   _retval = mMatches[aIndex].mFinalCompleteValue;
239   if (_retval.IsEmpty()) {
240     _retval = mMatches[aIndex].mValue;
241   }
242   return NS_OK;
243 }
244 
245 NS_IMETHODIMP
SetListener(nsIAutoCompleteSimpleResultListener * aListener)246 nsAutoCompleteSimpleResult::SetListener(
247     nsIAutoCompleteSimpleResultListener* aListener) {
248   mListener = aListener;
249   return NS_OK;
250 }
251 
252 NS_IMETHODIMP
GetListener(nsIAutoCompleteSimpleResultListener ** aListener)253 nsAutoCompleteSimpleResult::GetListener(
254     nsIAutoCompleteSimpleResultListener** aListener) {
255   nsCOMPtr<nsIAutoCompleteSimpleResultListener> listener(mListener);
256   listener.forget(aListener);
257   return NS_OK;
258 }
259 
260 NS_IMETHODIMP
RemoveValueAt(int32_t aRowIndex,bool aRemoveFromDb)261 nsAutoCompleteSimpleResult::RemoveValueAt(int32_t aRowIndex,
262                                           bool aRemoveFromDb) {
263   CHECK_MATCH_INDEX(aRowIndex, false);
264 
265   nsString value = mMatches[aRowIndex].mValue;
266   mMatches.RemoveElementAt(aRowIndex);
267 
268   if (mListener) {
269     mListener->OnValueRemoved(this, value, aRemoveFromDb);
270   }
271 
272   return NS_OK;
273 }
274