toolkit/components/places/nsNavHistoryResult.h

branch
TOR_BUG_3246
changeset 7
129ffea94266
equal deleted inserted replaced
-1:000000000000 0:0d4a67808fa8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /**
7 * The definitions of objects that make up a history query result set. This file
8 * should only be included by nsNavHistory.h, include that if you want these
9 * classes.
10 */
11
12 #ifndef nsNavHistoryResult_h_
13 #define nsNavHistoryResult_h_
14
15 #include "nsTArray.h"
16 #include "nsInterfaceHashtable.h"
17 #include "nsDataHashtable.h"
18 #include "nsCycleCollectionParticipant.h"
19 #include "mozilla/storage.h"
20 #include "Helpers.h"
21
22 class nsNavHistory;
23 class nsNavHistoryQuery;
24 class nsNavHistoryQueryOptions;
25
26 class nsNavHistoryContainerResultNode;
27 class nsNavHistoryFolderResultNode;
28 class nsNavHistoryQueryResultNode;
29
30 /**
31 * hashkey wrapper using int64_t KeyType
32 *
33 * @see nsTHashtable::EntryType for specification
34 *
35 * This just truncates the 64-bit int to a 32-bit one for using a hash number.
36 * It is used for bookmark folder IDs, which should be way less than 2^32.
37 */
38 class nsTrimInt64HashKey : public PLDHashEntryHdr
39 {
40 public:
41 typedef const int64_t& KeyType;
42 typedef const int64_t* KeyTypePointer;
43
44 nsTrimInt64HashKey(KeyTypePointer aKey) : mValue(*aKey) { }
45 nsTrimInt64HashKey(const nsTrimInt64HashKey& toCopy) : mValue(toCopy.mValue) { }
46 ~nsTrimInt64HashKey() { }
47
48 KeyType GetKey() const { return mValue; }
49 bool KeyEquals(KeyTypePointer aKey) const { return *aKey == mValue; }
50
51 static KeyTypePointer KeyToPointer(KeyType aKey) { return &aKey; }
52 static PLDHashNumber HashKey(KeyTypePointer aKey)
53 { return static_cast<uint32_t>((*aKey) & UINT32_MAX); }
54 enum { ALLOW_MEMMOVE = true };
55
56 private:
57 const int64_t mValue;
58 };
59
60
61 // Declare methods for implementing nsINavBookmarkObserver
62 // and nsINavHistoryObserver (some methods, such as BeginUpdateBatch overlap)
63 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
64 NS_DECL_NSINAVBOOKMARKOBSERVER \
65 NS_IMETHOD OnTitleChanged(nsIURI* aURI, const nsAString& aPageTitle, \
66 const nsACString& aGUID); \
67 NS_IMETHOD OnFrecencyChanged(nsIURI* aURI, int32_t aNewFrecency, \
68 const nsACString& aGUID, bool aHidden, \
69 PRTime aLastVisitDate); \
70 NS_IMETHOD OnManyFrecenciesChanged(); \
71 NS_IMETHOD OnDeleteURI(nsIURI *aURI, const nsACString& aGUID, \
72 uint16_t aReason); \
73 NS_IMETHOD OnClearHistory(); \
74 NS_IMETHOD OnPageChanged(nsIURI *aURI, uint32_t aChangedAttribute, \
75 const nsAString &aNewValue, \
76 const nsACString &aGUID); \
77 NS_IMETHOD OnDeleteVisits(nsIURI* aURI, PRTime aVisitTime, \
78 const nsACString& aGUID, uint16_t aReason, \
79 uint32_t aTransitionType);
80
81 // The internal version has an output aAdded parameter, it is incremented by
82 // query nodes when the visited uri belongs to them. If no such query exists,
83 // the history result creates a new query node dynamically.
84 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL \
85 NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
86 NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
87 int64_t aSessionId, int64_t aReferringId, \
88 uint32_t aTransitionType, const nsACString& aGUID, \
89 bool aHidden, uint32_t* aAdded);
90
91 // The external version is used by results.
92 #define NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL \
93 NS_DECL_BOOKMARK_HISTORY_OBSERVER_BASE \
94 NS_IMETHOD OnVisit(nsIURI* aURI, int64_t aVisitId, PRTime aTime, \
95 int64_t aSessionId, int64_t aReferringId, \
96 uint32_t aTransitionType, const nsACString& aGUID, \
97 bool aHidden);
98
99 // nsNavHistoryResult
100 //
101 // nsNavHistory creates this object and fills in mChildren (by getting
102 // it through GetTopLevel()). Then FilledAllResults() is called to finish
103 // object initialization.
104
105 #define NS_NAVHISTORYRESULT_IID \
106 { 0x455d1d40, 0x1b9b, 0x40e6, { 0xa6, 0x41, 0x8b, 0xb7, 0xe8, 0x82, 0x23, 0x87 } }
107
108 class nsNavHistoryResult : public nsSupportsWeakReference,
109 public nsINavHistoryResult,
110 public nsINavBookmarkObserver,
111 public nsINavHistoryObserver
112 {
113 public:
114 static nsresult NewHistoryResult(nsINavHistoryQuery** aQueries,
115 uint32_t aQueryCount,
116 nsNavHistoryQueryOptions* aOptions,
117 nsNavHistoryContainerResultNode* aRoot,
118 bool aBatchInProgress,
119 nsNavHistoryResult** result);
120
121 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULT_IID)
122
123 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
124 NS_DECL_NSINAVHISTORYRESULT
125 NS_DECL_BOOKMARK_HISTORY_OBSERVER_EXTERNAL
126 NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNavHistoryResult, nsINavHistoryResult)
127
128 void AddHistoryObserver(nsNavHistoryQueryResultNode* aNode);
129 void AddBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
130 void AddAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
131 void RemoveHistoryObserver(nsNavHistoryQueryResultNode* aNode);
132 void RemoveBookmarkFolderObserver(nsNavHistoryFolderResultNode* aNode, int64_t aFolder);
133 void RemoveAllBookmarksObserver(nsNavHistoryQueryResultNode* aNode);
134 void StopObserving();
135
136 public:
137 // two-stage init, use NewHistoryResult to construct
138 nsNavHistoryResult(nsNavHistoryContainerResultNode* mRoot);
139 virtual ~nsNavHistoryResult();
140 nsresult Init(nsINavHistoryQuery** aQueries,
141 uint32_t aQueryCount,
142 nsNavHistoryQueryOptions *aOptions);
143
144 nsRefPtr<nsNavHistoryContainerResultNode> mRootNode;
145
146 nsCOMArray<nsINavHistoryQuery> mQueries;
147 nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
148
149 // One of nsNavHistoryQueryOptions.SORY_BY_* This is initialized to mOptions.sortingMode,
150 // but may be overridden if the user clicks on one of the columns.
151 uint16_t mSortingMode;
152 // If root node is closed and we try to apply a sortingMode, it would not
153 // work. So we will apply it when the node will be reopened and populated.
154 // This var states the fact we need to apply sortingMode in such a situation.
155 bool mNeedsToApplySortingMode;
156
157 // The sorting annotation to be used for in SORT_BY_ANNOTATION_* modes
158 nsCString mSortingAnnotation;
159
160 // node observers
161 bool mIsHistoryObserver;
162 bool mIsBookmarkFolderObserver;
163 bool mIsAllBookmarksObserver;
164
165 typedef nsTArray< nsRefPtr<nsNavHistoryQueryResultNode> > QueryObserverList;
166 QueryObserverList mHistoryObservers;
167 QueryObserverList mAllBookmarksObservers;
168
169 typedef nsTArray< nsRefPtr<nsNavHistoryFolderResultNode> > FolderObserverList;
170 nsDataHashtable<nsTrimInt64HashKey, FolderObserverList*> mBookmarkFolderObservers;
171 FolderObserverList* BookmarkFolderObserversForId(int64_t aFolderId, bool aCreate);
172
173 typedef nsTArray< nsRefPtr<nsNavHistoryContainerResultNode> > ContainerObserverList;
174
175 void RecursiveExpandCollapse(nsNavHistoryContainerResultNode* aContainer,
176 bool aExpand);
177
178 void InvalidateTree();
179
180 bool mBatchInProgress;
181
182 nsMaybeWeakPtrArray<nsINavHistoryResultObserver> mObservers;
183 bool mSuppressNotifications;
184
185 ContainerObserverList mRefreshParticipants;
186 void requestRefresh(nsNavHistoryContainerResultNode* aContainer);
187 };
188
189 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)
190
191 // nsNavHistoryResultNode
192 //
193 // This is the base class for every node in a result set. The result itself
194 // is a node (nsNavHistoryResult inherits from this), as well as every
195 // leaf and branch on the tree.
196
197 #define NS_NAVHISTORYRESULTNODE_IID \
198 {0x54b61d38, 0x57c1, 0x11da, {0x95, 0xb8, 0x00, 0x13, 0x21, 0xc9, 0xf6, 0x9e}}
199
200 // These are all the simple getters, they can be used for the result node
201 // implementation and all subclasses. More complex are GetIcon, GetParent
202 // (which depends on the definition of container result node), and GetUri
203 // (which is overridded for lazy construction for some containers).
204 #define NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
205 NS_IMETHOD GetTitle(nsACString& aTitle) \
206 { aTitle = mTitle; return NS_OK; } \
207 NS_IMETHOD GetAccessCount(uint32_t* aAccessCount) \
208 { *aAccessCount = mAccessCount; return NS_OK; } \
209 NS_IMETHOD GetTime(PRTime* aTime) \
210 { *aTime = mTime; return NS_OK; } \
211 NS_IMETHOD GetIndentLevel(int32_t* aIndentLevel) \
212 { *aIndentLevel = mIndentLevel; return NS_OK; } \
213 NS_IMETHOD GetBookmarkIndex(int32_t* aIndex) \
214 { *aIndex = mBookmarkIndex; return NS_OK; } \
215 NS_IMETHOD GetDateAdded(PRTime* aDateAdded) \
216 { *aDateAdded = mDateAdded; return NS_OK; } \
217 NS_IMETHOD GetLastModified(PRTime* aLastModified) \
218 { *aLastModified = mLastModified; return NS_OK; }
219
220 #define NS_IMPLEMENT_SIMPLE_RESULTNODE \
221 NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
222 NS_IMETHOD GetItemId(int64_t* aId) \
223 { *aId = mItemId; return NS_OK; }
224
225 // This is used by the base classes instead of
226 // NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
227 // need to redefine GetType and GetUri rather than forwarding them. This
228 // implements all the simple getters instead of forwarding because they are so
229 // short and we can save a virtual function call.
230 //
231 // (GetUri is redefined only by QueryResultNode and FolderResultNode because
232 // the queries might not necessarily be parsed. The rest just return the node's
233 // buffer.)
234 #define NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \
235 NS_IMPLEMENT_SIMPLE_RESULTNODE_NO_GETITEMMID \
236 NS_IMETHOD GetIcon(nsACString& aIcon) \
237 { return nsNavHistoryResultNode::GetIcon(aIcon); } \
238 NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent) \
239 { return nsNavHistoryResultNode::GetParent(aParent); } \
240 NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult) \
241 { return nsNavHistoryResultNode::GetParentResult(aResult); } \
242 NS_IMETHOD GetTags(nsAString& aTags) \
243 { return nsNavHistoryResultNode::GetTags(aTags); } \
244 NS_IMETHOD GetPageGuid(nsACString& aPageGuid) \
245 { return nsNavHistoryResultNode::GetPageGuid(aPageGuid); } \
246 NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid) \
247 { return nsNavHistoryResultNode::GetBookmarkGuid(aBookmarkGuid); }
248
249 #define NS_FORWARD_COMMON_RESULTNODE_TO_BASE \
250 NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID \
251 NS_IMETHOD GetItemId(int64_t* aId) \
252 { *aId = mItemId; return NS_OK; }
253
254 class nsNavHistoryResultNode : public nsINavHistoryResultNode
255 {
256 public:
257 nsNavHistoryResultNode(const nsACString& aURI, const nsACString& aTitle,
258 uint32_t aAccessCount, PRTime aTime,
259 const nsACString& aIconURI);
260 virtual ~nsNavHistoryResultNode() {}
261
262 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYRESULTNODE_IID)
263
264 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
265 NS_DECL_CYCLE_COLLECTION_CLASS(nsNavHistoryResultNode)
266
267 NS_IMPLEMENT_SIMPLE_RESULTNODE
268 NS_IMETHOD GetIcon(nsACString& aIcon);
269 NS_IMETHOD GetParent(nsINavHistoryContainerResultNode** aParent);
270 NS_IMETHOD GetParentResult(nsINavHistoryResult** aResult);
271 NS_IMETHOD GetType(uint32_t* type)
272 { *type = nsNavHistoryResultNode::RESULT_TYPE_URI; return NS_OK; }
273 NS_IMETHOD GetUri(nsACString& aURI)
274 { aURI = mURI; return NS_OK; }
275 NS_IMETHOD GetTags(nsAString& aTags);
276 NS_IMETHOD GetPageGuid(nsACString& aPageGuid);
277 NS_IMETHOD GetBookmarkGuid(nsACString& aBookmarkGuid);
278
279 virtual void OnRemoving();
280
281 // Called from result's onItemChanged, see also bookmark observer declaration in
282 // nsNavHistoryFolderResultNode
283 NS_IMETHOD OnItemChanged(int64_t aItemId,
284 const nsACString &aProperty,
285 bool aIsAnnotationProperty,
286 const nsACString &aValue,
287 PRTime aNewLastModified,
288 uint16_t aItemType,
289 int64_t aParentId,
290 const nsACString& aGUID,
291 const nsACString& aParentGUID);
292
293 public:
294
295 nsNavHistoryResult* GetResult();
296 nsNavHistoryQueryOptions* GetGeneratingOptions();
297
298 // These functions test the type. We don't use a virtual function since that
299 // would take a vtable slot for every one of (potentially very many) nodes.
300 // Note that GetType() already has a vtable slot because its on the iface.
301 bool IsTypeContainer(uint32_t type) {
302 return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY ||
303 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
304 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
305 }
306 bool IsContainer() {
307 uint32_t type;
308 GetType(&type);
309 return IsTypeContainer(type);
310 }
311 static bool IsTypeURI(uint32_t type) {
312 return type == nsINavHistoryResultNode::RESULT_TYPE_URI;
313 }
314 bool IsURI() {
315 uint32_t type;
316 GetType(&type);
317 return IsTypeURI(type);
318 }
319 static bool IsTypeFolder(uint32_t type) {
320 return type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER ||
321 type == nsINavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
322 }
323 bool IsFolder() {
324 uint32_t type;
325 GetType(&type);
326 return IsTypeFolder(type);
327 }
328 static bool IsTypeQuery(uint32_t type) {
329 return type == nsINavHistoryResultNode::RESULT_TYPE_QUERY;
330 }
331 bool IsQuery() {
332 uint32_t type;
333 GetType(&type);
334 return IsTypeQuery(type);
335 }
336 bool IsSeparator() {
337 uint32_t type;
338 GetType(&type);
339 return type == nsINavHistoryResultNode::RESULT_TYPE_SEPARATOR;
340 }
341 nsNavHistoryContainerResultNode* GetAsContainer() {
342 NS_ASSERTION(IsContainer(), "Not a container");
343 return reinterpret_cast<nsNavHistoryContainerResultNode*>(this);
344 }
345 nsNavHistoryFolderResultNode* GetAsFolder() {
346 NS_ASSERTION(IsFolder(), "Not a folder");
347 return reinterpret_cast<nsNavHistoryFolderResultNode*>(this);
348 }
349 nsNavHistoryQueryResultNode* GetAsQuery() {
350 NS_ASSERTION(IsQuery(), "Not a query");
351 return reinterpret_cast<nsNavHistoryQueryResultNode*>(this);
352 }
353
354 nsRefPtr<nsNavHistoryContainerResultNode> mParent;
355 nsCString mURI; // not necessarily valid for containers, call GetUri
356 nsCString mTitle;
357 nsString mTags;
358 bool mAreTagsSorted;
359 uint32_t mAccessCount;
360 int64_t mTime;
361 nsCString mFaviconURI;
362 int32_t mBookmarkIndex;
363 int64_t mItemId;
364 int64_t mFolderId;
365 PRTime mDateAdded;
366 PRTime mLastModified;
367
368 // The indent level of this node. The root node will have a value of -1. The
369 // root's children will have a value of 0, and so on.
370 int32_t mIndentLevel;
371
372 // Frecency of the page. Valid only for URI nodes.
373 int32_t mFrecency;
374
375 // Hidden status of the page. Valid only for URI nodes.
376 bool mHidden;
377
378 // Transition type used when this node represents a single visit.
379 uint32_t mTransitionType;
380
381 // Unique Id of the page.
382 nsCString mPageGuid;
383
384 // Unique Id of the bookmark.
385 nsCString mBookmarkGuid;
386 };
387
388 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResultNode, NS_NAVHISTORYRESULTNODE_IID)
389
390
391 // nsNavHistoryContainerResultNode
392 //
393 // This is the base class for all nodes that can have children. It is
394 // overridden for nodes that are dynamically populated such as queries and
395 // folders. It is used directly for simple containers such as host groups
396 // in history views.
397
398 // derived classes each provide their own implementation of has children and
399 // forward the rest to us using this macro
400 #define NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY \
401 NS_IMETHOD GetState(uint16_t* _state) \
402 { return nsNavHistoryContainerResultNode::GetState(_state); } \
403 NS_IMETHOD GetContainerOpen(bool *aContainerOpen) \
404 { return nsNavHistoryContainerResultNode::GetContainerOpen(aContainerOpen); } \
405 NS_IMETHOD SetContainerOpen(bool aContainerOpen) \
406 { return nsNavHistoryContainerResultNode::SetContainerOpen(aContainerOpen); } \
407 NS_IMETHOD GetChildCount(uint32_t *aChildCount) \
408 { return nsNavHistoryContainerResultNode::GetChildCount(aChildCount); } \
409 NS_IMETHOD GetChild(uint32_t index, nsINavHistoryResultNode **_retval) \
410 { return nsNavHistoryContainerResultNode::GetChild(index, _retval); } \
411 NS_IMETHOD GetChildIndex(nsINavHistoryResultNode* aNode, uint32_t* _retval) \
412 { return nsNavHistoryContainerResultNode::GetChildIndex(aNode, _retval); } \
413 NS_IMETHOD FindNodeByDetails(const nsACString& aURIString, PRTime aTime, \
414 int64_t aItemId, bool aRecursive, \
415 nsINavHistoryResultNode** _retval) \
416 { return nsNavHistoryContainerResultNode::FindNodeByDetails(aURIString, aTime, aItemId, \
417 aRecursive, _retval); }
418
419 #define NS_NAVHISTORYCONTAINERRESULTNODE_IID \
420 { 0x6e3bf8d3, 0x22aa, 0x4065, { 0x86, 0xbc, 0x37, 0x46, 0xb5, 0xb3, 0x2c, 0xe8 } }
421
422 class nsNavHistoryContainerResultNode : public nsNavHistoryResultNode,
423 public nsINavHistoryContainerResultNode
424 {
425 public:
426 nsNavHistoryContainerResultNode(
427 const nsACString& aURI, const nsACString& aTitle,
428 const nsACString& aIconURI, uint32_t aContainerType,
429 bool aReadOnly, nsNavHistoryQueryOptions* aOptions);
430 nsNavHistoryContainerResultNode(
431 const nsACString& aURI, const nsACString& aTitle,
432 PRTime aTime,
433 const nsACString& aIconURI, uint32_t aContainerType,
434 bool aReadOnly, nsNavHistoryQueryOptions* aOptions);
435
436 virtual nsresult Refresh();
437 virtual ~nsNavHistoryContainerResultNode();
438
439 NS_DECLARE_STATIC_IID_ACCESSOR(NS_NAVHISTORYCONTAINERRESULTNODE_IID)
440
441 NS_DECL_ISUPPORTS_INHERITED
442 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsNavHistoryContainerResultNode, nsNavHistoryResultNode)
443 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
444 NS_IMETHOD GetType(uint32_t* type)
445 { *type = mContainerType; return NS_OK; }
446 NS_IMETHOD GetUri(nsACString& aURI)
447 { aURI = mURI; return NS_OK; }
448 NS_DECL_NSINAVHISTORYCONTAINERRESULTNODE
449
450 public:
451
452 virtual void OnRemoving();
453
454 bool AreChildrenVisible();
455
456 // Overridded by descendents to populate.
457 virtual nsresult OpenContainer();
458 nsresult CloseContainer(bool aSuppressNotifications = false);
459
460 virtual nsresult OpenContainerAsync();
461
462 // This points to the result that owns this container. All containers have
463 // their result pointer set so we can quickly get to the result without having
464 // to walk the tree. Yet, this also saves us from storing a million pointers
465 // for every leaf node to the result.
466 nsRefPtr<nsNavHistoryResult> mResult;
467
468 // For example, RESULT_TYPE_QUERY. Query and Folder results override GetType
469 // so this is not used, but is still kept in sync.
470 uint32_t mContainerType;
471
472 // When there are children, this stores the open state in the tree
473 // this is set to the default in the constructor.
474 bool mExpanded;
475
476 // Filled in by the result type generator in nsNavHistory.
477 nsCOMArray<nsNavHistoryResultNode> mChildren;
478
479 bool mChildrenReadOnly;
480
481 nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
482
483 void FillStats();
484 nsresult ReverseUpdateStats(int32_t aAccessCountChange);
485
486 // Sorting methods.
487 typedef nsCOMArray<nsNavHistoryResultNode>::nsCOMArrayComparatorFunc SortComparator;
488 virtual uint16_t GetSortType();
489 virtual void GetSortingAnnotation(nsACString& aSortingAnnotation);
490
491 static SortComparator GetSortingComparator(uint16_t aSortType);
492 virtual void RecursiveSort(const char* aData,
493 SortComparator aComparator);
494 uint32_t FindInsertionPoint(nsNavHistoryResultNode* aNode, SortComparator aComparator,
495 const char* aData, bool* aItemExists);
496 bool DoesChildNeedResorting(uint32_t aIndex, SortComparator aComparator,
497 const char* aData);
498
499 static int32_t SortComparison_StringLess(const nsAString& a, const nsAString& b);
500
501 static int32_t SortComparison_Bookmark(nsNavHistoryResultNode* a,
502 nsNavHistoryResultNode* b,
503 void* closure);
504 static int32_t SortComparison_TitleLess(nsNavHistoryResultNode* a,
505 nsNavHistoryResultNode* b,
506 void* closure);
507 static int32_t SortComparison_TitleGreater(nsNavHistoryResultNode* a,
508 nsNavHistoryResultNode* b,
509 void* closure);
510 static int32_t SortComparison_DateLess(nsNavHistoryResultNode* a,
511 nsNavHistoryResultNode* b,
512 void* closure);
513 static int32_t SortComparison_DateGreater(nsNavHistoryResultNode* a,
514 nsNavHistoryResultNode* b,
515 void* closure);
516 static int32_t SortComparison_URILess(nsNavHistoryResultNode* a,
517 nsNavHistoryResultNode* b,
518 void* closure);
519 static int32_t SortComparison_URIGreater(nsNavHistoryResultNode* a,
520 nsNavHistoryResultNode* b,
521 void* closure);
522 static int32_t SortComparison_VisitCountLess(nsNavHistoryResultNode* a,
523 nsNavHistoryResultNode* b,
524 void* closure);
525 static int32_t SortComparison_VisitCountGreater(nsNavHistoryResultNode* a,
526 nsNavHistoryResultNode* b,
527 void* closure);
528 static int32_t SortComparison_KeywordLess(nsNavHistoryResultNode* a,
529 nsNavHistoryResultNode* b,
530 void* closure);
531 static int32_t SortComparison_KeywordGreater(nsNavHistoryResultNode* a,
532 nsNavHistoryResultNode* b,
533 void* closure);
534 static int32_t SortComparison_AnnotationLess(nsNavHistoryResultNode* a,
535 nsNavHistoryResultNode* b,
536 void* closure);
537 static int32_t SortComparison_AnnotationGreater(nsNavHistoryResultNode* a,
538 nsNavHistoryResultNode* b,
539 void* closure);
540 static int32_t SortComparison_DateAddedLess(nsNavHistoryResultNode* a,
541 nsNavHistoryResultNode* b,
542 void* closure);
543 static int32_t SortComparison_DateAddedGreater(nsNavHistoryResultNode* a,
544 nsNavHistoryResultNode* b,
545 void* closure);
546 static int32_t SortComparison_LastModifiedLess(nsNavHistoryResultNode* a,
547 nsNavHistoryResultNode* b,
548 void* closure);
549 static int32_t SortComparison_LastModifiedGreater(nsNavHistoryResultNode* a,
550 nsNavHistoryResultNode* b,
551 void* closure);
552 static int32_t SortComparison_TagsLess(nsNavHistoryResultNode* a,
553 nsNavHistoryResultNode* b,
554 void* closure);
555 static int32_t SortComparison_TagsGreater(nsNavHistoryResultNode* a,
556 nsNavHistoryResultNode* b,
557 void* closure);
558 static int32_t SortComparison_FrecencyLess(nsNavHistoryResultNode* a,
559 nsNavHistoryResultNode* b,
560 void* closure);
561 static int32_t SortComparison_FrecencyGreater(nsNavHistoryResultNode* a,
562 nsNavHistoryResultNode* b,
563 void* closure);
564
565 // finding children: THESE DO NOT ADDREF
566 nsNavHistoryResultNode* FindChildURI(nsIURI* aURI, uint32_t* aNodeIndex)
567 {
568 nsAutoCString spec;
569 if (NS_FAILED(aURI->GetSpec(spec)))
570 return nullptr;
571 return FindChildURI(spec, aNodeIndex);
572 }
573 nsNavHistoryResultNode* FindChildURI(const nsACString& aSpec,
574 uint32_t* aNodeIndex);
575 // returns the index of the given node, -1 if not found
576 int32_t FindChild(nsNavHistoryResultNode* aNode)
577 { return mChildren.IndexOf(aNode); }
578
579 nsresult InsertChildAt(nsNavHistoryResultNode* aNode, int32_t aIndex,
580 bool aIsTemporary = false);
581 nsresult InsertSortedChild(nsNavHistoryResultNode* aNode,
582 bool aIsTemporary = false,
583 bool aIgnoreDuplicates = false);
584 bool EnsureItemPosition(uint32_t aIndex);
585
586 nsresult RemoveChildAt(int32_t aIndex, bool aIsTemporary = false);
587
588 void RecursiveFindURIs(bool aOnlyOne,
589 nsNavHistoryContainerResultNode* aContainer,
590 const nsCString& aSpec,
591 nsCOMArray<nsNavHistoryResultNode>* aMatches);
592 bool UpdateURIs(bool aRecursive, bool aOnlyOne, bool aUpdateSort,
593 const nsCString& aSpec,
594 nsresult (*aCallback)(nsNavHistoryResultNode*, const void*,
595 const nsNavHistoryResult*),
596 const void* aClosure);
597 nsresult ChangeTitles(nsIURI* aURI, const nsACString& aNewTitle,
598 bool aRecursive, bool aOnlyOne);
599
600 protected:
601
602 enum AsyncCanceledState {
603 NOT_CANCELED, CANCELED, CANCELED_RESTART_NEEDED
604 };
605
606 void CancelAsyncOpen(bool aRestart);
607 nsresult NotifyOnStateChange(uint16_t aOldState);
608
609 nsCOMPtr<mozIStoragePendingStatement> mAsyncPendingStmt;
610 AsyncCanceledState mAsyncCanceledState;
611 };
612
613 NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryContainerResultNode,
614 NS_NAVHISTORYCONTAINERRESULTNODE_IID)
615
616 // nsNavHistoryQueryResultNode
617 //
618 // Overridden container type for complex queries over history and/or
619 // bookmarks. This keeps itself in sync by listening to history and
620 // bookmark notifications.
621
622 class nsNavHistoryQueryResultNode : public nsNavHistoryContainerResultNode,
623 public nsINavHistoryQueryResultNode
624 {
625 public:
626 nsNavHistoryQueryResultNode(const nsACString& aTitle,
627 const nsACString& aIconURI,
628 const nsACString& aQueryURI);
629 nsNavHistoryQueryResultNode(const nsACString& aTitle,
630 const nsACString& aIconURI,
631 const nsCOMArray<nsNavHistoryQuery>& aQueries,
632 nsNavHistoryQueryOptions* aOptions);
633 nsNavHistoryQueryResultNode(const nsACString& aTitle,
634 const nsACString& aIconURI,
635 PRTime aTime,
636 const nsCOMArray<nsNavHistoryQuery>& aQueries,
637 nsNavHistoryQueryOptions* aOptions);
638
639 virtual ~nsNavHistoryQueryResultNode();
640
641 NS_DECL_ISUPPORTS_INHERITED
642 NS_FORWARD_COMMON_RESULTNODE_TO_BASE
643 NS_IMETHOD GetType(uint32_t* type)
644 { *type = nsNavHistoryResultNode::RESULT_TYPE_QUERY; return NS_OK; }
645 NS_IMETHOD GetUri(nsACString& aURI); // does special lazy creation
646 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY
647 NS_IMETHOD GetHasChildren(bool* aHasChildren);
648 NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly)
649 { return nsNavHistoryContainerResultNode::GetChildrenReadOnly(aChildrenReadOnly); }
650 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
651
652 bool CanExpand();
653 bool IsContainersQuery();
654
655 virtual nsresult OpenContainer();
656
657 NS_DECL_BOOKMARK_HISTORY_OBSERVER_INTERNAL
658 virtual void OnRemoving();
659
660 public:
661 // this constructs lazily mURI from mQueries and mOptions, call
662 // VerifyQueriesSerialized either this or mQueries/mOptions should be valid
663 nsresult VerifyQueriesSerialized();
664
665 // these may be constructed lazily from mURI, call VerifyQueriesParsed
666 // either this or mURI should be valid
667 nsCOMArray<nsNavHistoryQuery> mQueries;
668 uint32_t mLiveUpdate; // one of QUERYUPDATE_* in nsNavHistory.h
669 bool mHasSearchTerms;
670 nsresult VerifyQueriesParsed();
671
672 // safe options getter, ensures queries are parsed
673 nsNavHistoryQueryOptions* Options();
674
675 // this indicates whether the query contents are valid, they don't go away
676 // after the container is closed until a notification comes in
677 bool mContentsValid;
678
679 nsresult FillChildren();
680 void ClearChildren(bool unregister);
681 nsresult Refresh();
682
683 virtual uint16_t GetSortType();
684 virtual void GetSortingAnnotation(nsACString& aSortingAnnotation);
685 virtual void RecursiveSort(const char* aData,
686 SortComparator aComparator);
687
688 nsCOMPtr<nsIURI> mRemovingURI;
689 nsresult NotifyIfTagsChanged(nsIURI* aURI);
690
691 uint32_t mBatchChanges;
692
693 // Tracks transition type filters shared by all mQueries.
694 nsTArray<uint32_t> mTransitions;
695 };
696
697
698 // nsNavHistoryFolderResultNode
699 //
700 // Overridden container type for bookmark folders. It will keep the contents
701 // of the folder in sync with the bookmark service.
702
703 class nsNavHistoryFolderResultNode : public nsNavHistoryContainerResultNode,
704 public nsINavHistoryQueryResultNode,
705 public mozilla::places::AsyncStatementCallback
706 {
707 public:
708 nsNavHistoryFolderResultNode(const nsACString& aTitle,
709 nsNavHistoryQueryOptions* options,
710 int64_t aFolderId);
711
712 virtual ~nsNavHistoryFolderResultNode();
713
714 NS_DECL_ISUPPORTS_INHERITED
715 NS_FORWARD_COMMON_RESULTNODE_TO_BASE_NO_GETITEMMID
716 NS_IMETHOD GetType(uint32_t* type) {
717 if (mQueryItemId != -1) {
718 *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER_SHORTCUT;
719 } else {
720 *type = nsNavHistoryResultNode::RESULT_TYPE_FOLDER;
721 }
722 return NS_OK;
723 }
724 NS_IMETHOD GetUri(nsACString& aURI);
725 NS_FORWARD_CONTAINERNODE_EXCEPT_HASCHILDREN_AND_READONLY
726 NS_IMETHOD GetHasChildren(bool* aHasChildren);
727 NS_IMETHOD GetChildrenReadOnly(bool *aChildrenReadOnly);
728 NS_IMETHOD GetItemId(int64_t *aItemId);
729 NS_DECL_NSINAVHISTORYQUERYRESULTNODE
730
731 virtual nsresult OpenContainer();
732
733 virtual nsresult OpenContainerAsync();
734 NS_DECL_ASYNCSTATEMENTCALLBACK
735
736 // This object implements a bookmark observer interface without deriving from
737 // the bookmark observers. This is called from the result's actual observer
738 // and it knows all observers are FolderResultNodes
739 NS_DECL_NSINAVBOOKMARKOBSERVER
740
741 virtual void OnRemoving();
742
743 // this indicates whether the folder contents are valid, they don't go away
744 // after the container is closed until a notification comes in
745 bool mContentsValid;
746
747 // If the node is generated from a place:folder=X query, this is the query's
748 // itemId.
749 int64_t mQueryItemId;
750
751 nsresult FillChildren();
752 void ClearChildren(bool aUnregister);
753 nsresult Refresh();
754
755 bool StartIncrementalUpdate();
756 void ReindexRange(int32_t aStartIndex, int32_t aEndIndex, int32_t aDelta);
757
758 nsNavHistoryResultNode* FindChildById(int64_t aItemId,
759 uint32_t* aNodeIndex);
760
761 private:
762
763 nsresult OnChildrenFilled();
764 void EnsureRegisteredAsFolderObserver();
765 nsresult FillChildrenAsync();
766
767 bool mIsRegisteredFolderObserver;
768 int32_t mAsyncBookmarkIndex;
769 };
770
771 // nsNavHistorySeparatorResultNode
772 //
773 // Separator result nodes do not hold any data.
774 class nsNavHistorySeparatorResultNode : public nsNavHistoryResultNode
775 {
776 public:
777 nsNavHistorySeparatorResultNode();
778
779 NS_IMETHOD GetType(uint32_t* type)
780 { *type = nsNavHistoryResultNode::RESULT_TYPE_SEPARATOR; return NS_OK; }
781 };
782
783 #endif // nsNavHistoryResult_h_

mercurial