Changeset 11164:58a1f1863e0d in orange


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

Filter suggested widgets by compatible channel types.

Location:
Orange/OrangeCanvas/document
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/document/interactions.py

    r11163 r11164  
    6161class NoPossibleLinksError(ValueError): 
    6262    pass 
     63 
     64 
     65def reversed_arguments(func): 
     66    """Return a function with reversed argument order. 
     67    """ 
     68    def wrapped(*args): 
     69        return func(*reversed(args)) 
     70    return wrapped 
    6371 
    6472 
     
    231239                try: 
    232240                    node = self.create_new(event) 
     241                except Exception: 
     242                    log.error("Failed to create a new node, ending.", 
     243                              exc_info=True) 
     244                    node = None 
     245 
     246                if node is not None: 
    233247                    self.document.addNode(node) 
    234                 except Exception: 
    235                     log.error("Failed to create a new node, ending.") 
    236                     node = None 
    237248 
    238249            if node is not None: 
     
    250261        """ 
    251262        pos = event.screenPos() 
    252         quick_menu = self.document.quickMenu() 
    253  
    254         action = quick_menu.exec_(pos) 
     263        menu = self.document.quickMenu() 
     264        node = self.scene.node_for_item(self.from_item) 
     265        from_desc = node.description 
     266 
     267        def is_compatible(source, sink): 
     268            return any(scheme.compatible_channels(output, input) \ 
     269                       for output in source.outputs \ 
     270                       for input in sink.inputs) 
     271 
     272        if self.direction == self.FROM_SINK: 
     273            # Reverse the argument order. 
     274            is_compatible = reversed_arguments(is_compatible) 
     275 
     276        def filter(index): 
     277            desc = index.data(QtWidgetRegistry.WIDGET_DESC_ROLE) 
     278            if desc.isValid(): 
     279                desc = desc.toPyObject() 
     280                return is_compatible(from_desc, desc) 
     281            else: 
     282                return False 
     283 
     284        menu.setFilterFunc(filter) 
     285        try: 
     286            action = menu.exec_(pos) 
     287        finally: 
     288            menu.setFilterFunc(None) 
    255289 
    256290        if action: 
     
    401435        """ 
    402436        pos = event.screenPos() 
    403         quick_menu = self.document.quickMenu() 
    404  
    405         action = quick_menu.exec_(pos) 
     437        menu = self.document.quickMenu() 
     438        menu.setFilterFunc(None) 
     439 
     440        action = menu.exec_(pos) 
    406441        if action: 
    407442            item = action.property("item").toPyObject() 
  • Orange/OrangeCanvas/document/quickmenu.py

    r11163 r11164  
    1919 
    2020from PyQt4.QtCore import ( 
    21     Qt, QObject, QPoint, QSize, QRect, QEventLoop, QEvent 
     21    Qt, QObject, QPoint, QSize, QRect, QEventLoop, QEvent, QModelIndex 
    2222) 
    2323 
     
    363363 
    364364 
     365class SortFilterProxyModel(QSortFilterProxyModel): 
     366    def __init__(self, parent=None): 
     367        QSortFilterProxyModel.__init__(self, parent) 
     368        self.__filterFunc = None 
     369 
     370    def filterAcceptsRow(self, row, parent=QModelIndex()): 
     371        accepted = QSortFilterProxyModel.filterAcceptsRow(self, row, parent) 
     372        if accepted and self.__filterFunc is not None: 
     373            model = self.sourceModel() 
     374            index = model.index(row, self.filterKeyColumn(), parent) 
     375            return self.__filterFunc(index) 
     376        else: 
     377            return accepted 
     378 
     379    def filterFunc(self): 
     380        return self.__filterFunc 
     381 
     382    def setFilterFunc(self, func): 
     383        if self.__filterFunc is not func: 
     384            self.__filterFunc = func 
     385            self.invalidateFilter() 
     386 
     387 
    365388class SuggestMenuPage(ToolTree): 
    366389    def __init__(self, *args, **kwargs): 
     
    375398        flat.setSourceModel(model) 
    376399        flat.setFlatteningMode(flat.InternalNodesDisabled) 
    377         proxy = QSortFilterProxyModel(self) 
     400        proxy = SortFilterProxyModel(self) 
    378401        proxy.setFilterCaseSensitivity(False) 
    379402        proxy.setSourceModel(flat) 
     
    395418        filter_proxy.setFilterWildCard(pattern) 
    396419        self.ensureCurrent() 
     420 
     421    def setFilterFunc(self, func): 
     422        filter_proxy = self.view().model() 
     423        filter_proxy.setFilterFunc(func) 
    397424 
    398425 
     
    451478        self.__suggestPage.setIcon(icon_loader().get("icons/Search.svg")) 
    452479 
    453         self.addPage(self.tr("Quick Access"), self.__suggestPage) 
     480        self.addPage(self.tr("Quick Search"), self.__suggestPage) 
    454481 
    455482        self.__search.textEdited.connect( 
     
    528555        self.__model = model 
    529556        self.__suggestPage.setModel(model) 
     557 
     558    def setFilterFunc(self, func): 
     559        self.__suggestPage.setFilterFunc(func) 
    530560 
    531561    def popup(self, pos=None): 
Note: See TracChangeset for help on using the changeset viewer.