coriolis/hurricane/src/viewer/ControllerWidget.cpp

562 lines
17 KiB
C++
Raw Normal View History

// -*- C++ -*-
//
// This file is part of the Coriolis Software.
2012-12-31 05:52:42 -06:00
// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
//
2012-12-31 05:52:42 -06:00
// +-----------------------------------------------------------------+
// | 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 : "./ControllerWidget.cpp" |
2012-12-31 05:52:42 -06:00
// +-----------------------------------------------------------------+
#include <QAction>
#include <QFrame>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QCheckBox>
#include <QComboBox>
#include <vlsisapd/configuration/Configuration.h>
#include <vlsisapd/configuration/ConfigurationWidget.h>
#include <hurricane/DataBase.h>
#include <hurricane/Cell.h>
#include <hurricane/viewer/Graphics.h>
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/GraphicsWidget.h>
#include <hurricane/viewer/PaletteWidget.h>
#include <hurricane/viewer/DisplayFilterWidget.h>
#include <hurricane/viewer/NetlistWidget.h>
#include <hurricane/viewer/SelectionWidget.h>
#include <hurricane/viewer/InspectorWidget.h>
#include <hurricane/viewer/ControllerWidget.h>
namespace Hurricane {
using Cfg::Configuration;
// -------------------------------------------------------------------
// Class : "Hurricane::ControllerTab".
ControllerTab::ControllerTab ( QWidget* parent )
: QWidget(parent)
, _cellWidget(NULL)
{ }
void ControllerTab::setCellWidget ( CellWidget* cellWidget )
{
_cellWidget = cellWidget;
}
void ControllerTab::setCell ( Cell* )
{ }
void ControllerTab::updateTab ()
{ }
void ControllerTab::cellPreModificate ()
{ }
void ControllerTab::cellPostModificate ()
{ }
// -------------------------------------------------------------------
// Class : "Hurricane::TabGraphics".
TabGraphics::TabGraphics ( QWidget* parent )
: ControllerTab(parent)
, _graphics (new GraphicsWidget())
{
_graphics->setObjectName ( "controller.tabGraphics.graphics" );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 0, 0, 0, 0 );
wLayout->addWidget ( _graphics );
setLayout ( wLayout );
}
void TabGraphics::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget ( cellWidget );
_graphics->setCellWidget ( cellWidget );
}
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabDisplayFilter".
TabDisplayFilter::TabDisplayFilter ( QWidget* parent )
: ControllerTab (parent)
, _displayFilter(new DisplayFilterWidget())
{
* ./hurricane/src/hurricane : - New feature : remove Hurricane's original basic Timer and replace it with the one from Coriolis/crlcore. Added ability to get the elapsed time without stopping the timer. * ./hurricane/src/hviewer : - New feature : complete redesign of the drawing refreshment loop. Now there's a "secondary" loop managed by the "RedrawManager" object which bufferize the redraw requests. The "_redraw()" function has been made interruptible at coarse level (between layer). Important note about the redrawing design : the QApplication::processEvents() function cannot be called inside the paintEvent() functions/sub-functions. So the drawing is separated from the paintEvent. The paintEvent() performs only quick pixmap buffer copy. The _redraw() is triggered by the move/refresh events bufferized by the RedrawManager, flush periodically the loop event and send direct (not posted) paint events (repaint() call). Another constraint is that the displayed Widget can only be painted during the paintEvent(). Otherwise the painter refuses to initialize. - Ergonomy : adopt more standard key/mouse bindings. No more CTRL key for zooming (too small zooms are rejecteds, thresold at 10x10 pixels). Continuous move is enabled with SPACE+mouse. * ./coriolis/src/unicorn : - Reorganisation : Unicorn is now supplied as a separate library. Due to a limitation of cmake the binary can no longer be named "unicorn" as it conflicts with the library name. So it's been renamed into unimain (better candidates?)
2008-12-20 10:56:05 -06:00
_displayFilter->setObjectName ( "controller.tabDisplayFilter.displayFilter" );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 0, 0, 0, 0 );
wLayout->addWidget ( _displayFilter );
setLayout ( wLayout );
}
void TabDisplayFilter::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget ( cellWidget );
_displayFilter->setCellWidget ( cellWidget );
}
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabPalette".
TabPalette::TabPalette ( QWidget* parent )
: ControllerTab(parent)
, _palette (new PaletteWidget())
{
//_palette->setOneColumn ();
_palette->setObjectName ( "controller.tabPalette.palette" );
_palette->build ();
//_palette->setSectionVisible ( "Viewer", false );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 0, 0, 0, 0 );
wLayout->addWidget ( _palette );
setLayout ( wLayout );
}
void TabPalette::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() )
getCellWidget()->detachFromPalette ();
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget ( cellWidget );
if ( getCellWidget() ) {
getCellWidget()->bindToPalette ( _palette );
}
}
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabNetlist".
TabNetlist::TabNetlist ( QWidget* parent )
: ControllerTab (parent)
, _netlistBrowser (new NetlistWidget())
, _syncNetlist (new QCheckBox())
, _syncSelection (new QCheckBox())
, _cwCumulativeSelection(false)
{
_netlistBrowser->setObjectName ( "controller.tabNetlist.netlistBrowser" );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 10, 0, 10, 0 );
wLayout->setSpacing ( 0 );
_syncNetlist->setText ( tr("Sync Netlist") );
_syncNetlist->setChecked ( false );
_syncNetlist->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) );
connect ( _syncNetlist, SIGNAL(toggled(bool)), this, SLOT(setSyncNetlist(bool)) );
_syncSelection->setText ( tr("Sync Selection") );
_syncSelection->setChecked ( false );
_syncSelection->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) );
connect ( _syncSelection, SIGNAL(toggled(bool)), this, SLOT(setSyncSelection(bool)) );
QHBoxLayout* commands = new QHBoxLayout ();
commands->setContentsMargins ( 0, 0, 0, 0 );
commands->addStretch ();
commands->addWidget ( _syncNetlist );
commands->addStretch ();
commands->addWidget ( _syncSelection );
commands->addStretch ();
wLayout->addLayout ( commands );
QFrame* separator = new QFrame ();
separator->setFrameShape ( QFrame::HLine );
separator->setFrameShadow ( QFrame::Sunken );
wLayout->addWidget ( separator );
wLayout->addWidget ( _netlistBrowser );
setLayout ( wLayout );
}
void TabNetlist::setSyncNetlist ( bool state )
{
if ( state and getCellWidget() ) {
_netlistBrowser->setCell<SimpleNetInformations> ( getCellWidget()->getCell() );
} else {
_netlistBrowser->setCell<SimpleNetInformations> ( NULL );
}
}
void TabNetlist::setSyncSelection ( bool state )
{
if ( state and getCellWidget() and _syncNetlist->isChecked() ) {
_cwCumulativeSelection = getCellWidget()->cumulativeSelection();
if ( not _cwCumulativeSelection ) {
* ./hurricane/src/hviewer : - Bug: correction of the bad keyPress event handling in InspectorWidget (had to press twice the key for the action to be transmitted). Uses an eventFilter() at InspectorWidget instead of a keyPressEvent() overload. The keyPress event is first received by the QTableView then transmitted to the upper level. The eventFilter allows the InspectorWidget to catch the event *before* it gets to QTableView (but let pass thoses it don't want). - Bug: idem for SeletionWidget. - Change: do not draw the rectangular area of AreaCommand until it is bigger than a given threshold (programmable). Affect ZoomCommand and SelectCommand. ZoomCommand no longer issue a warning when the zoom is to small. - New feature: fit to net in the NetlistWidget. Uses simple contextual menu, another way to avoid overloading keyPressEvent(). - Change: in Query, the filter has now it's own subtype: Query::Mask. - Change: enhancement for the "start" model of signal propagation, used to re-implement the DisplayFilterWidget. - Change: more clear policy for signal emission: a signal must be emitted by any "setter" method (setStartLevel(), setStopLevel(), ...). Has to be enforced for all setter (work in progress). - Change: re-implemenation of the delayed refresh mechanism. No more flags propaged througout the functions calls but a session mechanism instead. See CellWidget::openRefreshSession() & CellWidget::closeRefreshSession(). Nothing is actually drawn until the last session is closed. Session mechanism can be invoked by signals/slots, see NetlistWidget. - Change: less dangerous key mapping: 'z' : zoom in. 'm' : zoom out. 'CTRL+z' : previous zoom level. 'CTRL+m' : next zoom level. 'CTRL+Up' : back in hierarchy. 'CTRL+Down' : go down in hierarchy. 'SHIFT+Up' : back in hierarchy stack. 'SHIFT+Down' : go down in hierarchy stack.
2009-02-02 08:45:48 -06:00
getCellWidget()->openRefreshSession ();
getCellWidget()->unselectAll ();
getCellWidget()->closeRefreshSession ();
}
getCellWidget()->setShowSelection ( true );
connect ( _netlistBrowser, SIGNAL(netSelected (Occurrence)), getCellWidget(), SLOT(select (Occurrence)) );
connect ( _netlistBrowser, SIGNAL(netUnselected(Occurrence)), getCellWidget(), SLOT(unselect(Occurrence)) );
_netlistBrowser->updateSelecteds ();
} else {
getCellWidget()->setShowSelection ( false );
getCellWidget()->setCumulativeSelection ( _cwCumulativeSelection );
_netlistBrowser->disconnect ( getCellWidget(), SLOT(select (const Net*)) );
_netlistBrowser->disconnect ( getCellWidget(), SLOT(unselect(const Net*)) );
}
}
void TabNetlist::setCell ( Cell* cell )
{
setSyncNetlist ( _syncNetlist->isChecked() );
}
void TabNetlist::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget ( cellWidget );
_netlistBrowser->setCellWidget<SimpleNetInformations> ( cellWidget );
if ( getCellWidget() ) {
* ./hurricane/src/hurricane : - New feature : remove Hurricane's original basic Timer and replace it with the one from Coriolis/crlcore. Added ability to get the elapsed time without stopping the timer. * ./hurricane/src/hviewer : - New feature : complete redesign of the drawing refreshment loop. Now there's a "secondary" loop managed by the "RedrawManager" object which bufferize the redraw requests. The "_redraw()" function has been made interruptible at coarse level (between layer). Important note about the redrawing design : the QApplication::processEvents() function cannot be called inside the paintEvent() functions/sub-functions. So the drawing is separated from the paintEvent. The paintEvent() performs only quick pixmap buffer copy. The _redraw() is triggered by the move/refresh events bufferized by the RedrawManager, flush periodically the loop event and send direct (not posted) paint events (repaint() call). Another constraint is that the displayed Widget can only be painted during the paintEvent(). Otherwise the painter refuses to initialize. - Ergonomy : adopt more standard key/mouse bindings. No more CTRL key for zooming (too small zooms are rejecteds, thresold at 10x10 pixels). Continuous move is enabled with SPACE+mouse. * ./coriolis/src/unicorn : - Reorganisation : Unicorn is now supplied as a separate library. Due to a limitation of cmake the binary can no longer be named "unicorn" as it conflicts with the library name. So it's been renamed into unimain (better candidates?)
2008-12-20 10:56:05 -06:00
connect ( getCellWidget(), SIGNAL(cellChanged(Cell*)), this, SLOT(setCell(Cell*)) );
}
setSyncNetlist ( _syncNetlist->isChecked() );
}
}
void TabNetlist::cellPreModificate ()
{
_netlistBrowser->setCell<SimpleNetInformations> ( NULL );
}
void TabNetlist::cellPostModificate ()
{
setSyncNetlist ( _syncNetlist->isChecked() );
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabSelection".
TabSelection::TabSelection ( QWidget* parent )
: ControllerTab(parent)
, _selection (new SelectionWidget())
{
_selection->setObjectName ( "controller.tabSelection.selection" );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 10, 10, 10, 0 );
wLayout->addWidget ( _selection );
setLayout ( wLayout );
}
void TabSelection::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget ( cellWidget );
_selection->setCellWidget ( cellWidget );
}
}
void TabSelection::updateTab ()
{
// if ( _cellWidget && _cellWidget->getCell() )
// _selection->setSelection ( _cellWidget->getSelectorSet(), _cellWidget->getCell() );
// else
// _selection->setSelection ( set<Selector*>() );
}
void TabSelection::cellPreModificate ()
{
_selection->clear ();
}
void TabSelection::cellPostModificate ()
{
//updateTab ();
if ( getCellWidget() && getCellWidget()->getCell() ) {
_selection->setSelection ( getCellWidget()->getSelectorSet() );
} else
_selection->clear ();
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabInspector".
TabInspector::TabInspector ( QWidget* parent )
: ControllerTab (parent)
, _inspectorWidget (new InspectorWidget())
, _bookmarks (new QComboBox())
, _selectionOccurrence()
, _updateFromSelection(true)
{
_inspectorWidget->setObjectName ( "controller.tabInspector.inspectorWidget" );
connect ( _bookmarks, SIGNAL(currentIndexChanged(int)), this, SLOT(bookmarkChanged(int)) );
QVBoxLayout* wLayout = new QVBoxLayout ();
wLayout->setContentsMargins ( 10, 10, 10, 0 );
//wLayout->setSpacing ( 0 );
_bookmarks->addItem ( tr("<Disabled>" ) );
_bookmarks->addItem ( tr("<DataBase>" ) );
_bookmarks->addItem ( tr("<Cell None>") );
_bookmarks->addItem ( tr("<Selection>") );
QHBoxLayout* commands = new QHBoxLayout ();
commands->setContentsMargins ( 0, 0, 0, 0 );
commands->addStretch ();
commands->addWidget ( _bookmarks );
commands->addStretch ();
wLayout->addLayout ( commands );
QFrame* separator = new QFrame ();
separator->setFrameShape ( QFrame::HLine );
separator->setFrameShadow ( QFrame::Sunken );
wLayout->addWidget ( separator );
wLayout->addWidget ( _inspectorWidget );
setLayout ( wLayout );
}
void TabInspector::setCell ( Cell* cell )
{
_bookmarks->setItemText ( 2, getString(cell).c_str() );
if ( _bookmarks->currentIndex() == 2 )
emit bookmarkChanged ( 2 );
}
void TabInspector::setCellWidget ( CellWidget* cellWidget )
{
if ( getCellWidget() != cellWidget ) {
ControllerTab::setCellWidget( cellWidget );
if ( getCellWidget() ) {
connect ( getCellWidget(), SIGNAL(cellChanged(Cell*)), this, SLOT(setCell(Cell*)) );
}
}
}
void TabInspector::bookmarkChanged ( int index )
{
switch ( index ) {
case 0: _inspectorWidget->setRootRecord ( NULL ); break;
case 1: _inspectorWidget->setRootRecord ( getRecord(DataBase::getDB()) ); break;
case 2:
if ( getCellWidget() && getCellWidget()->getCell() )
_inspectorWidget->setRootRecord ( getRecord(getCellWidget()->getCell()) );
break;
case 3:
if ( getCellWidget() && getCellWidget()->getCell() )
_inspectorWidget->setRootRecord ( getRecord(_selectionOccurrence) );
break;
}
}
void TabInspector::updateTab ()
{
if ( _updateFromSelection && (_bookmarks->currentIndex() == 3) ) {
_inspectorWidget->setRootRecord ( getRecord(_selectionOccurrence) );
}
_updateFromSelection = false;
}
void TabInspector::setSelectionOccurrence ( Occurrence& occurrence )
{
_updateFromSelection = true;
_selectionOccurrence = occurrence;
}
void TabInspector::cellPreModificate ()
{
_selectionOccurrence = Occurrence();
if ( _bookmarks->currentIndex() > 1 )
_inspectorWidget->setRootRecord ( NULL );
}
void TabInspector::cellPostModificate ()
{
if ( ( _bookmarks->currentIndex() == 2 ) && getCellWidget() && getCellWidget()->getCell() )
_inspectorWidget->setRootRecord ( getRecord(getCellWidget()->getCell()) );
}
// -------------------------------------------------------------------
// Class : "Hurricane::TabSettings".
TabSettings::TabSettings ( QWidget* parent )
: ControllerTab (parent)
, _configuration(Configuration::get()->buildWidget(ConfigurationWidget::Embedded))
{
setContentsMargins ( 5, 0, 5, 5 );
_configuration->setObjectName ( "controller.tabSettings.settings" );
QVBoxLayout* vLayout = new QVBoxLayout ();
vLayout->setContentsMargins ( 0, 0, 0, 0 );
vLayout->addWidget ( _configuration );
setLayout ( vLayout );
}
void TabSettings::setCellWidget ( CellWidget* )
{ }
// TabSettings::TabSettings ( QWidget* parent )
// : ControllerTab(parent)
// , _settings(new QTabWidget())
// {
// setContentsMargins ( 5, 0, 5, 5 );
// _settings->setObjectName ( "controller.tabSettings.settings" );
// QVBoxLayout* vLayout = new QVBoxLayout ();
// vLayout->setContentsMargins ( 0, 0, 0, 0 );
// vLayout->addWidget ( _settings );
// setLayout ( vLayout );
// }
// -------------------------------------------------------------------
// Class : "Hurricane::ControllerWidget".
ControllerWidget::ControllerWidget ( QWidget* parent )
: QTabWidget (parent)
, _cellWidget (NULL)
, _tabGraphics (new TabGraphics())
, _tabPalette (new TabPalette())
, _tabDisplayFilter(new TabDisplayFilter())
, _tabNetlist (new TabNetlist())
, _tabSelection (new TabSelection())
, _tabInspector (new TabInspector())
, _tabSettings (new TabSettings())
{
setObjectName ( "controller" );
setAttribute ( Qt::WA_QuitOnClose, false );
setWindowTitle ( tr("Controller") );
//connect ( _netlistBrowser, SIGNAL(destroyed()), this, SLOT(netlistBrowserDestroyed()) );
_tabGraphics ->setObjectName ( "controller.graphics" );
_tabPalette ->setObjectName ( "controller.palette" );
_tabDisplayFilter->setObjectName ( "controller.displayFilter" );
_tabNetlist ->setObjectName ( "controller.tabNetlist" );
_tabSelection ->setObjectName ( "controller.tabSelection" );
_tabInspector ->setObjectName ( "controller.tabInspector" );
_tabSettings ->setObjectName ( "controller.tabSettings" );
addTab ( _tabGraphics , "Look" );
addTab ( _tabDisplayFilter , "Filter" );
addTab ( _tabPalette , "Layers&&Gos" );
addTab ( _tabNetlist , "Netlist" );
addTab ( _tabSelection , "Selection" );
addTab ( _tabInspector , "Inspector" );
addTab ( _tabSettings , "Settings" );
QAction* toggleShow = new QAction ( tr("Controller"), this );
toggleShow->setObjectName ( "controller.action.hideShow" );
toggleShow->setShortcut ( QKeySequence(tr("CTRL+I")) );
addAction ( toggleShow );
connect ( toggleShow, SIGNAL(triggered()) , this, SLOT(toggleShow()) );
connect ( this , SIGNAL(currentChanged(int)), this, SLOT(updateTab(int)) );
connect ( _tabSelection->getSelection(), SIGNAL(inspect(Occurrence&))
, _tabInspector , SLOT (setSelectionOccurrence(Occurrence&)) );
resize ( 600, 560 );
}
void ControllerWidget::toggleShow ()
{ setVisible ( !isVisible() ); }
void ControllerWidget::setCellWidget ( CellWidget* cellWidget )
{
_cellWidget = cellWidget;
if ( _cellWidget ) {
for ( int i=0 ; i<count() ; ++i )
(static_cast<ControllerTab*>(widget(i)))->setCellWidget ( _cellWidget );
connect ( _cellWidget, SIGNAL(cellChanged(Cell*)) , this, SLOT(cellChanged(Cell*)) );
connect ( _cellWidget, SIGNAL(cellPreModificated()) , this, SLOT(cellPreModificate()) );
connect ( _cellWidget, SIGNAL(cellPostModificated()), this, SLOT(cellPostModificate()) );
}
}
void ControllerWidget::cellChanged ( Cell* cell )
{ }
void ControllerWidget::updateTab ( int index )
{
(static_cast<ControllerTab*>(widget(index)))->updateTab ();
}
void ControllerWidget::cellPreModificate ()
{
for ( int i=0 ; i<count() ; ++i )
(static_cast<ControllerTab*>(widget(i)))->cellPreModificate ();
}
void ControllerWidget::cellPostModificate ()
{
for ( int i=0 ; i<count() ; ++i )
(static_cast<ControllerTab*>(widget(i)))->cellPostModificate ();
}
} // End of Hurricane namespace.