OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/gtk/global_menu_bar.h" | |
6 | |
7 #include <gtk/gtk.h> | |
8 | |
9 #include "chrome/app/chrome_command_ids.h" | |
10 #include "chrome/browser/prefs/pref_service.h" | |
11 #include "chrome/browser/profiles/profile.h" | |
12 #include "chrome/browser/ui/browser.h" | |
13 #include "chrome/browser/ui/gtk/accelerators_gtk.h" | |
14 #include "chrome/common/pref_names.h" | |
15 #include "content/common/notification_service.h" | |
16 #include "grit/generated_resources.h" | |
17 #include "ui/base/l10n/l10n_util.h" | |
18 #include "ui/gfx/gtk_util.h" | |
19 | |
20 struct GlobalMenuBarCommand { | |
21 int str_id; | |
22 int command; | |
23 }; | |
24 | |
25 namespace { | |
26 | |
27 const int MENU_SEPARATOR =-1; | |
28 const int MENU_END = -2; | |
29 | |
30 GlobalMenuBarCommand file_menu[] = { | |
31 { IDS_NEW_TAB, IDC_NEW_TAB }, | |
Evan Stade
2011/04/11 19:01:35
where are you getting these items from? Are you tr
Elliot Glaysher
2011/04/11 23:18:52
This is a combination of mac chrome, and linux fir
| |
32 { IDS_NEW_WINDOW, IDC_NEW_WINDOW }, | |
33 { IDS_NEW_INCOGNITO_WINDOW, IDC_NEW_INCOGNITO_WINDOW }, | |
34 { IDS_REOPEN_CLOSED_TABS_LINUX, IDC_RESTORE_TAB }, | |
35 { IDS_OPEN_FILE_LINUX, IDC_OPEN_FILE }, | |
36 { IDS_OPEN_LOCATION_LINUX, IDC_FOCUS_LOCATION }, | |
37 | |
38 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
39 | |
40 { IDS_CREATE_SHORTCUTS, IDC_CREATE_SHORTCUTS }, | |
41 | |
42 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
43 | |
44 { IDS_CLOSE_WINDOW_LINUX, IDC_CLOSE_WINDOW }, | |
45 { IDS_CLOSE_TAB_LINUX, IDC_CLOSE_TAB }, | |
46 { IDS_SAVE_PAGE, IDC_SAVE_PAGE }, | |
47 | |
48 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
49 | |
50 { IDS_PRINT, IDC_PRINT }, | |
51 | |
52 { MENU_END, MENU_END } | |
53 }; | |
54 | |
55 // TODO(erg): Need to add support for undo/redo/other editing commands that | |
56 // don't go through the command id framework. | |
57 GlobalMenuBarCommand edit_menu[] = { | |
58 // TODO(erg): Undo | |
59 // TODO(erg): Redo | |
60 | |
61 // TODO(erg): Separator | |
62 | |
63 { IDS_CUT, IDC_CUT }, | |
64 { IDS_COPY, IDC_COPY }, | |
65 { IDS_PASTE, IDC_PASTE }, | |
66 // TODO(erg): Delete | |
67 | |
68 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
69 | |
70 // TODO(erg): Select All | |
71 // TODO(erg): Another separator | |
72 | |
73 { IDS_FIND, IDC_FIND }, | |
74 | |
75 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
76 | |
77 { IDS_PREFERENCES, IDC_OPTIONS }, | |
78 | |
79 { MENU_END, MENU_END } | |
80 }; | |
81 | |
82 // TODO(erg): The View menu should be overhauled and based on the Firefox view | |
83 // menu. | |
84 GlobalMenuBarCommand view_menu[] = { | |
85 { IDS_SHOW_BOOKMARK_BAR, IDC_SHOW_BOOKMARK_BAR }, | |
86 | |
87 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
88 | |
89 { IDS_STOP_MENU_LINUX, IDC_STOP }, | |
90 { IDS_RELOAD_MENU_LINUX, IDC_RELOAD }, | |
91 | |
92 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
93 | |
94 { IDS_FULLSCREEN, IDC_FULLSCREEN }, | |
95 { IDS_TEXT_DEFAULT_LINUX, IDC_ZOOM_NORMAL }, | |
96 { IDS_TEXT_BIGGER_LINUX, IDC_ZOOM_PLUS }, | |
97 { IDS_TEXT_SMALLER_LINUX, IDC_ZOOM_MINUS }, | |
98 | |
99 { MENU_END, MENU_END } | |
100 }; | |
101 | |
102 GlobalMenuBarCommand tools_menu[] = { | |
103 { IDS_SHOW_DOWNLOADS, IDC_SHOW_DOWNLOADS }, | |
104 { IDS_SHOW_HISTORY, IDC_SHOW_HISTORY }, | |
105 { IDS_SHOW_EXTENSIONS, IDC_MANAGE_EXTENSIONS }, | |
106 | |
107 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
108 | |
109 { IDS_TASK_MANAGER, IDC_TASK_MANAGER }, | |
110 { IDS_CLEAR_BROWSING_DATA, IDC_CLEAR_BROWSING_DATA }, | |
111 | |
112 { MENU_SEPARATOR, MENU_SEPARATOR }, | |
113 | |
114 { IDS_VIEW_SOURCE, IDC_VIEW_SOURCE }, | |
115 { IDS_DEV_TOOLS, IDC_DEV_TOOLS }, | |
116 { IDS_DEV_TOOLS_CONSOLE, IDC_DEV_TOOLS_CONSOLE }, | |
117 | |
118 { MENU_END, MENU_END } | |
119 }; | |
120 | |
121 GlobalMenuBarCommand help_menu[] = { | |
122 { IDS_FEEDBACK, IDC_FEEDBACK }, | |
123 { IDS_HELP_PAGE , IDC_HELP_PAGE }, | |
124 { MENU_END, MENU_END } | |
125 }; | |
126 | |
127 } // namespace | |
128 | |
129 GlobalMenuBar::GlobalMenuBar(Browser* browser, | |
130 BrowserWindowGtk* window) | |
131 : browser_(browser), | |
132 browser_window_(window), | |
133 menu_bar_(gtk_menu_bar_new()), | |
134 dummy_accel_group_(gtk_accel_group_new()), | |
135 block_activation_(false) { | |
136 // The global menu bar should never actually be shown in the app; it should | |
137 // instead remain in our widget hierarchy simply to be noticed by third party | |
138 // components. | |
139 gtk_widget_set_no_show_all(menu_bar_, TRUE); | |
140 | |
141 BuildGtkMenuFrom(IDS_FILE_MENU_LINUX, &id_to_menu_item_, file_menu); | |
142 BuildGtkMenuFrom(IDS_EDIT_MENU_LINUX, &id_to_menu_item_, edit_menu); | |
143 BuildGtkMenuFrom(IDS_VIEW_MENU_LINUX, &id_to_menu_item_, view_menu); | |
144 BuildGtkMenuFrom(IDS_TOOLS_MENU_LINUX, &id_to_menu_item_, tools_menu); | |
145 BuildGtkMenuFrom(IDS_HELP_MENU_LINUX, &id_to_menu_item_, help_menu); | |
146 | |
147 for (IDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); | |
148 it != id_to_menu_item_.end(); ++it) { | |
149 // Get the starting enabled state. | |
150 gtk_widget_set_sensitive( | |
151 it->second, | |
152 browser_->command_updater()->IsCommandEnabled(it->first)); | |
153 | |
154 // Set the accelerator for each menu item. | |
155 const ui::AcceleratorGtk* accelerator_gtk = | |
156 AcceleratorsGtk::GetInstance()->GetPrimaryAcceleratorForCommand( | |
157 it->first); | |
158 if (accelerator_gtk) { | |
159 gtk_widget_add_accelerator(it->second, | |
160 "activate", | |
161 dummy_accel_group_, | |
162 accelerator_gtk->GetGdkKeyCode(), | |
163 accelerator_gtk->gdk_modifier_type(), | |
164 GTK_ACCEL_VISIBLE); | |
165 } | |
166 | |
167 browser_->command_updater()->AddCommandObserver(it->first, this); | |
168 } | |
169 | |
170 // Listen for bookmark bar visibility changes and set the initial state. | |
171 registrar_.Add(this, NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, | |
172 NotificationService::AllSources()); | |
173 Observe(NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED, | |
174 NotificationService::AllSources(), | |
175 NotificationService::NoDetails()); | |
176 } | |
177 | |
178 GlobalMenuBar::~GlobalMenuBar() { | |
179 for (IDMenuItemMap::const_iterator it = id_to_menu_item_.begin(); | |
180 it != id_to_menu_item_.end(); ++it) { | |
181 browser_->command_updater()->RemoveCommandObserver(it->first, this); | |
182 } | |
183 | |
184 g_object_unref(dummy_accel_group_); | |
185 } | |
186 | |
187 void GlobalMenuBar::BuildGtkMenuFrom(int menu_str_id, | |
188 std::map<int, GtkWidget*>* id_to_menu_item, | |
189 GlobalMenuBarCommand* commands) { | |
190 GtkWidget* menu = gtk_menu_new(); | |
191 for (int i = 0; commands[i].str_id != MENU_END; ++i) { | |
192 GtkWidget* menu_item = NULL; | |
193 if (commands[i].str_id == MENU_SEPARATOR) { | |
194 menu_item = gtk_separator_menu_item_new(); | |
195 } else { | |
196 int command_id = commands[i].command; | |
197 std::string label = | |
198 gfx::ConvertAcceleratorsFromWindowsStyle( | |
199 l10n_util::GetStringUTF8(commands[i].str_id)); | |
200 | |
201 if (command_id == IDC_SHOW_BOOKMARK_BAR) | |
202 menu_item = gtk_check_menu_item_new_with_mnemonic(label.c_str()); | |
203 else | |
204 menu_item = gtk_menu_item_new_with_mnemonic(label.c_str()); | |
205 | |
206 id_to_menu_item->insert(std::make_pair(command_id, menu_item)); | |
207 g_object_set_data(G_OBJECT(menu_item), "command-id", | |
208 GINT_TO_POINTER(command_id)); | |
209 g_signal_connect(menu_item, "activate", | |
210 G_CALLBACK(OnItemActivatedThunk), this); | |
211 } | |
212 gtk_widget_show(menu_item); | |
213 gtk_menu_shell_append(GTK_MENU_SHELL(menu), menu_item); | |
214 } | |
215 | |
216 gtk_widget_show(menu); | |
217 | |
218 GtkWidget* menu_item = gtk_menu_item_new_with_mnemonic( | |
219 gfx::ConvertAcceleratorsFromWindowsStyle( | |
220 l10n_util::GetStringUTF8(menu_str_id)).c_str()); | |
221 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), menu); | |
222 gtk_widget_show(menu_item); | |
223 | |
224 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar_), menu_item); | |
225 } | |
226 | |
227 void GlobalMenuBar::EnabledStateChangedForCommand(int id, bool enabled) { | |
228 IDMenuItemMap::iterator it = id_to_menu_item_.find(id); | |
229 if (it != id_to_menu_item_.end()) | |
230 gtk_widget_set_sensitive(it->second, enabled); | |
231 } | |
232 | |
233 void GlobalMenuBar::Observe(NotificationType type, | |
234 const NotificationSource& source, | |
235 const NotificationDetails& details) { | |
236 DCHECK(type.value == NotificationType::BOOKMARK_BAR_VISIBILITY_PREF_CHANGED); | |
237 | |
238 IDMenuItemMap::iterator it = id_to_menu_item_.find(IDC_SHOW_BOOKMARK_BAR); | |
239 if (it != id_to_menu_item_.end()) { | |
240 PrefService* prefs = browser_->profile()->GetPrefs(); | |
241 | |
242 block_activation_ = true; | |
243 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(it->second), | |
244 prefs->GetBoolean(prefs::kShowBookmarkBar)); | |
245 block_activation_ = false; | |
246 } | |
247 } | |
248 | |
249 void GlobalMenuBar::OnItemActivated(GtkWidget* sender) { | |
250 if (block_activation_) | |
251 return; | |
252 | |
253 int id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(sender), "command-id")); | |
254 browser_->ExecuteCommandIfEnabled(id); | |
255 } | |
OLD | NEW |