cac8474e0a
* NEW: Control.PopupMenu is a new property that allows to define the name of the menu that will be automatically popped up when the user clicks on the control with the right mouse button, or press the menu key. Beware that if the Menu event handler is already defined for the control, the popup menu will not open. [GB.GTK] * NEW: Control.PopupMenu is a new property that allows to define the name of the menu that will be automatically popped up when the user clicks on the control with the right mouse button, or press the menu key. Beware that if the Menu event handler is already defined for the control, the popup menu will not open. git-svn-id: svn://localhost/gambas/trunk@3064 867c0c6c-44f3-4631-809d-bfa615b0a4ec
882 lines
17 KiB
C++
882 lines
17 KiB
C++
/***************************************************************************
|
|
|
|
CMenu.cpp
|
|
|
|
(c) 2000-2009 Benoît Minisini <gambas@users.sourceforge.net>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#define __CMENU_CPP
|
|
|
|
#undef QT3_SUPPORT
|
|
|
|
#include <QMenuBar>
|
|
#include <QMenu>
|
|
#include <QKeyEvent>
|
|
|
|
#include "gambas.h"
|
|
#include "gb_common.h"
|
|
|
|
#include "CWidget.h"
|
|
#include "CWindow.h"
|
|
#include "CMenu.h"
|
|
|
|
DECLARE_EVENT(EVENT_Click);
|
|
DECLARE_EVENT(EVENT_Show);
|
|
DECLARE_EVENT(EVENT_Hide);
|
|
|
|
DECLARE_METHOD(Control_Window);
|
|
DECLARE_METHOD(Control_Name);
|
|
DECLARE_METHOD(CMENU_hide);
|
|
|
|
static void clear_menu(CMENU *_object);
|
|
|
|
static int check_menu(void *_object)
|
|
{
|
|
return THIS->deleted || ACTION == 0;
|
|
}
|
|
|
|
static void refresh_menubar(CMENU *menu)
|
|
{
|
|
int i;
|
|
QList<QAction *> list;
|
|
QAction *action;
|
|
MyMainWindow *toplevel;
|
|
CWINDOW *window;
|
|
QMenuBar *menuBar;
|
|
|
|
if (!CMENU_is_toplevel(menu))
|
|
return;
|
|
|
|
toplevel = (MyMainWindow *)(menu->toplevel);
|
|
window = ((CWINDOW *)(menu->parent));
|
|
menuBar = window->menuBar;
|
|
if (!menuBar)
|
|
return;
|
|
|
|
list = menuBar->actions();
|
|
|
|
for (i = 0; i < list.count(); i++)
|
|
{
|
|
action = list.at(i);
|
|
menu = CMenu::dict[action];
|
|
if (!menu || menu->deleted)
|
|
continue;
|
|
if (action->isVisible() && !action->isSeparator())
|
|
break;
|
|
}
|
|
|
|
window->hideMenuBar = i == list.count();
|
|
toplevel->configure();
|
|
}
|
|
|
|
static void unregister_menu(CMENU *_object)
|
|
{
|
|
CACTION_register((CWIDGET *)THIS, NULL);
|
|
}
|
|
|
|
static void set_menu_visible(void *_object, bool v)
|
|
{
|
|
THIS->visible = v;
|
|
ACTION->setVisible(v);
|
|
refresh_menubar(THIS);
|
|
//update_accel_recursive(THIS);
|
|
}
|
|
|
|
static void delete_menu(CMENU *_object)
|
|
{
|
|
if (THIS->deleted)
|
|
return;
|
|
|
|
//qDebug("delete_menu: %s %p", THIS->widget.name, THIS);
|
|
|
|
THIS->deleted = true;
|
|
|
|
clear_menu(THIS);
|
|
|
|
if (THIS->menu)
|
|
{
|
|
delete THIS->menu;
|
|
THIS->menu = 0;
|
|
}
|
|
|
|
if (THIS->accel)
|
|
delete THIS->accel;
|
|
|
|
if (ACTION)
|
|
{
|
|
refresh_menubar(THIS);
|
|
delete ACTION;
|
|
}
|
|
|
|
// if (ACTION)
|
|
// {
|
|
// QAction *action = ACTION;
|
|
// THIS->widget.widget = 0;
|
|
// delete action;
|
|
// }
|
|
}
|
|
|
|
static void clear_menu(CMENU *_object)
|
|
{
|
|
int i;
|
|
CMENU *menu;
|
|
|
|
if (THIS->menu)
|
|
{
|
|
QList<QAction *> list = THIS->menu->actions();
|
|
|
|
for (i = 0; i < list.count(); i++)
|
|
{
|
|
menu = CMenu::dict[list.at(i)];
|
|
//GB.Ref(menu);
|
|
//delete ((QAction *)(menu->widget.widget));
|
|
if (menu)
|
|
delete_menu(menu);
|
|
//GB.Unref(POINTER(&menu));
|
|
}
|
|
}
|
|
}
|
|
|
|
static bool is_fully_enabled(CMENU *_object)
|
|
{
|
|
for(;;)
|
|
{
|
|
if (THIS->exec)
|
|
return true;
|
|
|
|
if (THIS->disabled)
|
|
return false;
|
|
|
|
if (CMENU_is_toplevel(THIS))
|
|
return true;
|
|
|
|
_object = (CMENU *)THIS->parent;
|
|
}
|
|
}
|
|
|
|
static void update_accel(CMENU *_object)
|
|
{
|
|
if (CMENU_is_toplevel(THIS))
|
|
return;
|
|
|
|
if (THIS->accel && !THIS->accel->isEmpty() && is_fully_enabled(THIS))
|
|
{
|
|
//if (!qstrcmp(THIS->widget.name, "mnuCopy"))
|
|
// qDebug("update_accel: %s: %s", THIS->widget.name, (const char *)THIS->accel->toString().toUtf8());
|
|
ACTION->setShortcut(*(THIS->accel));
|
|
}
|
|
else
|
|
{
|
|
//if (!qstrcmp(THIS->widget.name, "mnuCopy"))
|
|
// qDebug("update_accel: %s: NULL", THIS->widget.name);
|
|
ACTION->setShortcut(QKeySequence());
|
|
}
|
|
}
|
|
|
|
static void update_accel_recursive(CMENU *_object)
|
|
{
|
|
if (THIS->exec)
|
|
return;
|
|
|
|
update_accel(THIS);
|
|
|
|
if (THIS->menu)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < THIS->menu->actions().count(); i++)
|
|
update_accel_recursive(CMenu::dict[THIS->menu->actions().at(i)]);
|
|
}
|
|
}
|
|
|
|
static void update_check(CMENU *_object)
|
|
{
|
|
if (THIS->checked || THIS->toggle)
|
|
{
|
|
ACTION->setCheckable(true);
|
|
ACTION->setChecked(THIS->checked);
|
|
}
|
|
else
|
|
{
|
|
ACTION->setCheckable(false);
|
|
ACTION->setChecked(false);
|
|
}
|
|
}
|
|
|
|
#if 0
|
|
static void toggle_menu(CMENU *_object)
|
|
{
|
|
if (CMENU_is_toplevel(THIS))
|
|
return;
|
|
|
|
qDebug("toggle_menu: %s %d", TO_UTF8(ACTION->text()), ACTION->isChecked());
|
|
|
|
//ACTION->setCheckable(true);
|
|
ACTION->setChecked(!ACTION->isChecked());
|
|
//ACTION->setCheckable(false);
|
|
|
|
qDebug("--> %d", ACTION->isChecked());
|
|
}
|
|
#endif
|
|
|
|
BEGIN_METHOD(CMENU_new, GB_OBJECT parent; GB_BOOLEAN hidden)
|
|
|
|
QAction *action;
|
|
void *parent = VARG(parent);
|
|
QWidget *topLevel = 0;
|
|
QMenuBar *menuBar = 0;
|
|
|
|
//printf("CMENU_new %p\n", _object);
|
|
|
|
if (GB.CheckObject(parent))
|
|
return;
|
|
|
|
//qDebug("CMENU_new: (%s %p)", GB.GetClassName(THIS), THIS);
|
|
|
|
if (GB.Is(parent, CLASS_Menu))
|
|
{
|
|
CMENU *menu = (CMENU *)parent;
|
|
|
|
topLevel = menu->toplevel;
|
|
|
|
if (!menu->menu)
|
|
{
|
|
menu->menu = new QMenu();
|
|
menu->menu->setSeparatorsCollapsible(true);
|
|
((QAction *)(menu->widget.widget))->setMenu(menu->menu);
|
|
|
|
QObject::connect(menu->menu, SIGNAL(triggered(QAction *)), &CMenu::manager, SLOT(slotTriggered(QAction *)));
|
|
QObject::connect(menu->menu, SIGNAL(aboutToShow()), &CMenu::manager, SLOT(slotShown()));
|
|
QObject::connect(menu->menu, SIGNAL(aboutToHide()), &CMenu::manager, SLOT(slotHidden()));
|
|
}
|
|
|
|
action = new QAction(menu->menu);
|
|
action->setSeparator(true);
|
|
QObject::connect(action, SIGNAL(destroyed()), &CMenu::manager, SLOT(slotDestroyed()));
|
|
|
|
menu->menu->addAction(action);
|
|
//qDebug("New action %p for Menu %p", action, THIS);
|
|
}
|
|
else if (GB.Is(parent, CLASS_Window))
|
|
{
|
|
CWINDOW *window = (CWINDOW *)parent;
|
|
|
|
topLevel = QWIDGET(CWidget::getWindow((CWIDGET *)parent));
|
|
menuBar = window->menuBar;
|
|
if (!menuBar)
|
|
{
|
|
menuBar = new QMenuBar(topLevel);
|
|
window->menuBar = menuBar;
|
|
}
|
|
|
|
action = new QAction(menuBar);
|
|
action->setSeparator(true);
|
|
|
|
QObject::connect(action, SIGNAL(destroyed()), &CMenu::manager, SLOT(slotDestroyed()));
|
|
|
|
menuBar->addAction(action);
|
|
//qDebug("New action %p for top level Menu %p", action, THIS);
|
|
}
|
|
else
|
|
{
|
|
GB.Error("Type mismatch. The parent control of a Menu must be a Window or another Menu.");
|
|
return;
|
|
}
|
|
|
|
THIS->widget.widget = (QWidget *)action;
|
|
CMenu::dict.insert(action, THIS);
|
|
set_menu_visible(THIS, !VARGOPT(hidden, FALSE));
|
|
|
|
THIS->parent = parent;
|
|
THIS->widget.tag.type = GB_T_NULL;
|
|
THIS->widget.name = NULL;
|
|
THIS->picture = NULL;
|
|
THIS->deleted = false;
|
|
|
|
CWIDGET_init_name((CWIDGET *)THIS);
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("CMENU_new: item = %p (%d) parent = %p (%d) toplevel = %p", item, item->id, item->parent, item->parent ? item->parent->id : 0, item->toplevel);
|
|
#endif
|
|
|
|
THIS->toplevel = topLevel;
|
|
refresh_menubar(THIS);
|
|
//qDebug("*** CMENU_new %p", _object);
|
|
GB.Ref(THIS);
|
|
|
|
//qDebug("CMENU_new: (%s %p)", THIS->widget.name, THIS);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_free)
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("CMENU_free: item = %p '%s' (%d) parent = %p (%d)", item, item->text, item->id, item->parent, item->parent ? item->parent->id : 0);
|
|
#endif
|
|
|
|
//qDebug("CMENU_free: (%s %p)", THIS->widget.name, THIS);
|
|
|
|
delete_menu(THIS);
|
|
|
|
GB.StoreObject(NULL, POINTER(&(THIS->picture)));
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("*** CMENU_free: free tag");
|
|
#endif
|
|
|
|
GB.StoreVariant(NULL, &THIS->widget.tag);
|
|
|
|
//qDebug("free_name: %s %p (CMENU_free)", THIS->widget.name, THIS->widget.name);
|
|
//if (!strcmp(THIS->widget.name, "mnuCut"))
|
|
// BREAKPOINT();
|
|
GB.FreeString(&THIS->widget.name);
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("CMENU_free: item = %p '%s' (%d) is freed!", item, item->text, item->id);
|
|
#endif
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_text)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnNewZeroString(TO_UTF8(ACTION->text()));
|
|
else
|
|
{
|
|
QString text = QSTRING_PROP();
|
|
ACTION->setSeparator(text.isNull());
|
|
ACTION->setText(text);
|
|
refresh_menubar(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_picture)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnObject(THIS->picture);
|
|
else
|
|
{
|
|
QIcon icon;
|
|
|
|
GB.StoreObject(PROP(GB_OBJECT), POINTER(&(THIS->picture)));
|
|
if (THIS->picture)
|
|
icon = QIcon(*THIS->picture->pixmap);
|
|
ACTION->setIcon(icon);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_enabled)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(!THIS->disabled);
|
|
else
|
|
{
|
|
bool b = VPROP(GB_BOOLEAN);
|
|
THIS->disabled = !b;
|
|
ACTION->setEnabled(b);
|
|
//CMenu::enableAccel(THIS, b && !THIS->noshortcut);
|
|
update_accel_recursive(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(CMENU_checked)
|
|
|
|
if (CMENU_is_toplevel(THIS))
|
|
{
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(0);
|
|
}
|
|
else
|
|
{
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(THIS->checked);
|
|
else
|
|
{
|
|
THIS->checked = VPROP(GB_BOOLEAN);
|
|
update_check(THIS);
|
|
}
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_toggle)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(THIS->toggle);
|
|
else
|
|
{
|
|
THIS->toggle = VPROP(GB_BOOLEAN);
|
|
update_check(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
static void send_click_event(CMENU *_object);
|
|
|
|
BEGIN_PROPERTY(CMENU_value)
|
|
|
|
if (THIS->toggle)
|
|
{
|
|
CMENU_checked(_object, _param);
|
|
return;
|
|
}
|
|
|
|
if (READ_PROPERTY)
|
|
{
|
|
GB.ReturnBoolean(0);
|
|
}
|
|
else if (!CMENU_is_toplevel(THIS))
|
|
{
|
|
qDebug("CMENU_value: %s", THIS->widget.name);
|
|
GB.Ref(THIS);
|
|
send_click_event(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_shortcut)
|
|
|
|
if (CMENU_is_toplevel(THIS) || THIS->menu)
|
|
{
|
|
if (READ_PROPERTY)
|
|
GB.ReturnNull();
|
|
|
|
return;
|
|
}
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnNewZeroString(THIS->accel ? (const char *)THIS->accel->toString().toUtf8() : NULL);
|
|
else
|
|
{
|
|
if (THIS->accel)
|
|
delete THIS->accel;
|
|
THIS->accel = new QKeySequence;
|
|
*(THIS->accel) = QKeySequence::fromString(QSTRING_PROP());
|
|
|
|
update_accel(THIS);
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_visible)
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(THIS->visible);
|
|
else
|
|
set_menu_visible(THIS, VPROP(GB_BOOLEAN));
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_show)
|
|
|
|
set_menu_visible(THIS, true);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_hide)
|
|
|
|
set_menu_visible(THIS, false);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_delete)
|
|
|
|
delete_menu(THIS);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_count)
|
|
|
|
if (THIS->menu)
|
|
GB.ReturnInteger(THIS->menu->actions().count());
|
|
else
|
|
GB.ReturnInteger(0);
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_next)
|
|
|
|
int index;
|
|
|
|
if (!THIS->menu)
|
|
{
|
|
GB.StopEnum();
|
|
return;
|
|
}
|
|
|
|
index = ENUM(int);
|
|
|
|
if (index >= THIS->menu->actions().count())
|
|
{
|
|
GB.StopEnum();
|
|
return;
|
|
}
|
|
|
|
GB.ReturnObject(CMenu::dict[THIS->menu->actions().at(index)]);
|
|
|
|
ENUM(int) = index + 1;
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD(CMENU_get, GB_INTEGER index)
|
|
|
|
int index = VARG(index);
|
|
|
|
if (!THIS->menu || index < 0 || index >= THIS->menu->actions().count())
|
|
{
|
|
GB.Error(GB_ERR_BOUND);
|
|
return;
|
|
}
|
|
|
|
GB.ReturnObject(CMenu::dict[THIS->menu->actions().at(index)]);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD_VOID(CMENU_clear)
|
|
|
|
clear_menu(THIS);
|
|
|
|
END_METHOD
|
|
|
|
void CMENU_popup(CMENU *_object, const QPoint &pos)
|
|
{
|
|
bool disabled;
|
|
|
|
if (THIS->menu && !THIS->exec)
|
|
{
|
|
disabled = THIS->disabled;
|
|
if (disabled)
|
|
{
|
|
THIS->disabled = false;
|
|
update_accel_recursive(THIS);
|
|
THIS->disabled = true;
|
|
}
|
|
|
|
// The Click event is posted, it does not occur immediately.
|
|
THIS->exec = true;
|
|
THIS->menu->exec(pos);
|
|
THIS->exec = false;
|
|
|
|
update_accel_recursive(THIS);
|
|
|
|
//MyMainWindow *toplevel = (MyMainWindow *)(THIS->toplevel);
|
|
//CWINDOW_fix_menubar((CWINDOW *)CWidget::get(toplevel));
|
|
}
|
|
}
|
|
|
|
BEGIN_METHOD(Menu_Popup, GB_INTEGER x; GB_INTEGER y)
|
|
|
|
QPoint pos;
|
|
|
|
if (MISSING(x) || MISSING(y))
|
|
pos = QCursor::pos();
|
|
else
|
|
pos = QPoint(VARG(x), VARG(y));
|
|
|
|
CMENU_popup(THIS, pos);
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_PROPERTY(CMENU_window)
|
|
|
|
GB.ReturnObject(CWidget::get(THIS->toplevel));
|
|
|
|
END_PROPERTY
|
|
|
|
/*BEGIN_PROPERTY(CMENU_tear_off)
|
|
|
|
if (!THIS->menu)
|
|
return;
|
|
|
|
if (READ_PROPERTY)
|
|
GB.ReturnBoolean(THIS->menu->isTearOffEnabled());
|
|
else
|
|
THIS->menu->setTearOffEnabled(VPROP(GB_BOOLEAN));
|
|
|
|
END_PROPERTY*/
|
|
|
|
|
|
GB_DESC CMenuChildrenDesc[] =
|
|
{
|
|
GB_DECLARE(".MenuChildren", sizeof(CMENU)), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_METHOD("_next", "Menu", CMENU_next, NULL),
|
|
GB_METHOD("_get", "Menu", CMENU_get, "(Index)i"),
|
|
GB_METHOD("Clear", NULL, CMENU_clear, NULL),
|
|
GB_PROPERTY_READ("Count", "i", CMENU_count),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|
|
GB_DESC CMenuDesc[] =
|
|
{
|
|
GB_DECLARE("Menu", sizeof(CMENU)), //GB_HOOK_CHECK(CWIDGET_check),
|
|
GB_HOOK_CHECK(check_menu),
|
|
|
|
//GB_STATIC_METHOD("_init", NULL, CMENU_init, NULL),
|
|
GB_METHOD("_new", NULL, CMENU_new, "(Parent)o[(Hidden)b]"),
|
|
//GB_METHOD("_new", NULL, CMENU_new, "(Parent)o[(Visible)b]"),
|
|
GB_METHOD("_free", NULL, CMENU_free, NULL),
|
|
|
|
//GB_PROPERTY("Name", "s", CWIDGET_name),
|
|
|
|
//GB_PROPERTY_READ("Count", "i", CMENU_count),
|
|
|
|
//GB_PROPERTY_READ("Parent", "Control", CWIDGET_parent),
|
|
|
|
GB_PROPERTY("Name", "s", Control_Name),
|
|
GB_PROPERTY("Caption", "s", CMENU_text),
|
|
GB_PROPERTY("Text", "s", CMENU_text),
|
|
GB_PROPERTY("Enabled", "b", CMENU_enabled),
|
|
GB_PROPERTY("Checked", "b", CMENU_checked),
|
|
GB_PROPERTY("Tag", "v", Control_Tag),
|
|
GB_PROPERTY("Picture", "Picture", CMENU_picture),
|
|
//GB_PROPERTY("Stretch", "b", CMENU_stretch),
|
|
GB_PROPERTY("Shortcut", "s", CMENU_shortcut),
|
|
GB_PROPERTY("Visible", "b", CMENU_visible),
|
|
GB_PROPERTY("Toggle", "b", CMENU_toggle),
|
|
GB_PROPERTY("Value", "b", CMENU_value),
|
|
//GB_PROPERTY("TearOff", "b", CMENU_tear_off),
|
|
GB_PROPERTY("Action", "s", Control_Action),
|
|
GB_PROPERTY_READ("Window", "Window", CMENU_window),
|
|
|
|
GB_PROPERTY_SELF("Children", ".MenuChildren"),
|
|
//GB_PROPERTY_READ("Index", "i", CMENU_item_index),
|
|
|
|
MENU_DESCRIPTION,
|
|
|
|
GB_METHOD("Popup", NULL, Menu_Popup, "[(X)i(Y)i]"),
|
|
GB_METHOD("Delete", NULL, CMENU_delete, NULL),
|
|
GB_METHOD("Show", NULL, CMENU_show, NULL),
|
|
GB_METHOD("Hide", NULL, CMENU_hide, NULL),
|
|
|
|
//GB_EVENT("Delete", NULL, NULL, &EVENT_Destroy), // Must be first
|
|
GB_EVENT("Click", NULL, NULL, &EVENT_Click),
|
|
GB_EVENT("Show", NULL, NULL, &EVENT_Show),
|
|
GB_EVENT("Hide", NULL, NULL, &EVENT_Hide),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|
|
|
|
/* CMenu class */
|
|
|
|
CMenu CMenu::manager;
|
|
QHash<QAction *, CMENU *> CMenu::dict;
|
|
|
|
static void send_click_event(CMENU *_object)
|
|
{
|
|
if (THIS->toggle)
|
|
{
|
|
THIS->checked = !THIS->checked;
|
|
update_check(THIS);
|
|
}
|
|
|
|
GB.Raise(THIS, EVENT_Click, 0);
|
|
CACTION_raise((CWIDGET *)THIS);
|
|
GB.Unref(POINTER(&_object));
|
|
}
|
|
|
|
static void send_menu_event(CMENU *_object, intptr_t event)
|
|
{
|
|
GB.Raise(THIS, event, 0);
|
|
GB.Unref(POINTER(&_object));
|
|
}
|
|
|
|
void CMenu::slotTriggered(QAction *action)
|
|
{
|
|
GET_MENU_SENDER(parent);
|
|
CMENU *menu = CMenu::dict[action];
|
|
|
|
if (menu->parent != parent)
|
|
return;
|
|
|
|
//qDebug("slotTriggered: %s %s", menu->widget.name, (const char *)action->text().toUtf8());
|
|
GB.Ref(menu);
|
|
GB.Post((GB_POST_FUNC)send_click_event, (intptr_t)menu);
|
|
}
|
|
|
|
void CMenu::slotShown(void)
|
|
{
|
|
GET_MENU_SENDER(menu);
|
|
GB.Raise(menu, EVENT_Show, 0);
|
|
}
|
|
|
|
void CMenu::slotHidden(void)
|
|
{
|
|
GET_MENU_SENDER(menu);
|
|
|
|
if (GB.CanRaise(menu, EVENT_Hide))
|
|
{
|
|
GB.Ref(menu);
|
|
GB.Post2((GB_POST_FUNC)send_menu_event, (intptr_t)menu, EVENT_Hide);
|
|
}
|
|
}
|
|
|
|
|
|
#if 0
|
|
void CMenu::enableAccel(CMENU *item, bool enable, bool rec)
|
|
{
|
|
// Do not disable shortcuts when a menu is executed
|
|
if (item->exec && !enable)
|
|
return;
|
|
|
|
if (!rec)
|
|
qDebug("CMenu::enableAccel: %s: %s", item->widget.name, enable ? "ON" : "OFF");
|
|
|
|
item->noshortcut = !enable;
|
|
update_accel(item);
|
|
|
|
if (item->menu)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < item->menu->actions().count(); i++)
|
|
CMenu::enableAccel(CMenu::dict[item->menu->actions().at(i)], enable, true);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void CMenu::hideSeparators(CMENU *item)
|
|
{
|
|
if (!item->menu)
|
|
return;
|
|
|
|
#if 0
|
|
CMENU *child;
|
|
CMENU *last_child;
|
|
//QListIterator<CMENU> it(*item->children);
|
|
bool is_sep;
|
|
bool last_sep;
|
|
QList<CMENU *> children = *(item->children);
|
|
int i;
|
|
|
|
//qDebug("checking separators");
|
|
|
|
last_sep = true;
|
|
last_child = 0;
|
|
|
|
for(i = 0; i < children.count(); i++)
|
|
{
|
|
child = children.at(i);
|
|
|
|
is_sep = CMENU_is_separator(child);
|
|
|
|
//qDebug("separator = %d visible = %d (%p -> %p)", is_sep, CMENU_is_visible(child), child, it.current());
|
|
|
|
if (is_sep)
|
|
{
|
|
if (last_sep)
|
|
{
|
|
hide_menu(child);
|
|
}
|
|
else
|
|
{
|
|
show_menu(child);
|
|
last_sep = true;
|
|
last_child = child;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CMENU_is_visible(child))
|
|
last_sep = false;
|
|
}
|
|
}
|
|
|
|
if (last_sep && last_child)
|
|
hide_menu(last_child);
|
|
#endif
|
|
}
|
|
|
|
|
|
/*
|
|
void CMenu::unrefChildren(QWidget *w)
|
|
{
|
|
int i;
|
|
QList<QAction *> list = w->actions();
|
|
CMENU *child;
|
|
|
|
for (i = 0; i < list.count(); i++)
|
|
{
|
|
child = dict[list.at(i)];
|
|
//qDebug("CMenu::unrefChildren: (%s %p)", GB.GetClassName(child), child);
|
|
GB.Detach(child);
|
|
unregister_menu(child);
|
|
//qDebug("*** CMenu::destroy %p (child)", child);
|
|
GB.Unref(POINTER(&child));
|
|
}
|
|
}*/
|
|
|
|
void CMenu::slotDestroyed(void)
|
|
{
|
|
CMENU *_object = dict[(QAction *)sender()];
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("*** { CMenu::destroy %p", menu);
|
|
#endif
|
|
|
|
//qDebug("CMenu::slotDestroyed: action = %p THIS = %p", sender(), _object);
|
|
|
|
if (!_object)
|
|
return;
|
|
|
|
CMenu::dict.remove(ACTION);
|
|
//qDebug("CMenu::slotDestroyed: (%s %p)", GB.GetClassName(THIS), THIS);
|
|
|
|
//if (THIS->menu)
|
|
// unrefChildren(THIS->menu);
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("UNREF (%s %p)", THIS->widget.name, THIS);
|
|
#endif
|
|
|
|
THIS->widget.widget = 0;
|
|
|
|
unregister_menu(THIS);
|
|
GB.Unref(POINTER(&_object));
|
|
|
|
//menu->dict = dict;
|
|
|
|
#ifdef DEBUG_MENU
|
|
qDebug("*** } CMenu::destroy: %p", menu);
|
|
#endif
|
|
}
|
|
|