// -*- C++ -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved // // =================================================================== // // $Id$ // // x-----------------------------------------------------------------x // | | // | C O R I O L I S | // | V L S I B a c k e n d D a t a - B a s e | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./CellWidget.cpp" | // | *************************************************************** | // | U p d a t e s | // | | // x-----------------------------------------------------------------x #include #include #include #include #include #include #include #include #include #include #include #include "hurricane/SharedName.h" #include "hurricane/DataBase.h" #include "hurricane/Technology.h" #include "hurricane/BasicLayer.h" #include "hurricane/Cell.h" #include "hurricane/Instance.h" #include "hurricane/Slice.h" #include "hurricane/Segment.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" #include "hurricane/Contact.h" #include "hurricane/Pad.h" #include "hurricane/RoutingPad.h" #include "hurricane/ExtensionGo.h" #include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/PaletteItem.h" #include "hurricane/viewer/PaletteWidget.h" // #include "MapView.h" #include "hurricane/viewer/Command.h" #include "hurricane/viewer/CellWidget.h" namespace { using namespace std; string getTime ( const char* format ) { time_t t = time(NULL); struct tm* bt = localtime(&t); char formatted[1024]; strftime ( formatted, 1024, format, bt ); return formatted; } } // End of anonymous namespace. namespace Hurricane { // ------------------------------------------------------------------- // Collections. typedef Hurricane::Filter OccurrenceHF; typedef Hurricane::Locator OccurrenceHL; typedef Hurricane::Collection OccurrenceHC; // ------------------------------------------------------------------- // Class : "Occurrences_IsSelectable". class Occurrences_IsSelectable : public OccurrenceHF { public: inline Occurrences_IsSelectable ( const CellWidget* ); inline Occurrences_IsSelectable ( const Occurrences_IsSelectable& ); virtual OccurrenceHF* getClone () const; virtual bool accept ( Occurrence ) const; virtual string _getString () const; private: const CellWidget* _cellWidget; }; inline Occurrences_IsSelectable::Occurrences_IsSelectable ( const CellWidget* widget ) : OccurrenceHF() , _cellWidget(widget) { } inline Occurrences_IsSelectable::Occurrences_IsSelectable ( const Occurrences_IsSelectable& rhs ) : OccurrenceHF() , _cellWidget(rhs._cellWidget) { } OccurrenceHF* Occurrences_IsSelectable::getClone () const { return new Occurrences_IsSelectable(_cellWidget); } bool Occurrences_IsSelectable::accept ( Occurrence occurrence ) const { Entity* entity = occurrence.getEntity(); if ( !entity ) return false; ExtensionGo* eGo = dynamic_cast(entity); if ( eGo ) return _cellWidget->isSelectable ( eGo->getName() ); Component* component = dynamic_cast(entity); if ( component ) { return _cellWidget->isSelectable ( component->getLayer() ); } return true; } string Occurrences_IsSelectable::_getString () const { return ""; } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::Spot". CellWidget::Spot::Spot ( CellWidget* cw ) : _cellWidget(cw) , _spotPoint() , _restore(false) , _showSpot(true) { } void CellWidget::Spot::restore () { if ( _restore ) { _cellWidget->getDrawingPlanes().copyToScreen ( _spotPoint.x()-5, _spotPoint.y()-5, 10, 10 ); _restore = false; } } void CellWidget::Spot::setRestore ( bool state ) { _restore = state; } QPoint CellWidget::Spot::computeSpotPoint ( const QPoint& screenPoint ) { Point mousePoint = _cellWidget->screenToDbuPoint ( screenPoint ); Point spotPoint = Point ( _cellWidget->_onCursorGrid(mousePoint.getX()) , _cellWidget->_onCursorGrid(mousePoint.getY()) ); return _cellWidget->dbuToScreenPoint(spotPoint); } void CellWidget::Spot::moveTo ( const QPoint& screenPoint ) { restore (); if ( !_showSpot ) return; _restore = true; QPainter& screenPainter = _cellWidget->getDrawingPlanes().painter(PlaneId::Widget); _spotPoint = computeSpotPoint ( screenPoint ); screenPainter.setPen ( Graphics::getPen("spot") ); screenPainter.drawRect ( _spotPoint.x()-3, _spotPoint.y()-3, 6, 6 ); } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::RedrawEvent". CellWidget::RedrawEvent::RedrawEvent ( EventType type, int shift, CellWidget* widget ) : _type(type) , _shift(shift) { } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::RedrawManager". CellWidget::RedrawManager::RedrawManager ( CellWidget* widget ) : _widget (widget) , _events () , _refreshSession(0) , _processing (false) , _interrupted (false) { } CellWidget::RedrawManager::~RedrawManager () { while ( !_events.empty() ) { delete _events.front (); _events.pop_front (); } } void CellWidget::RedrawManager::goLeft ( int shift ) { #ifdef ALLOW_REQUEST_INTERRUPT list::iterator ievent = _events.end(); if ( !_events.empty() && (_events.back()->getType() == RedrawEvent::Refresh) ) --ievent; _events.insert ( ievent, new RedrawEvent(RedrawEvent::GoLeft,shift,_widget) ); #else _events.push_back ( new RedrawEvent(RedrawEvent::GoLeft,shift,_widget) ); #endif if ( !_processing ) process (); } void CellWidget::RedrawManager::goRight ( int shift ) { #ifdef ALLOW_REQUEST_INTERRUPT list::iterator ievent = _events.end(); if ( !_events.empty() && (_events.back()->getType() == RedrawEvent::Refresh) ) --ievent; _events.insert ( ievent, new RedrawEvent(RedrawEvent::GoRight,shift,_widget) ); #else _events.push_back ( new RedrawEvent(RedrawEvent::GoRight,shift,_widget) ); #endif if ( !_processing ) process (); } void CellWidget::RedrawManager::goUp ( int shift ) { #ifdef ALLOW_REQUEST_INTERRUPT list::iterator ievent = _events.end(); if ( !_events.empty() && (_events.back()->getType() == RedrawEvent::Refresh) ) --ievent; _events.insert ( ievent, new RedrawEvent(RedrawEvent::GoUp,shift,_widget) ); #else _events.push_back ( new RedrawEvent(RedrawEvent::GoUp,shift,_widget) ); #endif if ( !_processing ) process (); } void CellWidget::RedrawManager::goDown ( int shift ) { #ifdef ALLOW_REQUEST_INTERRUPT list::iterator ievent = _events.end(); if ( !_events.empty() && (_events.back()->getType() == RedrawEvent::Refresh) ) --ievent; _events.insert ( ievent, new RedrawEvent(RedrawEvent::GoDown,shift,_widget) ); #else _events.push_back ( new RedrawEvent(RedrawEvent::GoDown,shift,_widget) ); #endif if ( !_processing ) process (); } void CellWidget::RedrawManager::refresh () { #ifdef ALLOW_REQUEST_INTERRUPT if ( !_events.empty() && (_events.back()->getType() == RedrawEvent::Refresh) ) { _interrupted = true; } else if ( _events.empty() ) { _events.push_back ( new RedrawEvent(RedrawEvent::Refresh,0,_widget) ); if ( !_processing ) process (); } #else bool addRefresh = true; if ( _refreshSession ) { list::iterator ievent = _events.begin(); for ( ; ievent != _events.end() ; ievent++ ) { if ( (_events.back()->getType() == RedrawEvent::Refresh) ) { addRefresh = false; break; } } } if ( addRefresh ) _events.push_back ( new RedrawEvent(RedrawEvent::Refresh,0,_widget) ); if ( !_processing && (_refreshSession == 0) ) process (); #endif } void CellWidget::RedrawManager::process () { _processing = true; while ( !_events.empty() ) { RedrawEvent* event = _events.front (); switch ( event->getType() ) { case RedrawEvent::GoLeft: _widget->_goLeft ( event->getShift() ); break; case RedrawEvent::GoRight: _widget->_goRight ( event->getShift() ); break; case RedrawEvent::GoUp: _widget->_goUp ( event->getShift() ); break; case RedrawEvent::GoDown: _widget->_goDown ( event->getShift() ); break; case RedrawEvent::Refresh: _widget->_refresh (); break; } #ifdef ALLOW_REQUEST_INTERRUPT if ( event->getType() == RedrawEvent::Refresh ) { _events.pop_back (); } else _events.pop_front (); delete event; if ( _events.empty() && _interrupted ) { _events.push_back ( new RedrawEvent(RedrawEvent::Refresh,0,_widget) ); _interrupted = false; } #else delete _events.front (); _events.pop_front (); #endif } _processing = false; } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::DrawingPlanes". const int CellWidget::DrawingPlanes::_cartoucheWidth = 743; const int CellWidget::DrawingPlanes::_cartoucheHeight = 80; const int CellWidget::DrawingPlanes::_titleHeight = 60; CellWidget::DrawingPlanes::DrawingPlanes ( const QSize& size, CellWidget* cw ) : _cellWidget(cw) , _printer(NULL) , _image(NULL) , _normalPen() , _linePen() , _workingPlane(0) , _lineMode(false) { for ( size_t i=0 ; i<2 ; i++ ) _planes[i] = new QPixmap ( size ); } CellWidget::DrawingPlanes::~DrawingPlanes () { for ( size_t i=0 ; i<2 ; i++ ) { if ( _painters[i].isActive() ) _painters[i].end(); delete _planes[i]; } } void CellWidget::DrawingPlanes::setPen ( const QPen& pen ) { _normalPen = pen; _linePen = pen; _linePen.setStyle ( Qt::SolidLine ); _linePen.setWidth ( 1 ); if ( _lineMode ) painter().setPen ( _linePen ); else painter().setPen ( _normalPen ); } void CellWidget::DrawingPlanes::setBrush ( const QBrush& brush ) { painter().setBrush ( brush ); } void CellWidget::DrawingPlanes::setBackground ( const QBrush& brush ) { painter().setBackground ( brush ); painter().setBackground ( brush ); } void CellWidget::DrawingPlanes::setBackgroundMode ( Qt::BGMode mode ) { painter().setBackgroundMode ( mode ); painter().setBackgroundMode ( mode ); } void CellWidget::DrawingPlanes::setLineMode ( bool mode ) { if ( _lineMode != mode ) { _lineMode = mode; if ( _lineMode ) painter().setPen ( _linePen ); else painter().setPen ( _normalPen ); } } void CellWidget::DrawingPlanes::resize ( const QSize& size ) { for ( size_t i=0 ; i<2 ; i++ ) { bool activePainter = _painters[i].isActive(); if ( activePainter ) _painters[i].end(); delete _planes[i]; _planes[i] = new QPixmap ( size ); if ( activePainter ) _painters[i].begin ( _planes[i] ); } } void CellWidget::DrawingPlanes::shiftLeft ( int dx ) { buffersBegin (); _painters[PlaneId::Normal ].drawPixmap ( dx, 0, *_planes[PlaneId::Normal ], 0, 0, width()-dx, height() ); _painters[PlaneId::Selection].drawPixmap ( dx, 0, *_planes[PlaneId::Selection], 0, 0, width()-dx, height() ); buffersEnd (); } void CellWidget::DrawingPlanes::shiftRight ( int dx ) { buffersBegin (); _painters[PlaneId::Normal ].drawPixmap ( 0, 0, *_planes[PlaneId::Normal ], dx, 0, width()-dx, height() ); _painters[PlaneId::Selection].drawPixmap ( 0, 0, *_planes[PlaneId::Selection], dx, 0, width()-dx, height() ); buffersEnd (); } void CellWidget::DrawingPlanes::shiftUp ( int dy ) { buffersBegin (); _painters[PlaneId::Normal ].drawPixmap ( 0, dy, *_planes[PlaneId::Normal ], 0, 0, width(), height()-dy ); _painters[PlaneId::Selection].drawPixmap ( 0, dy, *_planes[PlaneId::Selection], 0, 0, width(), height()-dy ); buffersEnd (); } void CellWidget::DrawingPlanes::shiftDown ( int dy ) { buffersBegin (); _painters[PlaneId::Normal ].drawPixmap ( 0, 0, *_planes[PlaneId::Normal ], 0, dy, width(), height()-dy ); _painters[PlaneId::Selection].drawPixmap ( 0, 0, *_planes[PlaneId::Selection], 0, dy, width(), height()-dy ); buffersEnd (); } void CellWidget::DrawingPlanes::copyToSelect ( int sx, int sy, int w, int h ) { begin ( PlaneId::Selection ); _painters[PlaneId::Selection].setPen ( Qt::NoPen ); _painters[PlaneId::Selection].setBackground ( Graphics::getBrush("background") ); _painters[PlaneId::Selection].eraseRect ( sx, sy, w, h ); //_painters[PlaneId::Selection].setOpacity ( 0.5 ); _painters[PlaneId::Selection].drawPixmap ( sx, sy, *_planes[PlaneId::Normal], sx, sy, w, h ); end ( PlaneId::Selection ); } void CellWidget::DrawingPlanes::copyToScreen ( int sx, int sy, int w, int h ) { if ( _cellWidget->showSelection() ) _painters[PlaneId::Widget].drawPixmap ( sx, sy , *_planes[PlaneId::Selection] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); else _painters[PlaneId::Widget].drawPixmap ( sx, sy , *_planes[PlaneId::Normal] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); } void CellWidget::DrawingPlanes::drawCartouche ( int right , int bottom , const string& title , const string& area ) { QFont font ( "Bitstream Vera Sans", 18 ); font.setWeight ( QFont::Bold ); string user = getenv ( "USER" ); if ( user.empty() ) user = "unkown"; else { size_t equal = user.find('='); if ( equal != string::npos ) user.erase ( 0, equal ); } string date = getTime ( "%d %b %Y" ); QPen cartouchePen = QPen ( QBrush(QColor("black")), 1.0 ); _painters[PlaneId::Printer].setPen ( cartouchePen ); QRect cartoucheRect = QRect ( right - _cartoucheWidth , bottom - _cartoucheHeight , _cartoucheWidth , _cartoucheHeight ); QRect titleRect = cartoucheRect; titleRect.adjust ( 0, 0, 0, _titleHeight - _cartoucheHeight ); cartouchePen.setWidth ( 2 ); _painters[PlaneId::Printer].setPen ( cartouchePen ); _painters[PlaneId::Printer].drawRect ( cartoucheRect ); cartouchePen.setWidth ( 1 ); _painters[PlaneId::Printer].setPen ( cartouchePen ); _painters[PlaneId::Printer].drawLine ( titleRect.bottomLeft(), titleRect.bottomRight() ); _painters[PlaneId::Printer].setFont ( font ); _painters[PlaneId::Printer].drawText ( titleRect, Qt::AlignVCenter|Qt::AlignHCenter, title.c_str() ); QRect fieldRect = QRect ( cartoucheRect.x() , cartoucheRect.y() + _titleHeight , 100 , _cartoucheHeight - _titleHeight ); font.setPointSize ( 11 ); _painters[PlaneId::Printer].setFont ( font ); _painters[PlaneId::Printer].drawLine ( fieldRect.topRight(), fieldRect.bottomRight() ); _painters[PlaneId::Printer].drawText ( fieldRect, Qt::AlignVCenter|Qt::AlignHCenter, user.c_str() ); fieldRect = QRect ( cartoucheRect.x() + 100 , cartoucheRect.y() + _titleHeight , 120 , _cartoucheHeight - _titleHeight ); font.setWeight ( QFont::Normal ); _painters[PlaneId::Printer].setFont ( font ); _painters[PlaneId::Printer].drawLine ( fieldRect.topRight(), fieldRect.bottomRight() ); _painters[PlaneId::Printer].drawText ( fieldRect, Qt::AlignVCenter|Qt::AlignHCenter, date.c_str() ); fieldRect = QRect ( cartoucheRect.x() + 220 , cartoucheRect.y() + _titleHeight , 300 , _cartoucheHeight - _titleHeight ); _painters[PlaneId::Printer].setFont ( font ); _painters[PlaneId::Printer].drawLine ( fieldRect.topRight(), fieldRect.bottomRight() ); _painters[PlaneId::Printer].drawText ( fieldRect, Qt::AlignVCenter|Qt::AlignHCenter, area.c_str() ); } void CellWidget::DrawingPlanes::copyToPrinter ( int sx, int sy, int w, int h, QPrinter* printer, bool imageOnly ) { if ( !printer ) return; _printer = printer; _printer->setPageMargins ( 0.0, 0.0, 0.0, 0.0, QPrinter::DevicePixel ); int paperWidth = _printer->width (); int paperHeight = _printer->height (); int frameMargin = 25; int drawingWidth = paperWidth - (frameMargin<<1); int drawingHeight = paperHeight - (frameMargin<<1); int ximage = 0; int yimage = 0; // Substract the cartouche size only for A4 format. if ( _printer->paperSize () == QPrinter::A4 ) { if ( _printer->orientation() == QPrinter::Landscape ) { drawingWidth -= _cartoucheHeight; } else { drawingHeight -= _cartoucheHeight; } } if ( imageOnly ) { _printer->setPaperSize ( QSizeF(w,h), QPrinter::DevicePixel ); } else { ximage = frameMargin + ((drawingWidth > w) ? (drawingWidth -w)/2 : 0); yimage = frameMargin + ((drawingHeight > h) ? (drawingHeight-h)/2 : 0); } begin ( PlaneId::Printer ); if ( _cellWidget->showSelection() ) _painters[PlaneId::Printer].drawPixmap ( ximage, yimage , *_planes[PlaneId::Selection] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); else _painters[PlaneId::Printer].drawPixmap ( ximage, yimage , *_planes[PlaneId::Normal] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); if ( !imageOnly ) { DbU::Unit x1 = _cellWidget->displayToDbuX ( sx ); DbU::Unit x2 = _cellWidget->displayToDbuX ( sx+w ); DbU::Unit y1 = _cellWidget->displayToDbuY ( sy ); DbU::Unit y2 = _cellWidget->displayToDbuY ( sy+h ); string title = getString(_cellWidget->getCell()->getName()); string area = "Area: [" + DbU::getValueString(x1) + " " + DbU::getValueString(y1) + "] [" + DbU::getValueString(x2) + " " + DbU::getValueString(y2) + "]"; QPen framePen = QPen ( QBrush(QColor("black")), 1.0 ); _painters[PlaneId::Printer].setPen ( framePen ); _painters[PlaneId::Printer].drawRect ( frameMargin , frameMargin , paperWidth - (frameMargin<<1) , paperHeight - (frameMargin<<1) ); if ( (_printer->paperSize () == QPrinter::A4) && (_printer->orientation() == QPrinter::Landscape) ) { _painters[PlaneId::Printer].translate ( paperWidth - frameMargin, frameMargin ); _painters[PlaneId::Printer].rotate ( -90 ); } else _painters[PlaneId::Printer].translate ( paperWidth - frameMargin, paperHeight - frameMargin ); drawCartouche ( 0, 0, title , area ); } end ( PlaneId::Printer ); _printer = NULL; } void CellWidget::DrawingPlanes::copyToImage ( int sx, int sy, int w, int h, QImage* image, bool noScale ) { int ximage = 0; int yimage = 0; if ( !image ) return; _image = image; begin ( PlaneId::Image ); _painters[PlaneId::Image].setRenderHint ( QPainter::Antialiasing, false ); if ( _cellWidget->showSelection() ) { _painters[PlaneId::Image].drawPixmap ( ximage, yimage , *_planes[PlaneId::Selection] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); } else { _painters[PlaneId::Image].drawPixmap ( ximage, yimage , *_planes[PlaneId::Normal] , _cellWidget->getOffsetVA().rx()+sx, _cellWidget->getOffsetVA().ry()+sy , w, h ); } if ( !noScale ) { int xGradient = (w-510)/2; _painters[PlaneId::Image].setPen(Qt::white); _painters[PlaneId::Image].drawRect(xGradient-1, h+9, 512, 31); _painters[PlaneId::Image].setPen(Qt::NoPen); for ( unsigned i = 0 ; i < 256 ; i++ ) { _painters[PlaneId::Image].setBrush(Graphics::getColorScale(ColorScale::Fire).getBrush(i,100) ); _painters[PlaneId::Image].drawRect(xGradient+(i*2), h+10, 2, 30); if ( i==0 || i==51 || i==102 || i==153 || i==204 || i==255 ) { QRect tArea (xGradient+(i*2)-15, h+44, 30, 12); std::ostringstream oss; oss << (float)(i)/255; _painters[PlaneId::Image].setPen(Qt::white); _painters[PlaneId::Image].drawLine(xGradient+(i*2), h+38, xGradient+(i*2), h+42); _painters[PlaneId::Image].drawText(tArea, Qt::AlignCenter, oss.str().c_str()); _painters[PlaneId::Image].setPen(Qt::NoPen); } } } end ( PlaneId::Image ); _image = NULL; } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::DrawingQuery". CellWidget::DrawingQuery::DrawingQuery ( CellWidget* widget ) : Query() , _cellWidget(widget) , _drawExtensionGo(NULL) , _goCount(0) , _extensionGoCount(0) , _instanceCount(0) { } void CellWidget::DrawingQuery::setDrawExtensionGo ( const Name& name ) { map >::iterator idraw = _drawExtensionGos.find ( name ); if ( idraw != _drawExtensionGos.end() ) { _drawExtensionGo = idraw->second.second; if ( idraw->second.first ) idraw->second.first ( _cellWidget ); } else _drawExtensionGo = NULL; } bool CellWidget::DrawingQuery::hasMasterCellCallback () const { return true; } void CellWidget::DrawingQuery::masterCellCallback () { _instanceCount++; drawMasterCell ( getMasterCell(), getTransformation() ); } void CellWidget::DrawingQuery::drawMasterCell ( const Cell* cell , const Transformation& transformation ) { Box bbox = transformation.getBox(cell->getAbutmentBox()); _cellWidget->drawBox ( bbox ); } bool CellWidget::DrawingQuery::hasGoCallback () const { return true; } void CellWidget::DrawingQuery::goCallback ( Go* go ) { drawGo ( go, getBasicLayer(), getArea(), getTransformation() ); } void CellWidget::DrawingQuery::drawGo ( const Go* go , const BasicLayer* basicLayer , const Box& area , const Transformation& transformation ) { //cerr << "DrawingQuery::drawGo() - " << go << endl; static QRect rectangle; static unsigned int state; const Component* component = dynamic_cast(go); if ( component ) { _goCount++; Box bb = transformation.getBox(component->getBoundingBox(basicLayer)); rectangle = _cellWidget->dbuToDisplayRect ( bb ); state = ( (rectangle.width() > 2) ? 1:0) | ( (rectangle.height() > 2) ? 2:0); switch ( state ) { case 0: break; case 1: _cellWidget->drawScreenLine ( rectangle.bottomLeft(), rectangle.bottomRight() ); break; case 2: _cellWidget->drawScreenLine ( rectangle.bottomLeft(), rectangle.topLeft () ); break; case 3: _cellWidget->drawScreenRect ( rectangle ); break; } if ( _cellWidget->isDrawable("text.component") and (getDepth() < 2) and (rectangle.width () > 30) and (rectangle.height() > 30) ) { const Net* net = component->getNet(); if ( not net->isAutomatic() ) { const char* netName = net->getName()._getSharedName()->_getSString().c_str(); _cellWidget->drawDisplayText ( rectangle, netName, BigFont|Bold|Center|Frame ); } } } } bool CellWidget::DrawingQuery::hasExtensionGoCallback () const { return true; } void CellWidget::DrawingQuery::extensionGoCallback ( Go* go ) { drawExtensionGo ( _cellWidget, go, getBasicLayer(), getArea(), getTransformation() ); } void CellWidget::DrawingQuery::drawExtensionGo ( CellWidget* widget , const Go* go , const BasicLayer* basicLayer , const Box& area , const Transformation& transformation ) { if ( _drawExtensionGo ) { _extensionGoCount++; _drawExtensionGo ( widget, go, basicLayer, area, transformation ); } } bool CellWidget::DrawingQuery::hasMarkerCallback () const { return true; } void CellWidget::DrawingQuery::markerCallback ( Marker* marker ) { drawMarker ( marker, getArea(), getTransformation() ); } void CellWidget::DrawingQuery::drawMarker ( const Marker* marker , const Box& area , const Transformation& transformation ) { static QRect rectangle; const Reference* reference = dynamic_cast(marker); if ( reference and _cellWidget->isDrawable("text.reference") and (getDepth() < 2) ) { _goCount++; unsigned int flags = BigFont|Bold|Frame; Box bb = transformation.getBox ( reference->getBoundingBox() ); rectangle = _cellWidget->dbuToDisplayRect ( bb ); //rectangle.adjust ( 10, 10, 10, 10 ); if ( reference->getType() == Reference::Position ) { QPoint point = _cellWidget->dbuToDisplayPoint ( reference->getPoint() ); rectangle.translate ( point.x() - rectangle.x(), point.y() - rectangle.y() ); flags |= Left; } else { flags |= Center/*|Rounded*/; } const char* refName = reference->getName()._getSharedName()->_getSString().c_str(); _cellWidget->drawDisplayText ( rectangle, refName, flags ); if ( reference->getType() == Reference::Position ) { QPoint losange [5] = { QPoint(rectangle.x() ,rectangle.y()-6) , QPoint(rectangle.x()-6,rectangle.y() ) , QPoint(rectangle.x() ,rectangle.y()+6) , QPoint(rectangle.x()+6,rectangle.y() ) , QPoint(rectangle.x() ,rectangle.y()-6) }; _cellWidget->drawScreenPolyline ( losange, 5, 2 ); } } } bool CellWidget::DrawingQuery::hasRubberCallback () const { return true; } void CellWidget::DrawingQuery::rubberCallback ( Rubber* rubber ) { drawRubber ( rubber, getArea(), getTransformation() ); } void CellWidget::DrawingQuery::drawRubber ( const Rubber* rubber , const Box& area , const Transformation& transformation ) { static QPoint center; static QPoint extremity; static QPoint steiner; switch ( _cellWidget->getRubberShape() ) { case CellWidget::Steiner: center = _cellWidget->dbuToDisplayPoint(transformation.getPoint(rubber->getBarycenter())); forEach ( Hook*, hook, rubber->getHooks() ) { extremity = _cellWidget->dbuToDisplayPoint ( transformation.getPoint(hook->getComponent()->getCenter()) ); steiner = QPoint ( extremity.x(), center.y() ); _cellWidget->drawScreenLine ( center , steiner , PlaneId::Working, false ); _cellWidget->drawScreenLine ( steiner, extremity, PlaneId::Working, false ); } break; case CellWidget::Barycentric: center = _cellWidget->dbuToDisplayPoint(transformation.getPoint(rubber->getBarycenter())); forEach ( Hook*, hook, rubber->getHooks() ) { extremity = _cellWidget->dbuToDisplayPoint ( transformation.getPoint(hook->getComponent()->getCenter()) ); _cellWidget->drawScreenLine ( center, extremity, PlaneId::Working, false ); } break; case CellWidget::Centric: default: center = _cellWidget->dbuToDisplayPoint(transformation.getPoint(rubber->getCenter())); forEach ( Hook*, hook, rubber->getHooks() ) { extremity = _cellWidget->dbuToDisplayPoint ( transformation.getPoint(hook->getComponent()->getCenter()) ); _cellWidget->drawScreenLine ( center, extremity, PlaneId::Working, false ); } break; } } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::TextDrawingQuery". CellWidget::TextDrawingQuery::TextDrawingQuery ( CellWidget* widget ) : Query() ,_cellWidget(widget) { setBasicLayer ( NULL ); setFilter ( Query::DoMasterCells|Query::DoTerminalCells ); setStartLevel ( 0 ); setStopLevel ( 1 ); } bool CellWidget::TextDrawingQuery::hasMasterCellCallback () const { return true; } void CellWidget::TextDrawingQuery::masterCellCallback () { Box bbox = getTransformation().getBox(getMasterCell()->getAbutmentBox()); if ( getDepth() == 2 ) _cellWidget->drawText ( Point(bbox.getXMin(),bbox.getYMin()) , getString(getInstance()->getName()).c_str() , Reverse|Top , -90 ); } bool CellWidget::TextDrawingQuery::hasGoCallback () const { return false; } void CellWidget::TextDrawingQuery::goCallback ( Go* ) { } bool CellWidget::TextDrawingQuery::hasRubberCallback () const { return false; } void CellWidget::TextDrawingQuery::rubberCallback ( Rubber* ) { } bool CellWidget::TextDrawingQuery::hasExtensionGoCallback () const { return false; } void CellWidget::TextDrawingQuery::extensionGoCallback ( Go* ) { } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::SelectorCriterions". CellWidget::SelectorCriterions::SelectorCriterions () : _cellWidget(NULL) , _criterions() { } CellWidget::SelectorCriterions::~SelectorCriterions () { clear (); } bool CellWidget::SelectorCriterions::add ( const Net* net ) { if ( !_cellWidget ) return false; if ( !_cellWidget->isSelected(Occurrence(net)) ) { _criterions.push_back ( new NetSelectorCriterion(net) ); _criterions.back()->doSelection ( _cellWidget ); return true; } return false; } bool CellWidget::SelectorCriterions::add ( Box area ) { if ( !_cellWidget ) return false; _criterions.push_back ( new AreaSelectorCriterion(area) ); _criterions.back()->doSelection ( _cellWidget ); return true; } bool CellWidget::SelectorCriterions::remove ( const Net* net ) { if ( !_cellWidget ) return false; if ( !_cellWidget->isSelected(Occurrence(net)) ) return false; size_t i=0; for ( ; i<_criterions.size() ; i++ ) if ( _criterions[i]->getNet() == net ) break; if ( i < _criterions.size() ) { swap ( _criterions[i], *(_criterions.end()-1) ); _criterions.back()->undoSelection ( _cellWidget ); _criterions.pop_back (); } else return false; return true; } void CellWidget::SelectorCriterions::clear () { for ( size_t i=0 ; i<_criterions.size() ; i++ ) { delete _criterions[i]; } _criterions.clear (); } void CellWidget::SelectorCriterions::revalidate () { if ( !_cellWidget ) return; size_t i = 0; size_t last = _criterions.size (); while ( i < last ) { if ( _criterions[i]->isValid(_cellWidget) ) { _criterions[i]->doSelection ( _cellWidget ); ++i; } else swap ( _criterions[i], _criterions[--last] ); } _criterions.erase ( _criterions.begin()+last, _criterions.end() ); } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget::State". void CellWidget::State::setScale ( float scale ) { _scaleHistory.erase ( _scaleHistory.begin()+_ihistory+1,_scaleHistory.end() ); if ( _historyEnable ) { _scaleHistory.push_back ( ScaleEntry(scale,Point(0,0)) ); _ihistory++; } else { _scaleHistory[_ihistory]._scale = scale; _scaleHistory[_ihistory]._topLeft = Point(0,0); } } bool CellWidget::State::scaleHistoryUp () { if ( _ihistory == 0 ) return false; _ihistory--; return true; } bool CellWidget::State::scaleHistoryDown () { if ( _ihistory+2 > _scaleHistory.size() ) return false; _ihistory++; return true; } const Name& CellWidget::State::getName () const { static const Name noCell = "None"; if ( !_cell ) return noCell; return _cell->getName(); } // ------------------------------------------------------------------- // Class : "Hurricane::CellWidget". const int CellWidget::_stripWidth = 10; const int CellWidget::_initialSide = (400/_stripWidth)*_stripWidth; CellWidget::CellWidget ( QWidget* parent ) : QWidget (parent) , _technology (NULL) , _palette (NULL) , _displayArea (0,0,_initialSide+2*_stripWidth,_initialSide+2*_stripWidth) , _visibleArea (_stripWidth,_stripWidth,_initialSide,_initialSide) , _offsetVA (_stripWidth,_stripWidth) , _redrawManager (this) , _drawingPlanes (QSize(_initialSide+2*_stripWidth,_initialSide+2*_stripWidth),this) , _drawingQuery (this) , _textDrawingQuery (this) , _darkening (100) , _mousePosition (0,0) , _spot (this) , _state (new State(NULL)) , _cellChanged (true) , _selectionHasChanged (false) , _delaySelectionChanged(0) , _cellModificated (true) , _enableRedrawInterrupt(false) , _selectors () , _activeCommand (NULL) , _commands () , _redrawRectCount (0) , _textFontHeight (20) { //setBackgroundRole ( QPalette::Dark ); //setAutoFillBackground ( false ); setAttribute ( Qt::WA_OpaquePaintEvent ); setAttribute ( Qt::WA_NoSystemBackground ); setAttribute ( Qt::WA_PaintOnScreen ); setAttribute ( Qt::WA_StaticContents ); setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ); setFocusPolicy ( Qt::StrongFocus ); setMouseTracking ( true ); //_mapView = new MapView ( this ); DataBase* database = DataBase::getDB(); if ( database ) _technology = database->getTechnology (); QFont font = Graphics::getNormalFont(); _textFontHeight = QFontMetrics(font).ascent(); } CellWidget::~CellWidget () { unselectAll (); for ( size_t i=0 ; i<_commands.size() ; i++ ) unbindCommand ( _commands[i] ); } void CellWidget::setStyle ( int id ) { Graphics::setStyle ( (size_t)id ); refresh (); emit styleChanged (); } void CellWidget::updatePalette () { emit updatePalette(getCell()); } void CellWidget::bindToPalette ( PaletteWidget* palette ) { detachFromPalette (); _palette = palette; connect ( _palette, SIGNAL(paletteChanged()) , this , SLOT(refresh()) ); connect ( this , SIGNAL(cellChanged(Cell*)) , _palette, SLOT(updateExtensions(Cell*)) ); connect ( this , SIGNAL(updatePalette(Cell*)), _palette, SLOT(updateExtensions(Cell*)) ); connect ( this , SIGNAL(styleChanged()) , _palette, SLOT(changeStyle()) ); } void CellWidget::detachFromPalette () { if ( _palette ) { disconnect ( _palette, SIGNAL(paletteChanged()) , this , SLOT(refresh()) ); disconnect ( this , SIGNAL(cellChanged(Cell*)) , _palette, SLOT(updateExtensions(Cell*)) ); disconnect ( this , SIGNAL(updatePalette(Cell*)), _palette, SLOT(updateExtensions(Cell*)) ); disconnect ( this , SIGNAL(styleChanged(void*)) , _palette, SLOT(styleChange(void*)) ); _palette = NULL; } } void CellWidget::bindCommand ( Command* command ) { for ( size_t i=0 ; i<_commands.size() ; i++ ) if ( _commands[i] == command ) return; command->setCellWidget ( this ); _commands.push_back ( command ); } void CellWidget::unbindCommand ( Command* command ) { size_t i = 0; for ( ; i<_commands.size() ; i++ ) if ( _commands[i] == command ) break; if ( i < _commands.size() ) _commands[i]->setCellWidget ( NULL ); for ( ; i+1<_commands.size() ; i++ ) _commands[i] = _commands[i+1]; _commands.pop_back (); } void CellWidget::pushCursor ( Qt::CursorShape cursor ) { setCursor ( cursor ); _cursors.push_back ( cursor ); } void CellWidget::popCursor () { _cursors.pop_back (); if ( !_cursors.empty() ) setCursor ( _cursors.back() ); else unsetCursor (); } QSize CellWidget::minimumSizeHint () const { return QSize(_initialSide,_initialSide); } void CellWidget::rubberChange () { switch ( getRubberShape() ) { case Centric: setRubberShape(Barycentric); break; case Barycentric: setRubberShape(Steiner ); break; case Steiner: setRubberShape(Centric ); break; } } void CellWidget::changeDbuMode ( unsigned int mode, DbU::UnitPower p ) { if ( (_state->getDbuMode() != mode) or (_state->getUnitPower() != p) ) { _state->setDbuMode ( mode ); _state->setUnitPower ( p ); DbU::setStringMode ( mode, p ); updateMousePosition (); refresh (); emit dbuModeChanged ( _state->getDbuMode(), _state->getUnitPower() ); } } void CellWidget::setShowSelection ( bool state ) { if ( state != _state->showSelection() ) { _state->setShowSelection ( state ); _selectionHasChanged = false; refresh (); emit selectionModeChanged (); } } void CellWidget::setCumulativeSelection ( bool state ) { if ( state != _state->cumulativeSelection() ) { _state->setCumulativeSelection ( state ); emit selectionModeChanged (); } } void CellWidget::setShowBoundaries ( bool state ) { if ( _state->showBoundaries() != state ) { _state->setShowBoundaries ( state ); _redrawManager.refresh (); emit showBoundariesToggled ( state ); } } void CellWidget::changeQueryFilter () { _redrawManager.refresh (); emit queryFilterChanged (); } void CellWidget::_redraw ( QRect redrawArea ) { // cerr << "CellWidget::redraw() - start " // << _selectionHasChanged << " filter:" // << _state->getQueryFilter() << endl; // static bool timedout; // static Timer timer; if ( !isVisible() ) return; // timer.start (); // timedout = false; _cellChanged = false; _redrawRectCount = 0; pushCursor ( Qt::BusyCursor ); if ( ! ( _selectionHasChanged && _state->showSelection() ) || _cellModificated ) { _spot.setRestore ( false ); //_drawingPlanes.copyToSelect ( redrawArea ); _drawingPlanes.select ( PlaneId::Normal ); _drawingPlanes.begin (); _drawingPlanes.painter().setPen ( Qt::NoPen ); _drawingPlanes.painter().setBackground ( Graphics::getBrush("background") ); _drawingPlanes.painter().setClipRect ( redrawArea ); _drawingPlanes.painter().eraseRect ( redrawArea ); setDarkening ( (_state->showSelection()) ? Graphics::getDarkening() : 100 ); if ( getCell() ) { Box redrawBox = displayToDbuBox ( redrawArea ); _drawingQuery.resetGoCount (); _drawingQuery.resetExtensionGoCount(); _drawingQuery.resetInstanceCount(); _drawingQuery.setExtensionMask ( 0 ); _drawingQuery.setArea ( redrawBox ); _drawingQuery.setTransformation ( Transformation() ); forEach ( BasicLayer*, iLayer, _technology->getBasicLayers() ) { _drawingPlanes.setPen ( Graphics::getPen ((*iLayer)->getName(),getDarkening()) ); _drawingPlanes.setBrush ( Graphics::getBrush((*iLayer)->getName(),getDarkening()) ); if ( isDrawable((*iLayer)->getName()) ) { _drawingQuery.setBasicLayer ( *iLayer ); _drawingQuery.setFilter ( getQueryFilter().unset(Query::DoMasterCells|Query::DoRubbers|Query::DoMarkers) ); _drawingQuery.doQuery (); } if ( _enableRedrawInterrupt ) QApplication::processEvents(); if ( _redrawManager.interrupted() ) { //cerr << "CellWidget::redraw() - interrupt after " << (*iLayer)->getName() << endl; break; } //if ( timeout("redraw [layer]",timer,10.0,timedout) ) break; } if ( /*!timeout("redraw [boundaries]",timer,10.0,timedout) &&*/ (!_redrawManager.interrupted()) ) { if ( isDrawable("boundaries") ) { _drawingPlanes.setPen ( Graphics::getPen ("boundaries",getDarkening()) ); _drawingPlanes.setBrush ( Graphics::getBrush("boundaries",getDarkening()) ); _drawingQuery.setBasicLayer ( NULL ); _drawingQuery.setFilter ( getQueryFilter().unset(Query::DoComponents|Query::DoRubbers|Query::DoMarkers) ); _drawingQuery.doQuery (); } } if ( /*!timeout("redraw [markers]",timer,10.0,timedout) &&*/ (!_redrawManager.interrupted()) ) { if ( isDrawable("text.reference") ) { _drawingPlanes.setPen ( Graphics::getPen ("text.reference",getDarkening()) ); _drawingPlanes.setBrush ( Graphics::getBrush("text.reference",getDarkening()) ); _drawingQuery.setBasicLayer ( NULL ); _drawingQuery.setFilter ( getQueryFilter().unset(Query::DoComponents|Query::DoMasterCells) ); _drawingQuery.doQuery (); } } if ( /*!timeout("redraw [rubbers]",timer,10.0,timedout) &&*/ (!_redrawManager.interrupted()) ) { if ( isDrawable("rubber") ) { _drawingPlanes.setPen ( Graphics::getPen ("rubber",getDarkening()) ); _drawingPlanes.setBrush ( Graphics::getBrush("rubber",getDarkening()) ); _drawingQuery.setBasicLayer ( NULL ); _drawingQuery.setFilter ( getQueryFilter().unset(Query::DoComponents|Query::DoMasterCells|Query::DoMarkers) ); _drawingQuery.doQuery (); } } if ( _enableRedrawInterrupt ) QApplication::processEvents(); if ( /*!timeout("redraw [text.instances]",timer,10.0,timedout) &&*/ (!_redrawManager.interrupted()) ) { if ( isDrawable("text.instance") ) { _drawingPlanes.setPen ( Graphics::getPen ("text.instance",getDarkening()) ); _drawingPlanes.setBrush ( Graphics::getBrush("text.instance",getDarkening()) ); _drawingPlanes.setBackground ( Graphics::getBrush("boundaries" ,getDarkening()) ); _textDrawingQuery.setArea ( redrawBox ); _textDrawingQuery.setTransformation ( Transformation() ); _textDrawingQuery.doQuery (); } } //_drawingQuery.setFilter ( getQueryFilter() & ~Query::DoMasterCells ); forEach ( ExtensionSlice*, islice, getCell()->getExtensionSlices() ) { if ( _enableRedrawInterrupt ) QApplication::processEvents(); if ( /*timeout("redraw [extension]",timer,10.0,timedout) ||*/ (_redrawManager.interrupted()) ) break; if ( isDrawableExtension((*islice)->getName()) ) { _drawingQuery.setExtensionMask ( (*islice)->getMask() ); _drawingQuery.setDrawExtensionGo ( (*islice)->getName() ); _drawingQuery.setFilter ( Query::DoExtensionGos ); _drawingQuery.doQuery (); } } } _drawingPlanes.end (); _cellModificated = false; } if ( isDrawable("grid") ) drawGrid ( redrawArea ); if ( isDrawable("text.ruler") ) drawRulers ( redrawArea ); setDarkening ( 100 ); if ( _state->showSelection() ) redrawSelection ( redrawArea ); popCursor (); repaint (); // timer.stop (); // cerr << "CellWidget::redraw() - " << _redrawRectCount // << " in " << timer.getCombTime() << "s (" // << setprecision(3) << (timer.getCombTime()/_redrawRectCount) << " s/r)"; // if ( _drawingQuery.getGoCount() ) // cerr << " " << _drawingQuery.getGoCount() // << " (" << setprecision(3) << (timer.getCombTime()/_drawingQuery.getGoCount()) << " s/go)"; // else // cerr << " 0 Gos"; // if ( _drawingQuery.getExtensionGoCount() ) // cerr << " " << _drawingQuery.getExtensionGoCount() // << " (" << setprecision(3) << (timer.getCombTime()/_drawingQuery.getExtensionGoCount()) << " s/ego)"; // else // cerr << " 0 eGos"; // if ( _drawingQuery.getInstanceCount() ) // cerr << " " << _drawingQuery.getInstanceCount() // << " (" << setprecision(3) << (timer.getCombTime()/_drawingQuery.getInstanceCount()) << " s/inst)"; // else // cerr << " 0 Instances"; // cerr << endl; } void CellWidget::redrawSelection ( QRect redrawArea ) { _drawingPlanes.copyToSelect ( redrawArea.x() , redrawArea.y() , redrawArea.width() , redrawArea.height() ); _drawingPlanes.select ( PlaneId::Selection ); _drawingPlanes.begin (); _drawingPlanes.painter().setPen ( Qt::NoPen ); _drawingPlanes.painter().setBackground ( Graphics::getBrush("background") ); _drawingPlanes.painter().setClipRect ( redrawArea ); if ( getCell() ) { Box redrawBox = displayToDbuBox ( redrawArea ); SelectorSet::iterator iselector; forEach ( BasicLayer*, basicLayer, _technology->getBasicLayers() ) { //if ( !isDrawableLayer(basicLayer->getName()) ) continue; _drawingPlanes.setPen ( Graphics::getPen (basicLayer->getName()) ); _drawingPlanes.setBrush ( Graphics::getBrush(basicLayer->getName()) ); iselector = _selectors.begin(); for ( ; iselector != _selectors.end() ; iselector++ ) { Occurrence occurrence = (*iselector)->getOccurrence(); Component* component = dynamic_cast(occurrence.getEntity()); if ( !component ) break; if ( !component->getLayer() ) continue; if ( !component->getLayer()->contains(*basicLayer) ) continue; Transformation transformation = occurrence.getPath().getTransformation(); _drawingQuery.drawGo ( dynamic_cast(occurrence.getEntity()) , *basicLayer , redrawBox , transformation ); } } _drawingPlanes.setPen ( Graphics::getPen ("boundaries") ); _drawingPlanes.setBrush ( Graphics::getBrush("boundaries") ); for ( ; iselector != _selectors.end() ; iselector++ ) { Occurrence occurrence = (*iselector)->getOccurrence(); Instance* instance = dynamic_cast(occurrence.getEntity()); if ( instance ) { Transformation transformation = occurrence.getPath().getTransformation().getTransformation(instance->getTransformation()); _drawingQuery.drawMasterCell ( instance->getMasterCell(), transformation ); } } _drawingPlanes.setPen ( Graphics::getPen ("rubber") ); _drawingPlanes.setBrush ( Graphics::getBrush("rubber") ); for ( ; iselector != _selectors.end() ; iselector++ ) { Occurrence occurrence = (*iselector)->getOccurrence(); Rubber* rubber = dynamic_cast(occurrence.getEntity()); if ( !rubber ) break; Transformation transformation = occurrence.getPath().getTransformation(); _drawingQuery.drawRubber ( rubber, redrawBox, transformation ); } Name extensionName = ""; for ( ; iselector != _selectors.end() ; iselector++ ) { Occurrence occurrence = (*iselector)->getOccurrence(); ExtensionGo* eGo = dynamic_cast(occurrence.getEntity()); if ( !eGo ) break; Transformation transformation = occurrence.getPath().getTransformation(); if ( eGo->getName() != extensionName ) { extensionName = eGo->getName(); _drawingQuery.setDrawExtensionGo ( extensionName ); } if ( isDrawable(extensionName) ) _drawingQuery.drawExtensionGo ( this, eGo, NULL, redrawBox, transformation ); } } _drawingPlanes.end (); _selectionHasChanged = false; } void CellWidget::setLayerVisible ( const Name& layer, bool visible ) { if ( !_palette ) return; _palette->setItemVisible ( layer, visible ); } bool CellWidget::isDrawable ( const Name& name ) { PaletteItem* item = (_palette) ? _palette->find(name) : NULL; //DbU::Unit unity = symbolicMode() ? DbU::lambda(1.0) : DbU::grid(10.0); DbU::Unit unity = DbU::lambda(1.0); return (!item || item->isItemVisible()) && ( Graphics::getThreshold(name) < getScale()*unity ); } bool CellWidget::isDrawableLayer ( const Name& layerName ) { PaletteItem* item = (_palette) ? _palette->find(layerName) : NULL; return !item || item->isItemVisible(); } bool CellWidget::isDrawableExtension ( const Name& extensionName ) { PaletteItem* item = (_palette) ? _palette->find(extensionName) : NULL; return (!item || item->isItemVisible()); } bool CellWidget::isSelectable ( const Name& name ) const { PaletteItem* item = (_palette) ? _palette->find(name) : NULL; return (!item || item->isItemSelectable()); } bool CellWidget::isSelectable ( const Layer* layer ) const { PaletteItem* item = NULL; forEach ( BasicLayer*, ilayer, layer->getBasicLayers() ) { item = (_palette) ? _palette->find(ilayer->getName()) : NULL; if ( item && item->isItemSelectable() ) return true; } return false; } void CellWidget::drawBox ( DbU::Unit x1, DbU::Unit y1, DbU::Unit x2, DbU::Unit y2 ) { _redrawRectCount++; _drawingPlanes.setLineMode ( false ); _drawingPlanes.painter().drawRect ( dbuToDisplayRect(x1,y1,x2,y2) ); } void CellWidget::drawBox ( const Box& box ) { _redrawRectCount++; _drawingPlanes.setLineMode ( false ); _drawingPlanes.painter().drawRect ( dbuToDisplayRect(box) ); } void CellWidget::drawText ( const Point& point, const char* text, unsigned int flags, int angle ) { drawDisplayText ( dbuToDisplayPoint(point), text, flags, angle ); } void CellWidget::drawDisplayText ( const QRect& box, const char* text, unsigned int flags ) { QFont font = Graphics::getNormalFont(flags&Bold); if ( flags & BigFont ) font.setPointSize ( 18 ); QFontMetrics metrics = QFontMetrics(font); int width = metrics.width ( text ); //int height = metrics.height (); int angle = 0; if ( (width > box.width()) and (box.height() > 2*box.width()) ) angle = -90; drawDisplayText ( box.center(), text, flags, angle ); } void CellWidget::drawDisplayText ( const QPoint& point, const char* text, unsigned int flags, int angle ) { QPainter& painter = _drawingPlanes.painter(); QPen pen = painter.pen (); QBrush brush = painter.brush (); QFont font = Graphics::getNormalFont(flags&Bold); painter.save(); if ( flags & Reverse ) painter.setPen ( Graphics::getPen("background") ); if ( flags & Reverse ) painter.setBackgroundMode ( Qt::OpaqueMode ); if ( flags & BigFont ) font.setPointSize ( 18 ); QFontMetrics metrics = QFontMetrics(font); int width = metrics.width ( text ); int height = metrics.height (); pen.setStyle ( Qt::SolidLine ); pen.setColor ( painter.brush().color() ); brush.setStyle ( Qt::NoBrush ); painter.setPen ( pen ); painter.setBrush ( brush ); painter.setFont ( font ); painter.translate ( point ); painter.rotate ( angle ); QPoint bottomLeft ( 0, 0); if ( flags & Center ) { bottomLeft.rx() -= width /2; bottomLeft.ry() += height/2; } else if ( flags & Top ) { bottomLeft.ry() += height; } else if ( flags & Left ) { } if ( flags & Frame ) { if ( flags & Rounded ) painter.drawRoundedRect ( bottomLeft.x()-1, bottomLeft.y()-height, width+2, height, 8, 8 ); else painter.drawRect ( bottomLeft.x()-1, bottomLeft.y()-height, width+2, height ); } painter.drawText ( bottomLeft.x(), bottomLeft.y()-metrics.descent(), text ); painter.restore (); } void CellWidget::drawLine ( DbU::Unit x1, DbU::Unit y1, DbU::Unit x2, DbU::Unit y2, bool mode ) { _redrawRectCount++; _drawingPlanes.setLineMode ( mode ); _drawingPlanes.painter().drawLine ( dbuToDisplayPoint(x1,y1), dbuToDisplayPoint(x2,y2) ); } void CellWidget::drawLine ( const Point& p1, const Point& p2, bool mode ) { _redrawRectCount++; _drawingPlanes.setLineMode ( mode ); _drawingPlanes.painter().drawLine ( dbuToDisplayPoint(p1), dbuToDisplayPoint(p2) ); } void CellWidget::drawScreenLine ( const QPoint& p1, const QPoint& p2, size_t plane, bool mode ) { _redrawRectCount++; _drawingPlanes.setLineMode ( mode ); _drawingPlanes.painter(plane).drawLine ( p1, p2 ); } void CellWidget::drawScreenPolygon ( const QPoint* points, int count, size_t plane ) { _drawingPlanes.painter(plane).drawPolygon ( points, count ); } void CellWidget::drawScreenPolyline ( const QPoint* points, int count, int width, size_t plane ) { _drawingPlanes.painter(plane).save (); QPen pen = _drawingPlanes.painter(plane).pen (); pen.setWidth ( width ); _drawingPlanes.painter(plane).setPen ( pen ); _drawingPlanes.painter(plane).drawPolyline ( points, count ); _drawingPlanes.painter(plane).restore (); } void CellWidget::drawScreenRect ( const QPoint& p1, const QPoint& p2, size_t plane ) { _drawingPlanes.setLineMode ( false ); _drawingPlanes.painter(plane).drawRect ( QRect(p1,p2) ); } void CellWidget::drawScreenRect ( const QRect& r, size_t plane ) { _redrawRectCount++; _drawingPlanes.setLineMode ( false ); _drawingPlanes.painter(plane).drawRect ( r ); } bool CellWidget::_underDetailedGridThreshold () const { if ( symbolicMode() ) return Graphics::getThreshold("grid")/DbU::lambda(1.0) < getScale()/5; return Graphics::getThreshold("grid")/DbU::grid(10.0) < getScale()/5; } void CellWidget::drawGrid ( QRect redrawArea ) { _drawingPlanes.select ( PlaneId::Normal ); _drawingPlanes.begin (); _drawingPlanes.painter ().setClipRect ( redrawArea ); _drawingPlanes.painter ().setPen ( Graphics::getPen("grid") ); Box redrawBox = displayToDbuBox ( redrawArea ).inflate ( DbU::lambda(1.0) ); bool detailedGrid = _underDetailedGridThreshold(); DbU::Unit gridStep = _snapGridStep(); DbU::Unit superGridStep = gridStep*5; DbU::Unit xGrid; DbU::Unit yGrid; QPoint center; for ( yGrid = _onSnapGrid(redrawBox.getYMin()) ; yGrid < redrawBox.getYMax() ; yGrid += gridStep ) { for ( xGrid = _onSnapGrid(redrawBox.getXMin()) ; xGrid < redrawBox.getXMax() ; xGrid += gridStep ) { center = dbuToDisplayPoint(xGrid,yGrid); if ( (xGrid % superGridStep) || (yGrid % superGridStep) ) { if ( detailedGrid ) { _drawingPlanes.painter().drawPoint ( center ); } } else { if ( detailedGrid ) { _drawingPlanes.painter().drawLine ( center.x()-3, center.y() , center.x()+3, center.y() ); _drawingPlanes.painter().drawLine ( center.x() , center.y()-3, center.x() , center.y()+3 ); } else { _drawingPlanes.painter().drawPoint ( center ); } } } } _drawingPlanes.copyToSelect ( redrawArea ); _drawingPlanes.end (); } void CellWidget::drawRulers ( QRect redrawArea ) { _drawingPlanes.select ( PlaneId::Normal ); _drawingPlanes.begin (); _drawingPlanes.painter ().setClipRect ( redrawArea ); redrawArea.adjust ( -50, -50, 50, 50 ); Box redrawBox = displayToDbuBox ( redrawArea ); redrawArea.adjust ( 50, 50, -50, -50 ); RulerSet::iterator iruler = _state->getRulers().begin(); RulerSet::iterator end = _state->getRulers().end(); for ( ; iruler != end ; iruler++ ) { if ( !(*iruler)->intersect(redrawBox) ) continue; drawRuler ( *iruler ); } _drawingPlanes.copyToSelect ( redrawArea ); _drawingPlanes.end (); } void CellWidget::drawRuler ( shared_ptr ruler ) { QFont font = Graphics::getNormalFont(); QFontMetrics metrics = QFontMetrics(font); int tickLength = metrics.width ( "+00000u" ); Point origin = ruler->getOrigin (); Point extremity = ruler->getExtremity (); Point angle = ruler->getAngle (); DbU::Unit graduation; DbU::Unit gradStep; QPoint pxOrigin; QPoint pxExtremity; QPoint pxAngle; bool onScreen = ( _drawingPlanes.getWorkingPlane() > PlaneId::Selection ); // Never less than 5 pixels between two graduations ticks. if ( symbolicMode() ) gradStep = DbU::lambda(pow(10.0,ceil(log10(DbU::getLambda(displayToDbuLength(50))))))/10; else gradStep = DbU::grid(pow(10.0,ceil(log10(DbU::getGrid(displayToDbuLength(50))))))/10; if ( onScreen ) { pxOrigin = dbuToScreenPoint ( origin ); pxExtremity = dbuToScreenPoint ( extremity ); pxAngle = dbuToScreenPoint ( angle ); } else { pxOrigin = dbuToDisplayPoint ( origin ); pxExtremity = dbuToDisplayPoint ( extremity ); pxAngle = dbuToDisplayPoint ( angle ); } bool hRuler = ( abs(pxAngle.x() - pxOrigin.x()) >= abs(pxAngle.y() - pxOrigin.y()) ); int pxGrad; int pyGrad; string textGrad; int tick; _drawingPlanes.painter().setPen ( Graphics::getPen ("text.ruler") ); _drawingPlanes.painter().setBrush ( Graphics::getBrush("text.ruler") ); // The horizontal ruler. bool increase = ( origin.getX() < extremity.getX() ); if ( !increase ) gradStep = -gradStep; if ( hRuler and (abs(pxAngle.x() - pxOrigin.x()) > 20) ) { // The horizontal ruler axis. _drawingPlanes.painter().drawLine ( pxOrigin, pxAngle ); // The horizontal ruler ticks. for ( graduation=origin.getX(), tick=0 ; true ; graduation+=gradStep, tick++ ) { if ( increase ) { if ( graduation >= angle.getX() ) break; } else if ( graduation <= angle.getX() ) break; if ( onScreen ) pxGrad = dbuToScreenX ( graduation ); else pxGrad = dbuToDisplayX ( graduation ); if ( tick % 10 ) { _drawingPlanes.painter().drawLine ( pxGrad, pxOrigin.y() , pxGrad, pxOrigin.y()+((tick%2)?5:10) ); } else { // if ( tick == 0 ) { // int delta = (increase) ? 2 : -2; // _drawingPlanes.painter().drawLine ( pxGrad-delta, pxOrigin.y() // , pxGrad-delta, pxOrigin.y()+tickLength ); // } _drawingPlanes.painter().drawLine ( pxGrad, pxOrigin.y() , pxGrad, pxOrigin.y()+tickLength ); // if ( !tick ) continue; textGrad = DbU::getValueString( abs(gradStep*tick) , DbU::SmartTruncate|((symbolicMode())?DbU::Symbolic:DbU::Grid) ); textGrad.resize ( textGrad.size()-((*textGrad.rbegin()=='m')?2:1) ); drawDisplayText ( QPoint ( pxGrad - 1, pxOrigin.y() + tickLength ) , textGrad.c_str() , Bold , -90 ); } } // The last horizontal tick. _drawingPlanes.painter().drawLine ( pxAngle.x(), pxAngle.y() , pxAngle.x(), pxAngle.y()+tickLength ); textGrad = DbU::getValueString ( abs(angle.getX() - origin.getX()) , DbU::SmartTruncate|((symbolicMode())?DbU::Symbolic:DbU::Grid) ); //textGrad.resize ( textGrad.size()-1 ); drawDisplayText ( QPoint ( pxAngle.x() - 1,pxAngle.y() + tickLength ) , textGrad.c_str() , Bold , -90 ); } if ( not hRuler and (abs(pxAngle.y() - pxOrigin.y()) > 20) ) { // The vertical ruler. increase = ( origin.getY() < angle.getY() ); if ( increase xor ( gradStep > 0 ) ) gradStep = -gradStep; // The vertical ruler axis. _drawingPlanes.painter().drawLine ( pxOrigin, pxAngle ); // The vertical ruler ticks. for ( graduation=origin.getY(), tick=0 ; true ; graduation+=gradStep, tick++ ) { if ( increase ) { if ( graduation >= angle.getY() ) break; } else if ( graduation <= angle.getY() ) break; if ( onScreen ) pyGrad = dbuToScreenY ( graduation ); else pyGrad = dbuToDisplayY ( graduation ); if ( tick % 10 ) { _drawingPlanes.painter().drawLine ( pxOrigin.x() , pyGrad , pxOrigin.x()-((tick%2)?5:10), pyGrad ); } else { // if ( tick == 0 ) { // _drawingPlanes.painter().drawLine ( pxOrigin.x() , pyGrad-2 // , pxOrigin.x()-tickLength, pyGrad-2); // } _drawingPlanes.painter().drawLine ( pxOrigin.x() , pyGrad , pxOrigin.x()-tickLength, pyGrad ); // if ( !tick ) continue; textGrad = DbU::getValueString( abs(gradStep*tick) , DbU::SmartTruncate|((symbolicMode())?DbU::Symbolic:DbU::Grid) ); textGrad.resize ( textGrad.size()-((*textGrad.rbegin()=='m')?2:1) ); drawDisplayText ( QPoint(pxOrigin.x() - tickLength,pyGrad + 1) , textGrad.c_str() , Bold , 0 ); } } // The last vertical tick. _drawingPlanes.painter().drawLine ( pxOrigin.x() , pxAngle.y() , pxOrigin.x()-tickLength, pxAngle.y() ); textGrad = DbU::getValueString( abs(angle.getY() - origin.getY()) , DbU::SmartTruncate|((symbolicMode())?DbU::Symbolic:DbU::Grid) ); //textGrad.resize ( textGrad.size()-1 ); drawDisplayText ( QPoint(pxOrigin.x() - tickLength,pxAngle.y() + 1) , textGrad.c_str() , Bold , 0 ); } } void CellWidget::goLeft ( int dx ) { if ( !dx ) dx = geometry().size().width() / 4; _redrawManager.goLeft ( dx ); } void CellWidget::goRight ( int dx ) { if ( !dx ) dx = geometry().size().width() / 4; _redrawManager.goRight ( dx ); } void CellWidget::goUp ( int dy ) { if ( !dy ) dy = geometry().size().height() / 4; _redrawManager.goUp ( dy ); } void CellWidget::goDown ( int dy ) { if ( !dy ) dy = geometry().size().height() / 4; _redrawManager.goDown ( dy ); } void CellWidget::displayReframe () { _offsetVA.rx() = _stripWidth; _offsetVA.ry() = _stripWidth; DbU::Unit xmin = (DbU::Unit)( _visibleArea.getXMin() - ((float)_offsetVA.x()/getScale()) ); DbU::Unit xmax = (DbU::Unit)( xmin + ((float)_drawingPlanes.width()/getScale()) ) ; DbU::Unit ymax = (DbU::Unit)( _visibleArea.getYMax() + ((float)_offsetVA.y()/getScale()) ); DbU::Unit ymin = (DbU::Unit)( ymax - ((float)_drawingPlanes.height()/getScale()) ) ; _displayArea = Box ( xmin, ymin, xmax, ymax ); _redrawManager.refresh (); } Box CellWidget::computeVisibleArea ( float scale ) const { Point center = _visibleArea.getCenter(); return Box ( (DbU::Unit)( center.getX() - width () / (scale*2) ) , (DbU::Unit)( center.getY() - height() / (scale*2) ) , (DbU::Unit)( center.getX() + width () / (scale*2) ) , (DbU::Unit)( center.getY() + height() / (scale*2) ) ); } Box CellWidget::computeVisibleArea ( float scale, const Point& topLeft ) const { return Box ( topLeft.getX() , (DbU::Unit)( topLeft.getY() - height() / scale ) , (DbU::Unit)( topLeft.getX() + width () / scale ) , topLeft.getY() ); } Box CellWidget::computeVisibleArea ( const Box& area, float& scale ) const { int widgetWidth = width (); int widgetHeight = height (); float scaleX = widgetWidth / (float)area.getWidth (); float scaleY = widgetHeight / (float)area.getHeight(); scale = min ( scaleX, scaleY ); Point center = area.getCenter(); widgetWidth /= 2; widgetHeight /= 2; return Box ( (DbU::Unit)( center.getX() - widgetWidth / scale ) , (DbU::Unit)( center.getY() - widgetHeight / scale ) , (DbU::Unit)( center.getX() + widgetWidth / scale ) , (DbU::Unit)( center.getY() + widgetHeight / scale ) ); } void CellWidget::setScale ( float scale ) { //cerr << "CellWidget::setScale() - " << scale << endl; _state->setTopLeft ( getTopLeft() ); _visibleArea = computeVisibleArea ( scale ); _state->setScale ( scale ); //cerr << "_visibleArea: " << _visibleArea << " (offset: " << _offsetVA.x() << ")" << endl; //cerr << " " << center << endl; displayReframe (); } void CellWidget::scaleHistoryUp () { _state->setTopLeft ( getTopLeft() ); if ( _state->scaleHistoryUp () ) { _visibleArea = computeVisibleArea ( _state->getScale(), _state->getTopLeft() ); displayReframe (); } } void CellWidget::scaleHistoryDown () { _state->setTopLeft ( getTopLeft() ); if ( _state->scaleHistoryDown () ) { _visibleArea = computeVisibleArea ( _state->getScale(), _state->getTopLeft() ); displayReframe (); } } void CellWidget::reframe () { //cerr << "CellWidget::reframe() - scale:" << _state->getScale() // << " topLeft:" << _state->getTopLeft() << endl; _visibleArea = computeVisibleArea ( _state->getScale(), _state->getTopLeft() ); displayReframe (); } void CellWidget::reframe ( const Box& box, bool historyEnable ) { //cerr << "CellWidget::reframe() - " << box << endl; //cerr << " widget size := " << _drawingPlanes.width() << "x" << _drawingPlanes.height() << endl; //cerr << " CellWidget::reframe() - widget size := " << width() << "x" << height() << endl; bool backupHistoryEnable = _state->getHistoryEnable (); _state->setHistoryEnable ( historyEnable ); _state->setTopLeft ( getTopLeft() ); float scale; _visibleArea = computeVisibleArea ( box, scale ); _state->setScale ( scale ); displayReframe (); _state->setHistoryEnable ( backupHistoryEnable ); //cerr << " _displayArea: " << _displayArea << " (offset: " << _offsetVA.x() << ")" << endl; } void CellWidget::fitToContents ( bool historyEnable ) { //cerr << "CellWidget::fitToContents()" << endl; Box boundingBox = Box ( DbU::lambda(0) , DbU::lambda(0) , DbU::lambda(10) , DbU::lambda(50) ); if ( getCell() ) boundingBox = getCell()->getBoundingBox(); DbU::Unit expand; if ( boundingBox.getWidth() < boundingBox.getHeight() ) { expand = DbU::grid( DbU::getGrid(boundingBox.getWidth()) * 0.05 ); } else { expand = DbU::grid( DbU::getGrid(boundingBox.getHeight()) * 0.05 ); } reframe ( boundingBox.inflate(expand), historyEnable ); } void CellWidget::fitToNet ( const Net* net, bool historyEnable ) { if ( !net ) throw Error ( "CellWidget::fitToNet(): NULL net argument." ); if ( net->getCell() != getCell() ) throw Error ( "CellWidget::fitToNet():
" "Net %s (cell: %s) do not belong to Cell %s" , Graphics::toHtml(getString(net->getName())).c_str() , Graphics::toHtml(getString(net->getCell()->getName())).c_str() , Graphics::toHtml(getString(getCell()->getName())).c_str() ); Box boundingBox = net->getBoundingBox (); if ( !boundingBox.isEmpty() ) reframe ( boundingBox, historyEnable ); } void CellWidget::_goLeft ( int dx ) { _visibleArea.translate ( - (DbU::Unit)( dx / getScale() ) , 0 ); if ( _offsetVA.rx() - dx >= 0 ) { _offsetVA.rx() -= dx; repaint (); return; } int shift = ( 1 + ( dx - _offsetVA.rx() ) / _stripWidth ) * _stripWidth; _displayArea.translate ( - (DbU::Unit)( shift / getScale() ) , 0 ); _offsetVA.rx() -= dx - shift; if ( shift >= _drawingPlanes.width() ) _redrawManager.refresh (); else { _drawingPlanes.shiftLeft ( shift ); _redraw ( QRect ( QPoint(0,0), QSize(shift,_drawingPlanes.height()) ) ); } assert ( _offsetVA.rx() >= 0 ); } void CellWidget::_goRight ( int dx ) { //cerr << "CellWidget::goRight() - dx: " << dx << " (offset: " << _offsetVA.rx() << ")" << endl; _visibleArea.translate ( (DbU::Unit)( dx / getScale() ) , 0 ); if ( _offsetVA.rx() + dx < 2*_stripWidth ) { _offsetVA.rx() += dx; repaint (); return; } int shift = ( ( _offsetVA.rx() + dx ) / _stripWidth ) * _stripWidth; _displayArea.translate ( (DbU::Unit)( shift / getScale() ) , 0 ); _offsetVA.rx() += dx - shift; if ( shift >= _drawingPlanes.width() ) _redrawManager.refresh (); else { _drawingPlanes.shiftRight ( shift ); _redraw ( QRect ( QPoint(_drawingPlanes.width()-shift,0) , QSize (shift,_drawingPlanes.height()) ) ); } assert ( _offsetVA.rx() >= 0 ); } void CellWidget::_goUp ( int dy ) { //cerr << "CellWidget::shiftUp() - " << dy << " (offset: " << _offsetVA.ry() << ")" << endl; _visibleArea.translate ( 0, (DbU::Unit)( dy / getScale() ) ); if ( _offsetVA.ry() - dy >= 0 ) { _offsetVA.ry() -= dy; repaint (); return; } int shift = ( 1 + ( dy - _offsetVA.ry() ) / _stripWidth ) * _stripWidth; _displayArea.translate ( 0, (DbU::Unit)( shift / getScale() ) ); _offsetVA.ry() -= dy - shift; if ( shift >= _drawingPlanes.height() ) _redrawManager.refresh (); else { _drawingPlanes.shiftUp ( shift ); _redraw ( QRect ( QPoint(0,0), QSize(_drawingPlanes.width(),shift) ) ); } assert ( _offsetVA.ry() >= 0 ); } void CellWidget::_goDown ( int dy ) { //cerr << "CellWidget::shiftDown() - " << dy << " (offset: " << _offsetVA.ry() << ")" << endl; _visibleArea.translate ( 0, - (DbU::Unit)( dy / getScale() ) ); if ( _offsetVA.ry() + dy < 2*_stripWidth ) { _offsetVA.ry() += dy; repaint (); return; } int shift = ( ( _offsetVA.ry() + dy ) / _stripWidth ) * _stripWidth; _displayArea.translate ( 0, - (DbU::Unit)( shift / getScale() ) ); _offsetVA.ry() += dy - shift; if ( shift >= _drawingPlanes.height() ) _redrawManager.refresh (); else { _drawingPlanes.shiftDown ( shift ); _redraw ( QRect ( QPoint (0,_drawingPlanes.height()-shift) , QSize (_drawingPlanes.width(), shift) ) ); } assert ( _offsetVA.ry() >= 0 ); } void CellWidget::_refresh () { _redraw ( QRect(QPoint(0,0),_drawingPlanes.size()) ); } void CellWidget::showEvent ( QShowEvent* ) { //cerr << "CellWidget::showEvent() - size: " << geometry().width() << "x" << geometry().height() << endl; if ( _cellChanged ) fitToContents ( false ); } void CellWidget::paintEvent ( QPaintEvent* event ) { // static Timer timer; // static time_t prevTime = 0; // static time_t currTime = 0; // timer.start (); _drawingPlanes.pushWorkingPlane (); _drawingPlanes.select ( PlaneId::Widget ); _drawingPlanes.begin (); _drawingPlanes.copyToScreen (); for ( size_t i=0 ; i<_commands.size() ; i++ ) _commands[i]->draw (); if ( isDrawable("spot") ) _spot.moveTo ( _mousePosition ); _drawingPlanes.end (); _drawingPlanes.popWorkingPlane (); // timer.stop (); // time ( &currTime ); // double delta = difftime ( currTime, prevTime ); // if ( delta ) // cerr << "CellWidget::paintEvent() - lagging: " << delta << endl; // prevTime = currTime; } void CellWidget::resizeEvent ( QResizeEvent* ) { // cerr << "CellWidget::resizeEvent() - size: " << geometry().width() << "x" << geometry().height() << endl; QSize uaDelta ( 0, 0 ); QSize uaSize = geometry().size(); uaSize.rwidth () += 2*_stripWidth; uaSize.rheight() += 2*_stripWidth; if ( uaSize.width () > _drawingPlanes.width () ) uaDelta.rwidth () = uaSize.width () - _drawingPlanes.width (); if ( uaSize.height() > _drawingPlanes.height() ) uaDelta.rheight() = uaSize.height() - _drawingPlanes.height(); if ( uaDelta.width() || uaDelta.height() ) { _displayArea.inflate ( 0, 0, (DbU::Unit)(uaDelta.width()/getScale()), (DbU::Unit)(uaDelta.height()/getScale()) ); _visibleArea.inflate ( 0, 0, (DbU::Unit)(uaDelta.width()/getScale()), (DbU::Unit)(uaDelta.height()/getScale()) ); QSize bufferSize ( ( ( uaSize.width () / _stripWidth ) + 1 ) * _stripWidth , ( ( uaSize.height() / _stripWidth ) + 1 ) * _stripWidth ); _drawingPlanes.resize ( bufferSize ); } _redrawManager.refresh (); } void CellWidget::wheelEvent ( QWheelEvent* event ) { event->ignore (); for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; _commands[i]->wheelEvent ( event ); } } void CellWidget::keyPressEvent ( QKeyEvent* event ) { event->ignore (); //cerr << "CellWidget::keyPressEvent " << event->isAccepted() << endl; for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; //cerr << " Calling [" << i << "] " << _commands[i]->getName() << endl; _commands[i]->keyPressEvent ( event ); } } void CellWidget::keyReleaseEvent ( QKeyEvent* event ) { event->ignore (); //cerr << "CellWidget::keyReleaseEvent " << event->isAccepted() << endl; for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; //cerr << " Calling [" << i << "] " << _commands[i]->getName() << endl; _commands[i]->keyReleaseEvent ( event ); } } void CellWidget::mouseMoveEvent ( QMouseEvent* event ) { event->ignore (); for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; _commands[i]->mouseMoveEvent ( event ); } _mousePosition = event->pos(); updateMousePosition (); repaint (); } void CellWidget::mousePressEvent ( QMouseEvent* event ) { event->ignore (); //cerr << "CellWidget::mousePressEvent " << event->isAccepted() << endl; for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; //cerr << " Calling [" << i << "] " << _commands[i]->getName() << endl; _commands[i]->mousePressEvent ( event ); } _spot.setShowSpot ( !_activeCommand ); } void CellWidget::mouseReleaseEvent ( QMouseEvent* event ) { event->ignore (); //cerr << "CellWidget::mouseReleaseEvent " << event->isAccepted() << endl; for ( size_t i=0 ; (i<_commands.size()) and not event->isAccepted(); i++ ) { if ( _activeCommand and (_commands[i] != _activeCommand ) and (_commands[i]->getType() != Command::AlwaysActive) ) continue; //cerr << " Calling [" << i << "] " << _commands[i]->getName() << endl; _commands[i]->mouseReleaseEvent ( event ); } //if ( not _activeCommand ) QWidget::mouseReleaseEvent ( event ); _spot.setShowSpot ( true ); } QPoint CellWidget::dbuToDisplayPoint ( DbU::Unit x, DbU::Unit y ) const { return QPoint ( dbuToDisplayX(x), dbuToDisplayY(y) ); } QPoint CellWidget::dbuToDisplayPoint ( const Point& point ) const { return dbuToDisplayPoint ( point.getX(), point.getY() ); } QRect CellWidget::dbuToDisplayRect ( DbU::Unit x1, DbU::Unit y1, DbU::Unit x2, DbU::Unit y2, bool usePoint ) const { int width, height; if ( usePoint ) { width = dbuToDisplayX(x2) - dbuToDisplayX(x1); height = dbuToDisplayY(y1) - dbuToDisplayY(y2); } else { width = dbuToDisplayLength ( x2 - x1 ); height = dbuToDisplayLength ( y2 - y1 ); } return QRect ( dbuToDisplayX(x1) , dbuToDisplayY(y2) , width ? width : 1 , height ? height : 1 ); } QRect CellWidget::dbuToDisplayRect ( const Box& box, bool usePoint ) const { return dbuToDisplayRect ( box.getXMin() , box.getYMin() , box.getXMax() , box.getYMax() , usePoint ); } QPoint CellWidget::dbuToScreenPoint ( DbU::Unit x, DbU::Unit y ) const { return QPoint ( dbuToScreenX(x), dbuToScreenY(y) ); } void CellWidget::setCell ( Cell* cell ) { //cerr << "CellWidget::setCell() - " << cell << endl; if ( cell == getCell() ) return; openRefreshSession (); shared_ptr state ( new State(cell) ); setState ( state ); if ( cell and cell->isTerminal() ) setQueryFilter ( ~0 ); //setRealMode (); fitToContents ( false ); _state->setHistoryEnable ( true ); closeRefreshSession (); } void CellWidget::setState ( shared_ptr& state ) { //cerr << "CellWidget::setState() - " << state->getName() << endl; if ( state == _state ) return; openRefreshSession (); cellPreModificate (); _state->getSelection ().clear (); _state->setCellWidget ( NULL ); _state->setTopLeft ( getTopLeft() ); _cellChanged = true; _state = state; // cerr << " about to restore " << (void*)_state.get() // << " " << _state->getName() // << ": _state->setTopLeft(" // << DbU::getValueString(_state->getTopLeft().getX()) << "," // << DbU::getValueString(_state->getTopLeft().getY()) << ")" << endl; _state->setHistoryEnable ( false ); _state->setCellWidget ( this ); _drawingQuery .setCell ( getCell() ); _drawingQuery .setStartLevel ( _state->getStartLevel() ); _drawingQuery .setStopLevel ( _state->getStopLevel() ); _textDrawingQuery.setCell ( getCell() ); reframe (); _state->setHistoryEnable ( true ); emit cellChanged ( getCell() ); emit stateChanged ( _state ); emit queryFilterChanged (); cellPostModificate (); closeRefreshSession (); } Occurrences CellWidget::getOccurrencesUnder ( const Box& area ) const { return getCell()->getOccurrencesUnder(area,3).getSubSet(Occurrences_IsSelectable(this)); } void CellWidget::select ( const Net* net ) { ++_delaySelectionChanged; bool added = _state->getSelection().add ( net ); if ( !--_delaySelectionChanged && added ) emit selectionChanged(_selectors); } bool CellWidget::isSelected ( Occurrence occurrence ) { if ( !occurrence.isValid() ) throw Error ( "Can't select occurrence : invalid occurrence" ); if ( occurrence.getOwnerCell() != getCell() ) { string s1 = Graphics::toHtml ( getString(occurrence.getOwnerCell()) ); string s2 = Graphics::toHtml ( getString(getCell()) ); 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 ) return false; Selector* selector = dynamic_cast(property); if ( !selector ) throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); return selector->isAttachedTo(this); } void CellWidget::select ( Occurrence occurrence ) { if ( !occurrence.isValid() ) throw Error ( "Can't select occurrence : invalid occurrence" ); if ( occurrence.getOwnerCell() != getCell() ) { string s1 = Graphics::toHtml ( getString(occurrence.getOwnerCell()) ); string s2 = Graphics::toHtml ( getString(getCell()) ); throw Error ( "Can't select occurrence : incompatible occurrence %s vs. %s" , s1.c_str(), s2.c_str() ); } Property* property = occurrence.getProperty ( Selector::getPropertyName() ); Selector* selector = NULL; if ( !property ) selector = Selector::create ( occurrence ); else { selector = dynamic_cast(property); if ( !selector ) throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); } selector->attachTo(this); setShowSelection ( true ); _selectionHasChanged = true; if ( !_delaySelectionChanged ) emit selectionChanged(_selectors); } void CellWidget::selectOccurrencesUnder ( Box selectArea ) { ++_delaySelectionChanged; if ( !_state->cumulativeSelection() ) { openRefreshSession (); unselectAll (); closeRefreshSession (); } bool added = _state->getSelection().add ( selectArea ); if ( !--_delaySelectionChanged && added ) emit selectionChanged(_selectors); } void CellWidget::unselect ( const Net* net ) { ++_delaySelectionChanged; bool removed = _state->getSelection().remove ( net ); if ( !--_delaySelectionChanged && removed ) emit selectionChanged(_selectors); } void CellWidget::unselect ( Occurrence occurrence ) { if ( !occurrence.isValid() ) throw Error ( "Can't unselect occurrence : invalid occurrence" ); if ( occurrence.getOwnerCell() != getCell() ) throw Error ( "Can't unselect occurrence : incompatible occurrence" ); Property* property = occurrence.getProperty ( Selector::getPropertyName() ); if ( property ) { Selector* selector = dynamic_cast(property); if ( !selector ) throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); selector->detachFrom(this); } _selectionHasChanged = true; if ( !_delaySelectionChanged ) emit selectionChanged(_selectors); } void CellWidget::unselectAll () { ++_delaySelectionChanged; _state->getSelection().clear (); _unselectAll (); if ( !--_delaySelectionChanged ) emit selectionChanged(_selectors); } void CellWidget::toggleSelection ( Occurrence occurrence ) { if ( !occurrence.isValid() ) throw Error ( "Can't select occurrence : invalid occurrence" ); if ( occurrence.getOwnerCell() != getCell() ) throw Error ( "Can't select occurrence : incompatible occurrence" ); Property* property = occurrence.getProperty ( Selector::getPropertyName() ); Selector* selector = NULL; if ( !property ) { // Net special case. Net* net = dynamic_cast(occurrence.getEntity()); if ( net ) { if ( occurrence.getPath().isEmpty() ) { select ( net ); } else { cerr << "[UNIMPLEMENTED] Selection of " << occurrence << endl; } } else { selector = Selector::create ( occurrence ); selector->attachTo ( this ); setShowSelection ( true ); } } else { selector = dynamic_cast(property); if ( !selector ) throw Error ( "Abnormal property named " + getString(Selector::getPropertyName()) ); // Net special case. Net* net = dynamic_cast(occurrence.getEntity()); if ( net ) { if ( occurrence.getPath().isEmpty() ) { unselect ( net ); } else { cerr << "[UNIMPLEMENTED] Selection of " << occurrence << endl; } } else { selector->detachFrom ( this ); } } _selectionHasChanged = true; if ( _state->showSelection() ) _redrawManager.refresh (); emit selectionToggled ( occurrence ); } void CellWidget::_select ( const Net* net ) { select ( Occurrence(net) ); forEach ( Component*, component, net->getComponents() ) { Occurrence occurrence ( *component ); select ( occurrence ); } forEach ( Rubber*, rubber, net->getRubbers() ) { Occurrence occurrence ( *rubber ); select ( occurrence ); } if ( _state->showSelection() ) _redrawManager.refresh (); } void CellWidget::_unselect ( const Net* net ) { unselect ( Occurrence(net) ); forEach ( Component*, component, net->getComponents() ) { Occurrence occurrence ( *component ); unselect ( occurrence ); } forEach ( Rubber*, rubber, net->getRubbers() ) { Occurrence occurrence ( *rubber ); unselect ( occurrence ); } if ( _state->showSelection() ) _redrawManager.refresh (); } void CellWidget::_selectOccurrencesUnder ( Box selectArea ) { forEach ( Occurrence, ioccurrence, getOccurrencesUnder(selectArea) ) select ( *ioccurrence ); } void CellWidget::_unselectAll () { SelectorSet::iterator iselector; while ( !_selectors.empty() ) (*_selectors.begin())->detachFrom ( this ); if ( !_selectionHasChanged ) _selectionHasChanged = true; if ( _state->showSelection() ) _redrawManager.refresh (); } void CellWidget::cellPreModificate () { openRefreshSession (); _unselectAll (); emit selectionChanged(_selectors); emit cellPreModificated (); closeRefreshSession (); } void CellWidget::cellPostModificate () { openRefreshSession (); _cellModificated = true; ++_delaySelectionChanged; _state->getSelection().revalidate (); updatePalette (); _redrawManager.refresh (); --_delaySelectionChanged; emit selectionChanged(_selectors); emit cellPostModificated (); closeRefreshSession (); } } // End of Hurricane namespace.