Changeset 11192:d51939aa6f45 in orange


Ignore:
Timestamp:
11/21/12 19:37:17 (17 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Changed annotation item selection and (control point) geometry editing.

Control point editing is now fixed to the items focus state.

Location:
Orange/OrangeCanvas
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/canvas/items/annotationitem.py

    r11185 r11192  
    6060        self.__textItem.setTextWidth(rect.width() - 4) 
    6161        self.__textItem.setTabChangesFocus(True) 
     62        self.__textItem.setTextInteractionFlags(Qt.NoTextInteraction) 
    6263        self.__textInteractionFlags = Qt.NoTextInteraction 
    6364 
    6465        layout = self.__textItem.document().documentLayout() 
    6566        layout.documentSizeChanged.connect(self.__onDocumentSizeChanged) 
    66  
    67         self.setFocusProxy(self.__textItem) 
    6867 
    6968        self.__updateFrame() 
     
    154153    def setTextInteractionFlags(self, flags): 
    155154        self.__textInteractionFlags = flags 
    156         if self.__textItem.hasFocus(): 
    157             self.__textItem.setTextInteractionFlags(flags) 
    158155 
    159156    def textInteractionFlags(self): 
     
    173170        """Start the annotation text edit process. 
    174171        """ 
    175         self.__textItem.setTextInteractionFlags( 
    176                             self.__textInteractionFlags) 
     172        self.__textItem.setTextInteractionFlags(self.__textInteractionFlags) 
    177173        self.__textItem.setFocus(Qt.MouseFocusReason) 
    178174 
     
    186182        """End the annotation edit. 
    187183        """ 
    188         if self.__textItem.hasFocus(): 
    189             self.__textItem.clearFocus() 
    190  
    191184        self.__textItem.setTextInteractionFlags(Qt.NoTextInteraction) 
    192185        self.__textItem.removeSceneEventFilter(self) 
  • Orange/OrangeCanvas/canvas/items/controlpoints.py

    r11172 r11192  
    109109    rectChanged = Signal(QRectF) 
    110110    rectEdited = Signal(QRectF) 
    111  
    112     editingStarted = Signal() 
    113     editingFinished = Signal() 
    114111 
    115112    def __init__(self, parent=None, rect=None, constraints=0, **kwargs): 
     
    193190        pass 
    194191 
    195     def focusInEvent(self, event): 
    196         QGraphicsObject.focusInEvent(self, event) 
    197         if event.isAccepted(): 
    198             self.editingStarted.emit() 
    199  
    200     def focusOutEvent(self, event): 
    201         QGraphicsObject.focusOutEvent(self, event) 
    202         if event.isAccepted(): 
    203             self.editingFinished.emit() 
     192    def isControlActive(self): 
     193        """Return the state of the control. True if the control is 
     194        active (user is dragging one of the points) False otherwise. 
     195 
     196        """ 
     197        return self.__activeControl is not None 
    204198 
    205199    def itemChange(self, change, value): 
     
    312306    lineEdited = Signal(QLineF) 
    313307 
    314     editingStarted = Signal() 
    315     editingFinished = Signal() 
    316  
    317308    def __init__(self, parent=None, **kwargs): 
    318309        QGraphicsObject.__init__(self, parent, **kwargs) 
     
    330321        if self.scene(): 
    331322            self.__installFilter() 
     323 
    332324        for p in self.__points: 
    333325            p.setFlag(QGraphicsItem.ItemIsFocusable) 
     
    346338        return self.__line 
    347339 
    348     def focusInEvent(self, event): 
    349         QGraphicsObject.focusInEvent(self, event) 
    350         if event.isAccepted(): 
    351             self.editingStarted.emit() 
    352  
    353     def focusOutEvent(self, event): 
    354         QGraphicsObject.focusOutEvent(self, event) 
    355         if event.isAccepted(): 
    356             self.editingFinished.emit() 
     340    def isControlActive(self): 
     341        """Return the state of the control. True if the control is 
     342        active (user is dragging one of the points) False otherwise. 
     343 
     344        """ 
     345        return self.__activeControl is not None 
    357346 
    358347    def __installFilter(self): 
  • Orange/OrangeCanvas/document/interactions.py

    r11185 r11192  
    719719        if self.control is not None: 
    720720            self.scene.removeItem(self.control) 
     721 
    721722        self.control = None 
    722723        self.down_pos = None 
     
    734735        self.control = None 
    735736        self.savedFramePen = None 
     737        self.savedRect = None 
    736738 
    737739    def mousePressEvent(self, event): 
     
    741743            if item is not None and not item.hasFocus(): 
    742744                self.editItem(item) 
    743                 return True 
     745                return False 
    744746 
    745747        return UserInteraction.mousePressEvent(self, event) 
     
    752754 
    753755        self.savedFramePen = item.framePen() 
    754         self.initialRect = rect 
    755  
    756         control.setFocus() 
    757         control.editingFinished.connect(self.__on_editingFinished) 
     756        self.savedRect = rect 
     757 
    758758        control.rectEdited.connect(item.setGeometry) 
     759        control.setFocusProxy(item) 
    759760 
    760761        item.setFramePen(QPen(Qt.DashDotLine)) 
     762        item.geometryChanged.connect(self.__on_textGeometryChanged) 
    761763 
    762764        self.item = item 
     
    765767        self.control = control 
    766768 
     769    def commit(self): 
     770        """Commit the current item geometry state to the document. 
     771        """ 
     772        rect = self.item.geometry() 
     773        if self.savedRect != rect: 
     774            command = commands.SetAttrCommand( 
     775                self.annotation, "rect", 
     776                (rect.x(), rect.y(), rect.width(), rect.height()), 
     777                name="Edit text geometry" 
     778            ) 
     779            self.document.undoStack().push(command) 
     780            self.savedRect = rect 
     781 
    767782    def __on_editingFinished(self): 
    768         rect = self.item.geometry() 
    769         command = commands.SetAttrCommand( 
    770             self.annotation, "rect", 
    771             (rect.x(), rect.y(), rect.width(), rect.height()), 
    772             name="Edit text geometry" 
    773         ) 
    774         self.document.undoStack().push(command) 
     783        self.commit() 
    775784        self.end() 
    776785 
     
    778787        self.item.setGeometry(rect) 
    779788 
     789    def __on_textGeometryChanged(self): 
     790        if not self.control.isControlActive(): 
     791            rect = self.item.geometry() 
     792            self.control.setRect(rect) 
     793 
    780794    def cancel(self): 
    781         if self.item is not None: 
    782             self.item.setGeometry(self.initialRect) 
     795        if self.item is not None and self.savedRect is not None: 
     796            self.item.setGeometry(self.savedRect) 
    783797 
    784798        UserInteraction.cancel(self) 
     
    786800    def end(self): 
    787801        if self.control is not None: 
    788             self.control.clearFocus() 
    789802            self.scene.removeItem(self.control) 
    790803 
     
    805818        self.annotation = None 
    806819        self.control = None 
     820        self.savedLine = None 
    807821 
    808822    def mousePressEvent(self, event): 
     
    812826            if item is not None and not item.hasFocus(): 
    813827                self.editItem(item) 
    814                 return True 
     828                return False 
    815829 
    816830        return UserInteraction.mousePressEvent(self, event) 
     
    822836 
    823837        line = item.line() 
    824         self.initialLine = line 
     838        self.savedLine = line 
    825839 
    826840        p1, p2 = map(item.mapToScene, (line.p1(), line.p2())) 
    827841 
    828842        control.setLine(QLineF(p1, p2)) 
    829         control.setFocus() 
    830         control.editingFinished.connect(self.__on_editingFinished) 
     843        control.setFocusProxy(item) 
    831844        control.lineEdited.connect(self.__on_lineEdited) 
     845 
     846        item.geometryChanged.connect(self.__on_lineGeometryChanged) 
    832847 
    833848        self.item = item 
     
    835850        self.control = control 
    836851 
    837     def __on_editingFinished(self): 
     852    def commit(self): 
     853        """Commit the current geometry of the item to the document. 
     854 
     855        .. note:: Does nothing if the actual geometry is not changed. 
     856 
     857        """ 
    838858        line = self.control.line() 
    839859        p1, p2 = line.p1(), line.p2() 
    840860 
    841         command = commands.SetAttrCommand( 
    842             self.annotation, 
    843             "geometry", 
    844             ((p1.x(), p1.y()), (p2.x(), p2.y())), 
    845             name="Edit arrow geometry", 
    846         ) 
    847         self.document.undoStack().push(command) 
    848         self.control.hide() 
    849  
     861        if self.item.line() != self.savedLine: 
     862            command = commands.SetAttrCommand( 
     863                self.annotation, 
     864                "geometry", 
     865                ((p1.x(), p1.y()), (p2.x(), p2.y())), 
     866                name="Edit arrow geometry", 
     867            ) 
     868            self.document.undoStack().push(command) 
     869            self.savedLine = self.item.line() 
     870 
     871    def __on_editingFinished(self): 
     872        self.commit() 
    850873        self.end() 
    851874 
     
    855878        self.item.adjustGeometry() 
    856879 
     880    def __on_lineGeometryChanged(self): 
     881        # Possible geometry change from out of our control, for instance 
     882        # item move as a part of a selection group. 
     883        if not self.control.isControlActive(): 
     884            line = self.item.line() 
     885            p1, p2 = map(self.item.mapToScene, (line.p1(), line.p2())) 
     886            self.control.setLine(QLineF(p1, p2)) 
     887 
    857888    def cancel(self): 
    858         if self.item is not None: 
    859             self.item.setLine(self.initialLine) 
     889        if self.item is not None and self.savedLine is not None: 
     890            self.item.setLine(self.savedLine) 
    860891 
    861892        UserInteraction.cancel(self) 
     
    865896            self.scene.removeItem(self.control) 
    866897 
     898        if self.item is not None: 
     899            self.item.geometryChanged.disconnect(self.__on_lineGeometryChanged) 
     900 
    867901        self.control = None 
    868902        self.item = None 
  • Orange/OrangeCanvas/document/schemeedit.py

    r11165 r11192  
    3737 
    3838    def sceneEventFilter(self, obj, event): 
     39        print obj, event, event.type() 
    3940        if event.type() == QEvent.FocusIn and \ 
    4041                obj.flags() & QGraphicsItem.ItemIsFocusable: 
     
    197198 
    198199            self.__scene.set_registry(self.__registry) 
    199             self.__scene.set_scheme(scheme) 
    200  
    201             self.__scene.selectionChanged.connect( 
    202                 self.__onSelectionChanged 
    203             ) 
    204  
    205             self.__scene.node_item_activated.connect( 
    206                 self.__onNodeActivate 
    207             ) 
    208  
    209             self.__scene.annotation_added.connect( 
    210                 self.__onAnnotationAdded 
    211             ) 
    212  
    213             self.__scene.annotation_removed.connect( 
    214                 self.__onAnnotationRemoved 
    215             ) 
    216  
     200 
     201            # Focus listener 
    217202            self.__focusListener = GraphicsSceneFocusEventListener() 
    218203            self.__focusListener.itemFocusedIn.connect( 
     
    223208            ) 
    224209            self.__scene.addItem(self.__focusListener) 
     210 
     211            self.__scene.selectionChanged.connect( 
     212                self.__onSelectionChanged 
     213            ) 
     214 
     215            self.__scene.node_item_activated.connect( 
     216                self.__onNodeActivate 
     217            ) 
     218 
     219            self.__scene.annotation_added.connect( 
     220                self.__onAnnotationAdded 
     221            ) 
     222 
     223            self.__scene.annotation_removed.connect( 
     224                self.__onAnnotationRemoved 
     225            ) 
     226 
     227            self.__scene.set_scheme(scheme) 
    225228 
    226229    def scheme(self): 
     
    439442            return handler.mousePressEvent(event) 
    440443 
    441         annotation_item = scene.item_at(pos, (items.TextAnnotation, 
    442                                               items.ArrowAnnotation)) 
    443  
    444         if annotation_item and event.button() == Qt.LeftButton and \ 
    445                 not event.modifiers() & Qt.ControlModifier: 
    446             if isinstance(annotation_item, items.TextAnnotation): 
    447                 handler = interactions.ResizeTextAnnotation(self) 
    448             elif isinstance(annotation_item, items.ArrowAnnotation): 
    449                 handler = interactions.ResizeArrowAnnotation(self) 
    450             else: 
    451                 log.error("Unknown annotation item (%r).", annotation_item) 
    452                 return False 
    453  
    454             scene.clearSelection() 
    455  
    456             scene.set_user_interaction_handler(handler) 
    457             return handler.mousePressEvent(event) 
    458  
    459444        any_item = scene.item_at(pos) 
    460445        if not any_item and event.button() == Qt.LeftButton: 
     
    603588 
    604589    def __onAnnotationAdded(self, item): 
     590        log.debug("Annotation added (%r)", item) 
    605591        item.setFlag(QGraphicsItem.ItemIsSelectable) 
     592        item.setFlag(QGraphicsItem.ItemIsMovable) 
     593        item.setFlag(QGraphicsItem.ItemIsFocusable) 
     594 
     595        item.installSceneEventFilter(self.__focusListener) 
     596 
    606597        if isinstance(item, items.ArrowAnnotation): 
    607598            pass 
    608599        elif isinstance(item, items.TextAnnotation): 
     600            # Make the annotation editable. 
     601            item.setTextInteractionFlags(Qt.TextEditorInteraction) 
     602 
    609603            self.__editFinishedMapper.setMapping(item, item) 
    610604            item.editingFinished.connect( 
    611605                self.__editFinishedMapper.map 
    612606            ) 
     607 
    613608        self.__annotationGeomChanged.setMapping(item, item) 
    614609        item.geometryChanged.connect( 
     
    617612 
    618613    def __onAnnotationRemoved(self, item): 
     614        log.debug("Annotation removed (%r)", item) 
    619615        if isinstance(item, items.ArrowAnnotation): 
    620616            pass 
     
    623619                self.__editFinishedMapper.map 
    624620            ) 
     621 
     622        item.removeSceneEventFilter(self.__focusListener) 
     623 
    625624        self.__annotationGeomChanged.removeMappings(item) 
    626625        item.geometryChanged.disconnect( 
     
    629628 
    630629    def __onItemFocusedIn(self, item): 
    631         pass 
     630        """Annotation item has gained focus. 
     631        """ 
     632        if not self.__scene.user_interaction_handler: 
     633            self.__startControlPointEdit(item) 
    632634 
    633635    def __onItemFocusedOut(self, item): 
    634         pass 
     636        """Annotation item lost focus. 
     637        """ 
     638        self.__endControlPointEdit() 
    635639 
    636640    def __onEditingFinished(self, item): 
     641        """Text annotation editing has finished. 
     642        """ 
    637643        annot = self.__scene.annotation_for_item(item) 
    638644        text = unicode(item.toPlainText()) 
     
    661667 
    662668    def __toogleLinkEnabled(self, enabled): 
     669        """Link enabled state was toogled in the context menu. 
     670        """ 
    663671        if self.__contextMenuTarget: 
    664672            link = self.__contextMenuTarget 
     
    669677 
    670678    def __linkRemove(self): 
     679        """Remove link was requested from the context menu. 
     680        """ 
    671681        if self.__contextMenuTarget: 
    672682            self.removeLink(self.__contextMenuTarget) 
    673683 
    674684    def __linkReset(self): 
     685        """Link reset from the context menu was requested. 
     686        """ 
    675687        if self.__contextMenuTarget: 
    676688            link = self.__contextMenuTarget 
     
    679691            ) 
    680692            action.edit_links() 
     693 
     694    def __startControlPointEdit(self, item): 
     695        """Start a control point edit interaction for item. 
     696        """ 
     697        if isinstance(item, items.ArrowAnnotation): 
     698            handler = interactions.ResizeArrowAnnotation(self) 
     699        elif isinstance(item, items.TextAnnotation): 
     700            handler = interactions.ResizeTextAnnotation(self) 
     701        else: 
     702            log.warning("Unknown annotation item type %r" % item) 
     703            return 
     704 
     705        handler.editItem(item) 
     706        self.__scene.set_user_interaction_handler(handler) 
     707 
     708        log.info("Control point editing started (%r)." % item) 
     709 
     710    def __endControlPointEdit(self): 
     711        """End the current control point edit interaction. 
     712        """ 
     713        handler = self.__scene.user_interaction_handler 
     714        if isinstance(handler, (interactions.ResizeArrowAnnotation, 
     715                                interactions.ResizeTextAnnotation)): 
     716            handler.commit() 
     717            handler.end() 
     718 
     719            log.info("Control point editing finished.") 
    681720 
    682721 
Note: See TracChangeset for help on using the changeset viewer.