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; 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 // 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) 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 // 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* triggerSlot, const char* toggleSlot, QWidget* parent,
const char* aboutToShowSlot) 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")); NamedList* p = static_cast<NamedList*>(param->getObject("NamedList"));
if (p) { if (p) {
QMenu* subMenu = buildMenu(*p,*param,receiver,triggerSlot,toggleSlot,menu); QMenu* subMenu = buildMenu(*p,*param ? param->c_str() : p->getValue("title",*p),
if (subMenu) receiver,triggerSlot,toggleSlot,menu);
if (subMenu) {
menu->addMenu(subMenu); menu->addMenu(subMenu);
setImage(subMenu,params["image:" + *p]);
}
continue; continue;
} }
String name = param->name().substr(5); 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)); QAction* a = menu->addAction(QtClient::setUtf8(*param));
a->setObjectName(QtClient::setUtf8(name)); a->setObjectName(QtClient::setUtf8(name));
a->setParent(menu); a->setParent(menu);
setImage(a,params["image:" + name]);
} }
else if (!name) else if (!name)
menu->addSeparator()->setParent(menu); menu->addSeparator()->setParent(menu);
@ -3354,6 +3449,27 @@ bool QtClient::setWidget(QWidget* parent, QWidget* child)
return true; 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 * QtDriver

View File

@ -347,7 +347,7 @@ public:
* @param parent Optional widget parent * @param parent Optional widget parent
* @return QMenu pointer or 0 if failed to build it * @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* actionSlot, const char* toggleSlot, QWidget* parent = 0,
const char* aboutToShowSlot = 0); const char* aboutToShowSlot = 0);
@ -359,6 +359,14 @@ public:
*/ */
static bool setWidget(QWidget* parent, QWidget* child); 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 * 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 getCheck(const String& name, bool& checked);
virtual bool getSelect(const String& name, String& item); 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 * Set a property for this window or for a widget owned by it
* @param name Name of the element * @param name Name of the element

View File

@ -64,6 +64,8 @@ public:
setParams, setParams,
addLines, addLines,
createObject, createObject,
buildMenu,
removeMenu,
setProperty, setProperty,
getProperty, getProperty,
openUrl openUrl
@ -745,6 +747,12 @@ void ClientThreadProxy::process()
case createObject: case createObject:
m_rval = client->createObject(m_pointer,m_name,m_text,const_cast<NamedList*>(m_params)); m_rval = client->createObject(m_pointer,m_name,m_text,const_cast<NamedList*>(m_params));
break; 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: case setProperty:
m_rval = client->setProperty(m_name,m_item,m_text,m_wnd,m_skip); m_rval = client->setProperty(m_name,m_item,m_text,m_wnd,m_skip);
break; break;
@ -1681,6 +1689,50 @@ bool Client::getSelect(const String& name, String& item, Window* wnd, Window* sk
return false; 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 // Set a property
bool Client::setProperty(const String& name, const String& item, const String& value, bool Client::setProperty(const String& name, const String& item, const String& value,
Window* wnd, Window* skip) Window* wnd, Window* skip)

View File

@ -328,6 +328,22 @@ public:
*/ */
virtual bool getSelect(const String& name, String& item) = 0; 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 * Set a property for this window or for a widget owned by it
* @param name Name of the element * @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 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); 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 * Set a property
* @param name Name of the element * @param name Name of the element