1 /*
2 * Copyright (C) 2006 Zack Rusin <zack@kde.org>
3 * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include "ContextMenu.h"
29
30 #include "ContextMenuItem.h"
31 #include "ContextMenuController.h"
32 #include "Frame.h"
33 #include "FrameView.h"
34 #include "Document.h"
35
36 #include <wtf/Assertions.h>
37
38 #include <Looper.h>
39 #include <Menu.h>
40 #include <Message.h>
41
42
43 namespace WebCore {
44
45 // FIXME: This class isn't used yet
46 class ContextMenuReceiver : public BLooper
47 {
48 public:
ContextMenuReceiver(ContextMenu * menu)49 ContextMenuReceiver(ContextMenu* menu)
50 : BLooper("context_menu_receiver")
51 , m_menu(menu)
52 {
53 m_result = -1;
54 }
55
HandleMessage(BMessage * msg)56 void HandleMessage(BMessage* msg)
57 {
58 m_result = msg->what;
59 if (m_result != -1) {
60 BMenuItem* item = m_menu->platformDescription()->FindItem(m_result);
61 if (!item) {
62 printf("Error: Context menu item with code %i not found!\n", m_result);
63 return;
64 }
65 ContextMenuItem cmItem(item);
66 m_menu->controller()->contextMenuItemSelected(&cmItem);
67 cmItem.releasePlatformDescription();
68 }
69 }
70
Result()71 int Result()
72 {
73 return m_result;
74 }
75
76 private:
77 ContextMenu* m_menu;
78 int m_result;
79 };
80
ContextMenu(const HitTestResult & result)81 ContextMenu::ContextMenu(const HitTestResult& result)
82 : m_hitTestResult(result)
83 , m_platformDescription(NULL)
84 {
85 /* Get position */
86 if (result.innerNode() && result.innerNode()->document()) {
87 BView* view = result.innerNode()->document()->frame()->view()->platformWidget();
88 int child = 0;
89 while (view->ChildAt(child)) {
90 if (view->ChildAt(child)->Name() == "scroll_view_canvas") {
91 m_point = view->ChildAt(child)->ConvertToScreen(BPoint(result.point().x(), result.point().y()));
92 break;
93 }
94 child++;
95 }
96 }
97 m_platformDescription = new BMenu("context_menu");
98 }
99
~ContextMenu()100 ContextMenu::~ContextMenu()
101 {
102 delete m_platformDescription;
103 }
104
appendItem(ContextMenuItem & item)105 void ContextMenu::appendItem(ContextMenuItem& item)
106 {
107 checkOrEnableIfNeeded(item);
108
109 BMenuItem* bItem = item.releasePlatformDescription();
110 if (bItem)
111 m_platformDescription->AddItem(bItem);
112 }
113
itemCount() const114 unsigned ContextMenu::itemCount() const
115 {
116 return m_platformDescription->CountItems();
117 }
118
insertItem(unsigned position,ContextMenuItem & item)119 void ContextMenu::insertItem(unsigned position, ContextMenuItem& item)
120 {
121 checkOrEnableIfNeeded(item);
122
123 BMenuItem* bItem = item.releasePlatformDescription();
124 if (bItem)
125 m_platformDescription->AddItem(bItem, position);
126 }
127
platformDescription() const128 PlatformMenuDescription ContextMenu::platformDescription() const
129 {
130 return m_platformDescription;
131 }
132
setPlatformDescription(PlatformMenuDescription menu)133 void ContextMenu::setPlatformDescription(PlatformMenuDescription menu)
134 {
135 if (static_cast<BMenu*>(menu) == m_platformDescription)
136 return;
137
138 delete m_platformDescription;
139 m_platformDescription = static_cast<BMenu*>(menu);
140 }
141
142 } // namespace WebCore
143
144