|
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_ |