Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Highlighted
Developer
Posts: 154
Registered: ‎02-01-2009
My Device: Torch, PlayBook and Dev Alpha
My Carrier: SFR
Accepted Solution

HOWTO: Use context action item with ListView in C++

Hi,

 

I need your advice and the best way to manage the user action from the context menu linked to a ListItem (or the MultiSelectActionItem)

 

My ListView skeleton is defined in QML. Then in C++, I create and fill the ListView. The ListView can be instancied several times (each with its own data model). So for each ListView, I have the same context action.

 

Now, how to manage the action trigger signal. Sample, for ListItem delete action, I can't connect a slot to ListItem signal. Otherwise, I have to do it for each ListItem ! I think that it isn't the good way.

 

I have looked the bucket sample. The actions are managed directly from the datamodel. 

 

The second point is that the process linked to the action item is long and scheduled through the Qt event loop. (and of course the content list can change before the end of process).

 

An other solution could be : from QML send a custom signal from the ListView object (and not from the ListItem).

 

Nicolas

 

Retired
Posts: 499
Registered: ‎05-07-2012
My Device: developer
My Carrier: developer

Re: HOWTO: Use context action item with ListView in C++

I see what you mean about BucketList: there is an action set applied to each item.

 

In many cases it may make more sense to attach the actions to the list.  I suggest something along these lines:

 

Adding to stampcollector main.qml, in the ListView after the ListItemComponents:

                contextActions: [
                    ActionSet {
                        ActionItem {
                            objectName: "ooglyAction"
                            title: "oogly"
                        }
                        ActionItem {
                            objectName: "booglyAction"
                            title: "boogly"
                        }
                        DeleteActionItem {
                            objectName: "deleteAction"
                            title: "Delete"
                        }
                    }
                ]

 

In stampcollectorapp.cpp:

 

a) in the constructor:

 

    ActionItem* action = nav->findChild<ActionItem*>("ooglyAction");
    if (action)
    	connect(action, SIGNAL(triggered()), this, SLOT(onListActionOogly()));
    action = nav->findChild<ActionItem*>("booglyAction");
    if (action)
    	connect(action, SIGNAL(triggered()), this, SLOT(onListActionBoogly()));
    DeleteActionItem* daction = nav->findChild<DeleteActionItem*>("deleteAction");
    if (daction)
    	connect(daction, SIGNAL(triggered()), this, SLOT(onListActionDelete()));

 

(although you could use the same signal handler for all non-delete actions if you want, and switch on the action text in the handler)

 

b) as methods:

 

void StampCollectorApp::onListActionOogly()
{
	qDebug() << "Here I am: oogly!";
	qDebug() << sender();
}
void StampCollectorApp::onListActionBoogly()
{
	qDebug() << "Here I am: Boogly!";
	qDebug() << sender();
}
void StampCollectorApp::onListActionDelete()
{
	qDebug() << "Here I am: Delete!";
	qDebug() << sender();

	DeleteActionItem* action = dynamic_cast<DeleteActionItem*>(sender());
	if (action == 0)
	{
		qDebug() << "Not expected type";
		return;
	}
	qDebug() << "Yes, found!";

	QObject* parent = action->parent(); // get ActionSet
	if (parent != 0) parent = parent->parent();
	if (parent == 0)
	{
		qDebug() << "No parent!";
		return;
	}
	const QMetaObject* m = parent->metaObject();
	if (m == 0)
	{
		qDebug() << "No metaobject!";
	}
	qDebug() << m->className();
}

 

In other words, use sender()

 

Stuart