# This file is part of the Coral project.
# Please read the copyright notice in the LICENSE file.

import math
import copy
import types

import coral

import qt
import qtcanvas

from coral.modeler.coralmodeler import CoralModeler
DI = coral.lang.XMIDI20
from coral.modeler.diagram import layout
from coral.modeler.diagram import ui
import coral

from coral.modeler.diagram.defaultfont import defaultFont

import coral.modeler.diagram.di_support as DISUPP
import coral.modeler.diagram.di_support_gfx as DISUPPGFX

from coral import log
logger=log.getLogger("presentation")

###################################################################

##import sys
##if sys.platform=="cygwin":
##    defaultFont = qt.QFont("Helvetica",12)
##else:
##    defaultFont = qt.QFont("Helvetica",8)

PEN_THICKNESS = 0

###################################################################
# Extensions

class DiagramElementRenderer:

    def __init__( self, widget, ge, isref ):
        self.widget = widget
        self.ge = ge
        self.isref = isref
        self.element = self.ge.semanticModel.element

    def drawBeginConnector(self,painter):
        """Default begin connector is nothing."""
        self._preparePainter(painter)

    def drawEndConnector(self,painter):
        """Default end connector is nothing."""
        self._preparePainter(painter)

    def _preparePainter(self,painter):
        """Default preparation is nothing (?)."""
        pass
    
    def drawShape( self, painter ):
        painter.drawRect(0, 0, self.widget.width(), self.widget.height())

    def drawMainPolyline(self, painter, waypoints):
        """
        Default renderer for graphedges.
        Draws Bezier curves as well, if all waypoints
        are XMIDI20.BezierPoints. Otherwise draws
        a simple polyline.
        """
        self._preparePainter(painter)
        pa = []
        pa_straight = []
        is_bezier = True
        for p in waypoints:
            ix = int(p.x)
            iy = int(p.y)
            pa.append(ix)
            pa.append(iy)
            pa_straight.append(ix)
            pa_straight.append(iy)
            if is_bezier and p.oclIsKindOf(DI.BezierPoint):
                for c in p.controls:
                    # Control points are relative
                    pa.append(int(ix + c.x))
                    pa.append(int(iy + c.y))
                # Always a multiple of three!
                le = len(p.controls)
                if le < 1:
                    pa.append(ix)
                    pa.append(iy)
                if le < 2:
                    pa.append(ix)
                    pa.append(iy)
                    
            else:
                is_bezier = False

        ### print "DRAWING", pa

        if not is_bezier:
            pa = pa_straight

        p = qt.QPointArray(pa)
        if is_bezier:
            # QT draws only one bezier curve for every three points
            # Since we have x/y coords we're modulo 6
            assert len(pa) % 6 == 0
            # But QT wants stuff modulo 3
            # And we don't want to draw the last point
            for i in xrange(0, len(pa) / 2 - 3, 3):
                ### print "Drawing bezier index ", i
                painter.drawCubicBezier(p, i)
        else:
            painter.drawPolyline(p)

class NullRenderer(DiagramElementRenderer):
    """Guaranteed to never draw anything."""
    def drawShape( self, painter ):
        pass

class DiagramElementExt:

    def __init__( self, renderer, layouter = layout.DiagramElementLayouter,
                  userInterface=ui.DiagramElementUI ):
        self.rendererClass = renderer
        # Looks silly, but extension mechanism gives automatically
        # None to all unset named parameters. The values are classes
        # that are not instantiated. None can't be instantiated, so
        # we hack the default value here (TLU)
        if not layouter:
            self.layouterClass = layout.DiagramElementLayouter
        else:
            self.layouterClass = layouter
        if not userInterface:
            self.userInterfaceClass = ui.DiagramElementUI
        else:
            self.userInterfaceClass = userInterface

    def getRenderer( self ):
        return self.rendererClass

    def getLayouter( self ):
        return self.layouterClass

    def getUserInterface( self ):
        return self.userInterfaceClass


###################################################################
# Basic renderers

class DebugRenderer( DiagramElementRenderer ):

    def drawShape( self, painter ):
        # draw a grey frame and a label
        painter.save()
        try:
            DISUPPGFX.setPenColor(painter, qt.QColor(128,128,128))
            painter.setFont(qt.QFont("Helvetica",5))
            painter.drawRect(0,0,self.widget.width(),self.widget.height())
            if logger.level <= 20:
                text=""
                if self.ge.semanticModel.oclIsKindOf(DI.SimpleSemanticModelElement):
                    text = unicode(self.ge.semanticModel.typeInfo)
                elif self.ge.semanticModel.element:
                    text = unicode(self.ge.semanticModel.element.__type__())

                painter.drawText(0,0,self.widget.width(),self.widget.height(),
                             qt.Qt.AlignTop | qt.Qt.AlignLeft | qt.Qt.WordBreak,text)
        finally:
            painter.restore()
    


###################################################################
# Diagram element widgets

class DiagramElementWidget:

    def __init__( self, graphElement, ext=None ):
        self.graphElement = graphElement

        if ext: # This block is to enable showing leafelements
            self.graphElementRenderer = ext.getRenderer()(self,graphElement,
                                                          DISUPP.deHasReferentialRole(self.graphElement))

            ext.getLayouter()(self.graphElement)
            ext.getUserInterface()(self.graphElement)
        else: # We have a leafelement
            if graphElement.oclIsKindOf(DI.LeafElement):
                self.graphElementRenderer = None
                ui.LeafElementUI(self.graphElement)


    def updateWidget( self ):
        for w in self.contained():
            w.updateWidget()
        self.update()
        
    def selectable( self ):
        return self.graphElement.ui.__getPyValue__().selectable()

    def movable(self):
        return self.graphElement.ui.__getPyValue__().movable()

    def resizable(self):
        return self.graphElement.ui.__getPyValue__().resizable()

    def relinkable(self):
        return self.graphElement.ui.__getPyValue__().relinkable()




class GraphElementWidget( DiagramElementWidget ):

    def __init__( self, graphElement, ext ):
        DiagramElementWidget.__init__(self,graphElement,ext)

    def _contained( self, ge ):
        w = None
        p = None
        f = None
        for e in ge.contained:
            w = e.widget
            if w:
                p = w.__getPyValue__()
                if p:
                    yield p
                    continue
            for f in self._contained(e):
                yield f

    def contained( self ):
        """Yields the widgets contained by this widget. May go down deeper
        into XMI[DI] GraphElement hierarchy if there are intermediate
        GraphElements that have no widgets"""
        if not self.graphElement:
            return []
        else:
            return self._contained(self.graphElement)

    def attach(self, canvas):
        self.setCanvas(canvas)
        self.show()
        for s in self.selection:
            s.show()
            s.setCanvas(canvas)

    def detach(self):
        self.hide()
        self.setCanvas(None)
        for s in self.selection:
            s.hide()
            s.setCanvas(None)
        self.selection = []

    def shallowContainers( cls, set ):
        """Removes from the set (a dictionary) all widgets that
        have their containers (transitively) in the set"""
        toberemoved = {}
        for w in set:
            for c in coral.Element__getMyselfAndParents__(w.graphElement.container):
                if c.oclIsKindOf(DI.GraphElement):
                    c = c.widget.__getPyValue__()
                    if c in set:
                        toberemoved[w] = True
        for w in toberemoved:
            del set[w]
            
    shallowContainers = classmethod(shallowContainers)

class LeafElementWidget( DiagramElementWidget ):
    def __init__( self, graphElement):
        DiagramElementWidget.__init__(self,graphElement)


    def updateWidget(self):
        propL = [list((unicode(p.key),unicode(p.value))) for p in self.graphElement.property]
        self.prop = dict(propL)
        logger.debug(unicode(self.prop))


    def drawShape( self,painter ):
        pass

class PolylineWidget( LeafElementWidget, qtcanvas.QCanvasPolygon ):
    def __init__( self, graphElement, canvas=None ):
        LeafElementWidget.__init__(self,graphElement)
        qtcanvas.QCanvasPolygon.__init__(self,canvas)
        self.updateWidget()
        self.show()
        self.setVisible(True) #graphElement.isVisible)

    def updateWidget( self ):


        xo,yo = 0,0
        logger.debug("did local to global")
        self.points = [list((float(p.x)+xo, float(p.y)+yo)) for p in self.graphElement.waypoints ]
        self.pointsQ = []
        for (x,y) in self.points:
            self.pointsQ.append(x)
            self.pointsQ.append(y)
        logger.debug(unicode(self.pointsQ))

        self.polygon=qt.QPointArray(self.pointsQ)

        qtcanvas.QCanvasPolygon.setWinding(self,1)
        qtcanvas.QCanvasPolygon.setPoints(self,self.polygon)
        
        LeafElementWidget.updateWidget(self)
        
    def drawShape( self, painter ):

        painter.save()
        try:
            DISUPPGFX.setPenColor(painter, qt.Qt.black)
            LeafElementWidget.drawShape(self, painter)
            #qtcanvas.QCanvasPolygon.drawShape(self,painter)
            if self.graphElement.closed:
                painter.drawPolygon(self.polygon)
            else:
                painter.drawPolyline(self.polygon)
        finally:
            painter.restore()


class TextElementWidget( LeafElementWidget, qtcanvas.QCanvasText ):
    def __init__( self, graphElement, canvas=None ):
        LeafElementWidget.__init__(self,graphElement)
        qtcanvas.QCanvasText.__init__(self,canvas)
        self.setText(unicode(graphElement.text))
        self.updateWidget()
        # BUG This should happen in updateWidget, but moving it there
        # causes crashes?
        x, y = DISUPP.localToGlobalPosition(self.graphElement.container, 0, 0)
        self.move(x, y)
        self.show()


class ImageWidget( LeafElementWidget, qtcanvas.QCanvasSprite ):
    def __init__( self, graphElement, canvas=None ):
        LeafElementWidget.__init__(self,graphElement)
        # BUG Cache multiple loads of same qtcanvas.QCanvasPixmapArray
        self.__array = qtcanvas.QCanvasPixmapArray()
        uri = str(graphElement.uri)
        pixmap = qtcanvas.QCanvasPixmap(uri)
        # BUG add error checking here and show a dummy "broken picture" picture
        assert not pixmap.isNull()
        self.__array.setImage(0, pixmap)
        qtcanvas.QCanvasSprite.__init__(self, self.__array, canvas)
        self.updateWidget()
        # BUG This should happen in updateWidget, but moving it there
        # causes crashes?
        x, y = DISUPP.localToGlobalPosition(self.graphElement.container, 0, 0)
        self.move(x, y)
        self.show()

####    Not implemented
####class EllipseWidget( LeafElementWidget, qtcanvas.QCanvasEllipse ):
####    def __init__( self, graphElement, canvas=None ):
####        LeafElementWidget.__init__(self,graphElement)
####        qtcanvas.QCanvasEllipse.__init__(self,canvas)
####        self.updateWidget()
####        self.show()
####        self.setVisible(True)
####        self.setActive(True)

####    def updateWidget( self ):
####        print self.graphElement
####        # Must do a local2global
####        self.cx,self.cy = int(self.graphElement.center.x),int(self.graphElement.center.y)
####        self.rx,self.ry = int(self.graphElement.radiusX),int(self.graphElement.radiusY)
####        self.posX, self.posY = self.cx - 2*self.rx, self.cy - 2*self.ry
####        self.sAng = float(self.graphElement.startAngle)
####        self.eAng = float(self.graphElement.endAngle)
####        self.totAng = self.eAng  - self.sAng
####        self.rotation = float(self.graphElement.rotation)
####        qtcanvas.QCanvasEllipse.setWinding(self,True)
####        self.setSize(2*self.rx,2*self.ry)
####        self.setAngles(int(math.degrees(self.sAng)*16),int(math.degrees(self.totAng)*16))
####        self.setX(self.cx)
####        self.setY(self.cy)
####        LeafElementWidget.updateWidget(self)

####    def drawShape( self, painter ):
####        painter.save()
####        print "EllipseWidget updated"
####        LeafElementWidget.drawShape(self, painter)
####        if self.rotation:
####            painter.translate(self.cx,self.cy)
####            painter.rotate(-math.degrees(self.rotation))
####            painter.translate(-self.cx,-self.cy)


####        qtcanvas.QCanvasEllipse.drawShape( self,painter )
####        ap = self.areaPoints()
####        print ap
####        DISUPPGFX.setPenColor(painter, qt.Qt.black)
####        painter.drawPolyline(ap)
######        if math.degrees(math.fabs(self.eAng-self.sAng)) < 360.0:
######            painter.drawPie(self.posX,self.posY,2*self.rx,2*self.ry,int(math.degrees(self.sAng)*16),int(math.degrees(self.totAng)*16))
######        else:
######            painter.drawEllipse(self.posX,self.posY,2*self.rx,2*self.ry)
####        painter.restore()

####    def onModelChanged(self):
####        print "Ellipse detected onmodelchange"
####        self.updateWidget()

class GraphNodeWidget( GraphElementWidget, qtcanvas.QCanvasRectangle ):
    def __init__( self, graphElement, ext, canvas=None ):
        GraphElementWidget.__init__(self,graphElement,ext)
        qtcanvas.QCanvasRectangle.__init__(self,canvas)
        
        self.selection = []
        # self.edgeArranger = EdgeTranslator(0,0) # Refactoring

        self.setVisible(graphElement.isVisible)
        self.updateWidget()

    def setSelectionVisible( self, yes ):
        for s in self.selection:
            if yes:
                s.show()
                s.setCanvas(self.canvas())
            else:
                s.hide()
                s.setCanvas(None)


    def updateWidget(self):
        absx,absy = DISUPP.localToGlobalPosition(self.graphElement,0.0,0.0)
        if (self.x()!=int(absx) or self.y()!=int(absy) or 
            self.width()!=int(self.graphElement.size.width) or 
            self.height()!=int(self.graphElement.size.height)):
         
            self.setX(absx)
            self.setY(absy)
            self.setSize(int(self.graphElement.size.width),
                         int(self.graphElement.size.height))

        GraphElementWidget.updateWidget(self)

        for s in self.selection:
            s.updateWidget()

                  
    def drawShape(self,painter):
        if self.graphElementRenderer.__class__ == NullRenderer:
            return
        if self.graphElement.semanticModel:
            painter.save()
            try:
                x = self.x()
                y = self.y()
                ### We really don't need this and
                ### it makes the postscript output bad
                ### because some line edges are drawn slightly outside
                ### of the clip rectangle
                ###painter.setClipRect(x, y, self.width(), self.height(), 1)
                painter.translate(x, y)
                painter.setFont(defaultFont)
                painter.setBrush( qt.QBrush(DISUPPGFX.getBgColor(self.graphElement), qt.QBrush.SolidPattern) )
                c = DISUPPGFX.getFgColor(self.graphElement)
                DISUPPGFX.setPenColor(painter, c)
                self.graphElementRenderer.drawShape(painter)
            finally:
                painter.restore()
        else:
            qtcanvas.QCanvasRectangle.drawShape(self,painter)
            
class GraphEdgeWidget( GraphElementWidget, qtcanvas.QCanvasPolygon ):

    def __init__( self, graphElement, ext, canvas=None ):
        GraphElementWidget.__init__(self,graphElement,ext)
        qtcanvas.QCanvasPolygon.__init__(self,canvas)

        self.selection = []

        self.setVisible(graphElement.isVisible)
        self.updateWidget()

    def relinkable( self ):
        return True

    def setSelectionVisible( self, yes ):
        for s in self.selection:
            if yes:
                s.show()
                s.setCanvas(self.canvas())
            else:
                s.hide()
                s.setCanvas(None)


    def addPoint(self,x0,y0):
        """addPoint(self,x0,y0) adds the point (x0,y0) to the polyline between the two points where the
        ratio between the new length and the old length is the smallest.
        """
        minlength=(10000,0) # high sentinel minlength
        for i in range(len(self.points)-1):
            pia = self.points[i]
            pib = self.points[i+1]
            length = math.sqrt(math.pow(pia[0]-x0,2)+math.pow(pia[1]-y0,2)) +\
                     math.sqrt(math.pow(x0-pib[0],2)+math.pow(y0-pib[1],2))

            linelength = math.sqrt(math.pow(pia[0]-pib[0],2)+\
                                   math.pow(pia[1]-pib[1],2))
            
            if linelength:
                if length/linelength < minlength[0]:
                    minlength = (length/linelength,i)
        
        self.points.insert(minlength[1]+1,[x0,y0])
        self.updateElement()


    def removePoint(self,x0,y0):
        """removePoint(self,x0,y0) removes point in the polyline located nearest (x0,y0),
        if the nearest point is an endpoint of the polyline or user clicked more than 10 pixels away from
        a corner point, the command is ingnored. 
        """
        mindistance = (10000,0)
        for i in range(len(self.points)):
            distance = math.sqrt(math.pow(self.points[i][0]-x0,2)+math.pow(self.points[i][1]-y0,2))
            if distance < mindistance[0]:
                mindistance = (distance,i)
            
        if not(mindistance[1] == 0 or mindistance[1] == len(self.points)-1 or mindistance[0]>10):
            #we should not delete if it is the first or the last point or user clicked too far away from a point
            self.points = self.points[:mindistance[1]]+self.points[mindistance[1]+1:]
        self.updateElement()
            

    def updateBoundingBox(self,join=0,recurse=1):
        """updateElement calculates the bounding polygon for the AbstractLinkView,
        currently both join and recurse are unused.
        """
        logger.info("AbstractLinkView.updateElement()")
        fieldwidth = 5
        polygon = []
        normals = []

        xo,yo = DISUPP.localToGlobalPosition(self.graphElement,0.0,0.0)

        for segm in range(len(self.points)-1):
            x1,y1 = self.points[segm]
            x2,y2 = self.points[segm+1]
            dx = x2 - x1
            dy = y2 - y1
            vlen = math.sqrt(dx**2 + dy**2)

            if vlen:
                nv = (fieldwidth * dy / vlen, -fieldwidth * dx / vlen)
            else:
                nv = (0,0)
            normals.append(nv)

        x1 = self.points[0][0] + normals[0][0]
        y1 = self.points[0][1] + normals[0][1]
        for segm in range(len(self.points)-1):
            nv = normals[segm]
            x2 = self.points[segm+1][0] + nv[0]
            y2 = self.points[segm+1][1] + nv[1]
            polygon.append(x1)
            polygon.append(y1)
            polygon.append(x2)
            polygon.append(y2)
            if segm == len(self.points)-2:
                pass
            else:
                x2 = self.points[segm+1][0] + normals[segm+1][0]
                y2 = self.points[segm+1][1] + normals[segm+1][1]
            x1,y1 = x2,y2

        x1 = self.points[-1][0] - normals[-1][0]
        y1 = self.points[-1][1] - normals[-1][1]
        for segm in range(len(self.points)-2,-1,-1):
            nv = normals[segm]
            x2 = self.points[segm][0] - nv[0]
            y2 = self.points[segm][1] - nv[1]
            polygon.append(x1)
            polygon.append(y1)
            polygon.append(x2)
            polygon.append(y2)
            if segm == 0:
                pass
            else:
                x2 = self.points[segm][0]-normals[segm-1][0]
                y2 = self.points[segm][1]-normals[segm-1][1]
            x1,y1 = x2,y2

        self.polygon  = qt.QPointArray(polygon)

        qtcanvas.QCanvasPolygon.setWinding(self,1)
        qtcanvas.QCanvasPolygon.setPoints(self,self.polygon)
        qtcanvas.QCanvasPolygon.update(self)


    def drawShape(self,painter):
        """drawShape draws the link"""
        if self.graphElementRenderer.__class__ == NullRenderer:
            return
        if not self.graphElement.semanticModel:
            return
        painter.save()
        try:
            ger = self.graphElementRenderer

            if not ger:
                return

            c = DISUPPGFX.getFgColor(self.graphElement)
            DISUPPGFX.setPenColor(painter, c)
            painter.translate(self.x(), self.y())
            ger.drawMainPolyline(painter, self.graphElement.waypoints)

            slope1=math.atan2(self.points[1][1]-self.points[0][1],
                              self.points[1][0]-self.points[0][0])
            slope2=math.atan2(self.points[-1][1]-self.points[-2][1],
                              self.points[-1][0]-self.points[-2][0])

            # render begin connector
            dx = self.points[0][0]
            dy = self.points[0][1]
            # Add some magic here so that edge-ends are
            # at a slightly better position
            dx += math.cos(slope1)
            dy += math.sin(slope1)
            painter.save()
            try:
                painter.translate(dx, dy)
                painter.rotate(math.degrees(slope1))
                ger.drawBeginConnector(painter)
            finally:
                painter.restore()

            # render end connector
            # (last thing, so no need to save..restore)
            dx = self.points[-1][0]
            dy = self.points[-1][1]
            # Add some magic here so that edge-ends are
            # at a slightly better position
            dx -= math.cos(slope2)
            dy -= math.sin(slope2)
            painter.translate(dx, dy)
            painter.rotate(math.degrees(slope2))
            ger.drawEndConnector(painter)
        finally:   
            painter.restore()
        

    def updateWidget( self ):
        xo,yo = DISUPP.localToGlobalPosition(self.graphElement,0.0,0.0)
        self.setX(xo)
        self.setY(yo)
        self.points = [list((float(p.x),float(p.y))) for p in self.graphElement.waypoints ]
        self.updateBoundingBox()
        GraphElementWidget.updateWidget(self)
        for s in self.selection:
            s.updateWidget()
            


###################################################################
# Selection widgets

class MarkerRectangle( qtcanvas.QCanvasRectangle ):
    """MarkerRectange is a presentation element
    (the visible black bounding rect when selecting multiple items)
    """
    def __init__(self,presentation,x,y,w,h,canvas,plus=1):
        self.presentation=presentation
        self.oX=x
        self.oY=y
        self.oW=w
        self.oH=h
        self.plus=plus
        qtcanvas.QCanvasRectangle.__init__(self,x,y,w,h,canvas)
        self.setZ(30000)
        self.show()

    def selectable( self ):
        return False

    def drawShape(self,painter):
        x = self.x()
        y = self.y()
        w = self.width()
        h = self.height()
        painter.drawRect(x, y, w, h)
        if self.plus:
            painter.drawLine(x + w/2, y+h/2-2,
                             x + w/2, y+h/2+2)
            painter.drawLine(x + w/2-2, y+h/2,
                             x + w/2+2, y+h/2)



class HandleWidget( qtcanvas.QCanvasRectangle ):

    def __init__( self, onWidget, canvas=None ):
        qtcanvas.QCanvasRectangle.__init__(self,canvas)
        self.onWidget = onWidget
        self.setSize(5,5)
        self.setZ(30000)
        self.updateWidget()


    def selectable( self ):
        return False


    def updateWidget( self ):
        pass

    def drawShape( self, painter ):
        DISUPPGFX.setPenColor(painter, qt.Qt.black)
        painter.setBrush(qt.QBrush(qt.QColor(0,0,200)))
        painter.drawEllipse(self.rect())

    def cursor( self ):
        return qt.QCursor(qt.Qt.ArrowCursor)



class EdgeHandleWidget( HandleWidget ):

    def __init__( self, onWidget, n, canvas=None ):
        self.n = n
        HandleWidget.__init__(self,onWidget,canvas)


    def updateWidget( self ):
        p = self.onWidget.points
        # This shouldn't happen...
        if self.n >= len(p):
            return

        ix = self.onWidget.x()
        iy = self.onWidget.y()
        x = p[self.n][0] - self.width()/2 + ix
        y = p[self.n][1] - self.height()/2 + iy
        self.setX(x)
        self.setY(y)

        

class NodeHandleWidget( HandleWidget ):

    RESIZE_N=1
    RESIZE_E=2
    RESIZE_W=4
    RESIZE_S=8
    RESIZE_NE=RESIZE_N | RESIZE_E
    RESIZE_NW=RESIZE_N | RESIZE_W
    RESIZE_SE=RESIZE_S | RESIZE_E
    RESIZE_SW=RESIZE_S | RESIZE_W

    def __init__( self, onWidget, role, canvas=None ):
        self.role = role
        HandleWidget.__init__(self,onWidget,canvas)


    def updateWidget( self ):
        w = self.width()
        h = self.height()
        x = self.onWidget.x() + (self.onWidget.width() - w)/2
        y = self.onWidget.y() + (self.onWidget.height() - h)/2
        if self.role&self.RESIZE_N:
            y = self.onWidget.rect().top() - h/2
        if self.role&self.RESIZE_E:
            x = self.onWidget.rect().right() - w/2
        if self.role&self.RESIZE_W:
            x = self.onWidget.rect().left() - w/2
        if self.role&self.RESIZE_S:
            y = self.onWidget.rect().bottom() - h/2
        self.setX(x)
        self.setY(y)


    def cursor( self ):
        if not self.onWidget.resizable():
            return qt.QCursor()
        
        if self.role in (self.RESIZE_NE,self.RESIZE_SW):
            return qt.QCursor(qt.Qt.SizeBDiagCursor)
        elif self.role in (self.RESIZE_NW,self.RESIZE_SE):
            return qt.QCursor(qt.Qt.SizeFDiagCursor)
        elif self.role in (self.RESIZE_N,self.RESIZE_S):
            return qt.QCursor(qt.Qt.SizeVerCursor)
        elif self.role in (self.RESIZE_E,self.RESIZE_W):
            return qt.QCursor(qt.Qt.SizeHorCursor)

