Fix: The SelectionPopup widget was deleted after first use.

* Bug: In Viewer::SelectionPopup(), the window attribute
   Qt::WA_DeleteOnClose was *not* cleared. So the window was deleted
   after first use while it was though staying allocated.
     Again, generating weird crashes.
     Took the occasion to slightly redesign the behavior to select
   and highlight individual components.
This commit is contained in:
Jean-Paul Chaput 2022-01-01 16:47:09 +01:00
parent 0c54d109cc
commit 581f557aef
5 changed files with 59 additions and 41 deletions

View File

@ -0,0 +1 @@
jpc@lepka.3594897:1640548861

View File

@ -244,7 +244,7 @@ namespace Hurricane {
_selectionPopup->loadOccurrences( selection );
_selectionPopup->updateLayout();
_selectionPopup->move( event->globalPos() );
_selectionPopup->popup();
_selectionPopup->showPopup();
}
}
}

View File

@ -15,6 +15,7 @@
#include <QFontMetrics>
#include <QCursor>
#include <QLabel>
#include <QHeaderView>
#include <QKeyEvent>
@ -42,17 +43,19 @@ namespace Hurricane {
, _rowHeight(20)
, _charWidth(15)
{
setAttribute ( Qt::WA_DeleteOnClose );
setAttribute ( Qt::WA_QuitOnClose, false );
//setWindowFlags ( Qt::Popup );
setWindowFlags ( Qt::FramelessWindowHint );
setAttribute ( Qt::WA_DeleteOnClose, false );
setAttribute ( Qt::WA_QuitOnClose , false );
setWindowFlags ( Qt::Popup|Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint|Qt::Dialog );
setWindowOpacity( 0.9 );
setMouseTracking( true );
setFocusPolicy ( Qt::StrongFocus );
_rowHeight = QFontMetrics(Graphics::getFixedFont()).height() + 4;
_charWidth = QFontMetrics(Graphics::getFixedFont()).averageCharWidth() + 1;
_rowHeight = QFontMetrics( Graphics::getFixedFont() ).height() + 2;
_charWidth = QFontMetrics( Graphics::getFixedFont() ).averageCharWidth() + 1;
_model = new SelectionPopupModel ( this );
setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
_view = new QTableView ( this );
_view = new QTableView ();
_view->setShowGrid( false );
_view->setAlternatingRowColors( true );
_view->setSelectionBehavior( QAbstractItemView::SelectRows );
@ -69,61 +72,75 @@ namespace Hurricane {
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 1500 : 200 );
horizontalHeader->setVisible( false );
QHeaderView* verticalHeader = _view->verticalHeader ();
QHeaderView* verticalHeader = _view->verticalHeader();
verticalHeader->setVisible( false );
#if QT_VERSION < QT_VERSION_CHECK(5,0,0)
verticalHeader->setResizeMode( QHeaderView::Fixed );
#else
verticalHeader->setSectionResizeMode( QHeaderView::Fixed );
#endif
verticalHeader->setDefaultSectionSize( _rowHeight );
connect( _model, SIGNAL(layoutChanged()), this, SLOT(forceRowHeight()) );
QVBoxLayout* layout = new QVBoxLayout ();
layout->addWidget( _view );
setLayout( layout );
resize( Graphics::isHighDpi() ? 1500 : 600, 10 );
// if (Graphics::isHighDpi()) resize( 1500, 40 );
// else resize( 600, 20 );
}
bool SelectionPopup::popup ()
void SelectionPopup::showPopup ()
{
show();
grabMouse();
}
void SelectionPopup::forceRowHeight ()
{
for ( int rows=_model->rowCount()-1; rows >= 0 ; rows-- )
_view->setRowHeight ( rows, _rowHeight );
grabMouse( Qt::PointingHandCursor );
grabKeyboard();
setFocus();
}
void SelectionPopup::keyPressEvent ( QKeyEvent* event )
{
//cerr << "SelectionPopup::keyPressEvent()" << endl;
//QWidget::keyPressEvent ( event );
if (event->key() == Qt::Key_Escape) {
releaseMouse();
releaseKeyboard();
hide();
} else if (event->key() == Qt::Key_Space) {
if (_view->selectionModel()->hasSelection()) {
QModelIndex index = _view->selectionModel()->selectedRows().first();
Occurrence occurrence = _model->getOccurrence(index.row());
if (occurrence.getEntity()) {
if (_cellWidget) _cellWidget->setShowSelection( true );
emit selectionToggled( occurrence );
}
}
event->accept();
}
}
void SelectionPopup::mouseMoveEvent ( QMouseEvent* event )
{
QModelIndex index = _view->indexAt ( event->pos() );
if ( index.isValid() )
if ( index.isValid() ) {
_view->selectionModel()->select ( index, QItemSelectionModel::ClearAndSelect );
else
} else {
_view->selectionModel()->clearSelection ();
}
}
void SelectionPopup::mouseReleaseEvent ( QMouseEvent* event )
void SelectionPopup::mousePressEvent ( QMouseEvent* event )
{
releaseMouse();
hide();
QModelIndex index = _view->indexAt( event->pos() );
if (index.isValid()) {
Occurrence occurrence = _model->getOccurrence(index.row());
if (_view->selectionModel()->hasSelection()) {
QModelIndex index = _view->selectionModel()->selectedRows().first();
Occurrence occurrence = _model->getOccurrence(index.row());
if (occurrence.getEntity()) {
if (_cellWidget) _cellWidget->setShowSelection( true );
emit selectionToggled( occurrence );
}
}
clear();
event->accept();
}

View File

@ -79,10 +79,12 @@ namespace Hurricane {
{
_charWidth = 50;
if (not _occurrences) _occurrences = new vector<Occurrence> ();
forEach ( Occurrence, ioccurrence, occurrences.getSubSet(getFilter()) ) {
_occurrences->push_back( *ioccurrence );
string name = getString( (*ioccurrence).getPath().getName() ) + "::"
+ getString( (*ioccurrence).getEntity() );
else _occurrences->clear();
for ( Occurrence occurrence : occurrences.getSubSet(getFilter()) ) {
_occurrences->push_back( occurrence );
string name = getString( (occurrence).getPath().getName() ) + "::"
+ getString( (occurrence).getEntity() );
_charWidth = std::max( _charWidth, (int)name.size() );
}
if (showChange) emit layoutChanged ();

View File

@ -15,7 +15,6 @@
#pragma once
#include <QWidget>
#include <QTableView>
#include "hurricane/Commons.h"
#include "hurricane/Occurrence.h"
@ -45,7 +44,7 @@ namespace Hurricane {
SelectionPopup ( QWidget* parent=NULL );
inline void setCellWidget ( CellWidget* );
void updateLayout ();
bool popup ();
void showPopup ();
void clearFilter ();
void setFilter ( OccurrenceFilter );
signals:
@ -53,11 +52,10 @@ namespace Hurricane {
public slots:
void loadOccurrences ( Occurrences, bool showChange=false );
void clear ();
void forceRowHeight ();
protected:
virtual void keyPressEvent ( QKeyEvent * );
virtual void mouseMoveEvent ( QMouseEvent* );
virtual void mouseReleaseEvent ( QMouseEvent* );
virtual void mousePressEvent ( QMouseEvent* );
private:
CellWidget* _cellWidget;
SelectionPopupModel* _model;