source: orange-bioinformatics/widgets/OWKEGGPathwayBrowser.py @ 1525:669aad39c027

Revision 1525:669aad39c027, 25.5 KB checked in by ales_erjavec <ales.erjavec@…>, 2 years ago (diff)

Added save graph button.

Line 
1"""
2<name>KEGG Pathways</name>
3<description>Browse KEGG pathways that include an input set of genes.</description>
4<priority>2030</priority>
5<icon>icons/KEGG.png</icon>
6"""
7from __future__ import with_statement
8
9import sys
10import orange
11import obiKEGG, orngServerFiles
12import obiTaxonomy
13
14import webbrowser
15
16from OWWidget import *
17import OWGUI
18from collections import defaultdict
19
20from orngDataCaching import data_hints
21
22def split_and_strip(string, sep=None):
23    return [s.strip() for s in string.split(sep)]
24
25class EntryGraphicsItem(QGraphicsPathItem):
26    def __init__(self, graphics, *args):
27        QGraphicsPathItem.__init__(self, *args)
28        path = QPainterPath()
29        x, y, w, h = [int(graphics.get(c, 0)) for c in ["x", "y", "width", "height"]]
30        type = graphics.get("type", "rectangle")
31        if type == "rectangle":
32            path.addRect(QRectF(x - w/2, y - h/2, w, h))
33        elif type == "roundrectangle":
34            path.addRoundedRect(QRectF(x - w/2, y - h/2, w, h), 10, 10)
35        elif type == "circle":
36            path.addEllipse(QRectF(x - w/2, y - h/2, w, h))
37           
38        self.setPath(path)
39        self.setAcceptHoverEvents(True)
40        self._actions = []
41        self.link = None
42       
43    def hoverEnterEvent(self, event):
44        self.setBrush(QBrush(QColor(0, 100, 0, 100)))
45       
46    def hoverLeaveEvent(self, event):
47        self.setBrush(QBrush(Qt.NoBrush))
48       
49    def contextMenuEvent(self, event):
50        if self._actions:
51            self._menu = menu = QMenu()
52            for action in self._actions:
53                menu.addAction(action)
54            menu.popup(event.screenPos())
55           
56    def itemChange(self, change, value):
57        if change == QGraphicsItem.ItemSelectedHasChanged:
58            self.setPen(QPen(Qt.red if self.isSelected() else Qt.blue, 2))
59           
60        return QGraphicsPathItem.itemChange(self, change, value)
61           
62class GraphicsPathwayItem(QGraphicsPixmapItem):
63    def __init__(self, pathway, objects, *args, **kwargs):
64        QGraphicsPixmapItem.__init__(self, *args)
65        self.setTransformationMode(Qt.SmoothTransformation)
66        self.setPathway(pathway)
67        self.setMarkedObjects(objects, name_mapper=kwargs.get("name_mapper", {}))
68       
69    def setPathway(self, pathway):
70        self.pathway = pathway
71        if pathway:
72            image_filename = pathway.get_image()
73            self._pixmap = QPixmap(image_filename)
74        else:
75            self._pixmap = QPixmap()
76        self.setPixmap(self._pixmap)
77       
78    def setMarkedObjects(self, objects, name_mapper={}):
79        for entry in self.pathway.entrys() if self.pathway else []:
80            if entry.type == "group":
81                continue
82            graphics = entry.graphics
83            contained_objects = [obj for obj in objects if obj in entry.name]
84            item = EntryGraphicsItem(graphics, self, self.scene())
85            item.setToolTip(self.tooltip(entry, contained_objects, name_mapper))
86            item._actions = self.actions(entry, contained_objects)
87            item.marked_objects = contained_objects
88            if contained_objects:
89                item.setPen(QPen(Qt.blue, 2))
90                item.setFlag(QGraphicsItem.ItemIsSelectable, True)
91   
92    def actions(self, entry, marked_objects=[]):
93        actions = []
94        type = entry.type
95        if marked_objects:
96            action = QAction("View genes on kegg website", None)
97            org = set([s.split(":")[0] for s in marked_objects]).pop()
98            genes = [s.split(":")[-1] for s in marked_objects]
99            address = "http://www.genome.jp/dbget-bin/www_bget?" + "+".join([org] + genes)
100            QObject.connect(action, SIGNAL("triggered()"), lambda toggled=False, address=address: webbrowser.open(address))
101            actions.append(action)
102        elif hasattr(entry, "link"):
103            action = QAction("View %s on KEGG website" % str(type), None)
104            QObject.connect(action, SIGNAL("triggered()"), lambda toggled=False, address=entry.link: webbrowser.open(address))
105            actions.append(action)
106        return actions
107   
108    def tooltip(self, entry, objects, name_mapper={}):
109        names = [obj for obj in objects if obj in entry.name]
110        names = [name_mapper.get(name, name) for name in names]
111        text = "<p>%s</p>" % (entry.name[:16] + " ..." if len(entry.name) > 20 else entry.name)
112        if names:
113            text += "<br>".join(names)
114        return text
115   
116    def contextMenuEvent(self, event):
117        self._menu = menu = QMenu()
118        action = menu.addAction("View this pathway on KEGG website")
119        address ="http://www.kegg.jp/kegg-bin/show_pathway?%s%s" % (self.pathway.org, self.pathway.number)
120        QObject.connect(action, SIGNAL("triggered()"), lambda : webbrowser.open(address))
121        menu.popup(event.screenPos())
122
123class PathwayView(QGraphicsView):
124    def __init__(self, master, *args):
125        QGraphicsView.__init__(self, *args)
126        self.master = master
127       
128        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
129        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
130       
131        self.setRenderHints(QPainter.Antialiasing)
132        scene = QGraphicsScene(self)
133        self.pixmapGraphicsItem = QGraphicsPixmapItem(None, scene) 
134        self.setScene(scene)
135       
136        self.setMouseTracking(True)
137        self.viewport().setMouseTracking(True)
138       
139        self.setFocusPolicy(Qt.WheelFocus)
140       
141    def SetPathway(self, pathway=None, objects=[]):
142        self.scene().clear()
143        self.pathway = pathway
144        self.objects = objects
145        self.pathwayItem = GraphicsPathwayItem(pathway, objects, None, self.scene(), name_mapper=getattr(self.master, "uniqueGenesDict", {}))
146        self.scene().setSceneRect(self.pathwayItem.boundingRect())
147        self.updateTransform()
148   
149    def resizeEvent(self, event):
150        self.updateTransform()
151        return QGraphicsView.resizeEvent(self, event)
152           
153    def updateTransform(self):
154        if self.master.autoResize:
155            self.fitInView(self.scene().sceneRect().adjusted(-1, -1, 1, 1), Qt.KeepAspectRatio)
156        else:
157            self.setTransform(QTransform())
158           
159    def paintEvent(self, event):
160        QGraphicsView.paintEvent(self, event)
161        if getattr(self, "_userMessage", None):
162            painter = QPainter(self.viewport())
163            font = QFont(self.font())
164            font.setPointSize(15)
165            painter.setFont(font)
166            painter.drawText(self.viewport().geometry(), Qt.AlignCenter, self._userMessage)
167            painter.end()
168       
169   
170class OWKEGGPathwayBrowser(OWWidget):
171    settingsList = ["organismIndex", "geneAttrIndex", "autoCommit", "autoResize", "useReference", "useAttrNames", "caseSensitive", "showOrthology"]
172    contextHandlers = {"":DomainContextHandler("",[ContextField("organismIndex", DomainContextHandler.Required + DomainContextHandler.IncludeMetaAttributes),
173                                                   ContextField("geneAttrIndex", DomainContextHandler.Required + DomainContextHandler.IncludeMetaAttributes),
174                                                   ContextField("useAttrNames", DomainContextHandler.Required + DomainContextHandler.IncludeMetaAttributes)])}
175    def __init__(self, parent=None, signalManager=None, name="KEGG Pathways"):
176        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True)
177        self.inputs = [("Examples", ExampleTable, self.SetData), ("Reference", ExampleTable, self.SetRefData)]
178        self.outputs = [("Selected Examples", ExampleTable), ("Unselected Examples", ExampleTable)]
179        self.organismIndex = 0
180        self.geneAttrIndex = 0
181        self.autoCommit = False
182        self.autoResize = True
183        self.useReference = False
184        self.useAttrNames = 0
185        self.caseSensitive = True
186        self.showOrthology = True
187        self.autoFindBestOrg = False
188        self.loadSettings()
189
190        self.controlArea.setMaximumWidth(250)
191        box = OWGUI.widgetBox(self.controlArea, "Info")
192        self.infoLabel = OWGUI.widgetLabel(box, "No data on input\n")
193       
194        self.allOrganismCodes = {} 
195
196        self.organismCodes = []
197
198        self.organismComboBox = cb = OWGUI.comboBox(self.controlArea, self, "organismIndex", box="Organism", items=[], callback=self.Update, addSpace=True, debuggingEnabled=0)
199        cb.setMaximumWidth(200)
200       
201        self.signalManager.freeze(self).push() #setFreeze(1)
202        QTimer.singleShot(100, self.UpdateOrganismComboBox)
203       
204        box = OWGUI.widgetBox(self.controlArea, "Gene attribute")
205        self.geneAttrCombo = OWGUI.comboBox(box, self, "geneAttrIndex", callback=self.Update)
206        OWGUI.checkBox(box, self, "useAttrNames", "Use variable names", disables=[(-1, self.geneAttrCombo)], callback=self.UseAttrNamesCallback)
207        self.geneAttrCombo.setDisabled(bool(self.useAttrNames))
208       
209#        OWGUI.checkBox(box, self, "caseSensitive", "Case sensitive gene matching", callback=self.Update)
210        OWGUI.separator(self.controlArea)
211       
212        OWGUI.checkBox(self.controlArea, self, "useReference", "From signal", box="Reference", callback=self.Update)
213        OWGUI.separator(self.controlArea)
214
215        OWGUI.checkBox(self.controlArea, self, "showOrthology", "Show pathways in full orthology", box="Orthology", callback=self.UpdateListView)
216       
217        OWGUI.checkBox(self.controlArea, self, "autoResize", "Resize to fit", box="Image", callback=lambda :self.pathwayView.updateTransform())
218        OWGUI.separator(self.controlArea)
219
220        box = OWGUI.widgetBox(self.controlArea, "Selection")
221        OWGUI.checkBox(box, self, "autoCommit", "Commit on update")
222        OWGUI.button(box, self, "Commit", callback=self.Commit, default=True)
223        OWGUI.rubber(self.controlArea)
224       
225        spliter = QSplitter(Qt.Vertical, self.mainArea)
226        self.pathwayView = PathwayView(self, spliter)
227        self.mainArea.layout().addWidget(spliter)
228
229        self.listView = QTreeWidget(spliter)
230        spliter.addWidget(self.listView)
231       
232        self.listView.setAllColumnsShowFocus(1)
233        self.listView.setColumnCount(4)
234        self.listView.setHeaderLabels(["Pathway", "P value", "Genes", "Reference"])
235
236        self.listView.setSelectionMode(QAbstractItemView.SingleSelection)
237           
238        self.listView.setSortingEnabled(True)
239        #self.listView.setAllColumnsShowFocus(1)
240        self.listView.setMaximumHeight(200)
241       
242        self.connect(self.listView, SIGNAL("itemSelectionChanged()"), self.UpdatePathwayView)
243       
244        self.connect(self.graphButton, SIGNAL("clicked()"), self.saveGraph)
245       
246        self.ctrlPressed = False
247        self.selectedObjects = defaultdict(list)
248        self.data = None
249        self.refData = None
250        self.loadedOrganism = None
251       
252        self.resize(800, 600)
253       
254        self.connect(self, SIGNAL("widgetStateChanged(QString, int, QString)"), self.onStateChange)
255       
256    def UpdateOrganismComboBox(self):
257        try:
258            self.progressBarInit()
259            with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
260                genome = obiKEGG.KEGGGenome()
261            self.progressBarFinished()
262           
263            self.allOrganismCodes = genome
264   
265            essential = genome.essential_organisms()
266           
267            local = [name.split(".")[0].split("_")[-1] for name in orngServerFiles.listfiles("KEGG") if "kegg_genes" in name]
268            self.organismCodes = [(code, organism.definition) for code, organism in self.allOrganismCodes.items() if code in local or code in essential]
269            self.organismCodes.sort()
270            items = [desc for code, desc in self.organismCodes]
271            self.organismCodes = [code for code, desc in self.organismCodes]
272           
273            self.organismComboBox.addItems(items)
274        finally:
275            self.signalManager.freeze(self).pop() #setFreeze(0)
276
277       
278    def SetData(self, data=None):
279        if not self.organismCodes: ## delay this call until we retrieve organism codes from the server files
280            QTimer.singleShot(200, lambda: self.SetData(data))
281            return
282
283        self.closeContext()
284        self.data = data
285        self.warning(0)
286        if data:
287            self.SetGeneAttrCombo()
288            taxid = data_hints.get_hint(data, "taxid", None)
289            if taxid:
290                try:
291                    code = obiKEGG.from_taxid(taxid)
292                    self.organismIndex = self.organismCodes.index(code)
293                except Exception, ex:
294                    print ex, taxid
295           
296            self.useAttrNames = data_hints.get_hint(data, "genesinrows", self.useAttrNames)
297           
298            self.openContext("", data)
299            self.Update()
300        else:
301            self.infoLabel.setText("No data on input\n")
302            self.listView.clear()
303            self.selectedObjects = defaultdict(list)
304            self.pathwayView.SetPathway(None)
305            self.send("Selected Examples", None)
306            self.send("Unselected Examples", None)
307
308    def SetRefData(self, data=None):
309        self.refData = data
310        if self.useReference and self.data and self.organismCodes:
311            self.Update()
312
313    def UseAttrNamesCallback(self):
314##        self.geneAttrCombo.setDisabled(bool(self.useAttrNames))
315        self.Update()
316
317    def SetGeneAttrCombo(self):
318        self.geneAttrCandidates = self.data.domain.attributes + self.data.domain.getmetas().values()
319        self.geneAttrCandidates = filter(lambda v:v.varType in [orange.VarTypes.Discrete ,orange.VarTypes.String], self.geneAttrCandidates)
320        self.geneAttrCombo.clear()
321        #print 'geneAttrCandidates', self.geneAttrCandidates
322        self.geneAttrCombo.addItems([var.name for var in self.geneAttrCandidates])
323        return
324               
325    def PreDownload(self, org=None, pb=None):
326        pb, finish = (OWGUI.ProgressBar(self, 0), True) if pb is None else (pb, False)
327        files = ["kegg_brite.tar.gz", "kegg_pathways_map.tar.gz", "kegg_genome.tar.gz"]
328        if org:
329            files += ["kegg_genes_%s.tar.gz" % org, "kegg_pathways_%s.tar.gz" % org]
330        files = [file for file in files if file not in orngServerFiles.listfiles("KEGG")]
331        pb.iter += len(files) * 100
332        for i, filename in enumerate(files):
333#            print filename
334            orngServerFiles.download("KEGG", filename, callback=pb.advance)
335        if finish:
336            pb.finish()
337           
338    def UpdateListView(self):
339        self.bestPValueItem = None
340        self.listView.clear()
341        if not self.data:
342            return
343        allPathways = self.org.pathways()
344        allRefPathways = obiKEGG.pathways("map")
345        self.progressBarFinished()
346        items = []
347        if self.showOrthology:
348            self.koOrthology = obiKEGG.KEGGBrite("ko00001")
349            self.listView.setRootIsDecorated(True)
350            path_ids = set([s[-5:] for s in self.pathways.keys()])
351            def _walkCollect(koEntry):
352                num = koEntry.title[:5] if koEntry.title else None
353                if num  in path_ids:
354                    return [koEntry] + reduce(lambda li,c:li+_walkCollect(c), [child for child in koEntry.entrys], [])
355                else:
356                    c = reduce(lambda li,c:li+_walkCollect(c), [child for child in koEntry.entrys], [])
357                    return c + (c and [koEntry] or [])
358            allClasses = reduce(lambda li1, li2: li1+li2, [_walkCollect(c) for c in self.koOrthology], [])
359            def _walkCreate(koEntry, lvItem):
360                item = QTreeWidgetItem(lvItem)
361                id = "path:"+self.organismCodes[min(self.organismIndex, len(self.organismCodes)-1)] + koEntry.title[:5]
362                if koEntry.title[:5] in path_ids:
363                    genes, p_value, ref = self.pathways[id]
364                    item.setText(0, obiKEGG.KEGGPathway(id).title)
365#                    print id, obiKEGG.KEGGPathway(id).title
366                    item.setText(1, "%.5f" % p_value)
367                    item.setText(2, "%i of %i" %(len(genes), len(self.genes)))
368                    item.setText(3, "%i of %i" %(ref, len(self.referenceGenes)))
369                    item.pathway_id = id
370                else:
371                    item.setText(0, obiKEGG.KEGGPathway(id).title if id in allPathways else koEntry.title)
372                    if id in allPathways:
373                        item.pathway_id = id
374                    elif "path:map" + koEntry.title[:5] in allRefPathways:
375                        item.pathway_id = "path:map" + koEntry.title[:5]
376                    else:
377                        item.pathway_id = None
378               
379                for child in koEntry.entrys:
380                    if child in allClasses:
381                        _walkCreate(child, item)
382           
383            for koEntry in self.koOrthology:
384                if koEntry in allClasses:
385                    _walkCreate(koEntry, self.listView)
386                   
387            self.listView.update()
388        else:
389            self.listView.setRootIsDecorated(False)
390            pathways = self.pathways.items()
391            pathways.sort(lambda a,b:cmp(a[1][1], b[1][1]))
392            for id, (genes, p_value, ref) in pathways:
393                item = QTreeWidgetItem(self.listView)
394                item.setText(0, obiKEGG.KEGGPathway(id).title)
395                item.setText(1, "%.5f" % p_value)
396                item.setText(2, "%i of %i" %(len(genes), len(self.genes)))
397                item.setText(3, "%i of %i" %(ref, len(self.referenceGenes)))
398                item.pathway_id = id
399                items.append(item)
400               
401        self.bestPValueItem = items and items[0] or None
402        self.listView.expandAll()
403        for i in range(4):
404            self.listView.resizeColumnToContents(i)
405           
406        if self.bestPValueItem:
407            self.listView.selectionModel().select(self.listView.indexFromItem(self.bestPValueItem), QItemSelectionModel.ClearAndSelect)
408
409    def UpdatePathwayView(self):
410        items = self.listView.selectedItems()
411       
412        if len(items) > 0:
413            item = items[0]
414        else:
415            item = None
416           
417        self.selectedObjects = defaultdict(list)
418        self.Commit()
419        item = item or self.bestPValueItem
420        if not item or not item.pathway_id:
421            self.pathwayView.SetPathway(None)
422            return
423        self.pathway = obiKEGG.KEGGPathway(item.pathway_id)
424        self.pathwayView.SetPathway(self.pathway, self.pathways.get(item.pathway_id, [[]])[0])
425           
426           
427    def Update(self):
428        if not self.data:
429            return
430        self.error(0)
431        self.information(0)
432        pb = OWGUI.ProgressBar(self, 100)
433        if self.useAttrNames:
434            genes = [str(v.name).strip() for v in self.data.domain.attributes]
435        elif self.geneAttrCandidates:
436            geneAttr = self.geneAttrCandidates[min(self.geneAttrIndex, len(self.geneAttrCandidates)-1)]
437            genes = [str(e[geneAttr]) for e in self.data if not e[geneAttr].isSpecial()]
438            if any("," in gene for gene in genes):
439                genes = reduce(list.__add__, (split_and_strip(gene, ",") for gene in genes), [])
440                self.information(0, "Separators detected in input gene names. Assuming multiple genes per example.")
441        else:
442            self.error(0, "Cannot extact gene names from input")
443            genes = []
444        org_code = self.organismCodes[min(self.organismIndex, len(self.organismCodes)-1)]
445        if self.loadedOrganism != org_code:
446            self.PreDownload(org_code, pb=pb)
447            self.org = obiKEGG.KEGGOrganism(org_code)
448            self.loadedOrganism = org_code
449        uniqueGenes, conflicting, unknown = self.org.get_unique_gene_ids(set(genes), self.caseSensitive)
450        genesCount = len(set(genes))
451        self.infoLabel.setText("%i unique gene names on input\n%i (%.1f%%) genes names matched" % (genesCount, len(uniqueGenes), 100.0*len(uniqueGenes)/genesCount if genes else 0.0)) 
452#        if conflicting:
453#            print >> sys.stderr, "Conflicting genes:", conflicting
454#        if unknown:
455#            print >> sys.stderr, "Unknown genes:", unknown
456        self.information(1)
457        if self.useReference and self.refData:
458            if self.useAttrNames:
459                reference = [str(v.name).strip() for v in self.refData]
460            else:
461                geneAttr = self.geneAttrCandidates[min(self.geneAttrIndex, len(self.geneAttrCandidates)-1)]
462                reference = [str(e[geneAttr]) for e in self.refData if not e[geneAttr].isSpecial()]
463                if any("," in gene for gene in reference):
464                    reference = reduce(list.__add__, (split_and_strip(gene, ",") for gene in reference), [])
465                    self.information(1, "Separators detected in reference gene names. Assuming multiple genes per example.")
466            uniqueRefGenes, conflicting, unknown = self.org.get_unique_gene_ids(set(reference), self.caseSensitive)
467            self.referenceGenes = reference = uniqueRefGenes.keys()
468        else:
469            self.referenceGenes = reference = self.org.get_genes()
470        self.uniqueGenesDict = uniqueGenes
471        self.genes = uniqueGenes.keys()
472        self.revUniqueGenesDict = dict([(val, key) for key, val in self.uniqueGenesDict.items()])
473#        self.progressBarInit()
474#        with orngServerFiles.DownloadProgress.setredirect(self.progressBarSet):
475        self.pathways = self.org.get_enriched_pathways(self.genes, reference, callback=lambda value: pb.advance()) #self.progressBarSet)
476        if not self.pathways:
477            self.warning(0, "No enriched pathways found.")
478        else:
479            self.warning(0)
480           
481#        self.progressBarFinished()
482        self.UpdateListView()
483        pb.finish()
484##        print self.bestPValueItem
485        #self.bestPValueItem.setSelected(True)
486        #self.UpdatePathwayView()
487
488    def SelectObjects(self, objs):
489        if (not self.selectedObjects or self.ctrlPressed) and not objs:
490            return
491        if self.ctrlPressed:
492            for id, graphics in objs:
493                graphics = tuple(sorted(graphics.items()))
494                if id in self.selectedObjects[graphics]:
495                    self.selectedObjects[graphics].pop(self.selectedObjects[graphics].index(id))
496                    if not self.selectedObjects[graphics]:
497                        del self.selectedObjects[graphics]
498                else:
499                    self.selectedObjects[graphics].append(id)
500        else:
501            self.selectedObjects.clear()
502            for id, graphics in objs:
503                graphics = tuple(sorted(graphics.items()))
504                self.selectedObjects[graphics].append(id)
505        if self.autoCommit:
506            self.Commit()
507           
508
509    def Commit(self):
510        if self.data:
511            selectedItems = self.pathwayView.scene().selectedItems()
512            selectedGenes = reduce(set.union, [item.marked_objects for item in selectedItems], set())
513           
514            if self.useAttrNames:
515#                selectedGenes = reduce(set.union, self.selectedObjects.values(), set())
516                selectedVars = [self.data.domain[self.uniqueGenesDict[gene]] for gene in selectedGenes]
517                newDomain = orange.Domain(selectedVars ,0)
518                data = orange.ExampleTable(newDomain, self.data)
519                self.send("Selected Examples", data)
520            elif self.geneAttrCandidates:
521                geneAttr = self.geneAttrCandidates[min(self.geneAttrIndex, len(self.geneAttrCandidates)-1)]
522                selectedExamples = []
523                otherExamples = []
524#                selectedGenes = reduce(set.union, self.selectedObjects.values(), set())
525                for ex in self.data:
526                    names = [self.revUniqueGenesDict.get(name, None) for name in split_and_strip(str(ex[geneAttr]), ",")]
527                    if any(name and name in selectedGenes for name in names):
528                        selectedExamples.append(ex)
529                    else:
530                        otherExamples.append(ex)
531                       
532                if selectedExamples:
533                    selectedExamples = orange.ExampleTable(selectedExamples)
534                else:
535                    selectedExamples = None
536                   
537                if otherExamples:
538                    otherExamples = orange.ExampleTable(otherExamples)
539                else:
540                    otherExamples = None
541                   
542                self.send("Selected Examples", selectedExamples)
543                self.send("Unselected Examples", otherExamples)
544        else:
545            self.send("Selected Examples", None)
546            self.send("Unselected Examples", None)
547       
548    def keyPressEvent(self, key):
549        if key.key()==Qt.Key_Control:
550            self.ctrlPressed=True
551        else:
552            OWWidget.keyPressEvent(self, key)
553
554    def keyReleaseEvent(self, key):
555        if key.key()==Qt.Key_Control:
556            self.ctrlPressed=False
557        else:
558            OWWidget.keyReleaseEvent(self, key)
559           
560    def onStateChange(self, stateType, id, text):
561        if stateType == "Warning":
562            self.pathwayView._userMessage = text
563            self.pathwayView.viewport().update()
564           
565    def saveGraph(self):
566        from OWDlgs import OWChooseImageSizeDlg
567        sizeDlg = OWChooseImageSizeDlg(self.pathwayView.scene(), parent=self)
568        sizeDlg.exec_()
569
570if __name__=="__main__":
571    app = QApplication(sys.argv)
572    data = orange.ExampleTable("../../../../orange/doc/datasets/brown-selected.tab")
573    w = OWKEGGPathwayBrowser()
574    w.UpdateOrganismComboBox()
575##    app.setMainWidget(w)
576    w.show()
577    w.SetData(data)
578    app.exec_()
579    w.saveSettings()
Note: See TracBrowser for help on using the repository browser.