diff options
author | Javier <dev.git@javispedro.com> | 2014-01-28 17:21:16 +0100 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2014-01-28 17:21:16 +0100 |
commit | 982ebc96f2c77c1f9dbddd6a4c0a776c74b425de (patch) | |
tree | 6800326ba4da9c84dc14f0b442f088b1c2fb63bf /module/topmenumenubarimpl.cc | |
download | topmenu-qt-982ebc96f2c77c1f9dbddd6a4c0a776c74b425de.tar.gz topmenu-qt-982ebc96f2c77c1f9dbddd6a4c0a776c74b425de.zip |
initial import
Diffstat (limited to 'module/topmenumenubarimpl.cc')
-rw-r--r-- | module/topmenumenubarimpl.cc | 252 |
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); +} |