* Converted BrowsingHistory.h/cpp to Haiku coding style.
* Probably fixed a race condition on program launch. If you started typing into the URL field really fast, the static instance in BrowsingHistory::DefaultInstance() could be created by two threads, which may be responsible for the "recursive init" exception that GCC throws in this situation. It's not easy to trigger, maybe this was it. git-svn-id: http://svn.haiku-os.org/webpositive/webkit/trunk@335 94f232f2-1747-11df-bad5-a5bfde151594
This commit is contained in:
committed by
Alexandre Deckner
parent
cb8b9e4ffd
commit
e91fdd924a
@@ -169,7 +169,8 @@ BrowserApp::MessageReceived(BMessage* message)
|
|||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case PRELOAD_BROWSING_HISTORY:
|
case PRELOAD_BROWSING_HISTORY:
|
||||||
BrowsingHistory::defaultInstance();
|
// Accessing the default instance will load the history from disk.
|
||||||
|
BrowsingHistory::DefaultInstance();
|
||||||
break;
|
break;
|
||||||
case B_SILENT_RELAUNCH:
|
case B_SILENT_RELAUNCH:
|
||||||
_CreateNewPage("");
|
_CreateNewPage("");
|
||||||
|
|||||||
@@ -153,17 +153,17 @@ class BrowsingHistoryChoiceModel : public BAutoCompleter::ChoiceModel {
|
|||||||
fChoices.MakeEmpty();
|
fChoices.MakeEmpty();
|
||||||
|
|
||||||
// Search through BrowsingHistory for any matches.
|
// Search through BrowsingHistory for any matches.
|
||||||
BrowsingHistory* history = BrowsingHistory::defaultInstance();
|
BrowsingHistory* history = BrowsingHistory::DefaultInstance();
|
||||||
if (!history->Lock())
|
if (!history->Lock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BString lastBaseURL;
|
BString lastBaseURL;
|
||||||
int32 priority = INT_MAX;
|
int32 priority = INT_MAX;
|
||||||
|
|
||||||
count = history->countItems();
|
count = history->CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BrowsingHistoryItem item = history->historyItemAt(i);
|
BrowsingHistoryItem item = history->HistoryItemAt(i);
|
||||||
const BString& choiceText = item.url();
|
const BString& choiceText = item.URL();
|
||||||
int32 matchPos = choiceText.IFindFirst(pattern);
|
int32 matchPos = choiceText.IFindFirst(pattern);
|
||||||
if (matchPos < 0)
|
if (matchPos < 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -499,13 +499,13 @@ BrowserWindow::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CLEAR_HISTORY: {
|
case CLEAR_HISTORY: {
|
||||||
BrowsingHistory* history = BrowsingHistory::defaultInstance();
|
BrowsingHistory* history = BrowsingHistory::DefaultInstance();
|
||||||
if (history->countItems() == 0)
|
if (history->CountItems() == 0)
|
||||||
break;
|
break;
|
||||||
BAlert* alert = new BAlert("Confirmation", "Do you really want to "
|
BAlert* alert = new BAlert("Confirmation", "Do you really want to "
|
||||||
"clear the browsing history?", "Clear", "Cancel");
|
"clear the browsing history?", "Clear", "Cancel");
|
||||||
if (alert->Go() == 0)
|
if (alert->Go() == 0)
|
||||||
history->clear();
|
history->Clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -737,11 +737,11 @@ BrowserWindow::MenusBeginning()
|
|||||||
while ((menuItem = fGoMenu->RemoveItem(0L)))
|
while ((menuItem = fGoMenu->RemoveItem(0L)))
|
||||||
delete menuItem;
|
delete menuItem;
|
||||||
|
|
||||||
BrowsingHistory* history = BrowsingHistory::defaultInstance();
|
BrowsingHistory* history = BrowsingHistory::DefaultInstance();
|
||||||
if (!history->Lock())
|
if (!history->Lock())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32 count = history->countItems();
|
int32 count = history->CountItems();
|
||||||
BMenuItem* clearHistoryItem = new BMenuItem("Clear history",
|
BMenuItem* clearHistoryItem = new BMenuItem("Clear history",
|
||||||
new BMessage(CLEAR_HISTORY));
|
new BMessage(CLEAR_HISTORY));
|
||||||
clearHistoryItem->SetEnabled(count > 0);
|
clearHistoryItem->SetEnabled(count > 0);
|
||||||
@@ -783,25 +783,25 @@ BrowserWindow::MenusBeginning()
|
|||||||
BMenu* earlierMenu = new BMenu("Earlier");
|
BMenu* earlierMenu = new BMenu("Earlier");
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BrowsingHistoryItem historyItem = history->historyItemAt(i);
|
BrowsingHistoryItem historyItem = history->HistoryItemAt(i);
|
||||||
BMessage* message = new BMessage(GOTO_URL);
|
BMessage* message = new BMessage(GOTO_URL);
|
||||||
message->AddString("url", historyItem.url().String());
|
message->AddString("url", historyItem.URL().String());
|
||||||
|
|
||||||
BString truncatedUrl(historyItem.url());
|
BString truncatedUrl(historyItem.URL());
|
||||||
be_plain_font->TruncateString(&truncatedUrl, B_TRUNCATE_END, 480);
|
be_plain_font->TruncateString(&truncatedUrl, B_TRUNCATE_END, 480);
|
||||||
menuItem = new BMenuItem(truncatedUrl, message);
|
menuItem = new BMenuItem(truncatedUrl, message);
|
||||||
|
|
||||||
if (historyItem.dateTime() < fiveDaysAgoStart)
|
if (historyItem.DateTime() < fiveDaysAgoStart)
|
||||||
addItemToMenuOrSubmenu(earlierMenu, menuItem);
|
addItemToMenuOrSubmenu(earlierMenu, menuItem);
|
||||||
else if (historyItem.dateTime() < fourDaysAgoStart)
|
else if (historyItem.DateTime() < fourDaysAgoStart)
|
||||||
addItemToMenuOrSubmenu(fiveDaysAgoMenu, menuItem);
|
addItemToMenuOrSubmenu(fiveDaysAgoMenu, menuItem);
|
||||||
else if (historyItem.dateTime() < threeDaysAgoStart)
|
else if (historyItem.DateTime() < threeDaysAgoStart)
|
||||||
addItemToMenuOrSubmenu(fourDaysAgoMenu, menuItem);
|
addItemToMenuOrSubmenu(fourDaysAgoMenu, menuItem);
|
||||||
else if (historyItem.dateTime() < twoDaysAgoStart)
|
else if (historyItem.DateTime() < twoDaysAgoStart)
|
||||||
addItemToMenuOrSubmenu(threeDaysAgoMenu, menuItem);
|
addItemToMenuOrSubmenu(threeDaysAgoMenu, menuItem);
|
||||||
else if (historyItem.dateTime() < oneDayAgoStart)
|
else if (historyItem.DateTime() < oneDayAgoStart)
|
||||||
addItemToMenuOrSubmenu(twoDaysAgoMenu, menuItem);
|
addItemToMenuOrSubmenu(twoDaysAgoMenu, menuItem);
|
||||||
else if (historyItem.dateTime() < todayStart)
|
else if (historyItem.DateTime() < todayStart)
|
||||||
addItemToMenuOrSubmenu(yesterdayMenu, menuItem);
|
addItemToMenuOrSubmenu(yesterdayMenu, menuItem);
|
||||||
else
|
else
|
||||||
addItemToMenuOrSubmenu(todayMenu, menuItem);
|
addItemToMenuOrSubmenu(todayMenu, menuItem);
|
||||||
@@ -1048,7 +1048,7 @@ BrowserWindow::NavigationCapabilitiesChanged(bool canGoBackward,
|
|||||||
void
|
void
|
||||||
BrowserWindow::UpdateGlobalHistory(const BString& url)
|
BrowserWindow::UpdateGlobalHistory(const BString& url)
|
||||||
{
|
{
|
||||||
BrowsingHistory::defaultInstance()->addItem(BrowsingHistoryItem(url));
|
BrowsingHistory::DefaultInstance()->AddItem(BrowsingHistoryItem(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,251 +25,321 @@
|
|||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "BrowsingHistory.h"
|
#include "BrowsingHistory.h"
|
||||||
|
|
||||||
#include "BrowserApp.h"
|
#include <new>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
#include <Entry.h>
|
#include <Entry.h>
|
||||||
#include <File.h>
|
#include <File.h>
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <Path.h>
|
#include <Path.h>
|
||||||
#include <new>
|
|
||||||
#include <stdio.h>
|
#include "BrowserApp.h"
|
||||||
|
|
||||||
|
|
||||||
BrowsingHistoryItem::BrowsingHistoryItem(const BString& url)
|
BrowsingHistoryItem::BrowsingHistoryItem(const BString& url)
|
||||||
: m_url(url)
|
:
|
||||||
, m_dateTime(BDateTime::CurrentDateTime(B_LOCAL_TIME))
|
fURL(url),
|
||||||
, m_invokationCount(0)
|
fDateTime(BDateTime::CurrentDateTime(B_LOCAL_TIME)),
|
||||||
|
fInvokationCount(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BrowsingHistoryItem::BrowsingHistoryItem(const BrowsingHistoryItem& other)
|
BrowsingHistoryItem::BrowsingHistoryItem(const BrowsingHistoryItem& other)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BrowsingHistoryItem::BrowsingHistoryItem(const BMessage* archive)
|
BrowsingHistoryItem::BrowsingHistoryItem(const BMessage* archive)
|
||||||
{
|
{
|
||||||
if (!archive)
|
if (!archive)
|
||||||
return;
|
return;
|
||||||
BMessage dateTimeArchive;
|
BMessage dateTimeArchive;
|
||||||
if (archive->FindMessage("date time", &dateTimeArchive) == B_OK)
|
if (archive->FindMessage("date time", &dateTimeArchive) == B_OK)
|
||||||
m_dateTime = BDateTime(&dateTimeArchive);
|
fDateTime = BDateTime(&dateTimeArchive);
|
||||||
archive->FindString("url", &m_url);
|
archive->FindString("url", &fURL);
|
||||||
archive->FindUInt32("invokations", &m_invokationCount);
|
archive->FindUInt32("invokations", &fInvokationCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BrowsingHistoryItem::~BrowsingHistoryItem()
|
BrowsingHistoryItem::~BrowsingHistoryItem()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t BrowsingHistoryItem::archive(BMessage* archive) const
|
|
||||||
|
status_t
|
||||||
|
BrowsingHistoryItem::Archive(BMessage* archive) const
|
||||||
{
|
{
|
||||||
if (!archive)
|
if (!archive)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
BMessage dateTimeArchive;
|
BMessage dateTimeArchive;
|
||||||
status_t status = m_dateTime.Archive(&dateTimeArchive);
|
status_t status = fDateTime.Archive(&dateTimeArchive);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = archive->AddMessage("date time", &dateTimeArchive);
|
status = archive->AddMessage("date time", &dateTimeArchive);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = archive->AddString("url", m_url.String());
|
status = archive->AddString("url", fURL.String());
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = archive->AddUInt32("invokations", m_invokationCount);
|
status = archive->AddUInt32("invokations", fInvokationCount);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowsingHistoryItem& BrowsingHistoryItem::operator=(const BrowsingHistoryItem& other)
|
|
||||||
{
|
|
||||||
if (this == &other)
|
|
||||||
return *this;
|
|
||||||
|
|
||||||
m_url = other.m_url;
|
BrowsingHistoryItem&
|
||||||
m_dateTime = other.m_dateTime;
|
BrowsingHistoryItem::operator=(const BrowsingHistoryItem& other)
|
||||||
m_invokationCount = other.m_invokationCount;
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator==(const BrowsingHistoryItem& other) const
|
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return true;
|
return *this;
|
||||||
|
|
||||||
return m_url == other.m_url && m_dateTime == other.m_dateTime
|
fURL = other.fURL;
|
||||||
&& m_invokationCount == other.m_invokationCount;
|
fDateTime = other.fDateTime;
|
||||||
|
fInvokationCount = other.fInvokationCount;
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator!=(const BrowsingHistoryItem& other) const
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator==(const BrowsingHistoryItem& other) const
|
||||||
|
{
|
||||||
|
if (this == &other)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return fURL == other.fURL && fDateTime == other.fDateTime
|
||||||
|
&& fInvokationCount == other.fInvokationCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator!=(const BrowsingHistoryItem& other) const
|
||||||
{
|
{
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator<(const BrowsingHistoryItem& other) const
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator<(const BrowsingHistoryItem& other) const
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return m_dateTime < other.m_dateTime || m_url < other.m_url;
|
return fDateTime < other.fDateTime || fURL < other.fURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator<=(const BrowsingHistoryItem& other) const
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator<=(const BrowsingHistoryItem& other) const
|
||||||
{
|
{
|
||||||
return (*this == other) || (*this < other);
|
return (*this == other) || (*this < other);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator>(const BrowsingHistoryItem& other) const
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator>(const BrowsingHistoryItem& other) const
|
||||||
{
|
{
|
||||||
if (this == &other)
|
if (this == &other)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return m_dateTime > other.m_dateTime || m_url > other.m_url;
|
return fDateTime > other.fDateTime || fURL > other.fURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistoryItem::operator>=(const BrowsingHistoryItem& other) const
|
|
||||||
|
bool
|
||||||
|
BrowsingHistoryItem::operator>=(const BrowsingHistoryItem& other) const
|
||||||
{
|
{
|
||||||
return (*this == other) || (*this > other);
|
return (*this == other) || (*this > other);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BrowsingHistoryItem::invoked()
|
|
||||||
|
void
|
||||||
|
BrowsingHistoryItem::Invoked()
|
||||||
{
|
{
|
||||||
// Eventually, we may overflow...
|
// Eventually, we may overflow...
|
||||||
uint32 count = m_invokationCount + 1;
|
uint32 count = fInvokationCount + 1;
|
||||||
if (count > m_invokationCount)
|
if (count > fInvokationCount)
|
||||||
m_invokationCount = count;
|
fInvokationCount = count;
|
||||||
m_dateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME);
|
fDateTime = BDateTime::CurrentDateTime(B_LOCAL_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - BrowsingHistory
|
// #pragma mark - BrowsingHistory
|
||||||
|
|
||||||
|
|
||||||
|
BrowsingHistory
|
||||||
|
BrowsingHistory::sDefaultInstance;
|
||||||
|
|
||||||
|
|
||||||
BrowsingHistory::BrowsingHistory()
|
BrowsingHistory::BrowsingHistory()
|
||||||
: BLocker("browsing history")
|
:
|
||||||
|
BLocker("browsing history"),
|
||||||
|
fHistoryItems(64),
|
||||||
|
fSettingsLoaded(false)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BrowsingHistory::~BrowsingHistory()
|
||||||
|
{
|
||||||
|
_SaveSettings();
|
||||||
|
_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ BrowsingHistory*
|
||||||
|
BrowsingHistory::DefaultInstance()
|
||||||
|
{
|
||||||
|
if (sDefaultInstance.Lock()) {
|
||||||
|
sDefaultInstance._LoadSettings();
|
||||||
|
sDefaultInstance.Unlock();
|
||||||
|
}
|
||||||
|
return &sDefaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BrowsingHistory::AddItem(const BrowsingHistoryItem& item)
|
||||||
|
{
|
||||||
|
BAutolock _(this);
|
||||||
|
|
||||||
|
return _AddItem(item, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
BrowsingHistory::BrowsingHistory::CountItems() const
|
||||||
|
{
|
||||||
|
BAutolock _(const_cast<BrowsingHistory*>(this));
|
||||||
|
|
||||||
|
return fHistoryItems.CountItems();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BrowsingHistoryItem
|
||||||
|
BrowsingHistory::HistoryItemAt(int32 index) const
|
||||||
|
{
|
||||||
|
BAutolock _(const_cast<BrowsingHistory*>(this));
|
||||||
|
|
||||||
|
BrowsingHistoryItem* existingItem = reinterpret_cast<BrowsingHistoryItem*>(
|
||||||
|
fHistoryItems.ItemAt(index));
|
||||||
|
if (!existingItem)
|
||||||
|
return BrowsingHistoryItem(BString());
|
||||||
|
|
||||||
|
return BrowsingHistoryItem(*existingItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BrowsingHistory::Clear()
|
||||||
|
{
|
||||||
|
BAutolock _(this);
|
||||||
|
_Clear();
|
||||||
|
_SaveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - private
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BrowsingHistory::_Clear()
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
BrowsingHistoryItem* item = reinterpret_cast<BrowsingHistoryItem*>(
|
||||||
|
fHistoryItems.ItemAtFast(i));
|
||||||
|
delete item;
|
||||||
|
}
|
||||||
|
fHistoryItems.MakeEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BrowsingHistory::_AddItem(const BrowsingHistoryItem& item, bool internal)
|
||||||
|
{
|
||||||
|
int32 count = CountItems();
|
||||||
|
int32 insertionIndex = count;
|
||||||
|
for (int32 i = 0; i < count; i++) {
|
||||||
|
BrowsingHistoryItem* existingItem
|
||||||
|
= reinterpret_cast<BrowsingHistoryItem*>(
|
||||||
|
fHistoryItems.ItemAtFast(i));
|
||||||
|
if (item.URL() == existingItem->URL()) {
|
||||||
|
if (!internal) {
|
||||||
|
existingItem->Invoked();
|
||||||
|
_SaveSettings();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (item < *existingItem)
|
||||||
|
insertionIndex = i;
|
||||||
|
}
|
||||||
|
BrowsingHistoryItem* newItem = new(std::nothrow) BrowsingHistoryItem(item);
|
||||||
|
if (!newItem || !fHistoryItems.AddItem(newItem, insertionIndex)) {
|
||||||
|
delete newItem;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!internal) {
|
||||||
|
newItem->Invoked();
|
||||||
|
_SaveSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BrowsingHistory::_LoadSettings()
|
||||||
|
{
|
||||||
|
if (fSettingsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fSettingsLoaded = true;
|
||||||
|
|
||||||
BFile settingsFile;
|
BFile settingsFile;
|
||||||
if (openSettingsFile(settingsFile, B_READ_ONLY)) {
|
if (_OpenSettingsFile(settingsFile, B_READ_ONLY)) {
|
||||||
BMessage settingsArchive;
|
BMessage settingsArchive;
|
||||||
settingsArchive.Unflatten(&settingsFile);
|
settingsArchive.Unflatten(&settingsFile);
|
||||||
|
|
||||||
BMessage historyItemArchive;
|
BMessage historyItemArchive;
|
||||||
for (int32 i = 0; settingsArchive.FindMessage("history item", i, &historyItemArchive) == B_OK; i++) {
|
for (int32 i = 0; settingsArchive.FindMessage("history item", i,
|
||||||
privateAddItem(BrowsingHistoryItem(&historyItemArchive), true);
|
&historyItemArchive) == B_OK; i++) {
|
||||||
|
_AddItem(BrowsingHistoryItem(&historyItemArchive), true);
|
||||||
historyItemArchive.MakeEmpty();
|
historyItemArchive.MakeEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BrowsingHistory::~BrowsingHistory()
|
|
||||||
{
|
|
||||||
saveSettings();
|
|
||||||
privateClear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*static*/ BrowsingHistory* BrowsingHistory::defaultInstance()
|
void
|
||||||
{
|
BrowsingHistory::_SaveSettings()
|
||||||
static BrowsingHistory defaultInstance;
|
|
||||||
|
|
||||||
return &defaultInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowsingHistory::addItem(const BrowsingHistoryItem& item)
|
|
||||||
{
|
|
||||||
BAutolock _(this);
|
|
||||||
|
|
||||||
return privateAddItem(item, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 BrowsingHistory::BrowsingHistory::countItems() const
|
|
||||||
{
|
|
||||||
BAutolock _(const_cast<BrowsingHistory*>(this));
|
|
||||||
|
|
||||||
return m_historyItems.CountItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
BrowsingHistoryItem BrowsingHistory::historyItemAt(int32 index) const
|
|
||||||
{
|
|
||||||
BAutolock _(const_cast<BrowsingHistory*>(this));
|
|
||||||
|
|
||||||
BrowsingHistoryItem* existingItem = reinterpret_cast<BrowsingHistoryItem*>(
|
|
||||||
m_historyItems.ItemAt(index));
|
|
||||||
if (!existingItem)
|
|
||||||
return BrowsingHistoryItem(BString());
|
|
||||||
|
|
||||||
return BrowsingHistoryItem(*existingItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowsingHistory::clear()
|
|
||||||
{
|
|
||||||
BAutolock _(this);
|
|
||||||
privateClear();
|
|
||||||
saveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
// #pragma mark - private
|
|
||||||
|
|
||||||
void BrowsingHistory::privateClear()
|
|
||||||
{
|
|
||||||
int32 count = countItems();
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
BrowsingHistoryItem* item = reinterpret_cast<BrowsingHistoryItem*>(
|
|
||||||
m_historyItems.ItemAtFast(i));
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
m_historyItems.MakeEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BrowsingHistory::privateAddItem(const BrowsingHistoryItem& item, bool internal)
|
|
||||||
{
|
|
||||||
int32 count = countItems();
|
|
||||||
int32 insertionIndex = count;
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
|
||||||
BrowsingHistoryItem* existingItem = reinterpret_cast<BrowsingHistoryItem*>(
|
|
||||||
m_historyItems.ItemAtFast(i));
|
|
||||||
if (item.url() == existingItem->url()) {
|
|
||||||
if (!internal) {
|
|
||||||
existingItem->invoked();
|
|
||||||
saveSettings();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (item < *existingItem)
|
|
||||||
insertionIndex = i;
|
|
||||||
}
|
|
||||||
BrowsingHistoryItem* newItem = new(std::nothrow) BrowsingHistoryItem(item);
|
|
||||||
if (!newItem || !m_historyItems.AddItem(newItem, insertionIndex)) {
|
|
||||||
delete newItem;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!internal) {
|
|
||||||
newItem->invoked();
|
|
||||||
saveSettings();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void BrowsingHistory::saveSettings()
|
|
||||||
{
|
{
|
||||||
BFile settingsFile;
|
BFile settingsFile;
|
||||||
if (openSettingsFile(settingsFile, B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY)) {
|
if (_OpenSettingsFile(settingsFile,
|
||||||
|
B_CREATE_FILE | B_ERASE_FILE | B_WRITE_ONLY)) {
|
||||||
BMessage settingsArchive;
|
BMessage settingsArchive;
|
||||||
BMessage historyItemArchive;
|
BMessage historyItemArchive;
|
||||||
int32 count = countItems();
|
int32 count = CountItems();
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
BrowsingHistoryItem item = historyItemAt(i);
|
BrowsingHistoryItem item = HistoryItemAt(i);
|
||||||
if (item.archive(&historyItemArchive) != B_OK)
|
if (item.Archive(&historyItemArchive) != B_OK)
|
||||||
break;
|
break;
|
||||||
if (settingsArchive.AddMessage("history item", &historyItemArchive) != B_OK)
|
if (settingsArchive.AddMessage("history item",
|
||||||
break;
|
&historyItemArchive) != B_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
historyItemArchive.MakeEmpty();
|
historyItemArchive.MakeEmpty();
|
||||||
}
|
}
|
||||||
settingsArchive.Flatten(&settingsFile);
|
settingsArchive.Flatten(&settingsFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BrowsingHistory::openSettingsFile(BFile& file, uint32 mode)
|
|
||||||
|
bool
|
||||||
|
BrowsingHistory::_OpenSettingsFile(BFile& file, uint32 mode)
|
||||||
{
|
{
|
||||||
BPath path;
|
BPath path;
|
||||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
|
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK
|
||||||
|
|||||||
@@ -24,9 +24,8 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
#ifndef BROWSING_HISTORY_H
|
||||||
#ifndef BrowsingHistory_h
|
#define BROWSING_HISTORY_H
|
||||||
#define BrowsingHistory_h
|
|
||||||
|
|
||||||
#include "DateTime.h"
|
#include "DateTime.h"
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
@@ -35,58 +34,75 @@
|
|||||||
class BFile;
|
class BFile;
|
||||||
class BString;
|
class BString;
|
||||||
|
|
||||||
|
|
||||||
class BrowsingHistoryItem {
|
class BrowsingHistoryItem {
|
||||||
public:
|
public:
|
||||||
BrowsingHistoryItem(const BString& url);
|
BrowsingHistoryItem(const BString& url);
|
||||||
BrowsingHistoryItem(const BrowsingHistoryItem& other);
|
BrowsingHistoryItem(
|
||||||
BrowsingHistoryItem(const BMessage* archive);
|
const BrowsingHistoryItem& other);
|
||||||
~BrowsingHistoryItem();
|
BrowsingHistoryItem(const BMessage* archive);
|
||||||
|
~BrowsingHistoryItem();
|
||||||
|
|
||||||
status_t archive(BMessage* archive) const;
|
status_t Archive(BMessage* archive) const;
|
||||||
|
|
||||||
BrowsingHistoryItem& operator=(const BrowsingHistoryItem& other);
|
BrowsingHistoryItem& operator=(const BrowsingHistoryItem& other);
|
||||||
|
|
||||||
bool operator==(const BrowsingHistoryItem& other) const;
|
bool operator==(
|
||||||
bool operator!=(const BrowsingHistoryItem& other) const;
|
const BrowsingHistoryItem& other) const;
|
||||||
bool operator<(const BrowsingHistoryItem& other) const;
|
bool operator!=(
|
||||||
bool operator<=(const BrowsingHistoryItem& other) const;
|
const BrowsingHistoryItem& other) const;
|
||||||
bool operator>(const BrowsingHistoryItem& other) const;
|
bool operator<(
|
||||||
bool operator>=(const BrowsingHistoryItem& other) const;
|
const BrowsingHistoryItem& other) const;
|
||||||
|
bool operator<=(
|
||||||
|
const BrowsingHistoryItem& other) const;
|
||||||
|
bool operator>(
|
||||||
|
const BrowsingHistoryItem& other) const;
|
||||||
|
bool operator>=(
|
||||||
|
const BrowsingHistoryItem& other) const;
|
||||||
|
|
||||||
const BString& url() const { return m_url; }
|
const BString& URL() const { return fURL; }
|
||||||
const BDateTime& dateTime() const { return m_dateTime; }
|
const BDateTime& DateTime() const { return fDateTime; }
|
||||||
uint32 invokationCount() const { return m_invokationCount; }
|
uint32 InvokationCount() const {
|
||||||
void invoked();
|
return fInvokationCount; }
|
||||||
|
void Invoked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BString m_url;
|
BString fURL;
|
||||||
BDateTime m_dateTime;
|
BDateTime fDateTime;
|
||||||
uint32 m_invokationCount;
|
uint32 fInvokationCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class BrowsingHistory : public BLocker {
|
class BrowsingHistory : public BLocker {
|
||||||
public:
|
public:
|
||||||
static BrowsingHistory* defaultInstance();
|
static BrowsingHistory* DefaultInstance();
|
||||||
|
|
||||||
bool addItem(const BrowsingHistoryItem& item);
|
bool AddItem(const BrowsingHistoryItem& item);
|
||||||
|
|
||||||
// Should Lock() the object when using these in some loop or so:
|
// Should Lock() the object when using these in some loop or so:
|
||||||
int32 countItems() const;
|
int32 CountItems() const;
|
||||||
BrowsingHistoryItem historyItemAt(int32 index) const;
|
BrowsingHistoryItem HistoryItemAt(int32 index) const;
|
||||||
void clear();
|
void Clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BrowsingHistory();
|
BrowsingHistory();
|
||||||
virtual ~BrowsingHistory();
|
virtual ~BrowsingHistory();
|
||||||
void privateClear();
|
|
||||||
bool privateAddItem(const BrowsingHistoryItem& item, bool invoke);
|
|
||||||
|
|
||||||
void saveSettings();
|
void _Clear();
|
||||||
bool openSettingsFile(BFile& file, uint32 mode);
|
bool _AddItem(const BrowsingHistoryItem& item,
|
||||||
|
bool invoke);
|
||||||
|
|
||||||
|
void _LoadSettings();
|
||||||
|
void _SaveSettings();
|
||||||
|
bool _OpenSettingsFile(BFile& file, uint32 mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BList m_historyItems;
|
BList fHistoryItems;
|
||||||
|
|
||||||
|
static BrowsingHistory sDefaultInstance;
|
||||||
|
bool fSettingsLoaded;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BrowsingHistory_h
|
|
||||||
|
#endif // BROWSING_HISTORY_H
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user