Qt: Fix drag-and-drop from packet list

Only initiate drag-and-drop when the left mousebutton has been
clicked, and also add the filter as plain text, so to enable
dragging to external applications.

Change-Id: I2f6ac7f9c543d003070c2a6c0ce671ed5a215669
Reviewed-on: https://code.wireshark.org/review/33620
Petri-Dish: Roland Knall <rknall@gmail.com>
Reviewed-by: Stig Bjørlykke <stig@bjorlykke.org>
Tested-by: Petri Dish Buildbot
Reviewed-by: Roland Knall <rknall@gmail.com>
This commit is contained in:
Roland Knall 2019-06-16 12:02:37 +02:00
parent b4cd7bcf62
commit e4713e8745
6 changed files with 70 additions and 44 deletions

View File

@ -651,30 +651,35 @@ void PacketList::mousePressEvent (QMouseEvent *event)
setAutoScroll(false);
QTreeView::mousePressEvent(event);
setAutoScroll(true);
}
QModelIndex curIndex = indexAt(event->pos());
ctx_column_ = curIndex.column();
QString filter = getFilterFromRowAndColumn();
if ( ! filter.isEmpty() )
void PacketList::mouseMoveEvent (QMouseEvent *event)
{
if ( event->buttons() & Qt::LeftButton )
{
QString abbrev = filter.left(filter.indexOf(' '));
QString name = model()->headerData(ctx_column_, header()->orientation()).toString();
QModelIndex curIndex = indexAt(event->pos());
ctx_column_ = curIndex.column();
QString filter = getFilterFromRowAndColumn();
if ( ! filter.isEmpty() )
{
QString abbrev = filter.left(filter.indexOf(' '));
QString name = model()->headerData(ctx_column_, header()->orientation()).toString();
DisplayFilterMimeData * dfmd =
new DisplayFilterMimeData(name, abbrev, filter);
QDrag * drag = new QDrag(this);
drag->setMimeData(dfmd);
DisplayFilterMimeData * dfmd =
new DisplayFilterMimeData(name, abbrev, filter);
QDrag * drag = new QDrag(this);
drag->setMimeData(dfmd);
DragLabel * content = new DragLabel(dfmd->labelText(), this);
qreal dpr = window()->windowHandle()->devicePixelRatio();
QPixmap pixmap(content->size() * dpr);
pixmap.setDevicePixelRatio(dpr);
content->render(&pixmap);
drag->setPixmap(pixmap);
DragLabel * content = new DragLabel(dfmd->labelText(), this);
qreal dpr = window()->windowHandle()->devicePixelRatio();
QPixmap pixmap(content->size() * dpr);
pixmap.setDevicePixelRatio(dpr);
content->render(&pixmap);
drag->setPixmap(pixmap);
drag->exec(Qt::CopyAction);
drag->exec(Qt::CopyAction);
}
}
}
void PacketList::resizeEvent(QResizeEvent *event)

View File

@ -74,6 +74,7 @@ protected:
void timerEvent(QTimerEvent *event);
void paintEvent(QPaintEvent *event);
virtual void mousePressEvent (QMouseEvent *event);
virtual void mouseMoveEvent (QMouseEvent *event);
virtual void resizeEvent(QResizeEvent *event);
protected slots:

View File

@ -14,7 +14,9 @@ QMimeData(),
description_(description),
filter_(filter),
field_(field)
{}
{
setText(filter);
}
QString DisplayFilterMimeData::description() const
{

View File

@ -586,16 +586,18 @@ void DisplayFilterEdit::dropEvent(QDropEvent *event)
else
filterText = data->filter();
if ( text().length() > 0 && QApplication::keyboardModifiers() & Qt::MetaModifier)
bool prepare = QApplication::keyboardModifiers() & Qt::ShiftModifier;
if ( text().length() > 0 || QApplication::keyboardModifiers() & Qt::MetaModifier)
{
createFilterTextDropMenu(event, filterText);
createFilterTextDropMenu(event, prepare, filterText);
return;
}
setText(filterText);
// Holding down the Shift key will only prepare filter.
if (!(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
if ( ! prepare ) {
applyDisplayFilter();
}
@ -608,33 +610,45 @@ void DisplayFilterEdit::dropEvent(QDropEvent *event)
}
}
void DisplayFilterEdit::createFilterTextDropMenu(QDropEvent *event, QString filterText)
void DisplayFilterEdit::createFilterTextDropMenu(QDropEvent *event, bool prepare, QString filterText)
{
if ( filterText.isEmpty() )
return;
QMenu applyMenu(this);
QAction * andAction = new QAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and Selected"), this);
andAction->setData(QString("&& %1").arg(filterText));
connect(andAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * selAction = applyMenu.addAction(tr("Selected"));
selAction->setData(QString("%1").arg(filterText));
selAction->setProperty("clear", qVariantFromValue(true));
connect(selAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * orAction = new QAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or Selected"), this);
orAction->setData(QString("|| %1").arg(filterText));
connect(orAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * notSelAction = applyMenu.addAction(tr("Not Selected"));
notSelAction->setData(QString("!(%1)").arg(filterText));
notSelAction->setProperty("clear", qVariantFromValue(true));
connect(notSelAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * andNotAction = new QAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and not Selected"), this);
andNotAction->setData(QString("&& !(%1)").arg(filterText));
connect(andNotAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
if ( this->text().length() > 0 )
{
QAction * andAction = applyMenu.addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and Selected"));
andAction->setData(QString("&& %1").arg(filterText));
connect(andAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * orNotAction = new QAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or not Selected"), this);
orNotAction->setData(QString("|| !(%1)").arg(filterText));
connect(orNotAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * orAction = applyMenu.addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or Selected"));
orAction->setData(QString("|| %1").arg(filterText));
connect(orAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * andNotAction = applyMenu.addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "and not Selected"));
andNotAction->setData(QString("&& !(%1)").arg(filterText));
connect(andNotAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
QAction * orNotAction = applyMenu.addAction(tr(UTF8_HORIZONTAL_ELLIPSIS "or not Selected"));
orNotAction->setData(QString("|| !(%1)").arg(filterText));
connect(orNotAction, &QAction::triggered, this, &DisplayFilterEdit::dropActionMenuEvent);
}
foreach ( QAction * action, applyMenu.actions() )
action->setProperty("prepare", qVariantFromValue(prepare));
applyMenu.addAction(andAction);
applyMenu.addAction(orAction);
applyMenu.addAction(andNotAction);
applyMenu.addAction(orNotAction);
applyMenu.exec(this->mapToGlobal(event->pos()));
}
@ -646,14 +660,18 @@ void DisplayFilterEdit::dropActionMenuEvent()
return;
QString value = sendAction->data().toString();
bool prepare = sendAction->property("prepare").toBool();
QString filterText = QString("((%1) %2)").arg(this->text()).arg(value);
QString filterText;
if ( sendAction->property("clear").toBool() )
filterText = value;
else
filterText = QString("((%1) %2)").arg(this->text()).arg(value);
setText(filterText);
// Holding down the Shift key will only prepare filter.
if (!(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
if ( ! prepare )
applyDisplayFilter();
}
}
/*

View File

@ -69,7 +69,7 @@ private:
void setDefaultPlaceholderText();
void buildCompletionList(const QString& field_word);
void createFilterTextDropMenu(QDropEvent *event, QString filterText = QString());
void createFilterTextDropMenu(QDropEvent *event, bool prepare, QString filterText = QString());
signals:
void pushFilterSyntaxStatus(const QString&);

View File

@ -41,7 +41,7 @@ void PacketListHeader::dragEnterEvent(QDragEnterEvent *event)
if ( ! event )
return;
if (qobject_cast<const DisplayFilterMimeData *>(event->mimeData()))
if ( qobject_cast<const DisplayFilterMimeData *>(event->mimeData()) && event->source() != this->parent() )
{
if ( event->source() != this )
{