496 lines
14 KiB
C++
496 lines
14 KiB
C++
|
|
// -*- C++ -*-
|
|
//
|
|
// This file is part of the Coriolis Software.
|
|
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
|
|
//
|
|
// ===================================================================
|
|
//
|
|
// $Id$
|
|
//
|
|
// x-----------------------------------------------------------------x
|
|
// | |
|
|
// | H U R R I C A N E |
|
|
// | 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 : "./PaletteWidget.cpp" |
|
|
// | *************************************************************** |
|
|
// | U p d a t e s |
|
|
// | |
|
|
// x-----------------------------------------------------------------x
|
|
|
|
|
|
#include <limits>
|
|
|
|
#include <QLabel>
|
|
#include <QCheckBox>
|
|
#include <QPushButton>
|
|
#include <QHBoxLayout>
|
|
#include <QVBoxLayout>
|
|
#include <QGridLayout>
|
|
|
|
#include "hurricane/DataBase.h"
|
|
#include "hurricane/Technology.h"
|
|
#include "hurricane/BasicLayer.h"
|
|
#include "hurricane/BasicLayers.h"
|
|
#include "hurricane/ExtensionSlice.h"
|
|
#include "hurricane/Cell.h"
|
|
|
|
#include "hurricane/viewer/Graphics.h"
|
|
#include "hurricane/viewer/PaletteItem.h"
|
|
#include "hurricane/viewer/PaletteNamedItem.h"
|
|
#include "hurricane/viewer/PaletteLayerItem.h"
|
|
#include "hurricane/viewer/PaletteExtensionGoItem.h"
|
|
#include "hurricane/viewer/PaletteWidget.h"
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
using namespace std;
|
|
using namespace Hurricane;
|
|
|
|
|
|
class GridBuffer {
|
|
public:
|
|
GridBuffer ( QGridLayout*, size_t rowMax, size_t startRow=0, size_t startColumn=0 );
|
|
inline int getRow () const;
|
|
inline int getColumn () const;
|
|
inline int getCurrentRow () const;
|
|
void addSection ( QWidget*, Qt::Alignment align=0 );
|
|
void addWidget ( QWidget*, Qt::Alignment align=0 );
|
|
void newColumn ();
|
|
void flushWidgets ();
|
|
inline bool columnOverload () const;
|
|
protected:
|
|
QGridLayout* _grid;
|
|
size_t _rowMax;
|
|
size_t _row;
|
|
size_t _column;
|
|
vector<QWidget*> _widgets;
|
|
vector<Qt::Alignment> _aligns;
|
|
};
|
|
|
|
|
|
GridBuffer::GridBuffer ( QGridLayout* grid, size_t maxRow, size_t startRow, size_t startColumn )
|
|
: _grid (grid)
|
|
, _rowMax (maxRow)
|
|
, _row (startRow)
|
|
, _column (startColumn)
|
|
, _widgets()
|
|
, _aligns ()
|
|
{ }
|
|
|
|
|
|
inline int GridBuffer::getRow () const { return _row; }
|
|
inline int GridBuffer::getColumn () const { return _column; }
|
|
inline int GridBuffer::getCurrentRow () const { return _widgets.size() + _row; }
|
|
inline bool GridBuffer::columnOverload () const { return getCurrentRow() > (int)_rowMax; }
|
|
|
|
|
|
void GridBuffer::flushWidgets ()
|
|
{
|
|
if ( columnOverload() ) {
|
|
_column++;
|
|
_row = 0;
|
|
}
|
|
|
|
for ( size_t i=0 ; i < _widgets.size() ; ++i )
|
|
_grid->addWidget ( _widgets[i], _row++, _column, _aligns[i] );
|
|
_widgets.clear ();
|
|
_aligns.clear ();
|
|
}
|
|
|
|
|
|
void GridBuffer::newColumn ()
|
|
{
|
|
if ( columnOverload() ) return;
|
|
|
|
flushWidgets ();
|
|
_column++;
|
|
_row = 0;
|
|
}
|
|
|
|
|
|
void GridBuffer::addWidget ( QWidget* widget, Qt::Alignment align )
|
|
{
|
|
_widgets.push_back ( widget );
|
|
_aligns .push_back ( align );
|
|
}
|
|
|
|
|
|
void GridBuffer::addSection ( QWidget* widget, Qt::Alignment align )
|
|
{
|
|
flushWidgets ();
|
|
_widgets.push_back ( widget );
|
|
_aligns .push_back ( align );
|
|
}
|
|
|
|
|
|
} // End of anonymous namespace.
|
|
|
|
|
|
namespace Hurricane {
|
|
|
|
|
|
QWidget* PaletteWidget::_createGroupItem ( const Name& name )
|
|
{
|
|
QLabel* groupLabel = new QLabel ();
|
|
groupLabel->setText ( getString(name).c_str() );
|
|
groupLabel->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) );
|
|
return groupLabel;
|
|
}
|
|
|
|
|
|
PaletteNamedItem* PaletteWidget::_createNamedItem ( const Name& name, bool checked )
|
|
{
|
|
PaletteNamedItem* item = PaletteNamedItem::create ( name, checked );
|
|
connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) );
|
|
return item;
|
|
}
|
|
|
|
|
|
PaletteLayerItem* PaletteWidget::_createLayerItem ( BasicLayer* layer, bool checked )
|
|
{
|
|
PaletteLayerItem* item = PaletteLayerItem::create ( layer, checked );
|
|
connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) );
|
|
return item;
|
|
}
|
|
|
|
|
|
PaletteExtensionGoItem* PaletteWidget::_createExtensionGoItem ( const Name& name, bool checked )
|
|
{
|
|
PaletteExtensionGoItem* item = PaletteExtensionGoItem::create ( name );
|
|
connect ( item, SIGNAL(visibleToggled()), this, SIGNAL(paletteChanged()) );
|
|
return item;
|
|
}
|
|
|
|
|
|
PaletteWidget::PaletteWidget ( QWidget* parent )
|
|
: QWidget (parent)
|
|
, _scrollArea (new QScrollArea(this))
|
|
, _layerItems ()
|
|
, _extensionGoItems()
|
|
, _showAll (new QPushButton(_scrollArea))
|
|
, _hideAll (new QPushButton(_scrollArea))
|
|
, _grid (new QGridLayout())
|
|
, _columnHeight (22)
|
|
, _extensionRow (0)
|
|
, _extensionColumn (0)
|
|
, _extensionGroup (NULL)
|
|
{
|
|
setContentsMargins ( 0, 0, 0, 0 );
|
|
_scrollArea->setWidgetResizable ( true );
|
|
QVBoxLayout* vLayout = new QVBoxLayout ();
|
|
QHBoxLayout* hLayout = new QHBoxLayout ();
|
|
|
|
_showAll->setIcon ( QIcon(":/images/palette_show_all.png") );
|
|
_showAll->setFlat ( true );
|
|
|
|
_hideAll->setIcon ( QIcon(":/images/palette_hide_all.png") );
|
|
_hideAll->setFlat ( true );
|
|
|
|
connect ( _showAll, SIGNAL(clicked()), this, SLOT(showAll()) );
|
|
connect ( _hideAll, SIGNAL(clicked()), this, SLOT(hideAll()) );
|
|
|
|
hLayout->addStretch ();
|
|
hLayout->addWidget ( _showAll );
|
|
hLayout->addStretch ();
|
|
hLayout->addWidget ( _hideAll );
|
|
hLayout->addStretch ();
|
|
|
|
QFrame* separator = new QFrame ();
|
|
separator->setFrameShape ( QFrame::HLine );
|
|
separator->setFrameShadow ( QFrame::Sunken );
|
|
|
|
vLayout->setSpacing ( 0 );
|
|
vLayout->addLayout ( hLayout );
|
|
vLayout->addWidget ( separator );
|
|
vLayout->addSpacing ( 5 );
|
|
vLayout->addLayout ( _grid );
|
|
|
|
_grid->setHorizontalSpacing ( 10 );
|
|
_grid->setVerticalSpacing ( 0 );
|
|
//_grid->setSizeConstraint ( QLayout::SetFixedSize );
|
|
|
|
vLayout->addStretch ();
|
|
|
|
QWidget* scrollAdaptator = new QWidget ();
|
|
scrollAdaptator->setLayout ( vLayout );
|
|
_scrollArea->setContentsMargins ( 0, 0, 0, 0 );
|
|
_scrollArea->setWidget ( scrollAdaptator );
|
|
_scrollArea->setHorizontalScrollBarPolicy ( Qt::ScrollBarAsNeeded );
|
|
_scrollArea->setVerticalScrollBarPolicy ( Qt::ScrollBarAsNeeded );
|
|
_scrollArea->setFrameStyle ( QFrame::Plain );
|
|
|
|
vLayout = new QVBoxLayout ();
|
|
vLayout->setSpacing ( 0 );
|
|
vLayout->addWidget ( _scrollArea );
|
|
|
|
setLayout ( vLayout );
|
|
}
|
|
|
|
|
|
void PaletteWidget::build ()
|
|
{
|
|
GridBuffer gridBuffer ( _grid, _columnHeight );
|
|
|
|
size_t gi = 0;
|
|
const vector<DrawingGroup*>& groups = Graphics::getStyle()->getDrawingGroups();
|
|
const vector<DrawingStyle*>& styles = groups[gi]->getDrawingStyles();
|
|
|
|
gridBuffer.addSection ( _createGroupItem(groups[gi]->getName()), Qt::AlignHCenter );
|
|
for ( size_t si=0 ; si<styles.size() ; si++ ) {
|
|
if ( not styles[si]->isGoMatched() ) continue;
|
|
if ( styles[si]->getName() == DisplayStyle::Foreground ) continue;
|
|
if ( styles[si]->getName() == DisplayStyle::Background ) continue;
|
|
if ( styles[si]->getName() == DisplayStyle::SelectionDraw ) continue;
|
|
if ( styles[si]->getName() == DisplayStyle::SelectionFill ) continue;
|
|
|
|
PaletteNamedItem* item = _createNamedItem ( styles[si]->getName() );
|
|
gridBuffer.addWidget ( item );
|
|
_layerItems [ item->getName() ] = item;
|
|
}
|
|
if ( _columnHeight < numeric_limits<size_t>::max() )
|
|
gridBuffer.newColumn ();
|
|
else
|
|
gridBuffer.flushWidgets ();
|
|
|
|
DataBase* database = DataBase::getDB();
|
|
if ( database ) {
|
|
Technology* technology = database->getTechnology();
|
|
if ( technology ) {
|
|
for ( gi=1 ; gi<groups.size() ; gi++ ) {
|
|
gridBuffer.addSection ( _createGroupItem(groups[gi]->getName()), Qt::AlignHCenter );
|
|
|
|
const vector<DrawingStyle*>& styles = groups[gi]->getDrawingStyles();
|
|
for ( size_t si=0 ; si<styles.size() ; si++ ) {
|
|
BasicLayer* basicLayer = technology->getBasicLayer ( styles[si]->getName() );
|
|
|
|
if ( basicLayer ) {
|
|
PaletteLayerItem* item = _createLayerItem ( basicLayer );
|
|
gridBuffer.addWidget ( item );
|
|
_layerItems [ item->getName() ] = item;
|
|
}
|
|
}
|
|
}
|
|
size_t si = 0;
|
|
forEach ( BasicLayer*, basicLayer, technology->getBasicLayers() ) {
|
|
if ( !find((*basicLayer)->getName()) ) {
|
|
if ( !si )
|
|
gridBuffer.addSection ( _createGroupItem("Unmatcheds"), Qt::AlignHCenter );
|
|
|
|
PaletteLayerItem* item = _createLayerItem ( *basicLayer );
|
|
gridBuffer.addWidget ( item );
|
|
_layerItems [ item->getName() ] = item;
|
|
|
|
cerr << "[WARNING] BasicLayer \"" << (*basicLayer)->getName()
|
|
<< "\" has no associated DisplayStyle." << endl;
|
|
|
|
si++;
|
|
}
|
|
}
|
|
if ( si ) gi++;
|
|
}
|
|
}
|
|
|
|
if ( _columnHeight < numeric_limits<size_t>::max() )
|
|
gridBuffer.newColumn ();
|
|
else
|
|
gridBuffer.flushWidgets ();
|
|
|
|
_extensionRow = gridBuffer.getRow();
|
|
_extensionColumn = gridBuffer.getColumn();
|
|
_extensionGroup = _createGroupItem ( "Extensions" );
|
|
gridBuffer.addSection ( _extensionGroup, Qt::AlignHCenter );
|
|
gridBuffer.flushWidgets ();
|
|
}
|
|
|
|
|
|
void PaletteWidget::updateExtensions ( Cell* cell )
|
|
{
|
|
_grid->removeWidget ( _extensionGroup );
|
|
_extensionGroup->deleteLater ();
|
|
_extensionGroup = NULL;
|
|
|
|
PaletteItems::iterator iextension = _extensionGoItems.begin();
|
|
for ( ; iextension != _extensionGoItems.end() ; ++iextension ) {
|
|
_grid->removeWidget ( iextension->second );
|
|
iextension->second->deleteLater ();
|
|
}
|
|
_extensionGoItems.clear ();
|
|
|
|
|
|
GridBuffer gridBuffer ( _grid, _columnHeight, _extensionRow, _extensionColumn );
|
|
_extensionGroup = _createGroupItem ( "Extensions" );
|
|
gridBuffer.addSection ( _extensionGroup, Qt::AlignHCenter );
|
|
|
|
if ( cell ) {
|
|
forEach ( ExtensionSlice*, extension, cell->getExtensionSlices() ) {
|
|
PaletteExtensionGoItem* item = _createExtensionGoItem ( (*extension)->getName(), false );
|
|
gridBuffer.addWidget ( item );
|
|
_extensionGoItems [ item->getName() ] = item;
|
|
}
|
|
}
|
|
gridBuffer.flushWidgets ();
|
|
}
|
|
|
|
|
|
void PaletteWidget::_getSection ( const QString section, QLabel*& label, vector<PaletteItem*>& items ) const
|
|
{
|
|
label = NULL;
|
|
items.clear ();
|
|
|
|
bool found = false;
|
|
for ( int index=0 ; index < _grid->count() ; index++ ) {
|
|
QLayoutItem* item = _grid->itemAt ( index );
|
|
if ( !item ) continue;
|
|
|
|
QLabel* ilabel = dynamic_cast<QLabel*>(item->widget());
|
|
if ( ilabel ) {
|
|
if ( found ) break;
|
|
if ( ilabel->text() != section ) continue;
|
|
found = true;
|
|
|
|
label = ilabel;
|
|
} else if ( found ) {
|
|
PaletteItem* paletteItem = dynamic_cast<PaletteItem*>(item->widget());
|
|
if ( paletteItem ) items.push_back ( paletteItem );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void PaletteWidget::setSectionVisible ( const QString section, bool visible )
|
|
{
|
|
QLabel* label;
|
|
vector<PaletteItem*> items;
|
|
|
|
_getSection ( section, label, items );
|
|
if ( !label ) return;
|
|
|
|
if ( visible ) label->show ();
|
|
else label->hide ();
|
|
|
|
for ( size_t i=0 ; i<items.size() ; ++i ) {
|
|
if ( visible ) items[i]->show ();
|
|
else items[i]->hide ();
|
|
}
|
|
}
|
|
|
|
|
|
bool PaletteWidget::isDrawable ( const Name& name ) const
|
|
{
|
|
PaletteItem* item = find ( name );
|
|
if ( item )
|
|
return item->isItemVisible ();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
bool PaletteWidget::isSelectable ( const Name& name ) const
|
|
{
|
|
PaletteItem* item = find ( name );
|
|
if ( item )
|
|
return item->isItemSelectable ();
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void PaletteWidget::showAll ()
|
|
{
|
|
PaletteItems::iterator iitem = _layerItems.begin();
|
|
for ( ; iitem != _layerItems.end() ; iitem++ )
|
|
iitem->second->setItemVisible ( true );
|
|
|
|
iitem = _extensionGoItems.begin();
|
|
for ( ; iitem != _extensionGoItems.end() ; iitem++ )
|
|
iitem->second->setItemVisible ( true );
|
|
|
|
emit paletteChanged();
|
|
}
|
|
|
|
|
|
void PaletteWidget::hideAll ()
|
|
{
|
|
PaletteItems::iterator iitem = _layerItems.begin();
|
|
for ( ; iitem != _layerItems.end() ; iitem++ )
|
|
iitem->second->setItemVisible ( false );
|
|
|
|
iitem = _extensionGoItems.begin();
|
|
for ( ; iitem != _extensionGoItems.end() ; iitem++ )
|
|
iitem->second->setItemVisible ( false );
|
|
|
|
emit paletteChanged();
|
|
}
|
|
|
|
|
|
void PaletteWidget::showSection ( const QString section )
|
|
{
|
|
QLabel* label;
|
|
vector<PaletteItem*> items;
|
|
|
|
_getSection ( section, label, items );
|
|
if ( !label ) return;
|
|
|
|
for ( size_t i=0 ; i<items.size() ; ++i )
|
|
items[i]->setItemVisible ( true );
|
|
}
|
|
|
|
|
|
void PaletteWidget::hideSection ( const QString section )
|
|
{
|
|
QLabel* label;
|
|
vector<PaletteItem*> items;
|
|
|
|
_getSection ( section, label, items );
|
|
if ( !label ) return;
|
|
|
|
for ( size_t i=0 ; i<items.size() ; ++i )
|
|
items[i]->setItemVisible ( false );
|
|
}
|
|
|
|
|
|
PaletteItem* PaletteWidget::find ( const Name& name ) const
|
|
{
|
|
PaletteItems::const_iterator iitem = _layerItems.find(name);
|
|
if ( iitem != _layerItems.end() )
|
|
return iitem->second;
|
|
|
|
iitem = _extensionGoItems.find(name);
|
|
if ( iitem != _extensionGoItems.end() )
|
|
return iitem->second;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void PaletteWidget::setItemVisible ( const Name& name, bool visible )
|
|
{
|
|
PaletteItem* item = find ( name );
|
|
if ( item ) {
|
|
item->setItemVisible ( visible );
|
|
emit paletteChanged();
|
|
}
|
|
}
|
|
|
|
|
|
void PaletteWidget::changeStyle ()
|
|
{
|
|
PaletteItems::iterator iitem = _layerItems.begin();
|
|
for ( ; iitem != _layerItems.end() ; iitem++ )
|
|
iitem->second->changeStyle ();
|
|
|
|
iitem = _extensionGoItems.begin();
|
|
for ( ; iitem != _extensionGoItems.end() ; iitem++ )
|
|
iitem->second->changeStyle ();
|
|
}
|
|
|
|
|
|
} // End of Hurricane namespace.
|