Changeset 11134:306625da2200 in orange


Ignore:
Timestamp:
10/17/12 16:49:40 (18 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Added information, warning and error indicators to items in the canvas.

Location:
Orange
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/application/schemedocument.py

    r11124 r11134  
    110110        self.scene = CanvasScene(self) 
    111111        self.scene.setStickyFocus(False) 
     112 
    112113        self.scene.node_item_activated.connect(self._on_node_activate) 
    113114        self.scene.node_item_position_changed.connect( 
    114115            self._on_node_position_changed 
    115116        ) 
     117 
    116118        self.scene.set_registry(self.registry) 
    117119        self.scene.set_scheme(scheme) 
     
    122124            self.scheme.close_all_open_widgets() 
    123125            self.scheme.title_changed.disconnect(self.title_changed) 
     126            self.scheme.node_added.disconnect(self._on_node_added) 
    124127 
    125128        self.scheme = scheme 
     
    128131            self.scheme.title_changed.connect(self.title_changed) 
    129132            self.title_changed.emit(self.scheme.title) 
     133            self.scheme.node_added.connect(self._on_node_added) 
    130134 
    131135    def create_new_node(self, desc, position=None): 
     
    135139            item = self.scene.item_for_node(node) 
    136140            node.position = (item.pos().x(), item.pos().y()) 
     141 
     142    def node_for_widget(self, widget): 
     143        rev = dict(map(reversed, self.scheme.widget_for_node.items())) 
     144        return rev[widget] 
     145 
     146    def _on_node_added(self, node): 
     147        widget = self.scheme.widget_for_node[node] 
     148        widget.widgetStateChanged.connect(self._on_widget_state_changed) 
     149 
     150    def _on_widget_state_changed(self, *args): 
     151        widget = self.sender() 
     152        node = self.node_for_widget(widget) 
     153        item = self.scene.item_for_node(node) 
     154 
     155        info = widget.widgetStateToHtml(True, False, False) 
     156        warning = widget.widgetStateToHtml(False, True, False) 
     157        error = widget.widgetStateToHtml(False, False, True) 
     158 
     159        item.setInfoMessage(info or None) 
     160        item.setWarningMessage(warning or None) 
     161        item.setErrorMessage(error or None) 
    137162 
    138163    def _on_node_activate(self, item): 
  • Orange/OrangeCanvas/canvas/items/nodeitem.py

    r11102 r11134  
    1010    QGraphicsTextItem, QGraphicsDropShadowEffect, 
    1111    QPen, QBrush, QColor, QPalette, QFont, QIcon, QStyle, 
    12     QPainter, QPainterPath, QPainterPathStroker 
     12    QPainter, QPainterPath, QPainterPathStroker, QApplication 
    1313) 
    1414 
     
    323323 
    324324 
     325class MessageIcon(QGraphicsPixmapItem): 
     326    def __init__(self, *args, **kwargs): 
     327        QGraphicsPixmapItem.__init__(self, *args, **kwargs) 
     328 
     329 
     330def message_pixmap(standard_pixmap): 
     331    style = QApplication.instance().style() 
     332    icon = style.standardIcon(standard_pixmap) 
     333    return icon.pixmap(16, 16) 
     334 
     335 
    325336class NodeItem(QGraphicsObject): 
    326337    """An widget node item in the canvas. 
     
    353364        self.setFlag(QGraphicsItem.ItemIsFocusable, True) 
    354365 
     366        # central body shape item 
     367        self.shapeItem = None 
     368 
     369        # in/output anchor items 
     370        self.inputAnchorItem = None 
     371        self.outputAnchorItem = None 
     372 
    355373        # round anchor indicators on the anchor path 
    356374        self.inputAnchors = [] 
    357375        self.outputAnchors = [] 
    358376 
     377        # title text item 
     378        self.captionTextItem = None 
     379 
     380        # error, warning, info items 
     381        self.errorItem = None 
     382        self.warningItem = None 
     383        self.infoItem = None 
     384 
    359385        self.__title = "" 
    360386        self.__processingState = 0 
    361387        self.__progress = -1 
     388 
     389        self.__error = None 
     390        self.__warning = None 
     391        self.__info = None 
    362392 
    363393        self.setZValue(self.Z_VALUE) 
     
    419449        self.captionTextItem.setFont(font) 
    420450 
     451        self.errorItem = MessageIcon(self) 
     452        self.errorItem.setPixmap(message_pixmap(QStyle.SP_MessageBoxCritical)) 
     453        self.errorItem.hide() 
     454 
     455        self.warningItem = MessageIcon(self) 
     456        self.warningItem.setPixmap(message_pixmap(QStyle.SP_MessageBoxWarning)) 
     457        self.warningItem.hide() 
     458 
     459        self.infoItem = MessageIcon(self) 
     460        self.infoItem.setPixmap(message_pixmap(QStyle.SP_MessageBoxInformation)) 
     461        self.infoItem.hide() 
     462 
    421463    def setWidgetDescription(self, desc): 
    422464        """Set widget description. 
     
    466508            selectedColor = saturated(color, 150) 
    467509        palette = create_palette(color, selectedColor) 
    468 #        gradient = radial_gradient(color, selectedColor) 
    469 #        self.shapeItem.setBrush(QBrush(gradient)) 
    470510        self.shapeItem.setPalette(palette) 
    471511 
     
    527567 
    528568    def setErrorMessage(self, message): 
    529         pass 
     569        if self.__error != message: 
     570            self.__error = message 
     571            self.__updateMessages() 
    530572 
    531573    def setWarningMessage(self, message): 
    532         pass 
    533  
    534     def setInformationMessage(self, message): 
    535         pass 
     574        if self.__warning != message: 
     575            self.__warning = message 
     576            self.__updateMessages() 
     577 
     578    def setInfoMessage(self, message): 
     579        if self.__info != message: 
     580            self.__info = message 
     581            self.__updateMessages() 
    536582 
    537583    def newInputAnchor(self): 
     
    619665        # Should this return the union of all child items? 
    620666        return self.shapeItem.shape() 
    621  
    622 #    def _delegate(self, event): 
    623 #        """Called by child items. Delegate the event actions to the 
    624 #        appropriate actions. 
    625 # 
    626 #        """ 
    627 #        if event == "mouseDoubleClickEvent": 
    628 #            self.activated.emit() 
    629 #        elif event == "hoverEnterEvent": 
    630 #            self.hovered.emit() 
    631667 
    632668    def __updateTitleText(self): 
     
    647683        width = self.captionTextItem.textWidth() 
    648684        self.captionTextItem.setPos(-width / 2.0, 33) 
     685 
     686    def __updateMessages(self): 
     687        """Update message items (position, visibility and tool tips). 
     688        """ 
     689        items = [self.errorItem, self.warningItem, self.infoItem] 
     690        messages = [self.__error, self.__warning, self.__info] 
     691        for message, item in zip(messages, items): 
     692            item.setVisible(bool(message)) 
     693            item.setToolTip(message or "") 
     694        shown = [item for item in items if item.isVisible()] 
     695        count = len(shown) 
     696        if count: 
     697            spacing = 3 
     698            rects = [item.boundingRect() for item in shown] 
     699            width = sum(rect.width() for rect in rects) 
     700            width += spacing * max(0, count - 1) 
     701            height = max(rect.height() for rect in rects) 
     702            origin = self.shapeItem.boundingRect().top() - spacing - height 
     703            origin = QPointF(-width / 2, origin) 
     704            for item, rect in zip(shown, rects): 
     705                item.setPos(origin) 
     706                origin = origin + QPointF(rect.width() + spacing, 0) 
    649707 
    650708    def mousePressEvent(self, event): 
  • Orange/OrangeCanvas/canvas/items/tests/test_nodeitem.py

    r11102 r11134  
    7373        self.assertTrue(len(positions) > 0) 
    7474 
     75        file_item.setErrorMessage("message") 
     76        file_item.setWarningMessage("message") 
     77        file_item.setInfoMessage("I am alive") 
     78 
     79        file_item.setErrorMessage(None) 
     80        file_item.setWarningMessage(None) 
     81        file_item.setInfoMessage(None) 
     82 
     83        file_item.setInfoMessage("I am back.") 
     84 
    7585        def progress(): 
    7686            self.singleShot(10, progress) 
    77             nb_item.setProgress((nb_item.progress() + 1) % 100) 
     87            p = (nb_item.progress() + 1) % 100 
     88            nb_item.setProgress(p) 
     89 
     90            if p > 50: 
     91                nb_item.setInfoMessage("Over 50%") 
     92                file_item.setWarningMessage("Second") 
     93            else: 
     94                nb_item.setInfoMessage(None) 
     95                file_item.setWarningMessage(None) 
    7896 
    7997        progress() 
  • Orange/OrangeCanvas/scheme/widgetsscheme.py

    r11101 r11134  
    66from .utils import name_lookup 
    77from ..config import rc 
     8from ..gui.utils import signals_disabled 
    89 
    910log = logging.getLogger(__name__) 
     
    2627    def add_node(self, node): 
    2728        widget = self.create_widget_instance(node) 
    28         Scheme.add_node(self, node) 
     29 
     30        # don't emit the node_added signal until the widget is successfully 
     31        # added to signal manager etc. 
     32        with signals_disabled(self): 
     33            Scheme.add_node(self, node) 
     34 
    2935        self.widgets.append(widget) 
    3036 
     
    3238 
    3339        self.signal_manager.addWidget(widget) 
     40 
     41        self.node_added.emit(node) 
    3442 
    3543    def remove_node(self, node): 
  • Orange/OrangeWidgets/OWBaseWidget.py

    r11101 r11134  
    860860            #qApp.processEvents() 
    861861        return changed 
    862      
     862 
     863    widgetStateChanged = pyqtSignal(QString, int, QString) 
     864    """Widget state has changed first arg is the state type 
     865    ('Info', 'Warning' or 'Error') the second is the message id 
     866    and finally the message string.""" 
     867 
    863868    def widgetStateToHtml(self, info=True, warning=True, error=True): 
    864869        pixmaps = self.getWidgetStateIcons() 
     
    868873                    "Error": "canvasIcons:error.png"} 
    869874        for show, what in [(info, "Info"), (warning, "Warning"),(error, "Error")]: 
    870             if self.widgetState[what]: 
     875            if show and self.widgetState[what]: 
    871876                items.append('<img src="%s" style="float: left;"> %s' % (iconPath[what], "\n".join(self.widgetState[what].values()))) 
    872877        return "<br>".join(items) 
Note: See TracChangeset for help on using the changeset viewer.