diff --git a/src/apps/webpositive/BrowserWindow.cpp b/src/apps/webpositive/BrowserWindow.cpp index 4ce93f9344..0295c01eda 100644 --- a/src/apps/webpositive/BrowserWindow.cpp +++ b/src/apps/webpositive/BrowserWindow.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +68,7 @@ #include #include +#include #include #include "AuthenticationPanel.h" @@ -172,6 +175,142 @@ private: }; +class BookmarkBar: public BMenuBar { +public: + BookmarkBar(const char* title, BHandler* target, const entry_ref* navDir) + : BMenuBar(title) + { + BEntry(navDir).GetNodeRef(&fNodeRef); + } + + ~BookmarkBar() + { + stop_watching(BMessenger(this)); + } + + void AttachedToWindow() + { + BMenuBar::AttachedToWindow(); + watch_node(&fNodeRef, B_WATCH_DIRECTORY, BMessenger(this)); + + // Enumerate initial directory content + BDirectory dir(&fNodeRef); + BEntry bookmark; + while(dir.GetNextEntry(&bookmark) == B_OK) { + node_ref ref; + bookmark.GetNodeRef(&ref); + AddItem(ref.node, &bookmark); + } + } + + void MessageReceived(BMessage* message) + { + switch(message->what) { + case B_NODE_MONITOR: + int32 opcode = message->FindInt32("opcode"); + ino_t inode = message->FindInt64("node"); + switch(opcode) { + case B_ENTRY_CREATED: + { + entry_ref ref; + const char *name; + + message->FindInt32("device", &ref.device); + message->FindInt64("directory", &ref.directory); + message->FindString("name", &name); + ref.set_name(name); + + BEntry entry(&ref); + AddItem(inode, &entry); + break; + } + case B_ENTRY_MOVED: + { + if (fItemsMap[inode] == NULL) + { + entry_ref ref; + const char *name; + + message->FindInt32("device", &ref.device); + message->FindInt64("to directory", &ref.directory); + message->FindString("name", &name); + ref.set_name(name); + + BEntry entry(&ref); + AddItem(inode, &entry); + break; + } else { + // Existing item. Check if it's a rename or a move + // to some other folder. + ino_t from, to; + message->FindInt64("to directory", &to); + message->FindInt64("from directory", &from); + if (from == to) + { + const char *name; + message->FindString("name", &name); + fItemsMap[inode]->SetLabel(name); + break; + } + } + + // fall through: the item was moved from here to + // elsewhere, remove it from the bar. + } + case B_ENTRY_REMOVED: + { + IconMenuItem* item = fItemsMap[inode]; + RemoveItem(item); + fItemsMap.erase(inode); + delete item; + } + } + return; + } + + BMenuBar::MessageReceived(message); + } + +private: + void AddItem(ino_t inode, BEntry* entry) + { + char name[B_FILE_NAME_LENGTH]; + entry->GetName(name); + + // make sure the item doesn't already exists + if (fItemsMap[inode] != NULL) + return; + + entry_ref ref; + entry->GetRef(&ref); + + IconMenuItem* item = NULL; + + if(entry->IsDirectory()) { + BNavMenu* menu = new BNavMenu(name, B_REFS_RECEIVED, Window()); + menu->SetNavDir(&ref); + item = new IconMenuItem(menu, NULL, + "application/x-vnd.Be-directory", B_MINI_ICON); + + } else { + BNode node(entry); + BNodeInfo info(&node); + + BMessage* message = new BMessage(B_REFS_RECEIVED); + message->AddRef("refs", &ref); + item = new IconMenuItem(name, message, &info, + B_MINI_ICON); + } + + BMenuBar::AddItem(item); + fItemsMap[inode] = item; + } + + node_ref fNodeRef; + std::map fItemsMap; +}; + + class PageUserData : public BWebView::UserData { public: PageUserData(BView* focusedView) @@ -581,6 +720,8 @@ BrowserWindow::BrowserWindow(BRect frame, SettingsMessage* appSettings, #if !INTEGRATE_MENU_INTO_TAB_BAR .Add(menuBarGroup) #endif + .Add(new BookmarkBar(B_TRANSLATE("Bookmarks"), this, + &bookmarkRef)) .Add(fTabManager->TabGroup()) .Add(navigationGroup) .Add(fTabManager->ContainerView())