Implement the context menu a different way

It seems that this is the way this is supposed to be done - instead of
manually looking at what kind of click we get, Qt decides when to create
a context menu for us - this way things like the Windows Menu button
will work automagically.

As an example I also implemented the "remove dive from trip"
functionality, which exposes some other bugs (like the fact that the
dive that isn't part of a trip ends up being sorted at the very end of
the dive list).

This commit contains a "testSlot" implementation to remind me how to
figure out which dive / trip we are on.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2013-06-06 09:06:42 +09:00
parent 235833b93e
commit cd7488491f
2 changed files with 43 additions and 9 deletions

View file

@ -29,6 +29,7 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
model->setFilterKeyColumn(-1); // filter all columns
setModel(model);
setSortingEnabled(false);
setContextMenuPolicy(Qt::DefaultContextMenu);
header()->setContextMenuPolicy(Qt::ActionsContextMenu);
QAction *showSearchBox = new QAction(tr("Show Search Box"), this);
showSearchBox->setShortcut( Qt::CTRL + Qt::Key_F);
@ -272,23 +273,52 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS
Q_EMIT currentDiveChanged(selected_dive);
}
void DiveListView::mousePressEvent(QMouseEvent *event)
void DiveListView::removeFromTrip()
{
struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>();
if (!d) // shouldn't happen as we only are setting up this action if this is a dive
return;
remove_dive_from_trip(d);
reload();
}
void DiveListView::testSlot()
{
struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>();
if (d) {
qDebug("testSlot called on dive #%d", d->number);
} else {
QModelIndex child = contextMenuIndex.child(0, 0);
d = (struct dive *) child.data(TreeItemDT::DIVE_ROLE).value<void*>();
if (d)
qDebug("testSlot called on trip including dive #%d", d->number);
else
qDebug("testSlot called on trip with no dive");
}
}
void DiveListView::contextMenuEvent(QContextMenuEvent *event)
{
QAction *collapseAction = NULL;
// all we care about is the unmodified right click
if ( ! (event->modifiers() == Qt::NoModifier && event->buttons() & Qt::RightButton)) {
event->ignore();
QTreeView::mousePressEvent(event);
return;
}
// let's remember where we are
contextMenuIndex = indexAt(event->pos());
struct dive *d = (struct dive *) contextMenuIndex.data(TreeItemDT::DIVE_ROLE).value<void*>();
QMenu popup(this);
if (currentLayout == DiveTripModel::TREE) {
popup.addAction(tr("expand all"), this, SLOT(expandAll()));
popup.addAction(tr("collapse all"), this, SLOT(collapseAll()));
collapseAction = popup.addAction(tr("collapse"), this, SLOT(collapseAll()));
if (d) {
popup.addAction(tr("remove dive from trip"), this, SLOT(removeFromTrip()));
}
}
// "collapse all" really closes all trips,
// "collapse" keeps the trip with the selected dive open
if (popup.exec(event->globalPos()) == collapseAction && collapseAction)
QAction * actionTaken = popup.exec(event->globalPos());
if (actionTaken == collapseAction && collapseAction) {
this->setAnimated(false);
selectDive(current_dive, true);
this->setAnimated(true);
}
event->accept();
}

View file

@ -28,21 +28,25 @@ public:
bool eventFilter(QObject* , QEvent* );
void unselectDives();
void selectDive(struct dive *, bool scrollto = false);
void mousePressEvent(QMouseEvent *event);
void contextMenuEvent(QContextMenuEvent *event);
public slots:
void toggleColumnVisibilityByIndex();
void reloadHeaderActions();
void headerClicked(int);
void showSearchEdit();
void removeFromTrip();
void testSlot();
Q_SIGNALS:
void currentDiveChanged(int divenr);
private:
bool mouseClickSelection;
int currentHeaderClicked;
DiveTripModel::Layout currentLayout;
QLineEdit *searchBox;
QModelIndex contextMenuIndex;
};
#endif // DIVELISTVIEW_H