Added methods used to build and remove menus at runtime.

git-svn-id: http://yate.null.ro/svn/yate/trunk@3335 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
marian 2010-05-20 15:14:31 +00:00
parent 6ea274c2b4
commit 8b954ffe33
4 changed files with 250 additions and 4 deletions

View File

@ -1857,6 +1857,97 @@ bool QtWindow::getSelect(const String& name, String& item)
return false;
}
// Build a menu from a list of parameters
bool QtWindow::buildMenu(const NamedList& params)
{
QWidget* parent = wndWidget();
// Retrieve the owner
const String& owner = params["owner"];
if (owner && owner != m_id) {
parent = qFindChild<QWidget*>(wndWidget(),QtClient::setUtf8(owner));
if (!parent) {
DDebug(QtDriver::self(),DebugNote,
"QtWindow(%s) buildMenu(%s) owner '%s' not found [%p]",
m_id.c_str(),params.c_str(),owner.c_str(),this);
return false;
}
}
QWidget* target = parent;
const String& t = params["target"];
if (t) {
target = qFindChild<QWidget*>(wndWidget(),QtClient::setUtf8(t));
if (!target) {
DDebug(QtDriver::self(),DebugNote,
"QtWindow(%s) buildMenu(%s) target '%s' not found [%p]",
m_id.c_str(),params.c_str(),t.c_str(),this);
return false;
}
}
// Remove existing menu
removeMenu(params);
QMenu* menu = QtClient::buildMenu(params,params.getValue("title",params),this,
SLOT(action()),SLOT(toggled(bool)),parent);
if (!menu)
return false;
QMenuBar* mbOwner = qobject_cast<QMenuBar*>(target);
QMenu* mOwner = !mbOwner ? qobject_cast<QMenu*>(target) : 0;
if (mbOwner || mOwner) {
QAction* before = 0;
const String& bef = params["before"];
// Retrieve the action to insert before
if (bef) {
QString cmp = QtClient::setUtf8(bef);
QList<QAction*> list = target->actions();
for (int i = 0; !before && i < list.size(); i++) {
// Check action name or menu name if the action is associated with a menu
if (list[i]->objectName() == cmp)
before = list[i];
else if (list[i]->menu() && list[i]->menu()->objectName() == cmp)
before = list[i]->menu()->menuAction();
if (before && i && list[i - 1]->isSeparator() &&
params.getBoolValue("before_separator",true))
before = list[i - 1];
}
}
// Insert the menu
if (mbOwner)
mbOwner->insertMenu(before,menu);
else
mOwner->insertMenu(before,menu);
}
else {
QToolButton* tb = qobject_cast<QToolButton*>(target);
if (tb)
tb->setMenu(menu);
else {
QPushButton* pb = qobject_cast<QPushButton*>(target);
if (pb)
pb->setMenu(menu);
else
target->addAction(menu->menuAction());
}
}
return true;
}
// Remove a menu
bool QtWindow::removeMenu(const NamedList& params)
{
QWidget* parent = wndWidget();
// Retrieve the owner
const String& owner = params["owner"];
if (owner && owner != m_id) {
parent = qFindChild<QWidget*>(wndWidget(),QtClient::setUtf8(owner));
if (!parent)
return false;
}
QMenu* menu = qFindChild<QMenu*>(parent,QtClient::setUtf8(params));
if (!menu)
return false;
delete menu;
return true;
}
// Set a property for this window or for a widget owned by it
bool QtWindow::setProperty(const String& name, const String& item, const String& value)
{
@ -3243,7 +3334,7 @@ void QtClient::setAction(QWidget* parent)
}
// Build a menu object from a list of parameters
QMenu* QtClient::buildMenu(NamedList& params, const char* text, QObject* receiver,
QMenu* QtClient::buildMenu(const NamedList& params, const char* text, QObject* receiver,
const char* triggerSlot, const char* toggleSlot, QWidget* parent,
const char* aboutToShowSlot)
{
@ -3259,9 +3350,12 @@ QMenu* QtClient::buildMenu(NamedList& params, const char* text, QObject* receive
NamedList* p = static_cast<NamedList*>(param->getObject("NamedList"));
if (p) {
QMenu* subMenu = buildMenu(*p,*param,receiver,triggerSlot,toggleSlot,menu);
if (subMenu)
QMenu* subMenu = buildMenu(*p,*param ? param->c_str() : p->getValue("title",*p),
receiver,triggerSlot,toggleSlot,menu);
if (subMenu) {
menu->addMenu(subMenu);
setImage(subMenu,params["image:" + *p]);
}
continue;
}
String name = param->name().substr(5);
@ -3269,6 +3363,7 @@ QMenu* QtClient::buildMenu(NamedList& params, const char* text, QObject* receive
QAction* a = menu->addAction(QtClient::setUtf8(*param));
a->setObjectName(QtClient::setUtf8(name));
a->setParent(menu);
setImage(a,params["image:" + name]);
}
else if (!name)
menu->addSeparator()->setParent(menu);
@ -3354,6 +3449,27 @@ bool QtClient::setWidget(QWidget* parent, QWidget* child)
return true;
}
// Set an object's image property
bool QtClient::setImage(QObject* obj, const String& img)
{
if (!obj)
return false;
#define QtClient_setImage(Class,method,ImgClass) { \
Class* Class##var = qobject_cast<Class*>(obj); \
if (Class##var) { \
Class##var->method(ImgClass(setUtf8(img))); \
return true; \
} \
}
QtClient_setImage(QLabel,setPixmap,QPixmap);
QtClient_setImage(QAction,setIcon,QIcon);
QtClient_setImage(QAbstractButton,setIcon,QIcon);
QtClient_setImage(QMenu,setIcon,QIcon);
#undef QtClient_setIcon
return false;
}
/**
* QtDriver

View File

@ -347,7 +347,7 @@ public:
* @param parent Optional widget parent
* @return QMenu pointer or 0 if failed to build it
*/
static QMenu* buildMenu(NamedList& params, const char* text, QObject* receiver,
static QMenu* buildMenu(const NamedList& params, const char* text, QObject* receiver,
const char* actionSlot, const char* toggleSlot, QWidget* parent = 0,
const char* aboutToShowSlot = 0);
@ -359,6 +359,14 @@ public:
*/
static bool setWidget(QWidget* parent, QWidget* child);
/**
* Set an object's image property
* @param obj The object
* @param img Image file to load
* @return True on success
*/
static bool setImage(QObject* obj, const String& img);
/**
* Wrapper for QObject::connect() used to put a debug mesage on failure
*/
@ -490,6 +498,22 @@ public:
virtual bool getCheck(const String& name, bool& checked);
virtual bool getSelect(const String& name, String& item);
/**
* Build a menu from a list of parameters.
* See Client::buildMenu() for more info
* @param params Menu build parameters
* @return True on success
*/
virtual bool buildMenu(const NamedList& params);
/**
* Remove a menu from UI and memory
* See Client::removeMenu() for more info
* @param params Menu remove parameters
* @return True on success
*/
virtual bool removeMenu(const NamedList& params);
/**
* Set a property for this window or for a widget owned by it
* @param name Name of the element

View File

@ -64,6 +64,8 @@ public:
setParams,
addLines,
createObject,
buildMenu,
removeMenu,
setProperty,
getProperty,
openUrl
@ -745,6 +747,12 @@ void ClientThreadProxy::process()
case createObject:
m_rval = client->createObject(m_pointer,m_name,m_text,const_cast<NamedList*>(m_params));
break;
case buildMenu:
m_rval = m_params && client->buildMenu(*m_params,m_wnd,m_skip);
break;
case removeMenu:
m_rval = m_params && client->removeMenu(*m_params,m_wnd,m_skip);
break;
case setProperty:
m_rval = client->setProperty(m_name,m_item,m_text,m_wnd,m_skip);
break;
@ -1681,6 +1689,50 @@ bool Client::getSelect(const String& name, String& item, Window* wnd, Window* sk
return false;
}
// Build a menu from a list of parameters.
bool Client::buildMenu(const NamedList& params, Window* wnd, Window* skip)
{
if (!valid())
return false;
if (needProxy()) {
ClientThreadProxy proxy(ClientThreadProxy::buildMenu,String::empty(),&params,wnd,skip);
return proxy.execute();
}
if (wnd)
return wnd->buildMenu(params);
++s_changing;
bool ok = false;
for (ObjList* o = m_windows.skipNull(); o; o = o->skipNext()) {
wnd = static_cast<Window*>(o->get());
if (wnd != skip)
ok = wnd->buildMenu(params) || ok;
}
--s_changing;
return ok;
}
// Remove a menu
bool Client::removeMenu(const NamedList& params, Window* wnd, Window* skip)
{
if (!valid())
return false;
if (needProxy()) {
ClientThreadProxy proxy(ClientThreadProxy::removeMenu,String::empty(),&params,wnd,skip);
return proxy.execute();
}
if (wnd)
return wnd->removeMenu(params);
++s_changing;
bool ok = false;
for (ObjList* o = m_windows.skipNull(); o; o = o->skipNext()) {
wnd = static_cast<Window*>(o->get());
if (wnd != skip)
ok = wnd->removeMenu(params) || ok;
}
--s_changing;
return ok;
}
// Set a property
bool Client::setProperty(const String& name, const String& item, const String& value,
Window* wnd, Window* skip)

View File

@ -328,6 +328,22 @@ public:
*/
virtual bool getSelect(const String& name, String& item) = 0;
/**
* Build a menu from a list of parameters.
* See Client::buildMenu() for more info
* @param params Menu build parameters
* @return True on success
*/
virtual bool buildMenu(const NamedList& params) = 0;
/**
* Remove a menu (from UI and memory)
* See Client::removeMenu() for more info
* @param params Menu remove parameters
* @return True on success
*/
virtual bool removeMenu(const NamedList& params) = 0;
/**
* Set a property for this window or for a widget owned by it
* @param name Name of the element
@ -1096,6 +1112,44 @@ public:
bool getCheck(const String& name, bool& checked, Window* wnd = 0, Window* skip = 0);
bool getSelect(const String& name, String& item, Window* wnd = 0, Window* skip = 0);
/**
* Build a menu from a list of parameters and add it to a target.
* @param params Menu build parameters (list name is the menu name).
* Each menu item is indicated by a parameter item:[item_name]=[display_text].
* A separator will be added if 'item_name' is empty.
* A new item will be created if 'display_text' is not empty.
* Set 'display_text' to empty string to use an existing item.
* Item image can be set by an 'image:item_name' parameter.
* If the item parameter is a NamedPointer carrying a NamedList a submenu will be created.
* Menu item properties can be set from parameters with format
* property:item_name:property_name=value.
* The following parameters can be set:
* - title: menu display text (defaults to menu name)
* - owner: optional menu owner (the window building the menu is
* assumed to be the owner if this parameter is empty)
* - target: optional menu target (defaults to owner)
* - before: optional item to insert before if the target is a menu container
* (another menu or a menu bar)
* - before_separator: check if a separator already exists before the item
* 'before' and insert the menu before the separator
* @param wnd Optional target window
* @param skip Optional window to skip if wnd is 0
* @return True on success
*/
bool buildMenu(const NamedList& params, Window* wnd = 0, Window* skip = 0);
/**
* Remove a menu (from UI and memory)
* @param params Menu remove parameters.
* The following parameters can be set:
* - owner: optional menu owner (the window building the menu is
* assumed to be the owner if this parameter is empty)
* @param wnd Optional target window
* @param skip Optional window to skip if wnd is 0
* @return True on success
*/
bool removeMenu(const NamedList& params, Window* wnd = 0, Window* skip = 0);
/**
* Set a property
* @param name Name of the element