1 //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is Places code
17 * The Initial Developer of the Original Code is
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
23 * Brett Wilson <brettw@gmail.com> (original author)
24 * Shawn Wilsher <me@shawnwilsher.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * This file contains the definitions of nsNavHistoryQuery,
42 * nsNavHistoryQueryOptions, and those functions in nsINavHistory that directly
43 * support queries (specifically QueryStringToQueries and QueriesToQueryString).
46 #include "nsNavHistory.h"
47 #include "nsNavBookmarks.h"
49 #include "nsCOMArray.h"
50 #include "nsNetUtil.h"
54 class QueryKeyValuePair
61 // input : qwerty&key=value&qwerty
63 // aKeyBegin | aPastEnd (may point to NULL terminator)
66 // Special case: if aKeyBegin == aEquals, then there is only one string
67 // and no equal sign, so we treat the entire thing as a key with no value
69 QueryKeyValuePair(const nsCSubstring
& aSource
, PRInt32 aKeyBegin
,
70 PRInt32 aEquals
, PRInt32 aPastEnd
)
72 if (aEquals
== aKeyBegin
)
74 key
= Substring(aSource
, aKeyBegin
, aEquals
- aKeyBegin
);
75 if (aPastEnd
- aEquals
> 0)
76 value
= Substring(aSource
, aEquals
+ 1, aPastEnd
- aEquals
- 1);
82 static nsresult
TokenizeQueryString(const nsACString
& aQuery
,
83 nsTArray
<QueryKeyValuePair
>* aTokens
);
84 static nsresult
ParseQueryBooleanString(const nsCString
& aString
,
88 typedef NS_STDCALL_FUNCPROTO(nsresult
, BoolQueryGetter
, nsINavHistoryQuery
,
89 GetOnlyBookmarked
, (PRBool
*));
90 typedef NS_STDCALL_FUNCPROTO(nsresult
, Uint32QueryGetter
, nsINavHistoryQuery
,
91 GetBeginTimeReference
, (PRUint32
*));
92 typedef NS_STDCALL_FUNCPROTO(nsresult
, Int64QueryGetter
, nsINavHistoryQuery
,
93 GetBeginTime
, (PRInt64
*));
94 static void AppendBoolKeyValueIfTrue(nsACString
& aString
,
95 const nsCString
& aName
,
96 nsINavHistoryQuery
* aQuery
,
97 BoolQueryGetter getter
);
98 static void AppendUint32KeyValueIfNonzero(nsACString
& aString
,
99 const nsCString
& aName
,
100 nsINavHistoryQuery
* aQuery
,
101 Uint32QueryGetter getter
);
102 static void AppendInt64KeyValueIfNonzero(nsACString
& aString
,
103 const nsCString
& aName
,
104 nsINavHistoryQuery
* aQuery
,
105 Int64QueryGetter getter
);
108 typedef NS_STDCALL_FUNCPROTO(nsresult
, BoolQuerySetter
, nsINavHistoryQuery
,
109 SetOnlyBookmarked
, (PRBool
));
110 typedef NS_STDCALL_FUNCPROTO(nsresult
, Uint32QuerySetter
, nsINavHistoryQuery
,
111 SetBeginTimeReference
, (PRUint32
));
112 typedef NS_STDCALL_FUNCPROTO(nsresult
, Int64QuerySetter
, nsINavHistoryQuery
,
113 SetBeginTime
, (PRInt64
));
114 static void SetQueryKeyBool(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
115 BoolQuerySetter setter
);
116 static void SetQueryKeyUint32(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
117 Uint32QuerySetter setter
);
118 static void SetQueryKeyInt64(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
119 Int64QuerySetter setter
);
122 typedef NS_STDCALL_FUNCPROTO(nsresult
, BoolOptionsSetter
,
123 nsINavHistoryQueryOptions
,
124 SetExpandQueries
, (PRBool
));
125 typedef NS_STDCALL_FUNCPROTO(nsresult
, Uint32OptionsSetter
,
126 nsINavHistoryQueryOptions
,
127 SetMaxResults
, (PRUint32
));
128 typedef NS_STDCALL_FUNCPROTO(nsresult
, Uint16OptionsSetter
,
129 nsINavHistoryQueryOptions
,
130 SetResultType
, (PRUint16
));
131 static void SetOptionsKeyBool(const nsCString
& aValue
,
132 nsINavHistoryQueryOptions
* aOptions
,
133 BoolOptionsSetter setter
);
134 static void SetOptionsKeyUint16(const nsCString
& aValue
,
135 nsINavHistoryQueryOptions
* aOptions
,
136 Uint16OptionsSetter setter
);
137 static void SetOptionsKeyUint32(const nsCString
& aValue
,
138 nsINavHistoryQueryOptions
* aOptions
,
139 Uint32OptionsSetter setter
);
141 // Components of a query string.
142 // Note that query strings are also generated in nsNavBookmarks::GetFolderURI
143 // for performance reasons, so if you change these values, change that, too.
144 #define QUERYKEY_BEGIN_TIME "beginTime"
145 #define QUERYKEY_BEGIN_TIME_REFERENCE "beginTimeRef"
146 #define QUERYKEY_END_TIME "endTime"
147 #define QUERYKEY_END_TIME_REFERENCE "endTimeRef"
148 #define QUERYKEY_SEARCH_TERMS "terms"
149 #define QUERYKEY_MIN_VISITS "minVisits"
150 #define QUERYKEY_MAX_VISITS "maxVisits"
151 #define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked"
152 #define QUERYKEY_DOMAIN_IS_HOST "domainIsHost"
153 #define QUERYKEY_DOMAIN "domain"
154 #define QUERYKEY_FOLDER "folder"
155 #define QUERYKEY_NOTANNOTATION "!annotation"
156 #define QUERYKEY_ANNOTATION "annotation"
157 #define QUERYKEY_URI "uri"
158 #define QUERYKEY_URIISPREFIX "uriIsPrefix"
159 #define QUERYKEY_SEPARATOR "OR"
160 #define QUERYKEY_GROUP "group"
161 #define QUERYKEY_SORT "sort"
162 #define QUERYKEY_SORTING_ANNOTATION "sortingAnnotation"
163 #define QUERYKEY_RESULT_TYPE "type"
164 #define QUERYKEY_EXCLUDE_ITEMS "excludeItems"
165 #define QUERYKEY_EXCLUDE_QUERIES "excludeQueries"
166 #define QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS "excludeReadOnlyFolders"
167 #define QUERYKEY_EXCLUDE_ITEM_IF_PARENT_HAS_ANNOTATION "excludeItemIfParentHasAnnotation"
168 #define QUERYKEY_EXPAND_QUERIES "expandQueries"
169 #define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle"
170 #define QUERYKEY_INCLUDE_HIDDEN "includeHidden"
171 #define QUERYKEY_SHOW_SESSIONS "showSessions"
172 #define QUERYKEY_MAX_RESULTS "maxResults"
173 #define QUERYKEY_QUERY_TYPE "queryType"
175 inline void AppendAmpersandIfNonempty(nsACString
& aString
)
177 if (! aString
.IsEmpty())
180 inline void AppendInt16(nsACString
& str
, PRInt16 i
)
186 inline void AppendInt32(nsACString
& str
, PRInt32 i
)
192 inline void AppendInt64(nsACString
& str
, PRInt64 i
)
199 namespace PlacesFolderConversion
{
200 #define PLACES_ROOT_FOLDER "PLACES_ROOT"
201 #define BOOKMARKS_MENU_FOLDER "BOOKMARKS_MENU"
202 #define TAGS_FOLDER "TAGS"
203 #define UNFILED_BOOKMARKS_FOLDER "UNFILED_BOOKMARKS"
204 #define TOOLBAR_FOLDER "TOOLBAR"
207 * Converts a folder name to a folder id.
210 * The name of the folder to convert to a folder id.
211 * @returns the folder id if aName is a recognizable name, -1 otherwise.
213 inline PRInt64
DecodeFolder(const nsCString
&aName
)
215 nsNavBookmarks
*bs
= nsNavBookmarks::GetBookmarksService();
216 NS_ENSURE_TRUE(bs
, PR_FALSE
);
217 PRInt64 folderID
= -1;
219 if (aName
.EqualsLiteral(PLACES_ROOT_FOLDER
))
220 (void)bs
->GetPlacesRoot(&folderID
);
221 else if (aName
.EqualsLiteral(BOOKMARKS_MENU_FOLDER
))
222 (void)bs
->GetBookmarksMenuFolder(&folderID
);
223 else if (aName
.EqualsLiteral(TAGS_FOLDER
))
224 (void)bs
->GetTagsFolder(&folderID
);
225 else if (aName
.EqualsLiteral(UNFILED_BOOKMARKS_FOLDER
))
226 (void)bs
->GetUnfiledBookmarksFolder(&folderID
);
227 else if (aName
.EqualsLiteral(TOOLBAR_FOLDER
))
228 (void)bs
->GetToolbarFolder(&folderID
);
234 * Converts a folder id to a named constant, or a string representation of the
235 * folder id if there is no named constant for the folder, and appends it to
239 * The string to append the folder string to. This is generally a
240 * query string, but could really be anything.
242 * The folder ID to convert to the proper named constant.
244 inline void AppendFolder(nsCString
&aQuery
, PRInt64 aFolderID
)
246 nsNavBookmarks
*bs
= nsNavBookmarks::GetBookmarksService();
249 (void)bs
->GetPlacesRoot(&folderID
);
250 if (aFolderID
== folderID
) {
251 aQuery
.AppendLiteral(PLACES_ROOT_FOLDER
);
255 (void)bs
->GetBookmarksMenuFolder(&folderID
);
256 if (aFolderID
== folderID
) {
257 aQuery
.AppendLiteral(BOOKMARKS_MENU_FOLDER
);
261 (void)bs
->GetTagsFolder(&folderID
);
262 if (aFolderID
== folderID
) {
263 aQuery
.AppendLiteral(TAGS_FOLDER
);
267 (void)bs
->GetUnfiledBookmarksFolder(&folderID
);
268 if (aFolderID
== folderID
) {
269 aQuery
.AppendLiteral(UNFILED_BOOKMARKS_FOLDER
);
273 (void)bs
->GetToolbarFolder(&folderID
);
274 if (aFolderID
== folderID
) {
275 aQuery
.AppendLiteral(TOOLBAR_FOLDER
);
279 // It wasn't one of our named constants, so just convert it to a string
280 aQuery
.AppendInt(aFolderID
);
284 // nsNavHistory::QueryStringToQueries
286 // From C++ places code, you should use QueryStringToQueryArray, this is
287 // the harder-to-use XPCOM version.
290 nsNavHistory::QueryStringToQueries(const nsACString
& aQueryString
,
291 nsINavHistoryQuery
*** aQueries
,
292 PRUint32
* aResultCount
,
293 nsINavHistoryQueryOptions
** aOptions
)
297 nsCOMPtr
<nsNavHistoryQueryOptions
> options
;
298 nsCOMArray
<nsNavHistoryQuery
> queries
;
299 nsresult rv
= QueryStringToQueryArray(aQueryString
, &queries
,
300 getter_AddRefs(options
));
301 NS_ENSURE_SUCCESS(rv
, rv
);
303 *aResultCount
= queries
.Count();
304 if (queries
.Count() > 0) {
305 // convert COM array to raw
306 *aQueries
= static_cast<nsINavHistoryQuery
**>
307 (nsMemory::Alloc(sizeof(nsINavHistoryQuery
*) * queries
.Count()));
308 NS_ENSURE_TRUE(*aQueries
, NS_ERROR_OUT_OF_MEMORY
);
309 for (PRInt32 i
= 0; i
< queries
.Count(); i
++) {
310 (*aQueries
)[i
] = queries
[i
];
311 NS_ADDREF((*aQueries
)[i
]);
314 NS_ADDREF(*aOptions
= options
);
319 // nsNavHistory::QueryStringToQueryArray
321 // An internal version of QueryStringToQueries that fills a COM array for
325 nsNavHistory::QueryStringToQueryArray(const nsACString
& aQueryString
,
326 nsCOMArray
<nsNavHistoryQuery
>* aQueries
,
327 nsNavHistoryQueryOptions
** aOptions
)
333 nsRefPtr
<nsNavHistoryQueryOptions
> options(new nsNavHistoryQueryOptions());
335 return NS_ERROR_OUT_OF_MEMORY
;
337 nsTArray
<QueryKeyValuePair
> tokens
;
338 rv
= TokenizeQueryString(aQueryString
, &tokens
);
339 NS_ENSURE_SUCCESS(rv
, rv
);
341 if (tokens
.Length() > 0) {
342 rv
= TokensToQueries(tokens
, aQueries
, options
);
344 NS_WARNING("Unable to parse the query string: ");
345 NS_WARNING(PromiseFlatCString(aQueryString
).get());
347 NS_ENSURE_SUCCESS(rv
, rv
);
349 // when there are no tokens, leave the query array empty
351 NS_ADDREF(*aOptions
= options
);
356 // nsNavHistory::QueriesToQueryString
359 nsNavHistory::QueriesToQueryString(nsINavHistoryQuery
**aQueries
,
360 PRUint32 aQueryCount
,
361 nsINavHistoryQueryOptions
* aOptions
,
362 nsACString
& aQueryString
)
364 nsCOMPtr
<nsNavHistoryQueryOptions
> options
= do_QueryInterface(aOptions
);
365 NS_ENSURE_TRUE(options
, NS_ERROR_INVALID_ARG
);
367 nsCAutoString queryString
;
368 for (PRUint32 queryIndex
= 0; queryIndex
< aQueryCount
; queryIndex
++) {
369 nsINavHistoryQuery
* query
= aQueries
[queryIndex
];
370 if (queryIndex
> 0) {
371 AppendAmpersandIfNonempty(queryString
);
372 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_SEPARATOR
);
378 query
->GetHasBeginTime(&hasIt
);
380 AppendInt64KeyValueIfNonzero(queryString
,
381 NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME
),
382 query
, &nsINavHistoryQuery::GetBeginTime
);
383 AppendUint32KeyValueIfNonzero(queryString
,
384 NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME_REFERENCE
),
385 query
, &nsINavHistoryQuery::GetBeginTimeReference
);
389 query
->GetHasEndTime(&hasIt
);
391 AppendInt64KeyValueIfNonzero(queryString
,
392 NS_LITERAL_CSTRING(QUERYKEY_END_TIME
),
393 query
, &nsINavHistoryQuery::GetEndTime
);
394 AppendUint32KeyValueIfNonzero(queryString
,
395 NS_LITERAL_CSTRING(QUERYKEY_END_TIME_REFERENCE
),
396 query
, &nsINavHistoryQuery::GetEndTimeReference
);
400 query
->GetHasSearchTerms(&hasIt
);
402 nsAutoString searchTerms
;
403 query
->GetSearchTerms(searchTerms
);
404 nsCString escapedTerms
;
405 if (! NS_Escape(NS_ConvertUTF16toUTF8(searchTerms
), escapedTerms
,
407 return NS_ERROR_OUT_OF_MEMORY
;
409 AppendAmpersandIfNonempty(queryString
);
410 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_SEARCH_TERMS
"=");
411 queryString
+= escapedTerms
;
414 // min and max visits
416 if (NS_SUCCEEDED(query
->GetMinVisits(&minVisits
)) && minVisits
>= 0) {
417 AppendAmpersandIfNonempty(queryString
);
418 queryString
.Append(NS_LITERAL_CSTRING(QUERYKEY_MIN_VISITS
"="));
419 AppendInt32(queryString
, minVisits
);
423 if (NS_SUCCEEDED(query
->GetMaxVisits(&maxVisits
)) && maxVisits
>= 0) {
424 AppendAmpersandIfNonempty(queryString
);
425 queryString
.Append(NS_LITERAL_CSTRING(QUERYKEY_MAX_VISITS
"="));
426 AppendInt32(queryString
, maxVisits
);
430 AppendBoolKeyValueIfTrue(queryString
,
431 NS_LITERAL_CSTRING(QUERYKEY_ONLY_BOOKMARKED
),
432 query
, &nsINavHistoryQuery::GetOnlyBookmarked
);
434 // domain (+ is host), only call if hasDomain, which means non-IsVoid
435 // this means we may get an empty string for the domain in the result,
437 query
->GetHasDomain(&hasIt
);
439 AppendBoolKeyValueIfTrue(queryString
,
440 NS_LITERAL_CSTRING(QUERYKEY_DOMAIN_IS_HOST
),
441 query
, &nsINavHistoryQuery::GetDomainIsHost
);
442 nsCAutoString domain
;
443 nsresult rv
= query
->GetDomain(domain
);
444 NS_ASSERTION(NS_SUCCEEDED(rv
), "Failure getting value");
445 nsCString escapedDomain
;
446 PRBool success
= NS_Escape(domain
, escapedDomain
, url_XAlphas
);
447 NS_ENSURE_TRUE(success
, NS_ERROR_OUT_OF_MEMORY
);
449 AppendAmpersandIfNonempty(queryString
);
450 queryString
.Append(NS_LITERAL_CSTRING(QUERYKEY_DOMAIN
"="));
451 queryString
.Append(escapedDomain
);
455 query
->GetHasUri(&hasIt
);
457 AppendBoolKeyValueIfTrue(aQueryString
,
458 NS_LITERAL_CSTRING(QUERYKEY_URIISPREFIX
),
459 query
, &nsINavHistoryQuery::GetUriIsPrefix
);
460 nsCOMPtr
<nsIURI
> uri
;
461 query
->GetUri(getter_AddRefs(uri
));
462 NS_ENSURE_TRUE(uri
, NS_ERROR_FAILURE
); // hasURI should tell is if invalid
463 nsCAutoString uriSpec
;
464 nsresult rv
= uri
->GetSpec(uriSpec
);
465 NS_ENSURE_SUCCESS(rv
, rv
);
466 nsCAutoString escaped
;
467 PRBool success
= NS_Escape(uriSpec
, escaped
, url_XAlphas
);
468 NS_ENSURE_TRUE(success
, NS_ERROR_OUT_OF_MEMORY
);
470 AppendAmpersandIfNonempty(queryString
);
471 queryString
.Append(NS_LITERAL_CSTRING(QUERYKEY_URI
"="));
472 queryString
.Append(escaped
);
476 query
->GetHasAnnotation(&hasIt
);
478 AppendAmpersandIfNonempty(queryString
);
479 PRBool annotationIsNot
;
480 query
->GetAnnotationIsNot(&annotationIsNot
);
482 queryString
.AppendLiteral(QUERYKEY_NOTANNOTATION
"=");
484 queryString
.AppendLiteral(QUERYKEY_ANNOTATION
"=");
486 query
->GetAnnotation(annot
);
487 nsCAutoString escaped
;
488 PRBool success
= NS_Escape(annot
, escaped
, url_XAlphas
);
489 NS_ENSURE_TRUE(success
, NS_ERROR_OUT_OF_MEMORY
);
490 queryString
.Append(escaped
);
494 PRInt64
*folders
= nsnull
;
495 PRUint32 folderCount
= 0;
496 query
->GetFolders(&folderCount
, &folders
);
497 for (PRUint32 i
= 0; i
< folderCount
; ++i
) {
498 AppendAmpersandIfNonempty(queryString
);
499 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_FOLDER
"=");
500 PlacesFolderConversion::AppendFolder(queryString
, folders
[i
]);
502 nsMemory::Free(folders
);
506 if (options
->SortingMode() != nsINavHistoryQueryOptions::SORT_BY_NONE
) {
507 AppendAmpersandIfNonempty(queryString
);
508 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_SORT
"=");
509 AppendInt16(queryString
, options
->SortingMode());
510 if (options
->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_DESCENDING
||
511 options
->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_ASCENDING
) {
513 nsCAutoString sortingAnnotation
;
514 if (NS_SUCCEEDED(options
->GetSortingAnnotation(sortingAnnotation
))) {
516 if (!NS_Escape(sortingAnnotation
, escaped
, url_XAlphas
))
517 return NS_ERROR_OUT_OF_MEMORY
;
518 AppendAmpersandIfNonempty(queryString
);
519 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_SORTING_ANNOTATION
"=");
520 queryString
.Append(escaped
);
526 if (options
->ResultType() != nsINavHistoryQueryOptions::RESULTS_AS_URI
) {
527 AppendAmpersandIfNonempty(queryString
);
528 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_RESULT_TYPE
"=");
529 AppendInt16(queryString
, options
->ResultType());
533 if (options
->ExcludeItems()) {
534 AppendAmpersandIfNonempty(queryString
);
535 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEMS
"=1");
539 if (options
->ExcludeQueries()) {
540 AppendAmpersandIfNonempty(queryString
);
541 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_QUERIES
"=1");
544 // exclude read only folders
545 if (options
->ExcludeReadOnlyFolders()) {
546 AppendAmpersandIfNonempty(queryString
);
547 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS
"=1");
550 // exclude item if parent has annotation
551 nsCAutoString parentAnnotationToExclude
;
552 if (NS_SUCCEEDED(options
->GetExcludeItemIfParentHasAnnotation(parentAnnotationToExclude
)) &&
553 !parentAnnotationToExclude
.IsEmpty()) {
555 if (!NS_Escape(parentAnnotationToExclude
, escaped
, url_XAlphas
))
556 return NS_ERROR_OUT_OF_MEMORY
;
557 AppendAmpersandIfNonempty(queryString
);
558 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEM_IF_PARENT_HAS_ANNOTATION
"=");
559 queryString
.Append(escaped
);
563 if (!options
->ExpandQueries()) {
564 AppendAmpersandIfNonempty(queryString
);
565 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_EXPAND_QUERIES
"=0");
569 if (options
->IncludeHidden()) {
570 AppendAmpersandIfNonempty(queryString
);
571 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_INCLUDE_HIDDEN
"=1");
575 if (options
->ShowSessions()) {
576 AppendAmpersandIfNonempty(queryString
);
577 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_SHOW_SESSIONS
"=1");
581 if (options
->MaxResults()) {
582 AppendAmpersandIfNonempty(queryString
);
583 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_MAX_RESULTS
"=");
584 AppendInt32(queryString
, options
->MaxResults());
588 if (options
->QueryType() != nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY
) {
589 AppendAmpersandIfNonempty(queryString
);
590 queryString
+= NS_LITERAL_CSTRING(QUERYKEY_QUERY_TYPE
"=");
591 AppendInt16(queryString
, options
->QueryType());
594 aQueryString
.Assign(NS_LITERAL_CSTRING("place:") + queryString
);
599 // TokenizeQueryString
602 TokenizeQueryString(const nsACString
& aQuery
,
603 nsTArray
<QueryKeyValuePair
>* aTokens
)
605 // Strip off the "place:" prefix
606 const PRUint32 prefixlen
= 6; // = strlen("place:");
608 if (aQuery
.Length() > prefixlen
&&
609 Substring(aQuery
, 0, prefixlen
).EqualsLiteral("place:"))
610 query
= Substring(aQuery
, prefixlen
);
614 PRInt32 keyFirstIndex
= 0;
615 PRInt32 equalsIndex
= 0;
616 for (PRUint32 i
= 0; i
< query
.Length(); i
++) {
617 if (query
[i
] == '&') {
618 // new clause, save last one
619 if (i
- keyFirstIndex
> 1) {
620 if (! aTokens
->AppendElement(QueryKeyValuePair(query
, keyFirstIndex
,
622 return NS_ERROR_OUT_OF_MEMORY
;
624 keyFirstIndex
= equalsIndex
= i
+ 1;
625 } else if (query
[i
] == '=') {
630 // handle last pair, if any
631 if (query
.Length() - keyFirstIndex
> 1) {
632 if (! aTokens
->AppendElement(QueryKeyValuePair(query
, keyFirstIndex
,
633 equalsIndex
, query
.Length())))
634 return NS_ERROR_OUT_OF_MEMORY
;
639 // nsNavHistory::TokensToQueries
642 nsNavHistory::TokensToQueries(const nsTArray
<QueryKeyValuePair
>& aTokens
,
643 nsCOMArray
<nsNavHistoryQuery
>* aQueries
,
644 nsNavHistoryQueryOptions
* aOptions
)
647 if (aTokens
.Length() == 0)
648 return NS_OK
; // nothing to do
650 nsTArray
<PRInt64
> folders
;
652 nsCOMPtr
<nsNavHistoryQuery
> query(new nsNavHistoryQuery());
654 return NS_ERROR_OUT_OF_MEMORY
;
655 if (! aQueries
->AppendObject(query
))
656 return NS_ERROR_OUT_OF_MEMORY
;
657 for (PRUint32 i
= 0; i
< aTokens
.Length(); i
++) {
658 const QueryKeyValuePair
& kvp
= aTokens
[i
];
661 if (kvp
.key
.EqualsLiteral(QUERYKEY_BEGIN_TIME
)) {
662 SetQueryKeyInt64(kvp
.value
, query
, &nsINavHistoryQuery::SetBeginTime
);
664 // begin time reference
665 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_BEGIN_TIME_REFERENCE
)) {
666 SetQueryKeyUint32(kvp
.value
, query
, &nsINavHistoryQuery::SetBeginTimeReference
);
669 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_END_TIME
)) {
670 SetQueryKeyInt64(kvp
.value
, query
, &nsINavHistoryQuery::SetEndTime
);
672 // end time reference
673 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_END_TIME_REFERENCE
)) {
674 SetQueryKeyUint32(kvp
.value
, query
, &nsINavHistoryQuery::SetEndTimeReference
);
677 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_SEARCH_TERMS
)) {
678 nsCString unescapedTerms
= kvp
.value
;
679 NS_UnescapeURL(unescapedTerms
); // modifies input
680 rv
= query
->SetSearchTerms(NS_ConvertUTF8toUTF16(unescapedTerms
));
681 NS_ENSURE_SUCCESS(rv
, rv
);
684 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_MIN_VISITS
)) {
685 PRInt32 visits
= kvp
.value
.ToInteger((PRInt32
*)&rv
);
686 if (NS_SUCCEEDED(rv
))
687 query
->SetMinVisits(visits
);
689 NS_WARNING("Bad number for minVisits in query");
692 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_MAX_VISITS
)) {
693 PRInt32 visits
= kvp
.value
.ToInteger((PRInt32
*)&rv
);
694 if (NS_SUCCEEDED(rv
))
695 query
->SetMaxVisits(visits
);
697 NS_WARNING("Bad number for maxVisits in query");
699 // onlyBookmarked flag
700 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_ONLY_BOOKMARKED
)) {
701 SetQueryKeyBool(kvp
.value
, query
, &nsINavHistoryQuery::SetOnlyBookmarked
);
704 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_DOMAIN_IS_HOST
)) {
705 SetQueryKeyBool(kvp
.value
, query
, &nsINavHistoryQuery::SetDomainIsHost
);
708 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_DOMAIN
)) {
709 nsCAutoString
unescapedDomain(kvp
.value
);
710 NS_UnescapeURL(unescapedDomain
); // modifies input
711 rv
= query
->SetDomain(unescapedDomain
);
712 NS_ENSURE_SUCCESS(rv
, rv
);
715 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_FOLDER
)) {
717 if (PR_sscanf(kvp
.value
.get(), "%lld", &folder
) == 1) {
718 NS_ENSURE_TRUE(folders
.AppendElement(folder
), NS_ERROR_OUT_OF_MEMORY
);
720 folder
= PlacesFolderConversion::DecodeFolder(kvp
.value
);
722 NS_ENSURE_TRUE(folders
.AppendElement(folder
), NS_ERROR_OUT_OF_MEMORY
);
724 NS_WARNING("folders value in query is invalid, ignoring");
728 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_URI
)) {
729 nsCAutoString
unescapedUri(kvp
.value
);
730 NS_UnescapeURL(unescapedUri
); // modifies input
731 nsCOMPtr
<nsIURI
> uri
;
732 nsresult rv
= NS_NewURI(getter_AddRefs(uri
), unescapedUri
);
734 NS_WARNING("Unable to parse URI");
736 rv
= query
->SetUri(uri
);
737 NS_ENSURE_SUCCESS(rv
, rv
);
740 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_URIISPREFIX
)) {
741 SetQueryKeyBool(kvp
.value
, query
, &nsINavHistoryQuery::SetUriIsPrefix
);
744 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_NOTANNOTATION
)) {
745 nsCAutoString
unescaped(kvp
.value
);
746 NS_UnescapeURL(unescaped
); // modifies input
747 query
->SetAnnotationIsNot(PR_TRUE
);
748 query
->SetAnnotation(unescaped
);
751 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_ANNOTATION
)) {
752 nsCAutoString
unescaped(kvp
.value
);
753 NS_UnescapeURL(unescaped
); // modifies input
754 query
->SetAnnotationIsNot(PR_FALSE
);
755 query
->SetAnnotation(unescaped
);
757 // new query component
758 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_SEPARATOR
)) {
760 if (folders
.Length() != 0) {
761 query
->SetFolders(folders
.Elements(), folders
.Length());
765 query
= new nsNavHistoryQuery();
767 return NS_ERROR_OUT_OF_MEMORY
;
768 if (! aQueries
->AppendObject(query
))
769 return NS_ERROR_OUT_OF_MEMORY
;
772 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_SORT
)) {
773 SetOptionsKeyUint16(kvp
.value
, aOptions
,
774 &nsINavHistoryQueryOptions::SetSortingMode
);
775 // sorting annotation
776 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_SORTING_ANNOTATION
)) {
777 nsCString sortingAnnotation
= kvp
.value
;
778 NS_UnescapeURL(sortingAnnotation
);
779 rv
= aOptions
->SetSortingAnnotation(sortingAnnotation
);
780 NS_ENSURE_SUCCESS(rv
, rv
);
782 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_RESULT_TYPE
)) {
783 SetOptionsKeyUint16(kvp
.value
, aOptions
,
784 &nsINavHistoryQueryOptions::SetResultType
);
787 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_EXCLUDE_ITEMS
)) {
788 SetOptionsKeyBool(kvp
.value
, aOptions
,
789 &nsINavHistoryQueryOptions::SetExcludeItems
);
792 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_EXCLUDE_QUERIES
)) {
793 SetOptionsKeyBool(kvp
.value
, aOptions
,
794 &nsINavHistoryQueryOptions::SetExcludeQueries
);
796 // exclude read only folders
797 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS
)) {
798 SetOptionsKeyBool(kvp
.value
, aOptions
,
799 &nsINavHistoryQueryOptions::SetExcludeReadOnlyFolders
);
801 // exclude item if parent has annotation
802 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_EXCLUDE_ITEM_IF_PARENT_HAS_ANNOTATION
)) {
803 nsCString parentAnnotationToExclude
= kvp
.value
;
804 NS_UnescapeURL(parentAnnotationToExclude
);
805 rv
= aOptions
->SetExcludeItemIfParentHasAnnotation(parentAnnotationToExclude
);
806 NS_ENSURE_SUCCESS(rv
, rv
);
809 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_EXPAND_QUERIES
)) {
810 SetOptionsKeyBool(kvp
.value
, aOptions
,
811 &nsINavHistoryQueryOptions::SetExpandQueries
);
813 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_INCLUDE_HIDDEN
)) {
814 SetOptionsKeyBool(kvp
.value
, aOptions
,
815 &nsINavHistoryQueryOptions::SetIncludeHidden
);
818 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_SHOW_SESSIONS
)) {
819 SetOptionsKeyBool(kvp
.value
, aOptions
,
820 &nsINavHistoryQueryOptions::SetShowSessions
);
822 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_MAX_RESULTS
)) {
823 SetOptionsKeyUint32(kvp
.value
, aOptions
,
824 &nsINavHistoryQueryOptions::SetMaxResults
);
826 } else if (kvp
.key
.EqualsLiteral(QUERYKEY_QUERY_TYPE
)) {
827 SetOptionsKeyUint16(kvp
.value
, aOptions
,
828 &nsINavHistoryQueryOptions::SetQueryType
);
831 NS_WARNING("TokensToQueries(), ignoring unknown key: ");
832 NS_WARNING(kvp
.key
.get());
836 if (folders
.Length() != 0)
837 query
->SetFolders(folders
.Elements(), folders
.Length());
843 // ParseQueryBooleanString
845 // Converts a 0/1 or true/false string into a bool
848 ParseQueryBooleanString(const nsCString
& aString
, PRBool
* aValue
)
850 if (aString
.EqualsLiteral("1") || aString
.EqualsLiteral("true")) {
853 } else if (aString
.EqualsLiteral("0") || aString
.EqualsLiteral("false")) {
857 return NS_ERROR_INVALID_ARG
;
861 // nsINavHistoryQuery **********************************************************
863 NS_IMPL_ISUPPORTS2(nsNavHistoryQuery
, nsNavHistoryQuery
, nsINavHistoryQuery
)
865 // nsINavHistoryQuery::nsNavHistoryQuery
867 // This must initialize the object such that the default values will cause
868 // all history to be returned if this query is used. Then the caller can
869 // just set the things it's interested in.
871 nsNavHistoryQuery::nsNavHistoryQuery()
872 : mMinVisits(-1), mMaxVisits(-1), mBeginTime(0),
873 mBeginTimeReference(TIME_RELATIVE_EPOCH
),
874 mEndTime(0), mEndTimeReference(TIME_RELATIVE_EPOCH
),
875 mOnlyBookmarked(PR_FALSE
),
876 mDomainIsHost(PR_FALSE
), mUriIsPrefix(PR_FALSE
),
877 mAnnotationIsNot(PR_FALSE
)
879 // differentiate not set (IsVoid) from empty string (local files)
880 mDomain
.SetIsVoid(PR_TRUE
);
883 /* attribute PRTime beginTime; */
884 NS_IMETHODIMP
nsNavHistoryQuery::GetBeginTime(PRTime
*aBeginTime
)
886 *aBeginTime
= mBeginTime
;
889 NS_IMETHODIMP
nsNavHistoryQuery::SetBeginTime(PRTime aBeginTime
)
891 mBeginTime
= aBeginTime
;
895 /* attribute long beginTimeReference; */
896 NS_IMETHODIMP
nsNavHistoryQuery::GetBeginTimeReference(PRUint32
* _retval
)
898 *_retval
= mBeginTimeReference
;
901 NS_IMETHODIMP
nsNavHistoryQuery::SetBeginTimeReference(PRUint32 aReference
)
903 if (aReference
> TIME_RELATIVE_NOW
)
904 return NS_ERROR_INVALID_ARG
;
905 mBeginTimeReference
= aReference
;
909 /* readonly attribute boolean hasBeginTime; */
910 NS_IMETHODIMP
nsNavHistoryQuery::GetHasBeginTime(PRBool
* _retval
)
912 *_retval
= ! (mBeginTimeReference
== TIME_RELATIVE_EPOCH
&& mBeginTime
== 0);
916 /* readonly attribute PRTime absoluteBeginTime; */
917 NS_IMETHODIMP
nsNavHistoryQuery::GetAbsoluteBeginTime(PRTime
* _retval
)
919 *_retval
= nsNavHistory::NormalizeTime(mBeginTimeReference
, mBeginTime
);
923 /* attribute PRTime endTime; */
924 NS_IMETHODIMP
nsNavHistoryQuery::GetEndTime(PRTime
*aEndTime
)
926 *aEndTime
= mEndTime
;
929 NS_IMETHODIMP
nsNavHistoryQuery::SetEndTime(PRTime aEndTime
)
935 /* attribute long endTimeReference; */
936 NS_IMETHODIMP
nsNavHistoryQuery::GetEndTimeReference(PRUint32
* _retval
)
938 *_retval
= mEndTimeReference
;
941 NS_IMETHODIMP
nsNavHistoryQuery::SetEndTimeReference(PRUint32 aReference
)
943 if (aReference
> TIME_RELATIVE_NOW
)
944 return NS_ERROR_INVALID_ARG
;
945 mEndTimeReference
= aReference
;
949 /* readonly attribute boolean hasEndTime; */
950 NS_IMETHODIMP
nsNavHistoryQuery::GetHasEndTime(PRBool
* _retval
)
952 *_retval
= ! (mEndTimeReference
== TIME_RELATIVE_EPOCH
&& mEndTime
== 0);
956 /* readonly attribute PRTime absoluteEndTime; */
957 NS_IMETHODIMP
nsNavHistoryQuery::GetAbsoluteEndTime(PRTime
* _retval
)
959 *_retval
= nsNavHistory::NormalizeTime(mEndTimeReference
, mEndTime
);
963 /* attribute string searchTerms; */
964 NS_IMETHODIMP
nsNavHistoryQuery::GetSearchTerms(nsAString
& aSearchTerms
)
966 aSearchTerms
= mSearchTerms
;
969 NS_IMETHODIMP
nsNavHistoryQuery::SetSearchTerms(const nsAString
& aSearchTerms
)
971 mSearchTerms
= aSearchTerms
;
974 NS_IMETHODIMP
nsNavHistoryQuery::GetHasSearchTerms(PRBool
* _retval
)
976 *_retval
= (! mSearchTerms
.IsEmpty());
980 /* attribute PRInt32 minVisits; */
981 NS_IMETHODIMP
nsNavHistoryQuery::GetMinVisits(PRInt32
* _retval
)
983 NS_ENSURE_ARG_POINTER(_retval
);
984 *_retval
= mMinVisits
;
987 NS_IMETHODIMP
nsNavHistoryQuery::SetMinVisits(PRInt32 aVisits
)
989 mMinVisits
= aVisits
;
993 /* attribute PRint32 maxVisits; */
994 NS_IMETHODIMP
nsNavHistoryQuery::GetMaxVisits(PRInt32
* _retval
)
996 NS_ENSURE_ARG_POINTER(_retval
);
997 *_retval
= mMaxVisits
;
1000 NS_IMETHODIMP
nsNavHistoryQuery::SetMaxVisits(PRInt32 aVisits
)
1002 mMaxVisits
= aVisits
;
1006 /* attribute boolean onlyBookmarked; */
1007 NS_IMETHODIMP
nsNavHistoryQuery::GetOnlyBookmarked(PRBool
*aOnlyBookmarked
)
1009 *aOnlyBookmarked
= mOnlyBookmarked
;
1012 NS_IMETHODIMP
nsNavHistoryQuery::SetOnlyBookmarked(PRBool aOnlyBookmarked
)
1014 mOnlyBookmarked
= aOnlyBookmarked
;
1018 /* attribute boolean domainIsHost; */
1019 NS_IMETHODIMP
nsNavHistoryQuery::GetDomainIsHost(PRBool
*aDomainIsHost
)
1021 *aDomainIsHost
= mDomainIsHost
;
1024 NS_IMETHODIMP
nsNavHistoryQuery::SetDomainIsHost(PRBool aDomainIsHost
)
1026 mDomainIsHost
= aDomainIsHost
;
1030 /* attribute AUTF8String domain; */
1031 NS_IMETHODIMP
nsNavHistoryQuery::GetDomain(nsACString
& aDomain
)
1036 NS_IMETHODIMP
nsNavHistoryQuery::SetDomain(const nsACString
& aDomain
)
1041 NS_IMETHODIMP
nsNavHistoryQuery::GetHasDomain(PRBool
* _retval
)
1043 // note that empty but not void is still a valid query (local files)
1044 *_retval
= (! mDomain
.IsVoid());
1048 /* attribute boolean uriIsPrefix; */
1049 NS_IMETHODIMP
nsNavHistoryQuery::GetUriIsPrefix(PRBool
* aIsPrefix
)
1051 *aIsPrefix
= mUriIsPrefix
;
1054 NS_IMETHODIMP
nsNavHistoryQuery::SetUriIsPrefix(PRBool aIsPrefix
)
1056 mUriIsPrefix
= aIsPrefix
;
1060 /* attribute nsIURI uri; */
1061 NS_IMETHODIMP
nsNavHistoryQuery::GetUri(nsIURI
** aUri
)
1067 NS_IMETHODIMP
nsNavHistoryQuery::SetUri(nsIURI
* aUri
)
1072 NS_IMETHODIMP
nsNavHistoryQuery::GetHasUri(PRBool
* aHasUri
)
1074 *aHasUri
= (mUri
!= nsnull
);
1078 /* attribute boolean annotationIsNot; */
1079 NS_IMETHODIMP
nsNavHistoryQuery::GetAnnotationIsNot(PRBool
* aIsNot
)
1081 *aIsNot
= mAnnotationIsNot
;
1084 NS_IMETHODIMP
nsNavHistoryQuery::SetAnnotationIsNot(PRBool aIsNot
)
1086 mAnnotationIsNot
= aIsNot
;
1090 /* attribute AUTF8String annotation; */
1091 NS_IMETHODIMP
nsNavHistoryQuery::GetAnnotation(nsACString
& aAnnotation
)
1093 aAnnotation
= mAnnotation
;
1096 NS_IMETHODIMP
nsNavHistoryQuery::SetAnnotation(const nsACString
& aAnnotation
)
1098 mAnnotation
= aAnnotation
;
1101 NS_IMETHODIMP
nsNavHistoryQuery::GetHasAnnotation(PRBool
* aHasIt
)
1103 *aHasIt
= ! mAnnotation
.IsEmpty();
1107 NS_IMETHODIMP
nsNavHistoryQuery::GetFolders(PRUint32
*aCount
,
1110 PRUint32 count
= mFolders
.Length();
1111 PRInt64
*folders
= nsnull
;
1113 folders
= static_cast<PRInt64
*>
1114 (nsMemory::Alloc(count
* sizeof(PRInt64
)));
1115 NS_ENSURE_TRUE(folders
, NS_ERROR_OUT_OF_MEMORY
);
1117 for (PRUint32 i
= 0; i
< count
; ++i
) {
1118 folders
[i
] = mFolders
[i
];
1122 *aFolders
= folders
;
1126 NS_IMETHODIMP
nsNavHistoryQuery::GetFolderCount(PRUint32
*aCount
)
1128 *aCount
= mFolders
.Length();
1132 NS_IMETHODIMP
nsNavHistoryQuery::SetFolders(const PRInt64
*aFolders
,
1133 PRUint32 aFolderCount
)
1135 if (!mFolders
.ReplaceElementsAt(0, mFolders
.Length(),
1136 aFolders
, aFolderCount
)) {
1137 return NS_ERROR_OUT_OF_MEMORY
;
1143 NS_IMETHODIMP
nsNavHistoryQuery::Clone(nsINavHistoryQuery
** _retval
)
1147 nsNavHistoryQuery
*clone
= new nsNavHistoryQuery(*this);
1148 NS_ENSURE_TRUE(clone
, NS_ERROR_OUT_OF_MEMORY
);
1150 clone
->mRefCnt
= 0; // the clone doesn't inherit our refcount
1151 NS_ADDREF(*_retval
= clone
);
1156 // nsNavHistoryQueryOptions
1157 NS_IMPL_ISUPPORTS2(nsNavHistoryQueryOptions
, nsNavHistoryQueryOptions
, nsINavHistoryQueryOptions
)
1161 nsNavHistoryQueryOptions::GetSortingMode(PRUint16
* aMode
)
1167 nsNavHistoryQueryOptions::SetSortingMode(PRUint16 aMode
)
1169 if (aMode
> SORT_BY_ANNOTATION_DESCENDING
)
1170 return NS_ERROR_INVALID_ARG
;
1175 // sortingAnnotation
1177 nsNavHistoryQueryOptions::GetSortingAnnotation(nsACString
& _result
) {
1178 _result
.Assign(mSortingAnnotation
);
1183 nsNavHistoryQueryOptions::SetSortingAnnotation(const nsACString
& aSortingAnnotation
) {
1184 mSortingAnnotation
.Assign(aSortingAnnotation
);
1190 nsNavHistoryQueryOptions::GetResultType(PRUint16
* aType
)
1192 *aType
= mResultType
;
1196 nsNavHistoryQueryOptions::SetResultType(PRUint16 aType
)
1198 if (aType
> RESULTS_AS_TAG_CONTENTS
)
1199 return NS_ERROR_INVALID_ARG
;
1200 mResultType
= aType
;
1206 nsNavHistoryQueryOptions::GetExcludeItems(PRBool
* aExclude
)
1208 *aExclude
= mExcludeItems
;
1212 nsNavHistoryQueryOptions::SetExcludeItems(PRBool aExclude
)
1214 mExcludeItems
= aExclude
;
1220 nsNavHistoryQueryOptions::GetExcludeQueries(PRBool
* aExclude
)
1222 *aExclude
= mExcludeQueries
;
1226 nsNavHistoryQueryOptions::SetExcludeQueries(PRBool aExclude
)
1228 mExcludeQueries
= aExclude
;
1232 // excludeReadOnlyFolders
1234 nsNavHistoryQueryOptions::GetExcludeReadOnlyFolders(PRBool
* aExclude
)
1236 *aExclude
= mExcludeReadOnlyFolders
;
1240 nsNavHistoryQueryOptions::SetExcludeReadOnlyFolders(PRBool aExclude
)
1242 mExcludeReadOnlyFolders
= aExclude
;
1246 // excludeItemIfParentHasAnnotation
1248 nsNavHistoryQueryOptions::GetExcludeItemIfParentHasAnnotation(nsACString
& _result
) {
1249 _result
.Assign(mParentAnnotationToExclude
);
1254 nsNavHistoryQueryOptions::SetExcludeItemIfParentHasAnnotation(const nsACString
& aParentAnnotationToExclude
) {
1255 mParentAnnotationToExclude
.Assign(aParentAnnotationToExclude
);
1261 nsNavHistoryQueryOptions::GetExpandQueries(PRBool
* aExpand
)
1263 *aExpand
= mExpandQueries
;
1267 nsNavHistoryQueryOptions::SetExpandQueries(PRBool aExpand
)
1269 mExpandQueries
= aExpand
;
1275 nsNavHistoryQueryOptions::GetIncludeHidden(PRBool
* aIncludeHidden
)
1277 *aIncludeHidden
= mIncludeHidden
;
1281 nsNavHistoryQueryOptions::SetIncludeHidden(PRBool aIncludeHidden
)
1283 mIncludeHidden
= aIncludeHidden
;
1289 nsNavHistoryQueryOptions::GetShowSessions(PRBool
* aShowSessions
)
1291 *aShowSessions
= mShowSessions
;
1295 nsNavHistoryQueryOptions::SetShowSessions(PRBool aShowSessions
)
1297 mShowSessions
= aShowSessions
;
1303 nsNavHistoryQueryOptions::GetMaxResults(PRUint32
* aMaxResults
)
1305 *aMaxResults
= mMaxResults
;
1309 nsNavHistoryQueryOptions::SetMaxResults(PRUint32 aMaxResults
)
1311 mMaxResults
= aMaxResults
;
1317 nsNavHistoryQueryOptions::GetQueryType(PRUint16
* _retval
)
1319 *_retval
= mQueryType
;
1323 nsNavHistoryQueryOptions::SetQueryType(PRUint16 aQueryType
)
1325 mQueryType
= aQueryType
;
1330 nsNavHistoryQueryOptions::Clone(nsINavHistoryQueryOptions
** aResult
)
1332 nsNavHistoryQueryOptions
*clone
= nsnull
;
1333 nsresult rv
= Clone(&clone
);
1339 nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions
**aResult
)
1342 nsNavHistoryQueryOptions
*result
= new nsNavHistoryQueryOptions();
1344 return NS_ERROR_OUT_OF_MEMORY
;
1346 nsRefPtr
<nsNavHistoryQueryOptions
> resultHolder(result
);
1347 result
->mSort
= mSort
;
1348 result
->mResultType
= mResultType
;
1349 result
->mExcludeItems
= mExcludeItems
;
1350 result
->mExcludeQueries
= mExcludeQueries
;
1351 result
->mShowSessions
= mShowSessions
;
1352 result
->mExpandQueries
= mExpandQueries
;
1353 result
->mMaxResults
= mMaxResults
;
1354 result
->mQueryType
= mQueryType
;
1355 result
->mParentAnnotationToExclude
= mParentAnnotationToExclude
;
1357 resultHolder
.swap(*aResult
);
1362 // AppendBoolKeyValueIfTrue
1365 AppendBoolKeyValueIfTrue(nsACString
& aString
, const nsCString
& aName
,
1366 nsINavHistoryQuery
* aQuery
,
1367 BoolQueryGetter getter
)
1370 nsresult rv
= (aQuery
->*getter
)(&value
);
1371 NS_ASSERTION(NS_SUCCEEDED(rv
), "Failure getting boolean value");
1373 AppendAmpersandIfNonempty(aString
);
1375 aString
.AppendLiteral("=1");
1380 // AppendUint32KeyValueIfNonzero
1383 AppendUint32KeyValueIfNonzero(nsACString
& aString
,
1384 const nsCString
& aName
,
1385 nsINavHistoryQuery
* aQuery
,
1386 Uint32QueryGetter getter
)
1389 nsresult rv
= (aQuery
->*getter
)(&value
);
1390 NS_ASSERTION(NS_SUCCEEDED(rv
), "Failure getting value");
1392 AppendAmpersandIfNonempty(aString
);
1395 // AppendInt requires a concrete string
1396 nsCAutoString
appendMe("=");
1397 appendMe
.AppendInt(value
);
1398 aString
.Append(appendMe
);
1403 // AppendInt64KeyValueIfNonzero
1406 AppendInt64KeyValueIfNonzero(nsACString
& aString
,
1407 const nsCString
& aName
,
1408 nsINavHistoryQuery
* aQuery
,
1409 Int64QueryGetter getter
)
1412 nsresult rv
= (aQuery
->*getter
)(&value
);
1413 NS_ASSERTION(NS_SUCCEEDED(rv
), "Failure getting value");
1415 AppendAmpersandIfNonempty(aString
);
1417 nsCAutoString
appendMe("=");
1418 appendMe
.AppendInt(value
);
1419 aString
.Append(appendMe
);
1424 // SetQuery/OptionsKeyBool
1427 SetQueryKeyBool(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
1428 BoolQuerySetter setter
)
1431 nsresult rv
= ParseQueryBooleanString(aValue
, &value
);
1432 if (NS_SUCCEEDED(rv
)) {
1433 rv
= (aQuery
->*setter
)(value
);
1434 if (NS_FAILED(rv
)) {
1435 NS_WARNING("Error setting boolean key value");
1438 NS_WARNING("Invalid boolean key value in query string.");
1442 SetOptionsKeyBool(const nsCString
& aValue
, nsINavHistoryQueryOptions
* aOptions
,
1443 BoolOptionsSetter setter
)
1446 nsresult rv
= ParseQueryBooleanString(aValue
, &value
);
1447 if (NS_SUCCEEDED(rv
)) {
1448 rv
= (aOptions
->*setter
)(value
);
1449 if (NS_FAILED(rv
)) {
1450 NS_WARNING("Error setting boolean key value");
1453 NS_WARNING("Invalid boolean key value in query string.");
1458 // SetQuery/OptionsKeyUint32
1461 SetQueryKeyUint32(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
1462 Uint32QuerySetter setter
)
1465 PRUint32 value
= aValue
.ToInteger(reinterpret_cast<PRInt32
*>(&rv
));
1466 if (NS_SUCCEEDED(rv
)) {
1467 rv
= (aQuery
->*setter
)(value
);
1468 if (NS_FAILED(rv
)) {
1469 NS_WARNING("Error setting Int32 key value");
1472 NS_WARNING("Invalid Int32 key value in query string.");
1476 SetOptionsKeyUint32(const nsCString
& aValue
, nsINavHistoryQueryOptions
* aOptions
,
1477 Uint32OptionsSetter setter
)
1480 PRUint32 value
= aValue
.ToInteger(reinterpret_cast<PRInt32
*>(&rv
));
1481 if (NS_SUCCEEDED(rv
)) {
1482 rv
= (aOptions
->*setter
)(value
);
1483 if (NS_FAILED(rv
)) {
1484 NS_WARNING("Error setting Int32 key value");
1487 NS_WARNING("Invalid Int32 key value in query string.");
1492 SetOptionsKeyUint16(const nsCString
& aValue
, nsINavHistoryQueryOptions
* aOptions
,
1493 Uint16OptionsSetter setter
)
1496 PRUint16 value
= static_cast<PRUint16
>
1497 (aValue
.ToInteger(reinterpret_cast<PRInt32
*>(&rv
)));
1498 if (NS_SUCCEEDED(rv
)) {
1499 rv
= (aOptions
->*setter
)(value
);
1500 if (NS_FAILED(rv
)) {
1501 NS_WARNING("Error setting Int16 key value");
1504 NS_WARNING("Invalid Int16 key value in query string.");
1511 void SetQueryKeyInt64(const nsCString
& aValue
, nsINavHistoryQuery
* aQuery
,
1512 Int64QuerySetter setter
)
1516 if (PR_sscanf(aValue
.get(), "%lld", &value
) == 1) {
1517 rv
= (aQuery
->*setter
)(value
);
1518 if (NS_FAILED(rv
)) {
1519 NS_WARNING("Error setting Int64 key value");
1522 NS_WARNING("Invalid Int64 value in query string.");