1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_UI_GTK_GLOBAL_MENU_BAR_H_
6#define CHROME_BROWSER_UI_GTK_GLOBAL_MENU_BAR_H_
7
8#include <map>
9
10#include "base/compiler_specific.h"
11#include "base/prefs/pref_change_registrar.h"
12#include "chrome/browser/command_observer.h"
13#include "chrome/browser/ui/gtk/global_history_menu.h"
14#include "ui/base/gtk/gtk_signal.h"
15
16class Browser;
17struct GlobalMenuBarCommand;
18class GlobalMenuOwner;
19
20typedef struct _GtkAccelGroup GtkAccelGroup;
21typedef struct _GtkWidget GtkWidget;
22
23// Controls the Mac style menu bar on Linux.
24//
25// Unity and some configurations of GNOME have a Apple-like menu bar at the top
26// of the screen that changes depending on the active window. These mainly work
27// by inspecting the application's widget hierarchy, and intercepting any
28// GtkMenuBar found. Thankfully, these systems don't check to see if the menu
29// bar itself is visible, so we insert a GtkMenuBar into the window hierarchy
30// and set it to be invisible.
31class GlobalMenuBar : public CommandObserver {
32 public:
33  static const int TAG_NORMAL = 0;
34  static const int TAG_MOST_VISITED = 1;
35  static const int TAG_RECENTLY_CLOSED = 2;
36  static const int TAG_MOST_VISITED_HEADER = 3;
37  static const int TAG_RECENTLY_CLOSED_HEADER = 4;
38  static const int TAG_BOOKMARK_CLEARABLE = 5;
39
40  explicit GlobalMenuBar(Browser* browser);
41  virtual ~GlobalMenuBar();
42
43  // Use this method to remove the GlobalMenuBar from any further notifications
44  // and command updates but not destroy the widgets.
45  virtual void Disable();
46
47  GtkWidget* widget() { return menu_bar_; }
48
49 private:
50  typedef std::map<int, GtkWidget*> CommandIDMenuItemMap;
51
52  // Helper function that builds the data.
53  void BuildGtkMenuFrom(int menu_str_id,
54                        std::map<int, GtkWidget*>* id_to_menu_item,
55                        GlobalMenuBarCommand* commands,
56                        GlobalMenuOwner* owner);
57
58  // Builds an individual menu item.
59  GtkWidget* BuildMenuItem(int string_id,
60                           int command_id,
61                           int tag_id,
62                           std::map<int, GtkWidget*>* id_to_menu_item,
63                           GtkWidget* menu_to_add_to);
64
65  // CommandObserver:
66  virtual void EnabledStateChangedForCommand(int id, bool enabled) OVERRIDE;
67
68  // Updates the visibility of the bookmark bar on pref changes.
69  void OnBookmarkBarVisibilityChanged();
70
71  CHROMEGTK_CALLBACK_0(GlobalMenuBar, void, OnItemActivated);
72
73  Browser* browser_;
74
75  // Tracks value of the kShowBookmarkBar preference.
76  PrefChangeRegistrar pref_change_registrar_;
77
78  // Our menu bar widget.
79  GtkWidget* menu_bar_;
80
81  // Listens to the TabRestoreService and the HistoryService and keeps the
82  // history menu fresh.
83  GlobalHistoryMenu history_menu_;
84
85  // For some menu items, we want to show the accelerator, but not actually
86  // explicitly handle it. To this end we connect those menu items' accelerators
87  // to this group, but don't attach this group to any top level window.
88  GtkAccelGroup* dummy_accel_group_;
89
90  // A mapping from command ids to GtkMenuItem objects. We use this to update
91  // the command enable state.
92  CommandIDMenuItemMap id_to_menu_item_;
93
94  // gtk_check_menu_item_set_active() will call the "activate" signal. We need
95  // to block this activation while we change the checked state.
96  bool block_activation_;
97};
98
99#endif  // CHROME_BROWSER_UI_GTK_GLOBAL_MENU_BAR_H_
100