Support for Python plugins in CellViewer/Unicorn. ClockTree plugin.

* New: In Hurricane, in CellViewer, create a simpler API to graft menu
    and actions into the menubar. Mainly addToMenu() which take care of
    the QAction creation but also locate the relevant QMenu, base on
    the Qt object name. Regroup all the widget & action creation inside
    the body of the constructor, this way almost all actions can be
    removed from the attributes of the CellViewer.
      addToMenu() is supplied in three flavors:
        1. For C++ callbacks in GraphicToolEngines (with a binded
           member function method).
        2. For running Python scripts to be used by the plugin system.
        3. To insert separator in menus (to give a more homogeneous
           look).
    Remove the last remnants of Stratus scripts (unificated with basic
    Python scripts).
* New: In Hurricane, in PyCellViewer, export the interface to graft
    Python scripts into the CellViewer menu tree.
* Change: In Etesian, in GraphicEtesianEngine, use the new API to
    graft menus & callbacks into the CellViewer.
* Change: In Mauka, in GraphicMaukaEngine, use the new API to
    graft menus & callbacks into the CellViewer.
* Change: In Kite, in GraphicKiteEngine, use the new API to
    graft menus & callbacks into the CellViewer.
* New: In Cumulus, install Python scripts as plugins for Unicorn under
    <PYTHON_SITE_PACKAGES>/cumulus/plugins/.
* New: In Unicorn, in UnicornGui, make uses of the new API for creating
    menus in the CellViewer. Creates the stem menu for the P&R tools.
      Add a Python initialization mechanism to read the plugins
    installeds into <PYTHON_SITE_PACKAGES>/cumulus/plugins/.
This commit is contained in:
Jean-Paul Chaput 2014-06-25 19:50:34 +02:00
parent ff21d3c8a2
commit 01b97626a8
22 changed files with 1401 additions and 648 deletions

View File

@ -1,15 +1,9 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved
// Copyright (c) UPMC 2008-2014, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | C y c l o p - S i m p l e V i e w e r |
// | |
@ -17,25 +11,19 @@
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./Cyclop.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include <QAction>
#include <QMenu>
#include "hurricane/viewer/CellWidget.h"
#include "OpenCellDialog.h"
#include "DemoGo.h"
#include "Cyclop.h"
#include <QAction>
#include <QMenu>
#include "hurricane/viewer/CellWidget.h"
#include "OpenCellDialog.h"
#include "DemoGo.h"
#include "Cyclop.h"
namespace CRL {
// -------------------------------------------------------------------
// Class : "Cyclop".

View File

@ -1,6 +1,10 @@
# -*- explicit-buffer-name: "CMakeLists.txt<cumulus/src>" -*-
set ( pysources ${CMAKE_CURRENT_SOURCE_DIR}/placeandroute.py
${CMAKE_CURRENT_SOURCE_DIR}/ref.py
)
set ( pyplugins ${CMAKE_CURRENT_SOURCE_DIR}/ClockTree.py
)
install ( FILES ${pysources} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus )
install ( FILES ${pyplugins} DESTINATION ${PYTHON_SITE_PACKAGES}/cumulus/plugins )

567
cumulus/src/ClockTree.py Executable file
View File

@ -0,0 +1,567 @@
#!/usr/bin/env python
try:
import sys
import traceback
import os.path
import optparse
import math
import Cfg
import Hurricane
from Hurricane import DbU
from Hurricane import Box
from Hurricane import Path
from Hurricane import Occurrence
from Hurricane import UpdateSession
from Hurricane import Breakpoint
from Hurricane import Net
from Hurricane import RoutingPad
from Hurricane import Contact
from Hurricane import Horizontal
from Hurricane import Vertical
from Hurricane import Instance
from Hurricane import HyperNet
import Viewer
import CRL
from CRL import RoutingLayerGauge
from helpers import ErrorMessage
import Nimbus
import Metis
import Mauka
import Katabatic
import Kite
import Unicorn
except ImportError, e:
module = str(e).split()[-1]
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
print ' Please check the integrity of the <coriolis> package.'
sys.exit(1)
except Exception, e:
print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python'
print ' modules. Something may be wrong at Python/C API level.\n'
print ' %s' % e
sys.exit(2)
# Will be moved away from the students eyes in the future.
def breakpoint ( editor, level, message ):
if editor:
editor.fit()
editor.refresh()
Breakpoint.stop( level, message )
return
def getPlugByName ( instance, netName ):
masterCell = instance.getMasterCell()
masterNet = masterCell.getNet( netName )
if masterNet:
return instance.getPlug( masterNet )
return None
def getPlugByNet ( instance, net ):
#print 'getPlugByNet:', net, 'connected to', instance
for plug in net.getPlugs():
#print '|', plug
if plug.getInstance() == instance:
#print '| Found.'
return plug
#print '| NOT Found'
return None
def showNet ( cell, netName ):
net = cell.getNet(netName)
if not net:
print ErrorMessage( 3, 'Cell %s doesn\'t have net %s' % cell.getName(), netName )
return
print 'Components of', netName
for component in net.getComponents():
print '| ', component, component.getBoundingBox()
return
class HTree ( object ):
HAccess = 0x0001
@staticmethod
def create ( cell, clockBox ):
if clockBox.isEmpty(): raise ErrorMessage( 3, 'ClockTree: The clock area is empty.' )
aspectRatio = DbU.toLambda( clockBox.getWidth() ) / DbU.toLambda( clockBox.getHeight() )
if aspectRatio > 1.5 or aspectRatio < 0.5:
raise ErrorMessage( 3, 'ClockTree: aspect ratio %f is disproportionate, must be between 0.5 and 1.5.' \
% aspectRatio )
ht = HTree( cell, clockBox )
print ' o Creating Clock H-Tree for <%s>.' % cell.getName()
ht.build()
ht.place()
ht.route()
print ' - H-Tree depth: %d' % ht.getTreeDepth()
return ht
def __init__ ( self, cell, area ):
self.minSide = DbU.fromLambda( Cfg.getParamInt('clockTree.minimumSide').asInt() )
if self.minSide < DbU.fromLambda(100.0):
raise ErrorMessage( 3, 'ClockTree: clockTree.minimumSide (%g) is less than 100 lambda.' \
% DbU.toLambda(self.minSide) )
self.framework = CRL.AllianceFramework.get()
self.cell = cell
self.area = area
self.childs = []
self.bufferCell = self.framework.getCell( 'buf_x2', CRL.Catalog.State.Logical )
self.cellGauge = self.framework.getCellGauge()
self.routingGauge = self.framework.getRoutingGauge()
self.topBuffer = Instance( self.cell, 'ck_htree', self.bufferCell )
self.cloneds = [ self.cell ]
self.plugToRp = {}
self._createChildNet( self.topBuffer, 'ck_htree' )
topLayer = Cfg.getParamString('katabatic.topRoutingLayer').asString()
self.topLayerDepth = 0
for layerGauge in self.routingGauge.getLayerGauges():
if layerGauge.getLayer().getName() == topLayer:
self.topLayerDepth = layerGauge.getDepth()
break
if not self.topLayerDepth:
print '[WARNING] Gauge top layer not defined, using top of gauge (%d).' \
% self.routingGauge.getDepth()
self.topLayerDepth = self.routingGauge.getDepth()
self.horizontalDepth = 0
self.verticalDepth = 0
for depth in range(0,self.topLayerDepth+1):
if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal:
self.horizontalDepth = depth
if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Vertical:
self.verticalDepth = depth
self.masterClock = None
for net in cell.getNets():
if net.isClock():
self.masterClock = net
break
if not self.masterClock:
print '[WARNING] Cell %s has no clock net.' % cell.getName()
return
def _createChildNet ( self, ibuffer, tag ):
childNet = Net( self.cell, tag )
childNet.setType( Hurricane.TypeCLOCK )
getPlugByName(ibuffer, 'q').setNet( childNet )
return
def _createContact ( self, net, x, y ):
return Contact( net
, self.routingGauge.getContactLayer(self.horizontalDepth)
, x, y
, self.routingGauge.getLayerGauge(self.horizontalDepth).getViaWidth()
, self.routingGauge.getLayerGauge(self.horizontalDepth).getViaWidth()
)
def _createHorizontal ( self, source, target, y ):
return Horizontal( source
, target
, self.routingGauge.getRoutingLayer(self.horizontalDepth)
, y
, self.routingGauge.getLayerGauge(self.horizontalDepth).getWireWidth()
)
def _createVertical ( self, source, target, x ):
return Vertical( source
, target
, self.routingGauge.getRoutingLayer(self.verticalDepth)
, x
, self.routingGauge.getLayerGauge(self.verticalDepth).getWireWidth()
)
def _rpAccess ( self, rp, net, flags=0 ):
contact1 = Contact( rp, self.routingGauge.getContactLayer(0), 0, 0 )
if flags & HTree.HAccess: stopDepth = self.horizontalDepth
else: stopDepth = self.verticalDepth
for depth in range(1,stopDepth):
contact2 = Contact( net
, self.routingGauge.getContactLayer(depth)
, contact1.getX()
, contact1.getY()
, self.routingGauge.getLayerGauge(depth).getViaWidth()
, self.routingGauge.getLayerGauge(depth).getViaWidth()
)
if self.routingGauge.getLayerGauge(depth).getDirection() == RoutingLayerGauge.Horizontal:
Horizontal( contact1
, contact2
, self.routingGauge.getRoutingLayer(depth)
, contact1.getY()
, self.routingGauge.getLayerGauge(depth).getWireWidth()
)
else:
Vertical( contact1
, contact2
, self.routingGauge.getRoutingLayer(depth)
, contact1.getX()
, self.routingGauge.getLayerGauge(depth).getWireWidth()
)
contact1 = contact2
return contact1
def _rpAccessByOccurrence ( self, occurrence, net, flags=0 ):
plug = occurrence.getEntity()
if self.plugToRp.has_key(plug):
rp = self.plugToRp[plug]
else:
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
self.plugToRp[plug] = rp
return self._rpAccess( rp, net, flags )
def _rpAccessByPlug ( self, plug, net, flags=0 ):
if self.plugToRp.has_key(plug):
rp = self.plugToRp[plug]
else:
occurrence = Occurrence( plug, Path(self.cell,'') )
rp = RoutingPad.create( net, occurrence, RoutingPad.BiggestArea )
self.plugToRp[plug] = rp
return self._rpAccess( rp, net, flags )
def _rpAccessByPlugName ( self, instance, plugName, net, flags=0 ):
return self._rpAccessByPlug( getPlugByName(instance,plugName), net, flags )
def toXCellGrid ( self, x ): return x - (x % self.cellGauge.getSliceStep ())
def toYCellGrid ( self, y ): return y - (y % self.cellGauge.getSliceHeight())
def placeInstance ( self, instance, x, y ):
xslice = self.toXCellGrid(x)
yslice = self.toYCellGrid(y)
transformation = Hurricane.OrientationID
if (yslice / self.cellGauge.getSliceHeight()) % 2 != 0:
transformation = Hurricane.OrientationMY
yslice += self.cellGauge.getSliceHeight()
instance.setTransformation ( Hurricane.Transformation(xslice, yslice, transformation) )
instance.setPlacementStatus( Hurricane.PlacementStatusFIXED )
return
def getTreeDepth ( self ):
return self.childs[0].getTreeDepth()
def getLeafBufferUnder ( self, point ):
return self.childs[0].getLeafBufferUnder( point )
def build ( self ):
self.childs.append( HTreeNode( self, self.topBuffer, self.area, '', HTreeNode.RootBranch ) )
return
def place ( self ):
UpdateSession.open()
center = self.area.getCenter()
self.placeInstance( self.topBuffer, center.getX(), center.getY() )
self.childs[0].place()
UpdateSession.close()
return
def route ( self ):
UpdateSession.open()
self.childs[0].route()
UpdateSession.close()
return
def addDeepPlug ( self, topNet, path ):
if path.isEmpty(): return None
tailPath = path.getTailPath()
headInstance = path.getHeadInstance()
headPlug = getPlugByNet(headInstance,topNet)
if headPlug:
if tailPath.isEmpty(): return headPlug
return self.addDeepPlug( headPlug.getMasterNet(), tailPath )
masterCell = headInstance.getMasterCell()
masterNet = Net( masterCell, topNet.getName() )
masterNet.setExternal ( True )
masterNet.setType ( Hurricane.TypeCLOCK )
masterNet.setDirection( Hurricane.DirectionIN )
headPlug = headInstance.getPlug( masterNet )
if not headPlug:
raise ErrorMessage( 3, 'Plug not created for %s on instance %s of %s' \
% (topNet.getName(),headInstance.getName(),masterCell.getName()) )
headPlug.setNet( topNet )
if not masterCell in self.cloneds: self.cloneds.append( masterCell )
if tailPath.isEmpty(): return headPlug
return self.addDeepPlug( masterNet, tailPath )
def connectLeaf ( self ):
UpdateSession.open()
leafConnects = []
hyperMasterClock = HyperNet( Occurrence(self.masterClock) )
for plugOccurrence in hyperMasterClock.getLeafPlugOccurrences():
position = plugOccurrence.getBoundingBox().getCenter()
leafBuffer = self.getLeafBufferUnder( position )
leafCk = getPlugByName(leafBuffer,'q').getNet()
deepPlug = self.addDeepPlug( leafCk, plugOccurrence.getPath() )
leafConnects.append( (deepPlug,plugOccurrence,leafCk,leafBuffer) )
for deepPlug, plugOccurrence, leafCk, leafBuffer in leafConnects:
plugOccurrence.getEntity().setNet( deepPlug.getMasterNet() )
bufferContact = self._rpAccessByPlugName( leafBuffer, 'q', leafCk , HTree.HAccess )
registerContact = self._rpAccessByOccurrence( plugOccurrence, leafCk, 0 )
turn = self._createContact( leafCk, registerContact.getX(), bufferContact.getY() )
self._createVertical ( registerContact, turn, registerContact.getX() )
self._createHorizontal( turn, bufferContact, bufferContact.getY() )
getPlugByName( self.topBuffer, 'i' ).setNet( self.masterClock )
UpdateSession.close()
return
def _rsave ( self, cell ):
flags = CRL.Catalog.State.Physical
if cell.getName().endswith('_clocked'):
flags = flags | CRL.Catalog.State.Logical
self.framework.saveCell( cell, flags )
for instance in cell.getInstances():
masterCell = instance.getMasterCell()
if not masterCell.isTerminal():
self._rsave( masterCell )
def save ( self ):
for cell in self.cloneds:
cell.setName( cell.getName()+'_clocked' )
self._rsave( self.cell )
return
class HTreeNode ( object ):
RootBranch = 0x0001
LeftBranch = 0x0002
RightBranch = 0x0004
UpBranch = 0x0008
DownBranch = 0x0010
def __init__ ( self, topTree, sourceBuffer, area, prefix, flags ):
self.topTree = topTree
self.childs = []
self.flags = flags
self.sourceBuffer = sourceBuffer
self.area = area
self.prefix = prefix
self.blBuffer = Instance( self.topTree.cell, 'ck_htree'+self.prefix+'_bl_ins', self.topTree.bufferCell )
self.brBuffer = Instance( self.topTree.cell, 'ck_htree'+self.prefix+'_br_ins', self.topTree.bufferCell )
self.tlBuffer = Instance( self.topTree.cell, 'ck_htree'+self.prefix+'_tl_ins', self.topTree.bufferCell )
self.trBuffer = Instance( self.topTree.cell, 'ck_htree'+self.prefix+'_tr_ins', self.topTree.bufferCell )
self.ckNet = getPlugByName(self.sourceBuffer, 'q').getNet()
getPlugByName(self.blBuffer, 'i').setNet( self.ckNet )
getPlugByName(self.brBuffer, 'i').setNet( self.ckNet )
getPlugByName(self.tlBuffer, 'i').setNet( self.ckNet )
getPlugByName(self.trBuffer, 'i').setNet( self.ckNet )
self.topTree._createChildNet( self.blBuffer, 'ck_htree'+self.prefix+'_bl' )
self.topTree._createChildNet( self.brBuffer, 'ck_htree'+self.prefix+'_br' )
self.topTree._createChildNet( self.tlBuffer, 'ck_htree'+self.prefix+'_tl' )
self.topTree._createChildNet( self.trBuffer, 'ck_htree'+self.prefix+'_tr' )
halfWidth = self.area.getHalfWidth ()
halfHeight = self.area.getHalfHeight()
if halfWidth >= self.topTree.minSide and halfHeight >= self.topTree.minSide:
# Recursive call.
self.childs.append( HTreeNode( self.topTree, self.blBuffer, self.blArea(), self.prefix+'_bl', 0 ) )
self.childs.append( HTreeNode( self.topTree, self.brBuffer, self.brArea(), self.prefix+'_br', 0 ) )
self.childs.append( HTreeNode( self.topTree, self.tlBuffer, self.tlArea(), self.prefix+'_tl', 0 ) )
self.childs.append( HTreeNode( self.topTree, self.trBuffer, self.trArea(), self.prefix+'_tr', 0 ) )
return
def xmin ( self ): return self.area.getXMin()
def xmax ( self ): return self.area.getXMax()
def ymin ( self ): return self.area.getYMin()
def ymax ( self ): return self.area.getYMax()
def halfWidth ( self ): return self.area.getHalfWidth()
def halfHeight( self ): return self.area.getHalfHeight()
def blArea ( self ):
return Box( self.xmin() , self.ymin()
, self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight() )
def brArea ( self ):
return Box( self.xmin()+self.halfWidth(), self.ymin()
, self.xmax() , self.ymin()+self.halfHeight() )
def tlArea ( self ):
return Box( self.xmin() , self.ymin()+self.halfHeight()
, self.xmin()+self.halfWidth(), self.ymax() )
def trArea ( self ):
return Box( self.xmin()+self.halfWidth(), self.ymin()+self.halfHeight()
, self.xmax() , self.ymax() )
def getTreeDepth ( self ):
if self.childs: return self.childs[0].getTreeDepth()+1
return 1
def getLeafBufferUnder ( self, point ):
if self.childs:
if self.blArea().contains(point): return self.childs[0].getLeafBufferUnder(point)
if self.brArea().contains(point): return self.childs[1].getLeafBufferUnder(point)
if self.tlArea().contains(point): return self.childs[2].getLeafBufferUnder(point)
if self.trArea().contains(point): return self.childs[3].getLeafBufferUnder(point)
if self.blArea().contains(point): return self.blBuffer
if self.brArea().contains(point): return self.brBuffer
if self.tlArea().contains(point): return self.tlBuffer
return self.trBuffer
def place ( self ):
x = self.area.getXMin() + self.area.getWidth ()/4
y = self.area.getYMin() + self.area.getHeight()/4
halfWidth = self.area.getHalfWidth ()
halfHeight = self.area.getHalfHeight()
self.topTree.placeInstance( self.blBuffer, x , y )
self.topTree.placeInstance( self.brBuffer, x+halfWidth, y )
self.topTree.placeInstance( self.tlBuffer, x , y+halfHeight )
self.topTree.placeInstance( self.trBuffer, x+halfWidth, y+halfHeight )
for child in self.childs: child.place()
return
def route ( self ):
sourceContact = self.topTree._rpAccessByPlugName( self.sourceBuffer, 'q', self.ckNet , HTree.HAccess )
blContact = self.topTree._rpAccessByPlugName( self.blBuffer , 'i', self.ckNet )
brContact = self.topTree._rpAccessByPlugName( self.brBuffer , 'i', self.ckNet )
tlContact = self.topTree._rpAccessByPlugName( self.tlBuffer , 'i', self.ckNet )
trContact = self.topTree._rpAccessByPlugName( self.trBuffer , 'i', self.ckNet )
leftContact = self.topTree._createContact( self.ckNet, blContact.getX(), sourceContact.getY() )
rightContact = self.topTree._createContact( self.ckNet, brContact.getX(), sourceContact.getY() )
self.topTree._createHorizontal( leftContact , sourceContact, sourceContact.getY() )
self.topTree._createHorizontal( sourceContact, rightContact , sourceContact.getY() )
self.topTree._createVertical ( leftContact , blContact , leftContact.getX() )
self.topTree._createVertical ( tlContact , leftContact , leftContact.getX() )
self.topTree._createVertical ( rightContact , brContact , rightContact.getX() )
self.topTree._createVertical ( trContact , rightContact , rightContact.getX() )
for child in self.childs: child.route()
return
def computeAbutmentBox ( cell, spaceMargin, aspectRatio, cellGauge ):
sliceHeight = DbU.toLambda( cellGauge.getSliceHeight() )
instancesNb = 0
cellLength = 0
for occurrence in cell.getLeafInstanceOccurrences():
instance = occurrence.getEntity()
instancesNb += 1
cellLength += int( DbU.toLambda(instance.getMasterCell().getAbutmentBox().getWidth()) )
# ar = x/y S = x*y = spaceMargin*SH x=S/y ar = S/y^2
# y = sqrt(S/AR)
gcellLength = float(cellLength)*(1+spaceMargin) / sliceHeight
rows = math.sqrt( gcellLength/aspectRatio )
if math.trunc(rows) != rows: rows = math.trunc(rows) + 1
else: rows = math.trunc(rows)
columns = gcellLength / rows
if math.trunc(columns) != columns: columns = math.trunc(columns) + 1
else: columns = math.trunc(columns)
print ' o Creating abutment box (margin:%.1f%%, aspect ratio:%.1f%%, g-length:%.1fl)' \
% (spaceMargin*100.0,aspectRatio*100.0,(cellLength/sliceHeight))
print ' - GCell grid: [%dx%d]' % (columns,rows)
UpdateSession.open()
abutmentBox = Box( DbU.fromLambda(0)
, DbU.fromLambda(0)
, DbU.fromLambda(columns*sliceHeight)
, DbU.fromLambda(rows *sliceHeight)
)
cell.setAbutmentBox( abutmentBox )
UpdateSession.close()
return abutmentBox
def unicornHook ( editor ):
#print ' o Hooking up ClockTree script.'
moduleFile = sys.modules[__name__].__file__
if moduleFile.endswith('.pyc') or moduleFile.endswith('.pyo'):
moduleFile = moduleFile[:-1]
editor.addToMenu( 'plugins.clockTree'
, 'ClockTree'
, 'Build a buffered H-Tree for the clock'
, moduleFile
)
#print ' <%s>' % moduleFile
return
def ScriptMain ( cell=None ):
try:
errorCode = 0
print ' o Cleaning up any previous run.'
for fileName in os.listdir('.'):
if fileName.endswith('.ap'):
print ' - <%s>' % fileName
os.unlink(fileName)
editor = None
if globals().has_key('__editor'):
print ' o Editor detected, running in graphic mode.'
editor = __editor
if cell == None: cell = editor.getCell()
if cell == None:
raise ErrorMessage( 3, 'ClockTree: No cell loaded yet.' )
framework = CRL.AllianceFramework.get()
cellGauge = framework.getCellGauge()
if cell.getAbutmentBox().isEmpty():
spaceMargin = Cfg.getParamPercentage('nimbus.spaceMargin').asPercentage() / 100.0 + 0.02
aspectRatio = Cfg.getParamPercentage('nimbus.aspectRatio').asPercentage() / 100.0
computeAbutmentBox( cell, spaceMargin, aspectRatio, cellGauge )
if editor: editor.fit()
ht = HTree.create( cell, cell.getAbutmentBox() )
if editor: editor.refresh()
mauka = Mauka.MaukaEngine.create( cell )
mauka.run()
mauka.destroy()
ht.connectLeaf()
ht.save()
#showNet( cell, 'ck_htree_bl_bl_bl' )
#showNet( cell, 'ck_htree_bl_bl_br' )
#showNet( cell, 'ck_htree_bl_bl_tl' )
#showNet( cell, 'ck_htree_bl_bl_tr' )
except ErrorMessage, e:
print e; errorCode = e.code
except Exception, e:
print '\n\n', e; errorCode = 1
traceback.print_tb(sys.exc_info()[2])
return 0
if __name__ == '__main__':
ScriptMain()
sys.exit(0)

View File

@ -94,29 +94,16 @@ namespace Etesian {
}
void GraphicEtesianEngine::_resetPlacement ()
void GraphicEtesianEngine::_place ()
{
_viewer->clearToolInterrupt();
EtesianEngine* etesian = getForFramework( CreateEngine );
etesian->resetPlacement();
}
void GraphicEtesianEngine::_place ()
{
EtesianEngine* etesian = getForFramework( CreateEngine );
etesian->place();
}
void GraphicEtesianEngine::place ()
{
ExceptionWidget::catchAllWrapper( std::bind(&GraphicEtesianEngine::_resetPlacement,this) );
ExceptionWidget::catchAllWrapper( std::bind(&GraphicEtesianEngine::_place ,this) );
}
void GraphicEtesianEngine::postEvent ()
{
static unsigned int count = 0;
@ -139,35 +126,16 @@ namespace Etesian {
_viewer = viewer;
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute");
QMenu* stepMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute.stepByStep");
if (prMenu == NULL) {
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
if (menuBar == NULL) {
cerr << Warning( "GraphicEtesianEngine::addToMenu() - No MenuBar in parent widget." ) << endl;
return;
}
prMenu = menuBar->addMenu( tr("P&&R") );
prMenu->setObjectName( "viewer.menuBar.placeAndRoute" );
stepMenu = prMenu->addMenu( tr("&Step by Step") );
stepMenu->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep" );
prMenu->addSeparator();
if (_viewer->hasMenuAction("placeAndRoute.etesianPlace")) {
cerr << Warning( "GraphicEtesianEngine::addToMenu() - Etesian placer already hooked in." ) << endl;
return;
}
QAction* placeAction = _viewer->findChild<QAction*>("viewer.menuBar.placeAndRoute.etesianPlace");
if (placeAction)
cerr << Warning( "GraphicEtesianEngine::addToMenu() - Etesian detailed router already hooked in." ) << endl;
else {
QAction* placeAction = new QAction ( tr("Etesian - &Place"), _viewer );
placeAction->setObjectName( "viewer.menuBar.placeAndRoute.etesianPlace" );
placeAction->setStatusTip ( tr("Place the design") );
placeAction->setVisible ( true );
prMenu->addAction( placeAction );
connect( placeAction , SIGNAL(triggered()), this, SLOT(place ()) );
}
_viewer->addToMenu( "placeAndRoute.etesianPlace"
, "Etesian - Plac&e"
, "Run the <b>Etesian</b> placer"
, std::bind(&GraphicEtesianEngine::_place,this)
);
}

View File

@ -61,8 +61,6 @@ namespace Etesian {
virtual size_t release ();
virtual void addToMenu ( CellViewer* );
void postEvent ();
public slots:
void place ();
protected:
static size_t _references;
@ -71,7 +69,6 @@ namespace Etesian {
protected:
GraphicEtesianEngine ();
virtual ~GraphicEtesianEngine ();
void _resetPlacement ();
void _place ();
};

View File

@ -2,7 +2,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2013, All Rights Reserved
// Copyright (c) UPMC 2008-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2014, All Rights Reserved
// Copyright (c) UPMC 2008-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
@ -14,6 +14,7 @@
// +-----------------------------------------------------------------+
#include <Python.h>
#include <unistd.h>
#include <algorithm>
#include <sstream>
@ -29,10 +30,12 @@
#include <QPrintDialog>
#include <QFileDialog>
#include "vlsisapd/utilities/Path.h"
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/DataBase.h"
#include "hurricane/Cell.h"
//#include "MapView.h"
#include "hurricane/viewer/Script.h"
#include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/CellViewer.h"
#include "hurricane/viewer/CellPrinter.h"
@ -41,7 +44,6 @@
#include "hurricane/viewer/ControllerWidget.h"
#include "hurricane/viewer/ScriptWidget.h"
#include "hurricane/viewer/ExceptionWidget.h"
//#include "hurricane/viewer/StratusWidget.h"
#include "hurricane/viewer/GotoWidget.h"
#include "hurricane/viewer/SelectCommand.h"
@ -69,32 +71,15 @@ namespace Hurricane {
// -------------------------------------------------------------------
// Class : "CellViewer".
QString CellViewer::_prefixWPath ( "viewer.menuBar." );
CellViewer::CellViewer ( QWidget* parent ) : QMainWindow (parent)
, _cellObserver (this)
, _applicationName (tr("Viewer"))
, _toolInterruptAction (NULL)
, _openAction (NULL)
, _importAction (NULL)
, _nextAction (NULL)
, _printAction (NULL)
, _imageAction (NULL)
, _saveAction (NULL)
, _exportAction (NULL)
, _closeAction (NULL)
, _exitAction (NULL)
, _refreshAction (NULL)
, _fitToContentsAction (NULL)
, _gotoAction (NULL)
, _showSelectionAction (NULL)
, _rubberChangeAction (NULL)
, _clearRulersAction (NULL)
, _controllerAction (NULL)
, _scriptAction (NULL)
, _stratusAction (NULL)
, _fileMenu (NULL)
, _viewMenu (NULL)
, _toolsMenu (NULL)
, _debugMenu (NULL)
, _actionCallbacks ()
//, _mapView (NULL)
, _mousePosition (NULL)
, _controller (NULL)
@ -112,205 +97,13 @@ namespace Hurricane {
, _flags (0)
, _updateState (ExternalEmit)
{
setObjectName("viewer");
createMenus ();
createLayout ();
}
CellViewer::~CellViewer ()
{
_controller->deleteLater ();
//_script->deleteLater ();
_goto->deleteLater ();
}
void CellViewer::createActions ()
{
if ( _openAction ) return;
_toolInterruptAction = new QAction ( tr("Interrupt"), this );
_toolInterruptAction->setObjectName ( "viewer.interrupt" );
_toolInterruptAction->setShortcut ( QKeySequence(tr("CTRL+C")) );
//_toolInterruptAction->setIcon ( QIcon(":/images/stock_open.png") );
_toolInterruptAction->setStatusTip ( tr("Interrupt the running tool") );
connect ( _toolInterruptAction, SIGNAL(triggered()), this, SLOT(raiseToolInterrupt()) );
addAction ( _toolInterruptAction );
_openAction = new QAction ( tr("&Open Cell"), this );
_openAction->setObjectName ( "viewer.menuBar.file.openCell" );
_openAction->setShortcut ( QKeySequence(tr("CTRL+O")) );
_openAction->setIcon ( QIcon(":/images/stock_open.png") );
_openAction->setStatusTip ( tr("Open (load) a new Cell") );
_importAction = new QAction ( tr("&Import Cell"), this );
_importAction->setObjectName ( "viewer.menuBar.file.importCell" );
_importAction->setStatusTip ( tr("Import (convert) a new Cell") );
_nextAction = new QAction ( tr("&Next Breakpoint"), this );
_nextAction->setObjectName ( "viewer.menuBar.file.nextBreakpoint" );
_nextAction->setStatusTip ( tr("Proceed to the next breakpoint") );
for ( int i=0 ; i<CellHistorySize ; i++ ) {
_cellHistoryAction[i] = new QAction ( this );
_cellHistoryAction[i]->setObjectName ( QString("viewer.menuBar.file.cellHistory[%1]").arg(i) );
_cellHistoryAction[i]->setVisible ( false );
_cellHistoryAction[i]->setData ( i );
_cellHistoryAction[i]->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) );
connect ( _cellHistoryAction[i], SIGNAL(triggered()), this, SLOT(openHistoryCell()));
}
_printAction = new QAction ( tr("&Print"), this );
_printAction->setObjectName ( "viewer.menuBar.file.print" );
_printAction->setStatusTip ( tr("Print the displayed area") );
_printAction->setShortcut ( QKeySequence(tr("CTRL+P")) );
_printAction->setVisible ( true );
connect ( _printAction, SIGNAL(triggered()), this, SLOT(printDisplay()) );
_imageAction = new QAction ( tr("Save to &Image"), this );
_imageAction->setObjectName ( "viewer.menuBar.file.image" );
_imageAction->setStatusTip ( tr("Save the displayed area to image") );
_imageAction->setVisible ( true );
connect ( _imageAction, SIGNAL(triggered()), this, SLOT(imageDisplay()) );
_saveAction = new QAction ( tr("&Save Cell"), this );
_saveAction->setObjectName ( "viewer.menuBar.file.saveCell" );
_saveAction->setIcon ( QIcon(":/images/stock_save.png") );
_saveAction->setStatusTip ( tr("Save (write) the current Cell") );
_saveAction->setVisible ( false );
_exportAction = new QAction ( tr("&Export Cell"), this );
_exportAction->setObjectName ( "viewer.menuBar.file.exportCell" );
_exportAction->setStatusTip ( tr("Export (convert) Cell") );
_closeAction = new QAction ( tr("&Close"), this );
_closeAction->setObjectName ( "viewer.menuBar.file.close" );
_closeAction->setStatusTip ( tr("Close This Coriolis CellViewer") );
_closeAction->setShortcut ( QKeySequence(tr("CTRL+W")) );
connect ( _closeAction, SIGNAL(triggered()), this, SLOT(close()) );
_exitAction = new QAction ( tr("&Exit"), this );
_exitAction->setObjectName ( "viewer.menuBar.file.exit" );
_exitAction->setStatusTip ( tr("Exit All Coriolis CellViewer") );
_exitAction->setShortcut ( QKeySequence(tr("CTRL+Q")) );
connect ( _exitAction, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()) );
_refreshAction = new QAction ( tr("&Refresh"), this );
_refreshAction->setObjectName ( "viewer.menuBar.view.refresh" );
_refreshAction->setStatusTip ( tr("Force full redrawing of the display") );
_refreshAction->setShortcut ( QKeySequence(tr("CTRL+L")) );
_fitToContentsAction = new QAction ( tr("&Fit to Contents"), this );
_fitToContentsAction->setObjectName ( "viewer.menuBar.view.fit" );
_fitToContentsAction->setStatusTip ( tr("Adjust zoom to fit the whole cell's contents") );
_fitToContentsAction->setShortcut ( Qt::Key_F );
_gotoAction = new QAction ( tr("&Goto"), this );
_gotoAction->setObjectName ( "viewer.menuBar.view.goto" );
_gotoAction->setStatusTip ( tr("Center view on that point, with zoom adjustment") );
_gotoAction->setShortcut ( Qt::Key_G );
_showSelectionAction = new QAction ( tr("&Show Selection"), this );
_showSelectionAction->setObjectName ( "viewer.menuBar.view.showSelection" );
_showSelectionAction->setStatusTip ( tr("Highlight the selected items (darken others)") );
_showSelectionAction->setShortcut ( Qt::Key_S );
_showSelectionAction->setCheckable ( true );
_rubberChangeAction = new QAction ( tr("Change Rubber Style"), this );
_rubberChangeAction->setObjectName ( "viewer.menuBar.view.changeRubber" );
_rubberChangeAction->setStatusTip ( tr("Cycle through all avalaibles rubber drawing styles") );
_rubberChangeAction->setShortcut ( Qt::Key_Asterisk );
_clearRulersAction = new QAction ( tr("Clear Rulers"), this );
_clearRulersAction->setObjectName ( "viewer.menuBar.view.clearRulers" );
_clearRulersAction->setStatusTip ( tr("Remove all rulers") );
//_clearRulersAction->setShortcut ( QKeySequence(tr("K")) );
_controllerAction = new QAction ( tr("Controller"), this );
_controllerAction->setObjectName ( "viewer.menuBar.tools.controller" );
_controllerAction->setStatusTip ( tr("Fine Tune && Inspect DataBase") );
_controllerAction->setIcon ( QIcon(":/images/swiss-knife.png") );
_controllerAction->setShortcut ( QKeySequence(tr("CTRL+I")) );
_scriptAction = new QAction ( tr("Python Script"), this );
_scriptAction->setObjectName ( "viewer.menuBar.tools.script" );
_scriptAction->setStatusTip ( tr("Run Python Script. Must provide a ScripMain(cell) function") );
_scriptAction->setIcon ( QIcon(":/images/python-logo-v3.png") );
_scriptAction->setShortcut ( QKeySequence(tr("SHIFT+P,SHIFT+S")) );
//_stratusAction = new QAction ( tr("Stratus"), this );
//_stratusAction->setObjectName ( "viewer.menuBar.tools.stratusScript" );
//_stratusAction->setStatusTip ( tr("Run Stratus Script") );
//_stratusAction->setIcon ( QIcon(":/images/stratus-cloud.png") );
//_stratusAction->setShortcut ( QKeySequence(tr("SHIFT+P,SHIFT+S")) );
}
void CellViewer::createMenus ()
{
if ( _fileMenu ) return;
if ( !_openAction ) createActions ();
menuBar()->setObjectName ( tr("viewer.menuBar") );
_fileMenu = menuBar()->addMenu ( tr("File") );
_fileMenu->setObjectName ( "viewer.menuBar.file" );
_fileMenu->addAction ( _openAction );
_fileMenu->addSeparator ();
for ( size_t i=0 ; i<CellHistorySize ; i++ ) {
_fileMenu->addAction ( _cellHistoryAction[i] );
}
_fileMenu->addSeparator ();
_fileMenu->addAction ( _saveAction );
_fileMenu->addSeparator ();
_fileMenu->addAction ( _importAction );
_fileMenu->addAction ( _exportAction );
_fileMenu->addSeparator ();
_fileMenu->addAction ( _printAction );
_fileMenu->addAction ( _imageAction );
_fileMenu->addAction ( _nextAction );
_fileMenu->addSeparator ();
_fileMenu->addAction ( _closeAction );
_fileMenu->addAction ( _exitAction );
_viewMenu = menuBar()->addMenu ( tr("View") );
_viewMenu->setObjectName ( "viewer.menuBar.view" );
_viewMenu->addAction ( _refreshAction );
_viewMenu->addAction ( _fitToContentsAction );
_viewMenu->addAction ( _gotoAction );
_viewMenu->addAction ( _showSelectionAction );
_viewMenu->addAction ( _rubberChangeAction );
_viewMenu->addAction ( _clearRulersAction );
_toolsMenu = menuBar()->addMenu ( tr("Tools") );
_toolsMenu->setObjectName ( "viewer.menuBar.tools" );
_toolsMenu->addAction ( _controllerAction );
_toolsMenu->addAction ( _scriptAction );
//_toolsMenu->addAction ( _stratusAction );
}
QMenu* CellViewer::createDebugMenu ()
{
if ( !_debugMenu ) {
_debugMenu = menuBar()->addMenu ( tr("Debug") );
_debugMenu->setObjectName ( "viewer.menuBar.debug" );
}
return _debugMenu;
}
void CellViewer::createLayout ()
{
if (_cellWidget) return;
setObjectName( "viewer" );
menuBar()->setObjectName ( _getAbsWidgetPath("") );
_cellWidget = new CellWidget ();
_controller = new ControllerWidget();
_goto = new GotoWidget ();
_goto->changeDbuMode( _cellWidget->getDbuMode(), _cellWidget->getUnitPower() );
//_mapView = _cellWidget->getMapView ();
_cellWidget->bindCommand( &_moveCommand );
_cellWidget->bindCommand( &_zoomCommand );
@ -319,7 +112,7 @@ namespace Hurricane {
_cellWidget->bindCommand( &_hierarchyCommand );
_controller->setCellWidget( _cellWidget );
MousePositionWidget* _mousePosition = new MousePositionWidget();
_mousePosition = new MousePositionWidget();
statusBar()->addPermanentWidget( _mousePosition );
setCorner( Qt::TopLeftCorner , Qt::LeftDockWidgetArea );
@ -327,6 +120,7 @@ namespace Hurricane {
setCorner( Qt::TopRightCorner , Qt::RightDockWidgetArea );
setCorner( Qt::BottomRightCorner, Qt::RightDockWidgetArea );
//_mapView = _cellWidget->getMapView ();
//QDockWidget* mapViewDock = new QDockWidget ( tr("Map") );
//mapViewDock->setFeatures ( QDockWidget::DockWidgetVerticalTitleBar
// | QDockWidget::DockWidgetMovable
@ -339,41 +133,385 @@ namespace Hurricane {
setCentralWidget( _cellWidget );
connect( this , SIGNAL(cellPreModificated()) , _cellWidget, SLOT(cellPreModificate()) );
connect( this , SIGNAL(cellPostModificated()), _cellWidget, SLOT(cellPostModificate()) );
connect( this , SIGNAL(redrawCellWidget()) , _cellWidget, SLOT(refresh()) );
connect( _refreshAction , SIGNAL(triggered()) , _cellWidget, SLOT(refresh()) );
connect( _fitToContentsAction , SIGNAL(triggered()) , _cellWidget, SLOT(fitToContents()) );
connect( _showSelectionAction , SIGNAL(toggled(bool)) , this , SLOT(setShowSelection(bool)) );
connect( _rubberChangeAction , SIGNAL(triggered()) , _cellWidget, SLOT(rubberChange()) );
connect( _clearRulersAction , SIGNAL(triggered()) , _cellWidget, SLOT(clearRulers()) );
connect( _controllerAction , SIGNAL(triggered()) , _controller, SLOT(toggleShow()) );
connect( _scriptAction , SIGNAL(triggered()) , this , SLOT(runScript()) );
//connect( _stratusAction , SIGNAL(triggered()) , this , SLOT(runStratusScript()) );
connect( _gotoAction , SIGNAL(triggered()) , this , SLOT(doGoto()) );
createMenus();
connect( _cellWidget , SIGNAL(dbuModeChanged(unsigned int,DbU::UnitPower))
, _goto , SLOT (changeDbuMode (unsigned int,DbU::UnitPower)) );
connect( this , SIGNAL(cellPreModificated()) , _cellWidget, SLOT(cellPreModificate()) );
connect( this , SIGNAL(cellPostModificated()), _cellWidget, SLOT(cellPostModificate()) );
connect( this , SIGNAL(redrawCellWidget()) , _cellWidget, SLOT(refresh()) );
connect( _cellWidget , SIGNAL(mousePositionChanged(const Point&))
, _mousePosition , SLOT (setPosition(const Point&)) );
connect( _cellWidget , SIGNAL(dbuModeChanged(unsigned int,DbU::UnitPower))
, _goto , SLOT (changeDbuMode (unsigned int,DbU::UnitPower)) );
connect( _cellWidget , SIGNAL(selectionModeChanged())
, this , SLOT (changeSelectionMode ()) );
//connect( &_selectCommand , SIGNAL(selectionToggled (Occurrence))
// , _cellWidget , SLOT (toggleSelection (Occurrence)) );
connect( &_selectCommand , SIGNAL(selectionToggled (Occurrence))
, _cellWidget , SLOT (select (Occurrence)) );
connect( _cellWidget , SIGNAL(mousePositionChanged(const Point&))
, _mousePosition , SLOT (setPosition(const Point&)) );
connect( _cellWidget , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, this , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect( this , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, _cellWidget , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect( _cellWidget , SIGNAL(selectionModeChanged())
, this , SLOT (changeSelectionMode ()) );
connect( &_selectCommand, SIGNAL(selectionToggled (Occurrence))
, _cellWidget , SLOT (select (Occurrence)) );
connect( _cellWidget , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, this , SLOT (setState (shared_ptr<CellWidget::State>&)) );
connect( this , SIGNAL(stateChanged(shared_ptr<CellWidget::State>&))
, _cellWidget , SLOT (setState (shared_ptr<CellWidget::State>&)) );
_cellWidget->refresh();
}
CellViewer::~CellViewer ()
{
_controller->deleteLater ();
//_script->deleteLater ();
_goto->deleteLater ();
}
QString CellViewer::_getAbsWidgetPath ( const QString& relPath ) const
{
if (relPath.startsWith("viewer.")) return relPath;
return QString(_prefixWPath).append( relPath );
}
bool CellViewer::hasMenu( const QString& relativePath ) const
{ return findChild<QObject*>(_getAbsWidgetPath(relativePath)) != NULL; }
bool CellViewer::hasMenuAction( const QString& relativePath ) const
{ return findChild<QAction*>(_getAbsWidgetPath(relativePath)) != NULL; }
QMenu* CellViewer::_getParentMenu( const QString& absolutePath ) const
{
QString parentPath = absolutePath.section('.',0,-2);
QMenu* parentMenu = findChild<QMenu*>(parentPath);
if (parentMenu == NULL) {
if (parentPath != "viewer") {
cerr << Warning( "CellViewer::_getParentMenu() - Missing parent menu for %s."
, absolutePath.toStdString().c_str() ) << endl;
}
return NULL;
}
return parentMenu;
}
QMenu* CellViewer::addMenu ( const QString& path, string text, unsigned int flags )
{
QString absolutePath = _getAbsWidgetPath( path );
QMenu* menu = findChild<QMenu*>(absolutePath);
if (menu != NULL) return menu;
if (flags & TopMenu) {
menu = menuBar()->addMenu( tr(text.c_str()) );
menu->setObjectName( absolutePath );
} else {
QMenu* parentMenu = _getParentMenu( absolutePath );
if (parentMenu == NULL) return NULL;
menu = parentMenu->addMenu( tr(text.c_str()) );
menu->setObjectName( absolutePath );
}
return menu;
}
bool CellViewer::addToMenu ( const QString& path )
{
if (not path.endsWith("====")) return false;
QMenu* menu = _getParentMenu( _getAbsWidgetPath(path) );
if (menu == NULL) return false;
menu->addSeparator();
return true;
}
QAction* CellViewer::addToMenu ( const QString& path
, string text
, string textTip
, std::function< void() > callback
, QIcon icon )
{
QString absolutePath = _getAbsWidgetPath( path );
QAction* action = findChild<QAction*>(absolutePath);
if (action == NULL) {
QMenu* parentMenu = _getParentMenu( absolutePath );
if (parentMenu == NULL) return NULL;
action = new QAction( tr(text.c_str()), this );
action->setObjectName( absolutePath );
action->setStatusTip ( tr(textTip.c_str()) );
action->setVisible ( true );
if (not icon.isNull()) action->setIcon( icon );
parentMenu->addAction( action );
_actionCallbacks.insert( make_pair(absolutePath,boost::any(callback)) );
connect( action, SIGNAL(triggered()), this, SLOT(doAction()) );
}
return action;
}
QAction* CellViewer::addToMenu ( const QString& path
, string text
, string textTip
, string scriptPath )
{
QString absolutePath = _getAbsWidgetPath( path );
QAction* action = findChild<QAction*>(absolutePath);
if (action == NULL) {
action = new QAction( tr(text.c_str()), this );
action->setObjectName( absolutePath );
action->setStatusTip ( tr(textTip.c_str()) );
action->setVisible ( true );
QMenu* parentMenu = _getParentMenu( absolutePath );
if (parentMenu != NULL) {
parentMenu->addAction( action );
} else if (absolutePath == "viewer") {
addAction( action );
}
_actionCallbacks.insert( make_pair(absolutePath,boost::any(QString(scriptPath.c_str()))) );
connect( action, SIGNAL(triggered()), this, SLOT(doAction()) );
}
return action;
}
QAction* CellViewer::addToMenu ( QString path
, QString text
, QString textTip
, const QKeySequence& shortCut
, QIcon icon
//, QWidget* receiver
//, SlotMethod slotMethod
)
{
QString absolutePath = _getAbsWidgetPath( path );
QAction* action = findChild<QAction*>(absolutePath);
if (action == NULL) {
action = new QAction( text, this );
action->setObjectName( absolutePath );
action->setStatusTip ( textTip );
action->setShortcut ( shortCut );
action->setVisible ( true );
if (not icon.isNull()) action->setIcon( icon );
QMenu* parentMenu = _getParentMenu( absolutePath );
if (parentMenu != NULL) {
parentMenu->addAction( action );
} else if (absolutePath == "viewer") {
addAction( action );
}
//if ((receiver != NULL) and (slotMethod != NULL))
// connect( action, &QAction::triggered, receiver, slotMethod );
}
return action;
}
void CellViewer::doAction ()
{
QString path = sender()->objectName();
ActionLut::const_iterator iaction = _actionCallbacks.find( path );
if (iaction == _actionCallbacks.end()) {
cerr << Error( "CellViewer::doAction() - Path \"%s\" in not registered."
, path.toStdString().c_str() ) << endl;
return;
}
const boost::any& callback = iaction->second;
if (callback.type() == typeid( std::function<void()> )) {
cerr << "Called function " << qPrintable(path) << endl;
ExceptionWidget::catchAllWrapper( boost::any_cast< std::function<void()> >(callback) );
} else if (callback.type() == typeid( QString )) {
cerr << "Called script " << qPrintable(path) << ":"
<< qPrintable(boost::any_cast<QString>(callback)) << endl;
runScript( boost::any_cast<QString>(callback) );
} else {
cerr << Error("CellViewer::doAction(): For action \"%s\",\n"
" cannot cast the callback into QString or std::function<void()>."
, path.toStdString().c_str() ) << endl;
}
}
void CellViewer::createMenus ()
{
addMenu ( "file" , "File" , TopMenu );
addMenu ( "view" , "View" , TopMenu );
addMenu ( "tools", "Tools", TopMenu );
// Building the "File" menu.
QAction* action = addToMenu( "viewer.interrupt"
, tr("Interrupt")
, tr("Interrupt the running tool")
, QKeySequence(tr("CTRL+C"))
);
action->setVisible( false );
addAction( action );
connect( action, &QAction::triggered, this, &CellViewer::raiseToolInterrupt );
action = addToMenu( "file.openCell"
, tr("&Open Cell")
, tr("Open (load) a new Cell")
, QKeySequence(tr("CTRL+O"))
, QIcon(":/images/stock_open.png")
);
addToMenu( "file.========" );
for ( int i=0 ; i<CellHistorySize ; i++ ) {
_cellHistoryAction[i] = addToMenu( QString("file.cellHistory[%1]").arg(i)
, QString("Slot[%1]").arg(i)
, QString("History empty Slot[%1]").arg(i)
, QKeySequence()
);
_cellHistoryAction[i]->setVisible( false );
_cellHistoryAction[i]->setData ( i );
_cellHistoryAction[i]->setFont ( Graphics::getFixedFont(QFont::Bold,false,false) );
connect( _cellHistoryAction[i], &QAction::triggered, this, &CellViewer::openHistoryCell );
}
addToMenu( "file.========" );
action = addToMenu( "file.saveCell"
, tr("&Save Cell")
, tr("Save (write) the current Cell")
, QKeySequence()
, QIcon(":/images/stock_save.png")
);
action->setVisible( false );
addToMenu( "file.========" );
action = addToMenu( "file.importCell"
, tr("&Import Cell")
, tr("Import (convert) a new Cell")
, QKeySequence()
);
action = addToMenu( "file.exportCell"
, tr("&Export Cell")
, tr("Export (convert) Cell")
, QKeySequence()
);
addToMenu( "file.========" );
action = addToMenu( "file.print"
, tr("&Print")
, tr("Print the displayed area")
, QKeySequence(tr("CTRL+P"))
);
connect( action, &QAction::triggered, this, &CellViewer::printDisplay );
action = addToMenu( "file.image"
, tr("Save to &Image")
, tr("Save the displayed area to image")
, QKeySequence()
);
connect( action, &QAction::triggered, this, &CellViewer::imageDisplay );
action = addToMenu( "file.nextBreakpoint"
, tr("&Next Breakpoint")
, tr("Proceed to the next breakpoint")
, QKeySequence()
);
addToMenu( "file.========" );
action = addToMenu( "file.close"
, tr("&Close")
, tr("Close This Coriolis CellViewer")
, QKeySequence(tr("CTRL+W"))
);
connect( action, &QAction::triggered, this, &CellViewer::close );
action = addToMenu( "file.close"
, tr("&Close")
, tr("Close This Coriolis CellViewer")
, QKeySequence(tr("CTRL+W"))
);
action = addToMenu( "file.exit"
, tr("&Exit")
, tr("Exit All Coriolis CellViewer")
, QKeySequence(tr("CTRL+Q"))
);
connect ( action, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()) );
// Building the "View" menu.
action = addToMenu( "view.refresh"
, tr("&Refresh")
, tr("Force full redrawing of the display")
, QKeySequence(tr("CTRL+L"))
);
connect( action, &QAction::triggered, _cellWidget, &CellWidget::refresh );
action = addToMenu( "view.fit"
, tr("&Fit to Contents")
, tr("Adjust zoom to fit the whole cell's contents")
, Qt::Key_F
);
connect( action, &QAction::triggered, _cellWidget, &CellWidget::fitToContents );
action = addToMenu( "view.goto"
, tr("&Goto")
, tr("Center view on that point, with zoom adjustment")
, Qt::Key_G
);
connect( action, &QAction::triggered, this, &CellViewer::doGoto );
_showSelectionAction = addToMenu( "view.showSelection"
, tr("&Show Selection")
, tr("Highlight the selected items (darken others)")
, Qt::Key_S
);
_showSelectionAction->setCheckable( true );
connect( _showSelectionAction, &QAction::toggled, this, &CellViewer::setShowSelection );
action = addToMenu( "view.changeRubber"
, tr("Change Rubber Style")
, tr("Cycle through all avalaibles rubber drawing styles")
, Qt::Key_Asterisk
);
connect( action, &QAction::triggered, _cellWidget, &CellWidget::rubberChange );
action = addToMenu( "view.clearRulers"
, tr("Clear Rulers")
, tr("Remove all rulers")
, QKeySequence()
);
connect( action, &QAction::triggered, _cellWidget, &CellWidget::clearRulers );
// Building the "Tools" menu.
action = addToMenu( "tools.controller"
, tr("Controller")
, tr("Fine Tune && Inspect DataBase")
, QKeySequence(tr("CTRL+I"))
, QIcon(":/images/swiss-knife.png")
);
connect( action, &QAction::triggered, _controller, &ControllerWidget::toggleShow );
action = addToMenu( "tools.script"
, tr("Python Script")
, tr("Run Python Script. Must provide a ScripMain(cell) function")
, QKeySequence(tr("SHIFT+P,SHIFT+S"))
, QIcon(":/images/python-logo-v3.png")
);
connect( action, &QAction::triggered, this, &CellViewer::runScriptWidget );
}
QMenu* CellViewer::createDebugMenu ()
{
if (not _debugMenu)
addMenu ( "debug" , "Debug" , TopMenu );
return _debugMenu;
}
void CellViewer::refreshTitle ()
{
QString cellName = "None";
@ -619,18 +757,35 @@ namespace Hurricane {
}
void CellViewer::_runScript ()
void CellViewer::_runScript ( QString scriptPath )
{
if (scriptPath.endsWith(".py",Qt::CaseInsensitive))
scriptPath.truncate( scriptPath.size()-3 );
Utilities::Path userScript ( scriptPath.toStdString() );
Utilities::Path userDirectory ( userScript.dirname() );
if (not userDirectory.absolute())
userDirectory = Utilities::Path::cwd() / userDirectory;
Isobar::Script::addPath( userDirectory.string() );
dbo_ptr<Isobar::Script> script = Isobar::Script::create(userScript.basename().string());
script->setEditor ( this );
script->runFunction( "ScriptMain", getCell() );
Isobar::Script::removePath( userDirectory.string() );
}
void CellViewer::runScript ( QString scriptPath )
{ ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this, scriptPath ) ); }
void CellViewer::runScriptWidget ()
{ ScriptWidget::runScript( this, getCell() ); }
void CellViewer::runScript ()
{ ExceptionWidget::catchAllWrapper( std::bind( &CellViewer::_runScript, this ) ); }
//void CellViewer::runStratusScript ()
//{ StratusWidget::runScript ( this ); }
string CellViewer::_getString () const
{
ostringstream s;

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved
// Copyright (c) UPMC 2010-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -41,6 +40,95 @@ extern "C" {
DirectDestroyAttribute(PyCellViewer_destroy, PyCellViewer)
static PyObject* PyCellViewer_hasMenu ( PyCellViewer* self, PyObject* args )
{
trace << "PyCellViewer_hasMenu()" << endl;
HTRY
METHOD_HEAD("CellViewer.hasMenu()")
char* path = NULL;
if (not PyArg_ParseTuple(args,"s:CellViewer.hasMenu()", &path)) {
PyErr_SetString ( ConstructorError, "CellViewer.hasMenu(): Takes exactly one argument." );
return NULL;
}
if (cw->hasMenu( path )) Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
static PyObject* PyCellViewer_hasMenuAction ( PyCellViewer* self, PyObject* args )
{
trace << "PyCellViewer_hasMenuAction()" << endl;
HTRY
METHOD_HEAD("CellViewer.hasMenuAction()")
char* path = NULL;
if (not PyArg_ParseTuple(args,"s:CellViewer.hasMenuAction()", &path)) {
PyErr_SetString ( ConstructorError, "CellViewer.hasMenuAction(): Takes exactly one argument." );
return NULL;
}
if (cw->hasMenuAction( path )) Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
static PyObject* PyCellViewer_addMenu ( PyCellViewer* self, PyObject* args )
{
trace << "PyCellViewer_addMenu()" << endl;
HTRY
METHOD_HEAD("CellViewer.addMenu()")
char* path = NULL;
char* text = NULL;
long flags = 0;
if (not PyArg_ParseTuple(args,"ssl:CellViewer.addMenu()", &path, &text, &flags)) {
PyErr_SetString ( ConstructorError, "CellViewer.addMenu(): Takes exactly three arguments." );
return NULL;
}
if (cw->addMenu( path, text, flags )) Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
static PyObject* PyCellViewer_addToMenu ( PyCellViewer* self, PyObject* args )
{
trace << "PyCellViewer_addToMenu()" << endl;
HTRY
METHOD_HEAD("CellViewer.addToMenu()")
char* path = NULL;
char* text = NULL;
char* textTip = NULL;
char* scriptPath = NULL;
if (not PyArg_ParseTuple(args,"s|sss:CellViewer.addToMenu()", &path, &text, &textTip, &scriptPath)) {
PyErr_SetString ( ConstructorError, "CellViewer.addToMenu(): Takes one or four arguments exactly." );
return NULL;
}
if (text != NULL) {
if (cw->addToMenu( path, text, textTip, scriptPath )) Py_RETURN_TRUE;
} else {
if (cw->addToMenu( path )) Py_RETURN_TRUE;
}
HCATCH
Py_RETURN_FALSE;
}
static PyObject* PyCellViewer_getCell ( PyCellViewer* self )
{
trace << "PyCellViewer_getCell ()" << endl;
@ -170,7 +258,15 @@ extern "C" {
// PyCellViewer Attribute Method table.
PyMethodDef PyCellViewer_Methods[] =
{ { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS
{ { "hasMenu" , (PyCFunction)PyCellViewer_hasMenu , METH_VARARGS
, "Return true if the menu at \"path\" exists." }
, { "hasMenuAction" , (PyCFunction)PyCellViewer_hasMenuAction , METH_VARARGS
, "Return true if the menu action at \"path\" exists." }
, { "addMenu" , (PyCFunction)PyCellViewer_addMenu , METH_VARARGS
, "Create a new menu at \"path\" and returns true if success." }
, { "addToMenu" , (PyCFunction)PyCellViewer_addToMenu , METH_VARARGS
, "Creates a new action at \"path\" and returns true if success." }
, { "getCell" , (PyCFunction)PyCellViewer_getCell , METH_NOARGS
, "Return the currently edited Cell." }
, { "setCell" , (PyCFunction)PyCellViewer_setCell , METH_VARARGS
, "Load a Cell into the viewer." }
@ -205,6 +301,19 @@ extern "C" {
PyTypeRootObjectDefinitions(CellViewer)
static void CellViewerLoadConstants ( PyObject* dictionnary ) {
PyObject* constant;
LoadObjectConstant( dictionnary, CellViewer::NoFlags, "NoFlags" )
LoadObjectConstant( dictionnary, CellViewer::TopMenu, "TopMenu" )
}
extern void PyCellViewer_postModuleInit ()
{
CellViewerLoadConstants(PyTypeCellViewer.tp_dict);
}
# endif // End of Shared Library Code Part.

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved
// Copyright (c) UPMC/LIP6 2010-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -113,6 +112,7 @@ extern "C" {
PyModule_AddObject ( module, "CellViewer", (PyObject*)&PyTypeCellViewer );
PyDisplayStyle_postModuleInit();
PyCellViewer_postModuleInit();
trace << "Viewer.so loaded " << (void*)&typeid(string) << endl;
}

View File

@ -14,7 +14,6 @@
// +-----------------------------------------------------------------+
#include <Python.h>
#include <iostream>
#include <memory>
using namespace std;
@ -27,9 +26,7 @@ using namespace std;
#include <QCheckBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include "vlsisapd/utilities/Path.h"
#include "hurricane/Warning.h"
#include "hurricane/viewer/Script.h"
#include "hurricane/viewer/Graphics.h"
#include "hurricane/viewer/ScriptWidget.h"
#include "hurricane/viewer/CellViewer.h"
@ -94,34 +91,21 @@ namespace Hurricane {
}
bool ScriptWidget::runScript ( QWidget* parent, Cell* cell )
void ScriptWidget::runScript ( QWidget* parent, Cell* cell )
{
ScriptWidget* dialog = new ScriptWidget ( parent );
bool doRunScript = (dialog->exec() == Accepted);
QString scriptName = dialog->getScriptName ();
delete dialog;
if ( not doRunScript ) return false;
if (not doRunScript) return;
if ( scriptName.endsWith(".py",Qt::CaseInsensitive) )
scriptName.truncate ( scriptName.size()-3 );
Utilities::Path userScript ( scriptName.toStdString() );
Utilities::Path userDirectory ( userScript.dirname() );
if ( not userDirectory.absolute() )
userDirectory = Utilities::Path::cwd() / userDirectory;
Isobar::Script::addPath ( userDirectory.string() );
dbo_ptr<Isobar::Script> script = Isobar::Script::create(userScript.basename().string());
script->setEditor ( qobject_cast<CellViewer*>(parent) );
bool returnCode = script->runFunction ( "ScriptMain", cell );
Isobar::Script::removePath ( userDirectory.string() );
return returnCode;
CellViewer* cw = qobject_cast<CellViewer*>(parent);
if (not cw) {
cerr << Error("ScriptWidget::runScript(): The parent widget is *not* a CellViewer, cancelling.") << endl;
return;
}
cw->runScript( scriptName );
}

View File

@ -18,9 +18,11 @@
#define HURRICANE_CELL_VIEWER_H
#include <list>
#include <map>
#include <functional>
using namespace std;
#include <boost/any.hpp>
#include <QIcon>
#include <QMainWindow>
class QEvent;
class QKeyEvent;
@ -76,13 +78,39 @@ namespace Hurricane {
Q_OBJECT;
public:
enum { CellHistorySize = 10 };
enum Flag { InCellChange = 0x0001 };
enum { CellHistorySize = 10 };
enum Flag { InCellChange = 0x0001 };
enum FunctionFlag { NoFlags = 0x0000
, TopMenu = 0x0001 };
private:
typedef std::map< const QString, boost::any > ActionLut;
typedef bool (QWidget::* SlotMethod)();
public:
CellViewer ( QWidget* parent=NULL );
virtual ~CellViewer ();
inline bool isToolInterrupted () const;
QMenu* createDebugMenu ();
bool hasMenu ( const QString& path ) const;
bool hasMenuAction ( const QString& path ) const;
QMenu* addMenu ( const QString& path
, std::string text
, unsigned int flags=NoFlags
);
bool addToMenu ( const QString& path );
QAction* addToMenu ( const QString& path
, std::string text
, std::string textTip
, std::function< void() >
, QIcon icon=QIcon() );
QAction* addToMenu ( const QString& path
, std::string text
, std::string textTip
, std::string scriptPath );
QAction* addToMenu ( QString path
, QString text
, QString textTip
, const QKeySequence& shortCut
, QIcon icon =QIcon());
inline void setEnableRedrawInterrupt ( bool );
inline void setApplicationName ( const QString& );
inline CellObserver* getCellObserver ();
@ -98,9 +126,10 @@ namespace Hurricane {
void unselect ( Occurrence& );
void unselectAll ();
inline void setLayerVisible ( const Name& layer, bool visible );
void _runScript ();
void runScript ( QString scriptPath );
virtual std::string _getString () const;
public slots:
void doAction ();
void doGoto ();
void changeSelectionMode ();
void setShowSelection ( bool );
@ -111,8 +140,7 @@ namespace Hurricane {
void imageDisplay ();
void raiseToolInterrupt ();
void clearToolInterrupt ();
void runScript ();
//void runStratusScript ();
void runScriptWidget ();
inline void emitCellAboutToChange ();
inline void emitCellChanged ();
signals:
@ -122,56 +150,40 @@ namespace Hurricane {
void cellPreModificated ();
void cellPostModificated ();
protected:
void createActions ();
void createMenus ();
void createLayout ();
void refreshTitle ();
void refreshHistory ();
private:
QString _getAbsWidgetPath ( const QString& relPath ) const;
QMenu* _getParentMenu ( const QString& ) const;
void _runScript ( QString scriptPath );
protected:
CellObserver _cellObserver;
QString _applicationName;
QAction* _toolInterruptAction;
QAction* _openAction;
QAction* _importAction;
QAction* _nextAction;
QAction* _cellHistoryAction[CellHistorySize];
QAction* _printAction;
QAction* _imageAction;
QAction* _saveAction;
QAction* _exportAction;
QAction* _closeAction;
QAction* _exitAction;
QAction* _refreshAction;
QAction* _fitToContentsAction;
QAction* _gotoAction;
QAction* _showSelectionAction;
QAction* _rubberChangeAction;
QAction* _clearRulersAction;
QAction* _controllerAction;
QAction* _scriptAction;
QAction* _stratusAction;
QMenu* _fileMenu;
QMenu* _viewMenu;
QMenu* _toolsMenu;
QMenu* _debugMenu;
//MapView* _mapView;
MousePositionWidget* _mousePosition;
ControllerWidget* _controller;
ScriptWidget* _script;
GotoWidget* _goto;
CellWidget* _cellWidget;
MoveCommand _moveCommand;
ZoomCommand _zoomCommand;
RulerCommand _rulerCommand;
SelectCommand _selectCommand;
HierarchyCommand _hierarchyCommand;
list< shared_ptr<CellWidget::State> >
_cellHistory;
bool _firstShow;
bool _toolInterrupt;
unsigned int _flags;
UpdateState _updateState;
static QString _prefixWPath;
CellObserver _cellObserver;
QString _applicationName;
QAction* _openAction;
QAction* _cellHistoryAction[CellHistorySize];
QAction* _showSelectionAction;
QMenu* _debugMenu;
ActionLut _actionCallbacks;
// MapView* _mapView;
MousePositionWidget* _mousePosition;
ControllerWidget* _controller;
ScriptWidget* _script;
GotoWidget* _goto;
CellWidget* _cellWidget;
MoveCommand _moveCommand;
ZoomCommand _zoomCommand;
RulerCommand _rulerCommand;
SelectCommand _selectCommand;
HierarchyCommand _hierarchyCommand;
list< shared_ptr<CellWidget::State> >
_cellHistory;
bool _firstShow;
bool _toolInterrupt;
unsigned int _flags;
UpdateState _updateState;
};

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved
// Copyright (c) UPMC 2010-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -15,8 +14,8 @@
// +-----------------------------------------------------------------+
#ifndef __PY_HURRICANE_CELL_VIEWER__
#define __PY_HURRICANE_CELL_VIEWER__
#ifndef PY_HURRICANE_CELL_VIEWER_H
#define PY_HURRICANE_CELL_VIEWER_H
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/viewer/CellViewer.h"
@ -42,8 +41,9 @@ extern "C" {
extern PyTypeObject PyTypeCellViewer;
extern PyMethodDef PyCellViewer_Methods[];
extern PyObject* PyCellViewer_create ( PyObject* self, PyObject* args );
extern void PyCellViewer_LinkPyType ();
extern PyObject* PyCellViewer_create ( PyObject* self, PyObject* args );
extern void PyCellViewer_LinkPyType ();
extern void PyCellViewer_postModuleInit ();
#define IsPyCellViewer(v) ( (v)->ob_type == &PyTypeCellViewer )
@ -57,4 +57,4 @@ extern "C" {
} // End of Isobar namespace.
#endif // __PY_HURRICANE_CELL_VIEWER__
#endif // PY_HURRICANE_CELL_VIEWER_H

View File

@ -1,8 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
// Copyright (c) UPMC 2008-2014, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | H U R R I C A N E |
@ -15,8 +14,8 @@
// +-----------------------------------------------------------------+
# ifndef __ISOBAR_SCRIPT__
# define __ISOBAR_SCRIPT__
# ifndef ISOBAR_SCRIPT_H
# define ISOBAR_SCRIPT_H
#include <vector>
@ -78,4 +77,4 @@ namespace Isobar {
} // End of Isobar namespace.
# endif // __ISOBAR_SCRIPT__
# endif // ISOBAR_SCRIPT_H

View File

@ -30,7 +30,7 @@ namespace Hurricane {
class ScriptWidget : public QDialog {
Q_OBJECT;
public:
static bool runScript ( QWidget* parent, Cell* );
static void runScript ( QWidget* parent, Cell* );
const QString getScriptName () const;
protected:
ScriptWidget ( QWidget* parent=NULL );

View File

@ -159,7 +159,7 @@ namespace Kite {
void GraphicKiteEngine::_saveGlobalSolution ()
{
KiteEngine* kite = KiteEngine::get( getCell() );
KiteEngine* kite = getForFramework( NoFlags );
if (kite) kite->saveGlobalSolution ();
}
@ -214,6 +214,13 @@ namespace Kite {
}
}
void GraphicKiteEngine::_dumpMeasures ()
{
KiteEngine* kite = getForFramework( NoFlags );
if (kite) kite->dumpMeasures();
}
void GraphicKiteEngine::_save ()
{
@ -226,53 +233,20 @@ namespace Kite {
}
void GraphicKiteEngine::globalRoute ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_globalRoute,this) ); }
void GraphicKiteEngine::loadGlobalSolution ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_loadGlobalSolution,this) ); }
void GraphicKiteEngine::saveGlobalSolution ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_saveGlobalSolution,this) ); }
void GraphicKiteEngine::detailPreRoute ()
void GraphicKiteEngine::_detailRoute ()
{
ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_runNegociatePreRouted,this) );
_loadGlobalRouting ();
_balanceGlobalDensity();
_runNegociate ();
}
void GraphicKiteEngine::detailRoute ()
void GraphicKiteEngine::_route ()
{
ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_loadGlobalRouting ,this) );
ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_balanceGlobalDensity,this) );
ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_runNegociate ,this) );
}
void GraphicKiteEngine::finalize ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_finalize,this) ); }
void GraphicKiteEngine::save ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicKiteEngine::_save,this) ); }
void GraphicKiteEngine::route ()
{
detailPreRoute();
globalRoute ();
detailRoute ();
finalize ();
}
void GraphicKiteEngine::dumpMeasures ()
{
KiteEngine* kite = getForFramework( NoFlags );
if (kite) kite->dumpMeasures();
_runNegociatePreRouted();
_globalRoute ();
_detailRoute ();
_finalize ();
}
@ -298,93 +272,58 @@ namespace Kite {
_viewer = viewer;
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute");
QMenu* stepMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute.stepByStep");
if (prMenu == NULL) {
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
if (menuBar == NULL) {
cerr << Warning( "GraphicKiteEngine::addToMenu() - No MenuBar in parent widget." ) << endl;
return;
}
prMenu = menuBar->addMenu( tr("P&&R") );
prMenu->setObjectName( "viewer.menuBar.placeAndRoute" );
stepMenu = prMenu->addMenu( tr("&Step by Step") );
stepMenu->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep" );
prMenu->addSeparator();
}
QAction* dRouteAction = _viewer->findChild<QAction*>("viewer.menuBar.placeAndRoute.detailedRoute");
if (dRouteAction)
if (_viewer->hasMenuAction("placeAndRoute.route")) {
cerr << Warning( "GraphicKiteEngine::addToMenu() - Kite detailed router already hooked in." ) << endl;
else {
stepMenu->addSeparator();
QAction* dPreRouteAction = new QAction ( tr("Kite - Detailed Pre-Route"), _viewer );
dPreRouteAction->setObjectName( "viewer.menuBar.placeAndPreRoute.stepBystep.detailedPreRoute" );
dPreRouteAction->setStatusTip ( tr("Run the <b>Kite</b> detailed router on pre-routed nets") );
dPreRouteAction->setVisible ( true );
stepMenu->addAction( dPreRouteAction );
QAction* gRouteAction = new QAction ( tr("Kite - &Global Route"), _viewer );
gRouteAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.globalRoute" );
gRouteAction->setStatusTip ( tr("Run the <b>Knik</b> global router") );
gRouteAction->setVisible ( true );
stepMenu->addAction( gRouteAction );
QAction* gLoadSolutionAction = new QAction ( tr("Kite - &Load Global Routing"), _viewer );
gLoadSolutionAction->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep.loadGlobalRouting" );
gLoadSolutionAction->setStatusTip ( tr("Load a solution for the global routing (.kgr)") );
gLoadSolutionAction->setVisible ( true );
stepMenu->addAction( gLoadSolutionAction );
QAction* gSaveSolutionAction = new QAction ( tr("Kite - &Save Global Routing"), _viewer );
gSaveSolutionAction->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep.saveGlobalRouting" );
gSaveSolutionAction->setStatusTip ( tr("Save a global router solution (.kgr)") );
gSaveSolutionAction->setVisible ( true );
stepMenu->addAction( gSaveSolutionAction );
dRouteAction = new QAction ( tr("Kite - &Detailed Route"), _viewer );
dRouteAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.detailedRoute" );
dRouteAction->setStatusTip ( tr("Run the <b>Kite</b> detailed router") );
dRouteAction->setVisible ( true );
stepMenu->addAction( dRouteAction );
QAction* dFinalizeAction = new QAction( tr("Kite - &Finalize Routing"), _viewer );
dFinalizeAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.finalize" );
dFinalizeAction->setStatusTip ( tr("Closing Routing") );
dFinalizeAction->setVisible ( true );
stepMenu->addAction( dFinalizeAction );
QAction* dDumpMeasuresAction = new QAction ( tr("Kite - Dump &Measures"), _viewer );
dDumpMeasuresAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.dumpMeasures" );
dDumpMeasuresAction->setStatusTip ( tr("Dumping Measurements on the disk") );
dDumpMeasuresAction->setVisible ( true );
stepMenu->addAction( dDumpMeasuresAction );
QAction* dSaveAction = new QAction ( tr("Kite - &Save Design"), _viewer );
dSaveAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.save" );
dSaveAction->setStatusTip ( tr("Save routed design (temporary hack)") );
dSaveAction->setVisible ( true );
stepMenu->addAction( dSaveAction );
QAction* routeAction = new QAction ( tr("Kite - &Route"), _viewer );
routeAction->setObjectName( "viewer.menuBar.placeAndRoute.route" );
routeAction->setStatusTip ( tr("Route the design (global & detailed)") );
routeAction->setVisible ( true );
prMenu->addAction( routeAction );
connect( gLoadSolutionAction, SIGNAL(triggered()), this, SLOT(loadGlobalSolution()) );
connect( gSaveSolutionAction, SIGNAL(triggered()), this, SLOT(saveGlobalSolution()) );
connect( gRouteAction , SIGNAL(triggered()), this, SLOT(globalRoute ()) );
connect( dPreRouteAction , SIGNAL(triggered()), this, SLOT(detailPreRoute ()) );
connect( dRouteAction , SIGNAL(triggered()), this, SLOT(detailRoute ()) );
connect( dFinalizeAction , SIGNAL(triggered()), this, SLOT(finalize ()) );
connect( dSaveAction , SIGNAL(triggered()), this, SLOT(save ()) );
connect( dDumpMeasuresAction, SIGNAL(triggered()), this, SLOT(dumpMeasures ()) );
connect( routeAction , SIGNAL(triggered()), this, SLOT(route ()) );
return;
}
_viewer->addToMenu( "placeAndRoute.route"
, "Kite - &Route"
, "Route the design (global & detailed)"
, std::bind(&GraphicKiteEngine::_route,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.========" );
_viewer->addToMenu( "placeAndRoute.stepByStep.detailedPreRoute"
, "Kite - Detailed Pre-Route"
, "Run the <b>Kite</b> detailed router on pre-routed nets"
, std::bind(&GraphicKiteEngine::_runNegociatePreRouted,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.globalRoute"
, "Kite - &Global Route"
, "Run the <b>Knik</b> global router"
, std::bind(&GraphicKiteEngine::_globalRoute,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.loadGlobalRouting"
, "Kite - &Load Global Routing"
, "Load a solution for the global routing (.kgr)"
, std::bind(&GraphicKiteEngine::_loadGlobalSolution,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.saveGlobalRouting"
, "Kite - &Save Global Routing"
, "Save a global router solution (.kgr)"
, std::bind(&GraphicKiteEngine::_saveGlobalSolution,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.detailedRoute"
, "Kite - &Detailed Route"
, "Run the <b>Kite</b> detailed router"
, std::bind(&GraphicKiteEngine::_detailRoute,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.finalize"
, "Kite - &Finalize Routing"
, "Closing Routing"
, std::bind(&GraphicKiteEngine::_finalize,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.dumpMeasures"
, "Kite - Dump &Measures"
, "Dumping Measurements on the disk"
, std::bind(&GraphicKiteEngine::_dumpMeasures,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.save"
, "Kite - &Save Design"
, "Save routed design (temporary hack)"
, std::bind(&GraphicKiteEngine::_save,this)
);
}

View File

@ -76,16 +76,6 @@ namespace Kite {
virtual size_t release ();
virtual void addToMenu ( CellViewer* );
void postEvent ();
public slots:
void detailPreRoute ();
void loadGlobalSolution ();
void saveGlobalSolution ();
void globalRoute ();
void detailRoute ();
void finalize ();
void route ();
void save ();
void dumpMeasures ();
protected:
static size_t _references;
@ -94,6 +84,7 @@ namespace Kite {
protected:
GraphicKiteEngine ();
virtual ~GraphicKiteEngine ();
void _route ();
void _loadGlobalSolution ();
void _saveGlobalSolution ();
void _globalRoute ();
@ -101,8 +92,10 @@ namespace Kite {
void _balanceGlobalDensity ();
void _runNegociatePreRouted ();
void _runNegociate ();
void _detailRoute ();
void _finalize ();
void _save ();
void _dumpMeasures ();
};

View File

@ -206,13 +206,13 @@ namespace Mauka {
void GraphicMaukaEngine::_place ()
{
if (MetisEngine::isHMetisCapable()) {
doQuadriPart();
_doQuadriPart();
} else {
cerr << Warning("Mauka has not been compiled againts hMETIS.\n"
" Quadri-partition step is disabled, simulated annealing may be *very* long." ) << endl;
}
doSimulatedAnnealing();
_doSimulatedAnnealing();
_save();
}
@ -227,85 +227,32 @@ namespace Mauka {
}
void GraphicMaukaEngine::doQuadriPart ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_doQuadriPart,this) ); }
void GraphicMaukaEngine::doSimulatedAnnealing ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_doSimulatedAnnealing,this) ); }
void GraphicMaukaEngine::place ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_place,this) ); }
void GraphicMaukaEngine::save ()
{ ExceptionWidget::catchAllWrapper( std::bind(&GraphicMaukaEngine::_save,this) ); }
void GraphicMaukaEngine::addToMenu ( CellViewer* viewer )
{
assert ( _viewer == NULL );
assert( _viewer == NULL );
_viewer = viewer;
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute");
QMenu* stepMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute.stepByStep");
if ( prMenu == NULL ) {
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
if ( menuBar == NULL ) {
cerr << Warning("GraphicMaukaEngine::addToMenu() - No MenuBar in parent widget.") << endl;
return;
}
prMenu = menuBar->addMenu ( tr("P&&R") );
prMenu->setObjectName ( "viewer.menuBar.placeAndRoute" );
stepMenu = prMenu->addMenu ( tr("&Step by Step") );
stepMenu->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep" );
prMenu->addSeparator ();
if (_viewer->hasMenuAction("placeAndRoute.maukaPlace")) {
cerr << Warning( "GraphicMaukaEngine::addToMenu() - Mauka placer already hooked in." ) << endl;
return;
}
QAction* placeAction = _viewer->findChild<QAction*>("viewer.menuBar.placeAndRoute.maukaPlace");
if ( placeAction != NULL )
cerr << Warning("GraphicMaukaEngine::addToMenu() - Mauka placer already hooked in.") << endl;
else {
QAction* quadriPartAction = new QAction ( tr("Mauka - &QuadriPartition"), _viewer );
quadriPartAction->setObjectName ( "viewer.menuBar.placeAndRoute.quadriPartition" );
quadriPartAction->setStatusTip ( tr("Run the <b>hMETIS</b> quadri-partitioner") );
quadriPartAction->setVisible ( true );
stepMenu->addAction ( quadriPartAction );
QAction* annealingAction = new QAction ( tr("Mauka - &Place"), _viewer );
annealingAction->setObjectName ( "viewer.menuBar.placeAndRoute.maukaPlace" );
annealingAction->setStatusTip ( tr("Run the <b>Mauka</b> placer") );
annealingAction->setVisible ( true );
stepMenu->addAction ( annealingAction );
QAction* placeAction = new QAction ( tr("Mauka - &Place"), _viewer );
placeAction->setObjectName ( "viewer.menuBar.placeAndRoute.place" );
placeAction->setStatusTip ( tr("Run the <b>Mauka</b> placer") );
placeAction->setVisible ( true );
prMenu->addAction ( placeAction );
connect ( quadriPartAction, SIGNAL(triggered()), this, SLOT(doQuadriPart()) );
connect ( annealingAction , SIGNAL(triggered()), this, SLOT(doSimulatedAnnealing()) );
connect ( placeAction , SIGNAL(triggered()), this, SLOT(place()) );
}
// ControllerWidget* controller = _viewer->getControllerWidget();
// ConfigurationWidget* setting = controller->getSettings()
// ->findChild<ConfigurationWidget*>("controller.tabSettings.setting.mauka");
// if ( setting == NULL ) {
// setting = new ConfigurationWidget ();
// setting->setObjectName ( "controller.tabSettings.setting.mauka" );
// setting->setConfiguration ( Nimbus::Configuration::getDefault()
// , Metis::Configuration::getDefault()
// , Configuration::getDefault()
// );
// controller->addSetting ( setting, "Mauka" );
// }
_viewer->addToMenu( "placeAndRoute.maukaPlace"
, "Mauka - &Place"
, "Run the <b>Mauka</b> placer"
, std::bind(&GraphicMaukaEngine::_place,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.quadriPartition"
, "Mauka - &QuadriPartition"
, "Run the <b>hMETIS</b> quadri-partitioner"
, std::bind(&GraphicMaukaEngine::_doQuadriPart,this)
);
_viewer->addToMenu( "placeAndRoute.stepByStep.simulatedAnnealing"
, "Mauka - &Simulated Annealing"
, "Run the <b>Mauka</b> simulated annealing detailed placer"
, std::bind(&GraphicMaukaEngine::_doSimulatedAnnealing,this)
);
}

View File

@ -51,7 +51,6 @@ namespace Mauka {
public:
enum Flags { NoFlags=0x0000, CreateEngine=0x0001 };
public:
MaukaEngine* createEngine ();
MaukaEngine* getForFramework ( unsigned int flags );
@ -68,12 +67,6 @@ namespace Mauka {
virtual size_t release ();
virtual void addToMenu ( CellViewer* );
void refreshViewer ();
public slots:
void doQuadriPart ();
void doSimulatedAnnealing ();
void place ();
void save ();
protected:
static size_t _references;
static GraphicMaukaEngine* _singleton;

View File

@ -93,4 +93,6 @@
install ( FILES ${includes}
${mocincludes}
${pyIncludes} DESTINATION include/coriolis2/unicorn )
install ( FILES init/unicornInit.py
DESTINATION ${PYTHON_SITE_PACKAGES}/unicorn )

View File

@ -14,9 +14,11 @@
// +-----------------------------------------------------------------+
#include <Python.h>
#include <QAction>
#include <QMenu>
#include "hurricane/Warning.h"
#include "hurricane/viewer/Script.h"
#include "hurricane/viewer/CellWidget.h"
#include "crlcore/Catalog.h"
#include "crlcore/AllianceFramework.h"
@ -32,7 +34,9 @@
namespace Unicorn {
using Hurricane::dbo_ptr;
using Hurricane::Warning;
using CRL::System;
using CRL::Catalog;
using CRL::AllianceFramework;
using CRL::DefExport;
@ -56,13 +60,40 @@ namespace Unicorn {
, _tools ()
, _importDialog(new ImportCellDialog(this))
, _exportDialog(new ExportCellDialog(this))
{ }
{
addMenu ( "placeAndRoute" , "P&&R" , CellViewer::TopMenu );
addMenu ( "placeAndRoute.stepByStep", "&Step by Step" );
addToMenu( "placeAndRoute.========" );
_runUnicornInit();
}
UnicornGui::~UnicornGui ()
{ }
void UnicornGui::_runUnicornInit ()
{
Utilities::Path pythonSitePackages = System::getPath("pythonSitePackages");
Utilities::Path systemConfDir = pythonSitePackages / "unicorn";
Utilities::Path systemConfFile = systemConfDir / "unicornInit.py";
if (systemConfFile.exists()) {
Isobar::Script::addPath( systemConfDir.string() );
dbo_ptr<Isobar::Script> script = Isobar::Script::create( systemConfFile.stem().string() );
script->setEditor ( this );
script->runFunction( "unicornConfigure", getCell() );
Isobar::Script::removePath( systemConfDir.string() );
} else {
cerr << Warning("System configuration file:\n <%s> not found."
,systemConfFile.string().c_str()) << endl;
}
}
UnicornGui* UnicornGui::create ( QWidget* parent )
{
UnicornGui* unicorn = new UnicornGui ( parent );

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python
try:
import sys
import os.path
from helpers import ErrorMessage
from helpers import WarningMessage
import Viewer
except ImportError, e:
module = str(e).split()[-1]
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
print ' Please check the integrity of the <coriolis> package.'
sys.exit(1)
except Exception, e:
print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python'
print ' modules. Something may be wrong at Python/C API level.\n'
print ' %s' % e
sys.exit(2)
def unicornConfigure ( cell=None ):
editor = None
if globals().has_key('__editor'):
editor = __editor
else:
print ErrorMessage( 3, 'unicornConfigure.py: Must be run from a CellView derived class.' )
return
cumulusDir = None
for path in sys.path:
if path.endswith('/cumulus'):
cumulusDir = path
if not cumulusDir:
print ErrorMessage( 3, 'unicornConfigure.py: Cannot find <cumulus> in PYTHONPATH.' )
return
pluginsDir = os.path.join( cumulusDir, 'plugins' )
if not os.path.isdir(pluginsDir):
print ErrorMessage( 3, 'unicornConfigure.py: Cannot find <cumulus/plugins> directory:' \
, '<%s>' % pluginsDir )
return
sys.path.append( pluginsDir )
if editor.hasMenu( 'plugins' ):
print WarningMessage( 'The <plugins> menu has already been created.' )
return
editor.addMenu( 'plugins', 'Plu&gins', Viewer.CellViewer.TopMenu )
for pluginFile in os.listdir( pluginsDir ):
if not pluginFile.endswith('.py'): continue
moduleName = os.path.basename(pluginFile)[:-3]
module = __import__( moduleName, globals(), locals(), moduleName )
if not module.__dict__.has_key('unicornHook'):
print WarningMessage( 'Module <%s> do not provides the unicornHook() method, skipped.' \
% moduleName )
continue
module.__dict__['unicornHook']( editor )
return

View File

@ -47,22 +47,23 @@ namespace Unicorn {
class UnicornGui : public CellViewer {
Q_OBJECT;
public:
static UnicornGui* create ( QWidget* parent=NULL );
void destroy ();
static inline Banner& getBanner ();
virtual Cell* getCellFromDb ( const char* name );
void registerTool ( GraphicTool* );
virtual std::string _getString () const;
public slots:
void openCell ();
void saveCell ();
void importCell ();
void exportCell ();
protected:
UnicornGui ( QWidget* parent );
virtual ~UnicornGui ();
virtual void _postCreate ();
virtual void _preDestroy ();
static UnicornGui* create ( QWidget* parent=NULL );
void destroy ();
static inline Banner& getBanner ();
virtual Cell* getCellFromDb ( const char* name );
void registerTool ( GraphicTool* );
virtual std::string _getString () const;
public slots:
void openCell ();
void saveCell ();
void importCell ();
void exportCell ();
protected:
UnicornGui ( QWidget* parent );
virtual ~UnicornGui ();
virtual void _postCreate ();
virtual void _preDestroy ();
void _runUnicornInit ();
protected:
static Banner _banner;
set<GraphicTool*> _tools;