PDA

View Full Version : ListView Dynamic Popup menu



raphaelf
13th October 2006, 12:47
Hi everybody,

I have a listview. I create a menu for this listview.
The idea from this popup menu is that the user are able to delete songs from the list OR
add songs to a playlist.
But it depends if the user see the playlist or are searching songs..If the user see the playlist,
so he must be able just to "remove songs from the Playlist".
If he are searching songs, he should be able just to "add to Playlist". My popup is dynamic.


My situation now:
I am not able to call the function actionTriggered() on choosing a action from contextMenu2. The function
actionTriggered2 will always called.
I am able to call actionTriggered2() from contextMenu without problem.

How could i call actionTriggered() by choosesing "add to Playlist". And how could i call actionTriggered2() on choosing
"remove from Playlist"?
Thanks :crying:



contextMenu2 = new Q3PopupMenu( this);
contextMenu2 = new Q3PopupMenu( this);



contextMenu = new Q3PopupMenu( this);
contextMenu2 = new Q3PopupMenu( this);


connect(contextMenu2,SIGNAL(triggered(QAction *)),this,SLOT(actionTriggered(QAction *)));
connect(contextMenu,SIGNAL(triggered(QAction *)),this,SLOT(actionTriggered2(QAction *)));


void MainWindow::PlaylistMenu( Q3ListViewItem *Item, const QPoint &point, int)
{
contextMenu2->clear();
contextMenu->clear();

if( Item )
contextMenu->popup( point );
Q_CHECK_PTR( contextMenu );


//Die Playlist Funktionen sollen nur angezeigt werden, wenn auch
//eine Playlist gewählt wurde und auch einen song vorhanden ist
if((ui.playlistname_cb->currentText() != "") && (ui.listView->childCount() > 0))
{
contextMenu->insertItem( "&remove from Playlist");
contextMenu->exec( QCursor::pos() );
//delete contextMenu;
return;
}
if((ui.playlistname_cb->currentText() == "") && (ui.listView->childCount() > 0))
{
contextMenu2->setTitle("add to Playlist");
int items = ui.playlistname_cb->count();
for(int i = 1; i < items; i++)
{
QString playlistname = ui.playlistname_cb->itemText(i);
contextMenu2->addAction(playlistname);
contextMenu->addMenu(contextMenu2);
}
contextMenu->exec( QCursor::pos() );
//delete contextMenu;
//delete contextMenu2;
return;
}
}


void MainWindow::actionTriggered(QAction *a)
{
QString playlistname = a->text();
addToPlaylist(&playlistname);
}

void MainWindow::actionTriggered2(QAction *a)
{
QString songname = (ui.listView->currentItem() )->text( 0 );
QString artist = (ui.listView->currentItem() )->text( 1 );
switch( QMessageBox::warning( this, "DSM",
"Remove " + songname + " of " + artist + " from Playlist "
+ ui.playlistname_cb->currentText() + " ?\n\n",
"Yes",
"No", 0, 0, 1 ) )
{
case 1:
break;
case 0:
//Song aus der aktuelle Playlist löschen
removeFromPlaylist();
//Aktualisieren
getPlaylist();
}
}

wysota
13th October 2006, 20:17
First of all I suggest you stopped using the Q3Support library (Q3PopupMenu - why not use QMenu?).

I see you misunderstand the concept of actions and menus. I'd suggest something like this (this is not a complete code!):

class MyClass : public ... {
//...
private:
QAction *m_addAction;
QAction *m_removeAction;
};

MyClass::MyClass() {
//...
m_addAction = new QAction("Add to playlist", this);
m_removeAction = new QAction("Remove from playlist", this);
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addToPlaylist()));
connect(m_removeAction, SIGNAL(triggered()), this, SLOT(removeFromPlaylist()));
//...
}

void MyClass::playListMenu(QPoint &pt){
QMenu menu;
if(shouldAddToPlaylist()){
menu.addAction(m_addAction);
} else {
menu.addAction(m_removeAction);
}
menu.exec(pt);
}
You can also add both actions and simply disable or hide the one you don't want. You'll get cleaner code then. Although for the QListView I'd use QWidget::customContextMenuRequested( const QPoint & pos ) signal and QAbstractItemView::indexAt() to fetch the item under cursor, but I don't know what you're exactly doing so some other approach might be better.

raphaelf
14th October 2006, 08:45
Hi wysota :D

Thank you very much for your example..now i now how and where to use QAction and QMenu :p

The only thing i was not able to do is to insert a submenu in the menu.
If the user would like to insert song to a playlist, he should choose which playlist. I was able to fill the submenu with all playlists. But how could i make this:
add to playlist->Playlist1
Playlist2
Playlist3
If the user choose a playlist, i have to call everytime this function: "addToPlaylist()"



m_addAction = new QAction("Add to playlist", this);
m_removeAction = new QAction("Remove from playlist", this);
connect(m_addAction, SIGNAL(triggered()), this, SLOT(addToPlaylist()));
connect(m_removeAction, SIGNAL(triggered()), this, SLOT(removeFromPlaylist()));
.
.

QMenu menu;
QMenu submenu;
if((ui.playlistname_cb->currentText() != "") && (ui.listView->childCount() > 0)){
menu.addAction(m_removeAction);
//getPlaylist();

}
if((ui.playlistname_cb->currentText() == "") && (ui.listView->childCount() > 0)){
menu.addAction(m_addAction);
int items = ui.playlistname_cb->count();
for(int i = 1; i < items; i++)
{
QString playlistname = ui.playlistname_cb->itemText(i);
submenu.addMenu(playlistname);
//menu.addAction(submenu);
}


}
menu.exec(point);

wysota
14th October 2006, 19:26
QMenu topmenu;
topmenu.addAction(action1);
QMenu submenu;
submenu.addAction(action2);
topmenu.addMenu(&submenu);