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 );
printer.setOutputFileName ( "unicorn-snapshot.pdf" );
printer.setPaperSize ( (QPrinter::PaperSize )Cfg::getParamEnumerate("viewer.printer.paper" ,0)->asInt() );
printer.setOrientation( (QPrinter::Orientation)Cfg::getParamEnumerate("viewer.printer.orientation",0)->asInt() );
printer.setPageSize ( (QPrinter::PaperSize )Cfg::getParamEnumerate("viewer.printer.paper" ,0)->asInt() );
printer.setPageOrientation( (QPageLayout::Orientation)Cfg::getParamEnumerate("viewer.printer.orientation",0)->asInt() );
QPrintDialog dialog ( &printer );
if ( dialog.exec() == QDialog::Accepted )

View File

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

View File

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

View File

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

View File

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

View File

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