2 * Copyright (C) 2010 Stephan Aßmus <superstippi@gmx.de>
4 * All rights reserved. Distributed under the terms of the MIT License.
7 #include "BrowsingHistory.h"
15 #include <FindDirectory.h>
19 #include "BrowserApp.h"
22 BrowsingHistoryItem::BrowsingHistoryItem(const BString
& url
)
25 fDateTime(BDateTime::CurrentDateTime(B_LOCAL_TIME
)),
31 BrowsingHistoryItem::BrowsingHistoryItem(const BrowsingHistoryItem
& other
)
37 BrowsingHistoryItem::BrowsingHistoryItem(const BMessage
* archive
)
41 BMessage dateTimeArchive
;
42 if (archive
->FindMessage("date time", &dateTimeArchive
) == B_OK
)
43 fDateTime
= BDateTime(&dateTimeArchive
);
44 archive
->FindString("url", &fURL
);
45 archive
->FindUInt32("invokations", &fInvokationCount
);
49 BrowsingHistoryItem::~BrowsingHistoryItem()
55 BrowsingHistoryItem::Archive(BMessage
* archive
) const
59 BMessage dateTimeArchive
;
60 status_t status
= fDateTime
.Archive(&dateTimeArchive
);
62 status
= archive
->AddMessage("date time", &dateTimeArchive
);
64 status
= archive
->AddString("url", fURL
.String());
66 status
= archive
->AddUInt32("invokations", fInvokationCount
);
72 BrowsingHistoryItem::operator=(const BrowsingHistoryItem
& other
)
78 fDateTime
= other
.fDateTime
;
79 fInvokationCount
= other
.fInvokationCount
;
86 BrowsingHistoryItem::operator==(const BrowsingHistoryItem
& other
) const
91 return fURL
== other
.fURL
&& fDateTime
== other
.fDateTime
92 && fInvokationCount
== other
.fInvokationCount
;
97 BrowsingHistoryItem::operator!=(const BrowsingHistoryItem
& other
) const
99 return !(*this == other
);
104 BrowsingHistoryItem::operator<(const BrowsingHistoryItem
& other
) const
109 return fDateTime
< other
.fDateTime
|| fURL
< other
.fURL
;
114 BrowsingHistoryItem::operator<=(const BrowsingHistoryItem
& other
) const
116 return (*this == other
) || (*this < other
);
121 BrowsingHistoryItem::operator>(const BrowsingHistoryItem
& other
) const
126 return fDateTime
> other
.fDateTime
|| fURL
> other
.fURL
;
131 BrowsingHistoryItem::operator>=(const BrowsingHistoryItem
& other
) const
133 return (*this == other
) || (*this > other
);
138 BrowsingHistoryItem::Invoked()
140 // Eventually, we may overflow...
141 uint32 count
= fInvokationCount
+ 1;
142 if (count
> fInvokationCount
)
143 fInvokationCount
= count
;
144 fDateTime
= BDateTime::CurrentDateTime(B_LOCAL_TIME
);
148 // #pragma mark - BrowsingHistory
152 BrowsingHistory::sDefaultInstance
;
155 BrowsingHistory::BrowsingHistory()
157 BLocker("browsing history"),
159 fMaxHistoryItemAge(7),
160 fSettingsLoaded(false)
165 BrowsingHistory::~BrowsingHistory()
172 /*static*/ BrowsingHistory
*
173 BrowsingHistory::DefaultInstance()
175 if (sDefaultInstance
.Lock()) {
176 sDefaultInstance
._LoadSettings();
177 sDefaultInstance
.Unlock();
179 return &sDefaultInstance
;
184 BrowsingHistory::AddItem(const BrowsingHistoryItem
& item
)
188 return _AddItem(item
, false);
193 BrowsingHistory::BrowsingHistory::CountItems() const
195 BAutolock
_(const_cast<BrowsingHistory
*>(this));
197 return fHistoryItems
.CountItems();
202 BrowsingHistory::HistoryItemAt(int32 index
) const
204 BAutolock
_(const_cast<BrowsingHistory
*>(this));
206 BrowsingHistoryItem
* existingItem
= reinterpret_cast<BrowsingHistoryItem
*>(
207 fHistoryItems
.ItemAt(index
));
209 return BrowsingHistoryItem(BString());
211 return BrowsingHistoryItem(*existingItem
);
216 BrowsingHistory::Clear()
225 BrowsingHistory::SetMaxHistoryItemAge(int32 days
)
228 if (fMaxHistoryItemAge
!= days
) {
229 fMaxHistoryItemAge
= days
;
236 BrowsingHistory::MaxHistoryItemAge() const
238 return fMaxHistoryItemAge
;
242 // #pragma mark - private
246 BrowsingHistory::_Clear()
248 int32 count
= CountItems();
249 for (int32 i
= 0; i
< count
; i
++) {
250 BrowsingHistoryItem
* item
= reinterpret_cast<BrowsingHistoryItem
*>(
251 fHistoryItems
.ItemAtFast(i
));
254 fHistoryItems
.MakeEmpty();
259 BrowsingHistory::_AddItem(const BrowsingHistoryItem
& item
, bool internal
)
261 int32 count
= CountItems();
262 int32 insertionIndex
= count
;
263 for (int32 i
= 0; i
< count
; i
++) {
264 BrowsingHistoryItem
* existingItem
265 = reinterpret_cast<BrowsingHistoryItem
*>(
266 fHistoryItems
.ItemAtFast(i
));
267 if (item
.URL() == existingItem
->URL()) {
269 existingItem
->Invoked();
274 if (item
< *existingItem
)
277 BrowsingHistoryItem
* newItem
= new(std::nothrow
) BrowsingHistoryItem(item
);
278 if (!newItem
|| !fHistoryItems
.AddItem(newItem
, insertionIndex
)) {
293 BrowsingHistory::_LoadSettings()
298 fSettingsLoaded
= true;
301 if (_OpenSettingsFile(settingsFile
, B_READ_ONLY
)) {
302 BMessage settingsArchive
;
303 settingsArchive
.Unflatten(&settingsFile
);
304 if (settingsArchive
.FindInt32("max history item age",
305 &fMaxHistoryItemAge
) != B_OK
) {
306 fMaxHistoryItemAge
= 7;
308 BDateTime oldestAllowedDateTime
309 = BDateTime::CurrentDateTime(B_LOCAL_TIME
);
310 oldestAllowedDateTime
.Date().AddDays(-fMaxHistoryItemAge
);
312 BMessage historyItemArchive
;
313 for (int32 i
= 0; settingsArchive
.FindMessage("history item", i
,
314 &historyItemArchive
) == B_OK
; i
++) {
315 BrowsingHistoryItem
item(&historyItemArchive
);
316 if (oldestAllowedDateTime
< item
.DateTime())
317 _AddItem(item
, true);
318 historyItemArchive
.MakeEmpty();
325 BrowsingHistory::_SaveSettings()
328 if (_OpenSettingsFile(settingsFile
,
329 B_CREATE_FILE
| B_ERASE_FILE
| B_WRITE_ONLY
)) {
330 BMessage settingsArchive
;
331 settingsArchive
.AddInt32("max history item age", fMaxHistoryItemAge
);
332 BMessage historyItemArchive
;
333 int32 count
= CountItems();
334 for (int32 i
= 0; i
< count
; i
++) {
335 BrowsingHistoryItem item
= HistoryItemAt(i
);
336 if (item
.Archive(&historyItemArchive
) != B_OK
)
338 if (settingsArchive
.AddMessage("history item",
339 &historyItemArchive
) != B_OK
) {
342 historyItemArchive
.MakeEmpty();
344 settingsArchive
.Flatten(&settingsFile
);
350 BrowsingHistory::_OpenSettingsFile(BFile
& file
, uint32 mode
)
353 if (find_directory(B_USER_SETTINGS_DIRECTORY
, &path
) != B_OK
354 || path
.Append(kApplicationName
) != B_OK
355 || path
.Append("BrowsingHistory") != B_OK
) {
358 return file
.SetTo(path
.Path(), mode
) == B_OK
;