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:
parent
ff21d3c8a2
commit
01b97626a8
|
@ -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".
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -93,4 +93,6 @@
|
|||
install ( FILES ${includes}
|
||||
${mocincludes}
|
||||
${pyIncludes} DESTINATION include/coriolis2/unicorn )
|
||||
install ( FILES init/unicornInit.py
|
||||
DESTINATION ${PYTHON_SITE_PACKAGES}/unicorn )
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue