From 581f557aef3d1ab2d527e6b6ac7d444d4e3d1686 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 1 Jan 2022 16:47:09 +0100 Subject: [PATCH] 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. --- hurricane/src/viewer/.#SelectionPopup.cpp | 1 + hurricane/src/viewer/SelectCommand.cpp | 2 +- hurricane/src/viewer/SelectionPopup.cpp | 81 +++++++++++-------- hurricane/src/viewer/SelectionPopupModel.cpp | 10 ++- .../viewer/hurricane/viewer/SelectionPopup.h | 6 +- 5 files changed, 59 insertions(+), 41 deletions(-) create mode 120000 hurricane/src/viewer/.#SelectionPopup.cpp diff --git a/hurricane/src/viewer/.#SelectionPopup.cpp b/hurricane/src/viewer/.#SelectionPopup.cpp new file mode 120000 index 00000000..f47956fa --- /dev/null +++ b/hurricane/src/viewer/.#SelectionPopup.cpp @@ -0,0 +1 @@ +jpc@lepka.3594897:1640548861 \ No newline at end of file diff --git a/hurricane/src/viewer/SelectCommand.cpp b/hurricane/src/viewer/SelectCommand.cpp index ccfa77d5..bfb8da63 100644 --- a/hurricane/src/viewer/SelectCommand.cpp +++ b/hurricane/src/viewer/SelectCommand.cpp @@ -244,7 +244,7 @@ namespace Hurricane { _selectionPopup->loadOccurrences( selection ); _selectionPopup->updateLayout(); _selectionPopup->move( event->globalPos() ); - _selectionPopup->popup(); + _selectionPopup->showPopup(); } } } diff --git a/hurricane/src/viewer/SelectionPopup.cpp b/hurricane/src/viewer/SelectionPopup.cpp index 11f72968..f91df5e7 100644 --- a/hurricane/src/viewer/SelectionPopup.cpp +++ b/hurricane/src/viewer/SelectionPopup.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -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(); } diff --git a/hurricane/src/viewer/SelectionPopupModel.cpp b/hurricane/src/viewer/SelectionPopupModel.cpp index 3c9bd5a5..47ad60e6 100644 --- a/hurricane/src/viewer/SelectionPopupModel.cpp +++ b/hurricane/src/viewer/SelectionPopupModel.cpp @@ -79,10 +79,12 @@ namespace Hurricane { { _charWidth = 50; if (not _occurrences) _occurrences = new vector (); - 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 (); diff --git a/hurricane/src/viewer/hurricane/viewer/SelectionPopup.h b/hurricane/src/viewer/hurricane/viewer/SelectionPopup.h index 50e4aef2..90f96871 100644 --- a/hurricane/src/viewer/hurricane/viewer/SelectionPopup.h +++ b/hurricane/src/viewer/hurricane/viewer/SelectionPopup.h @@ -15,7 +15,6 @@ #pragma once -#include #include #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;