aboutsummaryrefslogtreecommitdiff
path: root/module/topmenumenubarimpl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'module/topmenumenubarimpl.cc')
-rw-r--r--module/topmenumenubarimpl.cc252
1 files changed, 252 insertions, 0 deletions
diff --git a/module/topmenumenubarimpl.cc b/module/topmenumenubarimpl.cc
new file mode 100644
index 0000000..1753394
--- /dev/null
+++ b/module/topmenumenubarimpl.cc
@@ -0,0 +1,252 @@
+#include <gtk/gtk.h>
+#include <topmenu-client.h>
+#include <topmenu-monitor.h>
+#include <topmenu-appmenubar.h>
+#include <QtCore/QDebug>
+#include <QtGui/QActionEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QX11Info>
+
+#include "topmenumenubarimpl.h"
+#include "appmenu.h"
+#include "qtkeysyms.h"
+
+bool TopMenuMenuBarImpl::staticInitialized = false;
+TopMenuMonitor * TopMenuMenuBarImpl::menuMonitor;
+
+static inline QShortcut * get_shortcut_for_action(QAction *action)
+{
+ QVariant v = action->property("topmenu-shortcut");
+ if (v.isValid()) {
+ return static_cast<QShortcut*>(v.value<QObject*>());
+ }
+ return 0;
+}
+
+static inline void set_shortcut_for_action(QAction *action, QShortcut *shortcut)
+{
+ if (shortcut) {
+ action->setProperty("topmenu-shortcut", QVariant::fromValue<QObject*>(shortcut));
+ } else {
+ action->setProperty("topmenu-shortcut", QVariant());
+ }
+}
+
+static inline QAction * get_action_for_shortcut(QShortcut *shortcut)
+{
+ QVariant v = shortcut->property("topmenu-action");
+ if (v.isValid()) {
+ return static_cast<QAction*>(v.value<QObject*>());
+ }
+ return 0;
+}
+
+static inline void set_action_for_shortcut(QShortcut *shortcut, QAction *action)
+{
+ if (shortcut) {
+ shortcut->setProperty("topmenu-action", QVariant::fromValue<QObject*>(action));
+ } else {
+ shortcut->setProperty("topmenu-action", QVariant());
+ }
+}
+
+TopMenuMenuBarImpl::TopMenuMenuBarImpl(QObject *parent) :
+ MenuProxy(parent),
+ m_window(0), m_menubar(0), m_appmenu(0),
+ m_disable(false), m_visible(true)
+{
+ // A new instance of this class will be created for each window.
+ if (!staticInitialized) {
+ XErrorHandler qt_x_errhandler = XSetErrorHandler(0);
+ gtk_init(NULL, NULL);
+ XSetErrorHandler(qt_x_errhandler);
+
+ menuMonitor = topmenu_monitor_get_instance();
+ // TODO g_signal_connect()
+
+ staticInitialized = true;
+ }
+}
+
+TopMenuMenuBarImpl::~TopMenuMenuBarImpl()
+{
+ if (m_menubar) {
+ g_object_unref(m_menubar);
+ m_menubar = 0;
+ }
+}
+
+void TopMenuMenuBarImpl::init(QMenuBar *menuBar)
+{
+ Q_ASSERT(menuBar);
+ Q_ASSERT(!m_menubar);
+ m_menubar = topmenu_app_menu_bar_new();
+ g_object_ref_sink(m_menubar);
+ m_appmenu = new AppMenu(this);
+ topmenu_app_menu_bar_set_app_menu(m_menubar,
+ GTK_WIDGET(m_appmenu->getGtkMenu()));
+ gtk_widget_show(GTK_WIDGET(m_menubar));
+ setTargetMenu(GTK_MENU_SHELL(m_menubar));
+}
+
+void TopMenuMenuBarImpl::setVisible(bool visible)
+{
+ m_visible = visible;
+}
+
+void TopMenuMenuBarImpl::actionEvent(QActionEvent *e)
+{
+ switch (e->type()) {
+ case QEvent::ActionAdded:
+ addAction(e->action(), e->before(), 0);
+ break;
+ case QEvent::ActionRemoved:
+ removeAction(e->action());
+ break;
+ case QEvent::ActionChanged:
+ updateAction(e->action());
+ break;
+ default:
+ break;
+ }
+}
+
+void TopMenuMenuBarImpl::handleReparent(QWidget *oldParent, QWidget *newParent, QWidget *oldWindow, QWidget *newWindow)
+{
+ Q_UNUSED(oldParent);
+ Q_UNUSED(newParent);
+
+ if (oldWindow) {
+ GdkWindow *old_window = gdk_window_foreign_new(oldWindow->winId());
+ topmenu_client_disconnect_window(old_window);
+
+ Q_FOREACH(QAction *action, m_rootitems) {
+ QShortcut *shortcut = get_shortcut_for_action(action);
+ if (shortcut) {
+ set_shortcut_for_action(action, 0);
+ delete shortcut;
+ }
+ }
+ }
+
+ if (newWindow) {
+ Q_ASSERT(m_menubar);
+ GdkWindow *new_window = gdk_window_foreign_new(newWindow->winId());
+ topmenu_client_connect_window_widget(new_window, GTK_WIDGET(m_menubar));
+
+ Q_FOREACH(QAction *action, m_rootitems) {
+ createMnemonicShortcut(action, newWindow);
+ }
+ }
+
+ m_window = newWindow;
+}
+
+bool TopMenuMenuBarImpl::allowCornerWidgets() const
+{
+ return !isNativeMenuBar();
+}
+
+void TopMenuMenuBarImpl::popupAction(QAction *act)
+{
+ qDebug() << "TODO Popup action: " << act->text();
+}
+
+void TopMenuMenuBarImpl::setNativeMenuBar(bool value)
+{
+ m_disable = !value;
+}
+
+bool TopMenuMenuBarImpl::isNativeMenuBar() const
+{
+ if (m_disable || QCoreApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar))
+ return false;
+ return menuMonitor->available;
+}
+
+bool TopMenuMenuBarImpl::shortcutsHandledByNativeMenuBar() const
+{
+ return false;
+}
+
+bool TopMenuMenuBarImpl::menuBarEventFilter(QObject *src, QEvent *event)
+{
+ Q_UNUSED(src);
+ Q_UNUSED(event);
+ return false;
+}
+
+GtkMenuItem * TopMenuMenuBarImpl::addAction(QAction* action, QAction* before, QMenu* parent)
+{
+ if (!parent) {
+ m_rootitems.append(action);
+
+ if (m_window) {
+ createMnemonicShortcut(action, m_window);
+ }
+ }
+
+ if (m_appmenu) {
+ m_appmenu->addAction(action);
+ }
+
+ return MenuProxy::addAction(action, before, parent);
+}
+
+void TopMenuMenuBarImpl::removeAction(QAction *action)
+{
+ m_rootitems.removeAll(action);
+ QShortcut *shortcut = get_shortcut_for_action(action);
+ if (shortcut) {
+ set_shortcut_for_action(action, 0);
+ delete shortcut;
+ }
+
+ if (m_appmenu) {
+ m_appmenu->removeAction(action);
+ }
+
+ MenuProxy::removeAction(action);
+}
+
+void TopMenuMenuBarImpl::updateAction(QAction *action)
+{
+ if (!action->isSeparator() && m_rootitems.contains(action) && m_window) {
+ QShortcut *shortcut = get_shortcut_for_action(action);
+ if (shortcut) {
+ shortcut->setKey(QKeySequence::mnemonic(action->text()));
+ } else {
+ shortcut = createMnemonicShortcut(action, m_window);
+ }
+ shortcut->setEnabled(action->isEnabled());
+ }
+
+ if (m_appmenu) {
+ m_appmenu->updateAction(action);
+ }
+
+ MenuProxy::updateAction(action);
+}
+
+QShortcut * TopMenuMenuBarImpl::createMnemonicShortcut(QAction *action, QWidget *parent)
+{
+ QShortcut *shortcut = new QShortcut(parent);
+
+ set_shortcut_for_action(action, shortcut);
+ set_action_for_shortcut(shortcut, action);
+
+ shortcut->setKey(QKeySequence::mnemonic(action->text()));
+
+ connect(shortcut, SIGNAL(activated()),
+ this, SLOT(handleShortcutActivated()));
+
+ return shortcut;
+}
+
+void TopMenuMenuBarImpl::handleShortcutActivated()
+{
+ QShortcut *shortcut = static_cast<QShortcut*>(sender());
+ QAction *action = get_action_for_shortcut(shortcut);
+ GtkMenuItem *item = getItemForAction(action);
+ gtk_widget_mnemonic_activate(GTK_WIDGET(item), FALSE);
+}