WebPositive: Add context menu to bookmarkbar items

Allows to rename and delete bookmarks

Fixes #10963.

Change-Id: I21cbc34291f1f564c92ce2dcb4d76098823987bb
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6082
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
omesh-barhate
2025-01-03 19:50:41 +00:00
committed by waddlesplash
parent b487eec70b
commit 855fbbc3a6
3 changed files with 175 additions and 5 deletions
+169 -3
View File
@@ -6,17 +6,32 @@
#include "BookmarkBar.h" #include "BookmarkBar.h"
#include <Alert.h>
#include <Catalog.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
#include <GroupLayout.h>
#include <IconMenuItem.h> #include <IconMenuItem.h>
#include <Messenger.h> #include <Messenger.h>
#include <PopUpMenu.h>
#include <PromptWindow.h>
#include <TextControl.h>
#include <Window.h> #include <Window.h>
#include "BrowserWindow.h"
#include "NavMenu.h" #include "NavMenu.h"
#include <stdio.h> #include <stdio.h>
#define B_TRANSLATION_CONTEXT "BookmarkBar"
const uint32 kOpenNewTabMsg = 'opnt';
const uint32 kDeleteMsg = 'dele';
const uint32 kAskBookmarkNameMsg = 'askn';
const uint32 kRenameBookmarkMsg = 'rena';
BookmarkBar::BookmarkBar(const char* title, BHandler* target, BookmarkBar::BookmarkBar(const char* title, BHandler* target,
const entry_ref* navDir) const entry_ref* navDir)
: :
@@ -27,6 +42,12 @@ BookmarkBar::BookmarkBar(const char* title, BHandler* target,
fOverflowMenu = new BMenu(B_UTF8_ELLIPSIS); fOverflowMenu = new BMenu(B_UTF8_ELLIPSIS);
fOverflowMenuAdded = false; fOverflowMenuAdded = false;
fPopUpMenu = new BPopUpMenu("Bookmark Popup", false, false);
fPopUpMenu->AddItem(new BMenuItem(B_TRANSLATE("Open in New Tab"),
new BMessage(kOpenNewTabMsg)));
fPopUpMenu->AddItem(new BMenuItem(B_TRANSLATE("Delete"), new BMessage(kDeleteMsg)));
fPopUpMenu->AddItem(new BMenuItem(B_TRANSLATE("Rename"), new BMessage(kAskBookmarkNameMsg)));
} }
@@ -35,6 +56,50 @@ BookmarkBar::~BookmarkBar()
stop_watching(BMessenger(this)); stop_watching(BMessenger(this));
if (!fOverflowMenuAdded) if (!fOverflowMenuAdded)
delete fOverflowMenu; delete fOverflowMenu;
delete fPopUpMenu;
}
void
BookmarkBar::MouseDown(BPoint where)
{
fSelectedItemIndex = -1;
BMessage* message = Window()->CurrentMessage();
if (message != nullptr) {
int32 buttons = 0;
if (message->FindInt32("buttons", &buttons) == B_OK) {
if (buttons & B_SECONDARY_MOUSE_BUTTON) {
bool foundItem = false;
for (int32 i = 0; i < CountItems(); i++) {
BRect itemBounds = ItemAt(i)->Frame();
if (itemBounds.Contains(where)) {
foundItem = true;
fSelectedItemIndex = i;
break;
}
}
if (foundItem) {
BPoint screenWhere(where);
ConvertToScreen(&screenWhere);
if (ItemAt(fSelectedItemIndex)->Message() == NULL) {
// This is a directory item, disable "open in new tab"
fPopUpMenu->ItemAt(0)->SetEnabled(false);
} else {
fPopUpMenu->ItemAt(0)->SetEnabled(true);
}
// Pop up the menu
fPopUpMenu->SetTargetForItems(this);
fPopUpMenu->Go(screenWhere, true, true, true);
return;
}
}
}
}
BMenuBar::MouseDown(where);
} }
@@ -127,13 +192,114 @@ BookmarkBar::MessageReceived(BMessage* message)
// Reevaluate whether the "more" menu is still needed // Reevaluate whether the "more" menu is still needed
BRect rect = Bounds(); BRect rect = Bounds();
FrameResized(rect.Width(), rect.Height()); FrameResized(rect.Width(), rect.Height());
break;
} }
} }
return; break;
} }
}
BMenuBar::MessageReceived(message); case kOpenNewTabMsg:
{
if (fSelectedItemIndex >= 0 && fSelectedItemIndex < CountItems()) {
// Get the bookmark refs
entry_ref ref;
BMenuItem* selectedItem = ItemAt(fSelectedItemIndex);
if (selectedItem->Message() == NULL
|| selectedItem->Message()->FindRef("refs", &ref) != B_OK) {
break;
}
// Use the entry_ref to create a BEntry instance and get its path
BEntry entry(&ref, true);
BPath path;
entry.GetPath(&path);
BMessage* message = new BMessage(B_REFS_RECEIVED);
message->AddRef("refs", &ref);
Window()->PostMessage(message);
}
break;
}
case kDeleteMsg:
{
if (fSelectedItemIndex >= 0 && fSelectedItemIndex < CountItems()) {
BMenuItem* selectedItem = ItemAt(fSelectedItemIndex);
// Get the bookmark refs
entry_ref ref;
if (selectedItem->Message()->FindRef("refs", &ref) != B_OK)
break;
// Use the entry_ref to create a BEntry instance and get its path
BEntry entry(&ref, true);
BPath path;
entry.GetPath(&path);
// Remove the bookmark file
if (entry.Remove() != B_OK) {
// handle error case if necessary
BString errorMessage = B_TRANSLATE("Failed to delete bookmark %path%");
errorMessage.ReplaceFirst("%path%", path.Path());
BAlert* alert = new BAlert("Error", errorMessage.String(), B_TRANSLATE("OK"));
alert->Go();
break;
}
// Remove the item from the bookmark bar
if (!RemoveItem(fSelectedItemIndex)) {
// handle error case if necessary
BString errorMessage = B_TRANSLATE("Failed to remove bookmark %path% "
"from path");
errorMessage.ReplaceFirst("%path%", path.Path());
BAlert* alert = new BAlert("Error", errorMessage.String(), B_TRANSLATE("OK"));
alert->Go();
}
}
break;
}
case kAskBookmarkNameMsg:
{
// Get the index of the selected item
int32 index = fSelectedItemIndex;
// Get the selected item
if (index >= 0 && index < CountItems()) {
BMenuItem* selectedItem = ItemAt(index);
BString oldName = selectedItem->Label();
BMessage* message = new BMessage(kRenameBookmarkMsg);
message->AddPointer("item", selectedItem);
BString request;
request.SetToFormat(B_TRANSLATE("Old name: %s"), oldName.String());
// Create a text control to get the new name from the user
PromptWindow* prompt = new PromptWindow(B_TRANSLATE("Rename bookmark"),
B_TRANSLATE("New name:"), request, this, message);
prompt->Show();
prompt->CenterOnScreen();
}
break;
}
case kRenameBookmarkMsg:
{
// User clicked OK, get the new name
BString newName = message->FindString("text");
BMenuItem* selectedItem = NULL;
message->FindPointer("item", (void**)&selectedItem);
// Rename the bookmark file
entry_ref ref;
if (selectedItem->Message()->FindRef("refs", &ref) == B_OK) {
BEntry entry(&ref, true);
entry.Rename(newName.String());
// Update the menu item label
selectedItem->SetLabel(newName);
}
break;
}
default:
BMenuBar::MessageReceived(message);
break;
}
} }
+4
View File
@@ -11,6 +11,7 @@
#include <MenuBar.h> #include <MenuBar.h>
#include <Node.h> #include <Node.h>
#include <NodeMonitor.h> #include <NodeMonitor.h>
#include <PopUpMenu.h>
#include <Size.h> #include <Size.h>
@@ -34,6 +35,7 @@ public:
void FrameResized(float width, float height); void FrameResized(float width, float height);
BSize MinSize(); BSize MinSize();
void MouseDown(BPoint where);
private: private:
void _AddItem(ino_t inode, BEntry* entry); void _AddItem(ino_t inode, BEntry* entry);
@@ -43,6 +45,8 @@ private:
BMenu* fOverflowMenu; BMenu* fOverflowMenu;
// True if fOverflowMenu is currently added to BookmarkBar // True if fOverflowMenu is currently added to BookmarkBar
bool fOverflowMenuAdded; bool fOverflowMenuAdded;
BPopUpMenu* fPopUpMenu;
int32 fSelectedItemIndex;
}; };
+2 -2
View File
@@ -114,6 +114,8 @@ public:
virtual void MenusBeginning(); virtual void MenusBeginning();
virtual void MenusEnded(); virtual void MenusEnded();
virtual void NewWindowRequested(const BString& url,
bool primaryAction);
virtual void ScreenChanged(BRect screenSize, virtual void ScreenChanged(BRect screenSize,
color_space format); color_space format);
virtual void WorkspacesChanged(uint32 oldWorkspaces, virtual void WorkspacesChanged(uint32 oldWorkspaces,
@@ -133,8 +135,6 @@ private:
// WebPage notification API implementations // WebPage notification API implementations
virtual void NavigationRequested(const BString& url, virtual void NavigationRequested(const BString& url,
BWebView* view); BWebView* view);
virtual void NewWindowRequested(const BString& url,
bool primaryAction);
virtual void CloseWindowRequested(BWebView* view); virtual void CloseWindowRequested(BWebView* view);
virtual void NewPageCreated(BWebView* view, virtual void NewPageCreated(BWebView* view,
BRect windowFrame, bool modalDialog, BRect windowFrame, bool modalDialog,