// build a context menu void UserMenuTree::contextMenuRequested(const QPoint &pos) { KILE_DEBUG() << "context menu requested ..." ; m_popupItem = dynamic_cast<UserMenuItem*>(itemAt(pos)); if ( !m_popupItem ) { KILE_DEBUG() << "... no item found"; return; } KILE_DEBUG() << "... popup item found: " << m_popupItem->text(0); bool submenu = ( m_popupItem->menutype() == UserMenuData::Submenu ); bool separator = ( m_popupItem->menutype() == UserMenuData::Separator ); KMenu popup; QAction *action = NULL; QSignalMapper signalMapper; connect(&signalMapper, SIGNAL(mapped(int)), this, SLOT(slotPopupActivated(int))); // insert standard menu items action = popup.addAction(KIcon("usermenu-insert-above.png"),i18n("Insert above"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_INSERT_ABOVE); action = popup.addAction(KIcon("usermenu-insert-below.png"),i18n("Insert below"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_INSERT_BELOW); popup.addSeparator(); // insert separators if ( !separator ) { action = popup.addAction(KIcon("usermenu-separator-above.png"),i18n("Insert a separator above"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SEPARATOR_ABOVE); action = popup.addAction(KIcon("usermenu-separator-below.png"),i18n("Insert a separator below"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SEPARATOR_BELOW); popup.addSeparator(); } // insert submenus action = popup.addAction(KIcon("usermenu-submenu-above.png"),i18n("Insert a submenu above"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SUBMENU_ABOVE); action = popup.addAction(KIcon("usermenu-submenu-below.png"),i18n("Insert a submenu below"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SUBMENU_BELOW); popup.addSeparator(); // insert into submenus if ( submenu ) { action = popup.addAction(KIcon("usermenu-into-submenu.png"),i18n("Insert into this submenu"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_INTO_SUBMENU); action = popup.addAction(i18n("Insert a separator into this submenu"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SEPARATOR_INTO_SUBMENU); action = popup.addAction(i18n("Insert a submenu into this submenu"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_SUBMENU_INTO_SUBMENU); popup.addSeparator(); } // delete actions action = popup.addAction(KIcon("usermenu-delete.png"),i18n("Delete this item"), &signalMapper, SLOT(map())); signalMapper.setMapping(action,POPUP_DELETE_ITEM); popup.addSeparator(); action = popup.addAction(KIcon("usermenu-clear.png"),i18n("Delete the complete tree"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_DELETE_TREE); // expand/collapse tree if ( submenu ) { popup.addSeparator(); if ( m_popupItem->isExpanded() ) { action = popup.addAction(i18n("Collapse submenu"), &signalMapper, SLOT(map())); signalMapper.setMapping(action,POPUP_COLLAPSE_ITEM); } else { action = popup.addAction(i18n("Expand submenu"), &signalMapper, SLOT(map())); signalMapper.setMapping(action,POPUP_EXPAND_ITEM); } popup.addSeparator(); action = popup.addAction(i18n("Collapse complete tree"), &signalMapper, SLOT(map())); signalMapper.setMapping(action,POPUP_COLLAPSE_TREE); action = popup.addAction(i18n("Expand complete tree"), &signalMapper, SLOT(map())); signalMapper.setMapping(action,POPUP_EXPAND_TREE); } // if there are any errors with this item, some info is available int error = m_popupItem->data(0,Qt::UserRole+2).toInt(); if ( error != UserMenuItem::MODEL_ERROR_NONE ) { popup.addSeparator(); action = popup.addAction(KIcon("help-about.png"),i18n("Info"), &signalMapper, SLOT(map())); signalMapper.setMapping(action, POPUP_ITEM_INFO); } // const QPoint& pos parameter in the customContextMenuRequested() signal is normally in widget coordinates. // But classes like QTreeWidget, which inherit from QAbstractScrollArea1 instead use the coordinates of their viewport() if ( !popup.isEmpty() ) { popup.exec( viewport()->mapToGlobal(pos) ); } }