Correct the selection bug in Net mode in CellWidget.

In SelectorCriterion & SelectorCriterions, when selecting a Net occurrence,
we where storing the Net only. This was fine if the Net was belonging to
the Cell's top level. But when it was an occurrence of a non-top level
net, this was creating the elusive incoherent Occurrence problem.
Now we truly store the occurrence of the Net, to be accurate, the root
of the HyperNet.

* Change: In SelectorCriterions::add(), the Net* argument is replaced
    by a Occurrence of Net. Must be an HyperNet root occurrence.
      Same goes for SelectorCriterions::remove().
* Change: In CellWidget::select(), when called with a Net occurrence,
    select the whole HyperNet components.
* Change: In NetSelectorCriterion, now use a Net occurrence instead
    of directly a Net. Must be an HyperNet root net occurrence.
This commit is contained in:
Jean-Paul Chaput 2022-07-13 11:20:24 +02:00
parent 9d818df5b1
commit f453dbc6f9
7 changed files with 96 additions and 98 deletions

View File

@ -852,8 +852,8 @@ namespace Hurricane {
QPrinter printer ( QPrinter::ScreenResolution ); QPrinter printer ( QPrinter::ScreenResolution );
printer.setOutputFileName ( "unicorn-snapshot.pdf" ); printer.setOutputFileName ( "unicorn-snapshot.pdf" );
printer.setPaperSize ( (QPrinter::PaperSize )Cfg::getParamEnumerate("viewer.printer.paper" ,0)->asInt() ); printer.setPageSize ( (QPrinter::PaperSize )Cfg::getParamEnumerate("viewer.printer.paper" ,0)->asInt() );
printer.setOrientation( (QPrinter::Orientation)Cfg::getParamEnumerate("viewer.printer.orientation",0)->asInt() ); printer.setPageOrientation( (QPageLayout::Orientation)Cfg::getParamEnumerate("viewer.printer.orientation",0)->asInt() );
QPrintDialog dialog ( &printer ); QPrintDialog dialog ( &printer );
if ( dialog.exec() == QDialog::Accepted ) if ( dialog.exec() == QDialog::Accepted )

View File

@ -921,16 +921,19 @@ namespace Hurricane {
{ clear (); } { clear (); }
SelectorCriterion* CellWidget::SelectorCriterions::add ( const Net* net ) SelectorCriterion* CellWidget::SelectorCriterions::add ( Occurrence hyperNetOcc )
{ {
if ( _cellWidget == NULL ) return NULL; if (_cellWidget == NULL) return NULL;
if ( not _cellWidget->isSelected(Occurrence(net)) ) { if (not _cellWidget->isSelected(hyperNetOcc)) {
_criterions.push_back ( new NetSelectorCriterion(net) ); _criterions.push_back ( new NetSelectorCriterion(hyperNetOcc) );
//_criterions.back()->doSelection ( _cellWidget ); //_criterions.back()->doSelection ( _cellWidget );
return _criterions.back(); return _criterions.back();
} }
for ( size_t i=0 ; i<_criterions.size() ; ++i ) { for ( size_t i=0 ; i<_criterions.size() ; ++i ) {
if ( _criterions[i]->getNet() == net ) return _criterions[i]; if (not _criterions[i]->getNetOccurrence().getEntity())
continue;
if (_criterions[i]->getNetOccurrence() == hyperNetOcc)
return _criterions[i];
} }
return NULL; return NULL;
} }
@ -949,19 +952,19 @@ namespace Hurricane {
} }
bool CellWidget::SelectorCriterions::remove ( const Net* net ) bool CellWidget::SelectorCriterions::remove ( Occurrence netOccurrence )
{ {
if ( _cellWidget == NULL ) return false; if (not _cellWidget) return false;
if ( not _cellWidget->isSelected(Occurrence(net)) ) return false; if (not _cellWidget->isSelected(netOccurrence)) return false;
size_t i=0; size_t i=0;
for ( ; i<_criterions.size() ; i++ ) for ( ; i<_criterions.size() ; i++ )
if ( _criterions[i]->getNet() == net ) break; if (_criterions[i]->getNetOccurrence() == netOccurrence) break;
if ( i < _criterions.size() ) { if (i < _criterions.size()) {
swap ( _criterions[i], *(_criterions.end()-1) ); swap( _criterions[i], *(_criterions.end()-1) );
//_criterions.back()->undoSelection ( _cellWidget ); //_criterions.back()->undoSelection ( _cellWidget );
_criterions.pop_back (); _criterions.pop_back();
} else } else
return false; return false;
@ -1700,7 +1703,7 @@ namespace Hurricane {
if ( flags & BigFont ) font.setPointSize ( Graphics::isHighDpi() ? 7 : 18 ); if ( flags & BigFont ) font.setPointSize ( Graphics::isHighDpi() ? 7 : 18 );
QFontMetrics metrics = QFontMetrics(font); QFontMetrics metrics = QFontMetrics(font);
int width = metrics.width ( text ); int width = metrics.horizontalAdvance( text );
//int height = metrics.height (); //int height = metrics.height ();
int angle = 0; int angle = 0;
@ -1857,7 +1860,7 @@ namespace Hurricane {
, std::max( 1.0 , std::max( 1.0
, std::floor( std::log10( longerSide / _snapGridStep() )))); , std::floor( std::log10( longerSide / _snapGridStep() ))));
DbU::Unit gridStep = ((symbolicMode()) ? 1 : 10) * _snapGridStep(); //DbU::Unit gridStep = ((symbolicMode()) ? 1 : 10) * _snapGridStep();
DbU::Unit superGridStep = _snapGridStep() * scale; DbU::Unit superGridStep = _snapGridStep() * scale;
DbU::Unit xGrid; DbU::Unit xGrid;
DbU::Unit yGrid; DbU::Unit yGrid;
@ -1940,7 +1943,7 @@ namespace Hurricane {
{ {
QFont font = Graphics::getNormalFont(); QFont font = Graphics::getNormalFont();
QFontMetrics metrics = QFontMetrics(font); QFontMetrics metrics = QFontMetrics(font);
int tickLength = metrics.width ( "+00000u" ); int tickLength = metrics.horizontalAdvance( "+00000u" );
Point origin = ruler->getOrigin (); Point origin = ruler->getOrigin ();
Point extremity = ruler->getExtremity (); Point extremity = ruler->getExtremity ();
Point angle = ruler->getAngle (); Point angle = ruler->getAngle ();
@ -2622,23 +2625,23 @@ namespace Hurricane {
bool CellWidget::isSelected ( Occurrence occurrence ) bool CellWidget::isSelected ( Occurrence occurrence )
{ {
if ( !occurrence.isValid() ) if (not occurrence.isValid())
throw Error ( "Can't select occurrence : invalid occurrence" ); throw Error( "Can't select occurrence : invalid occurrence" );
if ( occurrence.getOwnerCell() != getCell() ) { if (occurrence.getOwnerCell() != getCell()) {
string s1 = Graphics::toHtml ( getString(getCell()) ); string s1 = Graphics::toHtml( getString(getCell()) );
string s2 = Graphics::toHtml ( getString(occurrence.getOwnerCell()) ); string s2 = Graphics::toHtml( getString(occurrence.getOwnerCell()) );
throw Error ( "Can't select occurrence : incompatible occurrence %s vs. %s" throw Error( "Can't select occurrence : incompatible occurrence %s vs. %s"
, s1.c_str(), s2.c_str() ); , s1.c_str(), s2.c_str() );
} }
Property* property = occurrence.getProperty ( Selector::getPropertyName() ); Property* property = occurrence.getProperty( Selector::getPropertyName() );
if ( !property ) if (not property)
return false; return false;
Selector* selector = dynamic_cast<Selector*>(property); Selector* selector = dynamic_cast<Selector*>(property);
if ( !selector ) if ( !selector )
throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); throw Error( "Abnormal property named " + getString(Selector::getPropertyName()) );
return selector->isAttachedTo(this); return selector->isAttachedTo(this);
} }
@ -2687,34 +2690,38 @@ namespace Hurricane {
void CellWidget::select ( Occurrence occurrence ) void CellWidget::select ( Occurrence occurrence )
{ {
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) { if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
openRefreshSession (); openRefreshSession();
unselectAll (); unselectAll();
closeRefreshSession (); closeRefreshSession();
} }
if (not occurrence.isValid()) if (not occurrence.isValid())
throw Error ( "Can't select occurrence : invalid occurrence" ); throw Error( "Can't select occurrence : invalid occurrence" );
if (occurrence.getOwnerCell() != getCell()) { if (occurrence.getOwnerCell() != getCell()) {
string s1 = Graphics::toHtml( getString(getCell()) ); string s1 = Graphics::toHtml( getString(getCell()) );
string s2 = Graphics::toHtml( getString(occurrence.getOwnerCell()) ); string s2 = Graphics::toHtml( getString(occurrence.getOwnerCell()) );
throw Error ( "Can't select occurrence : incompatible occurrence %s vs. %s" throw Error( "Can't select occurrence : incompatible occurrence %s vs. %s"
, s1.c_str(), s2.c_str() ); , s1.c_str(), s2.c_str() );
} }
bool selected = true; bool selected = true;
const Net* net = dynamic_cast<const Net*>( occurrence.getEntity() ); const Net* net = dynamic_cast<const Net*>( occurrence.getEntity() );
if ( net ) { if (net) {
SelectorCriterion* criterion = _state->getSelection().add( net ); SelectorCriterion* criterion = _state->getSelection().add( occurrence );
if ( criterion and (not criterion->isEnabled()) ) { if ( criterion and (not criterion->isEnabled()) ) {
criterion->enable(); criterion->enable();
for ( Component* component : net->getComponents() ) { HyperNet hyperNet ( occurrence );
Occurrence occurrence ( component ); for ( Occurrence netOcc : hyperNet.getNetOccurrences() ) {
select( occurrence ); Net* subNet = static_cast<Net*>( netOcc.getEntity() );
} for ( Component* component : subNet->getComponents() ) {
for ( Rubber* rubber : net->getRubbers() ) { Occurrence occurrence ( component, netOcc.getPath() );
Occurrence occurrence ( rubber ); select( occurrence );
select( occurrence ); }
for ( Rubber* rubber : subNet->getRubbers() ) {
Occurrence occurrence ( rubber, netOcc.getPath() );
select( occurrence );
}
} }
} else } else
selected = false; selected = false;
@ -2753,29 +2760,29 @@ namespace Hurricane {
void CellWidget::unselect ( Occurrence occurrence ) void CellWidget::unselect ( Occurrence occurrence )
{ {
if ( not occurrence.isValid() ) if (not occurrence.isValid())
throw Error ( "Can't unselect occurrence : invalid occurrence" ); throw Error ( "Can't unselect occurrence : invalid occurrence" );
if ( occurrence.getOwnerCell() != getCell() ) if (occurrence.getOwnerCell() != getCell())
throw Error ( "Can't unselect occurrence : incompatible occurrence" ); throw Error ( "Can't unselect occurrence : incompatible occurrence" );
bool unselected = true; bool unselected = true;
const Net* net = dynamic_cast<const Net*>(occurrence.getEntity()); const Net* net = dynamic_cast<const Net*>(occurrence.getEntity());
if ( net ) { if (net) {
unselected = _state->getSelection().remove ( net ); unselected = _state->getSelection().remove( occurrence );
} }
Property* property = occurrence.getProperty ( Selector::getPropertyName() ); Property* property = occurrence.getProperty( Selector::getPropertyName() );
if ( property ) { if (property) {
Selector* selector = dynamic_cast<Selector*>(property); Selector* selector = dynamic_cast<Selector*>( property );
if ( not selector ) if (not selector)
throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); throw Error( "Abnormal property named " + getString(Selector::getPropertyName()) );
selector->detachFrom(this); selector->detachFrom( this );
} }
_selectionHasChanged = true; _selectionHasChanged = true;
if ( (_delaySelectionChanged == 0) and unselected ) emit selectionChanged(_selectors); if ( (_delaySelectionChanged == 0) and unselected ) emit selectionChanged( _selectors );
} }

View File

@ -132,20 +132,18 @@ namespace Hurricane {
for ( ; _primaryLoc->isValid() ; _primaryLoc->progress() ) { for ( ; _primaryLoc->isValid() ; _primaryLoc->progress() ) {
Occurrence element = _primaryLoc->getElement(); Occurrence element = _primaryLoc->getElement();
Component* component = dynamic_cast<Component*>(element.getEntity()); Component* component = dynamic_cast<Component*>( element.getEntity() );
if ( not component ) continue; if (not component) continue;
Net* net = component->getNet(); Net* net = component->getNet();
Occurrence netOccurrence ( net, element.getPath() ); Occurrence netOccurrence ( net, element.getPath() );
if ( _hideAnonymous if (_hideAnonymous and QString(getString(net->getName()).c_str()).contains("onymous") )
and QString(getString(net->getName()).c_str()).contains("onymous") )
continue; continue;
_element = getHyperNetRootNetOccurrence ( netOccurrence ); _element = getHyperNetRootNetOccurrence( netOccurrence );
if (_netOccurrences.find(_element) != _netOccurrences.end()) continue;
if ( _netOccurrences.find(_element) != _netOccurrences.end() ) continue; _netOccurrences.insert( _element );
_netOccurrences.insert ( _element );
break; break;
} }

View File

@ -29,8 +29,8 @@ namespace Hurricane {
{ } { }
const Net* SelectorCriterion::getNet () const Occurrence SelectorCriterion::getNetOccurrence () const
{ return NULL; } { return Occurrence(); }
const Box& SelectorCriterion::getArea () const const Box& SelectorCriterion::getArea () const
@ -45,9 +45,8 @@ namespace Hurricane {
// Class : "Hurricane::NetSelectorCriterion". // Class : "Hurricane::NetSelectorCriterion".
NetSelectorCriterion::NetSelectorCriterion ( const Net* net ) NetSelectorCriterion::NetSelectorCriterion ( Occurrence netOccurrence )
: _net (net) : _netOccurrence(netOccurrence)
, _name(_net->getName())
{ } { }
@ -56,27 +55,26 @@ namespace Hurricane {
NetSelectorCriterion* NetSelectorCriterion::clone () const NetSelectorCriterion* NetSelectorCriterion::clone () const
{ return new NetSelectorCriterion(_net); } { return new NetSelectorCriterion(_netOccurrence); }
const Net* NetSelectorCriterion::getNet () const Occurrence NetSelectorCriterion::getNetOccurrence () const
{ return _net; } { return _netOccurrence; }
bool NetSelectorCriterion::isValid ( CellWidget* cw ) const bool NetSelectorCriterion::isValid ( CellWidget* cw ) const
{ {
if ( cw->getCell() == NULL ) return false; if (cw->getCell() == NULL) return false;
if ( not cw->getCell()->getNet(_name) ) return false; return _netOccurrence.isValid();
return true;
} }
void NetSelectorCriterion::doSelection ( CellWidget* cw ) void NetSelectorCriterion::doSelection ( CellWidget* cw )
{ cw->select ( Occurrence(_net) ); } { cw->select( _netOccurrence ); }
void NetSelectorCriterion::undoSelection ( CellWidget* cw ) void NetSelectorCriterion::undoSelection ( CellWidget* cw )
{ cw->unselect ( Occurrence(_net) ); } { cw->unselect( _netOccurrence ); }
string NetSelectorCriterion::_getTypeName () const string NetSelectorCriterion::_getTypeName () const
@ -85,7 +83,7 @@ namespace Hurricane {
string NetSelectorCriterion::_getString () const string NetSelectorCriterion::_getString () const
{ {
string s = "<" + _getTypeName() + " " + getString(_net) + ">"; string s = "<" + _getTypeName() + " " + getString(_netOccurrence) + ">";
return s; return s;
} }
@ -93,7 +91,7 @@ namespace Hurricane {
Record* NetSelectorCriterion::_getRecord () const Record* NetSelectorCriterion::_getRecord () const
{ {
Record* record = new Record ( _getString() ); Record* record = new Record ( _getString() );
record->add ( getSlot("_net",_net) ); record->add ( getSlot("_netOccurrence",&_netOccurrence) );
return record; return record;
} }

View File

@ -52,8 +52,8 @@ namespace Hurricane {
void ZoomCommand::wheelEvent ( QWheelEvent* event ) void ZoomCommand::wheelEvent ( QWheelEvent* event )
{ {
if ( event->delta() > 0 ) _cellWidget->setScale ( _cellWidget->getScale()/1.2 ); if (event->delta() > 0) _cellWidget->setScale ( _cellWidget->getScale()/1.2 );
else if ( event->delta() < 0 ) _cellWidget->setScale ( _cellWidget->getScale()*1.2 ); else if (event->delta() < 0) _cellWidget->setScale ( _cellWidget->getScale()*1.2 );
event->accept (); event->accept ();
} }

View File

@ -536,10 +536,10 @@ namespace Hurricane {
~SelectorCriterions (); ~SelectorCriterions ();
inline void setCellWidget ( CellWidget* ); inline void setCellWidget ( CellWidget* );
inline const vector<SelectorCriterion*>& getCriterions () const; inline const vector<SelectorCriterion*>& getCriterions () const;
SelectorCriterion* add ( const Net* net ); SelectorCriterion* add ( Occurrence netOccurrence );
SelectorCriterion* add ( Box area ); SelectorCriterion* add ( Box area );
inline SelectorCriterion* add ( SelectorCriterion* ); inline SelectorCriterion* add ( SelectorCriterion* );
bool remove ( const Net* net ); bool remove ( Occurrence netOccurrence );
void clear (); void clear ();
void invalidate (); void invalidate ();
void revalidate (); void revalidate ();

View File

@ -14,9 +14,7 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef HURRICANE_SELECTOR_CRITERION_H #pragma once
#define HURRICANE_SELECTOR_CRITERION_H
#include <string> #include <string>
#include "hurricane/Commons.h" #include "hurricane/Commons.h"
#include "hurricane/Name.h" #include "hurricane/Name.h"
@ -35,7 +33,7 @@ namespace Hurricane {
virtual SelectorCriterion* clone () const = 0; virtual SelectorCriterion* clone () const = 0;
virtual bool isValid ( CellWidget* ) const = 0; virtual bool isValid ( CellWidget* ) const = 0;
inline bool isEnabled () const; inline bool isEnabled () const;
virtual const Net* getNet () const; virtual Occurrence getNetOccurrence () const;
virtual const Box& getArea () const; virtual const Box& getArea () const;
inline void enable (); inline void enable ();
inline void disable (); inline void disable ();
@ -57,19 +55,18 @@ namespace Hurricane {
class NetSelectorCriterion : public SelectorCriterion { class NetSelectorCriterion : public SelectorCriterion {
public: public:
NetSelectorCriterion ( const Net* ); NetSelectorCriterion ( Occurrence netOccurrence );
virtual ~NetSelectorCriterion (); virtual ~NetSelectorCriterion ();
virtual NetSelectorCriterion* clone () const; virtual NetSelectorCriterion* clone () const;
virtual const Net* getNet () const; virtual Occurrence getNetOccurrence () const;
virtual bool isValid ( CellWidget* ) const; virtual bool isValid ( CellWidget* ) const;
virtual void doSelection ( CellWidget* ); virtual void doSelection ( CellWidget* );
virtual void undoSelection ( CellWidget* ); virtual void undoSelection ( CellWidget* );
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual string _getString () const; virtual string _getString () const;
virtual string _getTypeName () const; virtual string _getTypeName () const;
protected: protected:
const Net* _net; const Occurrence _netOccurrence;
const Name _name;
}; };
@ -93,5 +90,3 @@ namespace Hurricane {
INSPECTOR_P_SUPPORT(Hurricane::SelectorCriterion); INSPECTOR_P_SUPPORT(Hurricane::SelectorCriterion);
#endif // HURRICANE_SELECTOR_CRITERION_H