source: orange/orange/OrangeCanvas/orngCanvas.pyw @ 7731:763a8292bf0f

Revision 7731:763a8292bf0f, 47.2 KB checked in by ales_erjavec <ales.erjavec@…>, 3 years ago (diff)

The last commit broke the widget TreeView during initialization. This fixes it.

Line 
1# Author: Gregor Leban (gregor.leban@fri.uni-lj.si)
2# Description:
3#    main file, that creates the MDI environment
4
5# This module has to be imported first because it takes care of the system PATH variable
6# Namely, it throws out the MikTeX directories which contain an incompatible Qt .dll's
7import orngEnviron, orngAddOns
8
9from PyQt4.QtCore import *
10from PyQt4.QtGui import *
11   
12import sys, os, cPickle, orngRegistry, OWGUI
13import orngTabs, orngDoc, orngDlgs, orngOutput, orngHelp, OWReport
14import  user, orngMisc
15
16RedR = False
17product = "Red R" if RedR else "Orange"
18
19
20class OrangeCanvasDlg(QMainWindow):
21    def __init__(self, app, parent=None, flags=0):
22        QMainWindow.__init__(self, parent)
23        self.debugMode = 1        # print extra output for debuging
24        self.setWindowTitle("%s Canvas" % product)
25        self.windows = []    # list of id for windows in Window menu
26        self.recentDocs = []
27        self.iconNameToIcon = {}
28        self.toolbarIconSizeList = [16, 32, 40, 48, 60]
29        self.schemeIconSizeList = [32, 40, 48]
30        self.widgetsToolBar = None
31        self.originalPalette = QApplication.palette()
32
33        self.__dict__.update(orngEnviron.directoryNames)
34               
35        self.defaultPic = os.path.join(self.picsDir, "Unknown.png")
36        self.defaultBackground = os.path.join(self.picsDir, "frame.png")
37        canvasPicsDir = os.path.join(self.canvasDir, "icons")
38        self.file_new = os.path.join(canvasPicsDir, "doc.png")
39        self.outputPix = os.path.join(canvasPicsDir, "output.png")
40        self.file_open = os.path.join(canvasPicsDir, "open.png")
41        self.file_save = os.path.join(canvasPicsDir, "save.png")
42        if RedR:
43            self.reload_pic = os.path.join(canvasPicsDir, "update1.png")
44        self.text_icon = os.path.join(canvasPicsDir, "text.png")
45        self.file_print = os.path.join(canvasPicsDir, "print.png")
46        self.file_exit = os.path.join(canvasPicsDir, "exit.png")
47        canvasIconName = os.path.join(canvasPicsDir, "CanvasIcon.png")
48        if os.path.exists(canvasIconName):
49            self.setWindowIcon(QIcon(canvasIconName))
50           
51        self.settings = {}
52        if RedR:
53            self.settings['svnSettings'] = {}
54            self.settings['versionNumber'] = 'Version1.0'
55        self.menuSaveSettingsID = -1
56        self.menuSaveSettings = 1
57
58        self.loadSettings()
59        if RedR:
60            import updateRedR
61            self.settings['svnSettings'], self.settings['versionNumber'] = updateRedR.start(self.settings['svnSettings'], self.settings['versionNumber'])
62           
63#        self.widgetSelectedColor = QColor(*self.settings["widgetSelectedColor"])
64#        self.widgetActiveColor = QColor(*self.settings["widgetActiveColor"])
65#        self.lineColor = QColor(*self.settings["lineColor"])
66
67        if not self.settings.has_key("WidgetTabs") or self.settings["WidgetTabs"] == []:
68            f = open(os.path.join(self.canvasDir, "WidgetTabs.txt"), "r")
69            defaultTabs = [c for c in [line.split("#")[0].strip() for line in f.readlines()] if c!=""]
70            for i in xrange(len(defaultTabs)-1,0,-1):
71                if defaultTabs[i] in defaultTabs[0:i]:
72                    del defaultTabs[i]
73            self.settings["WidgetTabs"] = [(name, Qt.Checked) for name in defaultTabs] + [("Prototypes", Qt.Unchecked)]
74       
75        # output window
76        self.output = orngOutput.OutputWindow(self)
77        self.output.catchException(1)
78        self.output.catchOutput(1)
79
80        # create error and warning icons
81        informationIconName = os.path.join(canvasPicsDir, "information.png")
82        warningIconName = os.path.join(canvasPicsDir, "warning.png")
83        errorIconName = os.path.join(canvasPicsDir, "error.png")
84        if os.path.exists(errorIconName) and os.path.exists(warningIconName) and os.path.exists(informationIconName):
85            self.errorIcon = QPixmap(errorIconName)
86            self.warningIcon = QPixmap(warningIconName)
87            self.informationIcon = QPixmap(informationIconName)
88            self.widgetIcons = {"Info": self.informationIcon, "Warning": self.warningIcon, "Error": self.errorIcon}
89        else:
90            self.errorIcon = None
91            self.warningIcon = None
92            self.informationIcon = None
93            self.widgetIcons = None
94            print "Unable to load all necessary icons. Please reinstall Orange."
95
96        self.setStatusBar(MyStatusBar(self))
97               
98        self.widgetRegistry = orngRegistry.readCategories()
99        self.updateStyle()
100       
101        # create toolbar
102        self.toolbar = self.addToolBar("Toolbar")
103        self.toolbar.setOrientation(Qt.Horizontal)
104#        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
105        if not self.settings.get("showToolbar", True):
106            self.toolbar.hide()
107       
108        # create a schema
109        self.schema = orngDoc.SchemaDoc(self)
110        self.setCentralWidget(self.schema)
111        self.schema.setFocus()
112
113        self.toolbar.addAction(QIcon(self.file_open), "Open schema", self.menuItemOpen)
114#        self.toolbar.addAction(QIcon(self.style().standardIcon(QStyle.SP_FileIcon)), "Open schema", self.menuItemOpen)
115        self.toolSave = self.toolbar.addAction(QIcon(self.file_save), "Save schema", self.menuItemSave)
116#        self.toolSave = self.toolbar.addAction(QIcon(self.style().standardIcon(QStyle.SP_DialogSaveButton)), "Save schema", self.menuItemSave)
117        if RedR:
118            self.toolReloadWidgets = self.toolbar.addAction(QIcon(self.reload_pic), "Reload Widgets", self.reloadWidgets)
119        self.toolbar.addSeparator()
120        self.toolbar.addAction(QIcon(self.file_print), "Print", self.menuItemPrinter)
121        self.toolbar.addSeparator()
122        w = QWidget()
123        w.setLayout(QHBoxLayout())
124       
125        items = ["Tool box", "Tree view", "Tree view (no icons)", "Tabs without labels", "Tabs with labels"]
126        ind = max(len(items) - 1, self.settings["widgetListType"])
127        self.widgetListTypeCB = OWGUI.comboBox(w, self.settings, "widgetListType", label="Style:", orientation="horizontal", items=items, callback=self.createWidgetsToolbar, debuggingEnabled=0)
128        self.widgetListTypeCB.setFocusPolicy(Qt.TabFocus)
129        self.toolbar.addWidget(w)
130       
131        self.toolbar.addSeparator()
132
133        w = QWidget()
134        w.setLayout(QHBoxLayout())
135        items = ["%d x %d" % (v, v) for v in self.toolbarIconSizeList]
136        self.settings["toolbarIconSize"] = min(len(items) - 1, self.settings["toolbarIconSize"])
137        cb = OWGUI.comboBoxWithCaption(w, self.settings, "toolbarIconSize", "Icon size:", items=items, tooltip="Set the size of the widget icons in the toolbar, tool box, and tree view area", callback=self.createWidgetsToolbar, debuggingEnabled=0)
138        cb.setFocusPolicy(Qt.TabFocus)
139       
140        self.toolbar.addWidget(w)
141       
142        self.freezeAction = self.toolbar.addAction("Freeze signals")
143        self.freezeAction.setCheckable(True)
144        self.freezeAction.setIcon(QIcon(self.style().standardIcon(QStyle.SP_MediaPause))) #self.schema_pause))
145       
146        def toogleSchemaFreeze(freeze):
147            self.freezeAction.setIcon(QIcon(self.style().standardIcon(QStyle.SP_MediaPlay if freeze else QStyle.SP_MediaPause))) #self.schema_pause))
148            self.schema.setFreeze(freeze)
149           
150        self.connect(self.freezeAction, SIGNAL("toggled(bool)"), toogleSchemaFreeze) #lambda bool: self.schema.setFreeze(bool))
151       
152        # Restore geometry before calling createWidgetsToolbar.
153        # On Mac OSX with unified title bar the canvas can move up on restarts
154        state = self.settings.get("CanvasMainWindowGeometry", None)
155        if state is not None:
156            state = self.restoreGeometry(QByteArray(state))
157            width, height = self.width(), self.height()
158       
159        if not state:
160            width, height = self.settings.get("canvasWidth", 700), self.settings.get("canvasHeight", 600)
161
162        # center window in the desktop
163        # on multiheaded desktops it it does not fit
164       
165        desktop = qApp.desktop()
166        space = desktop.availableGeometry(self)
167        geometry, frame = self.geometry(), self.frameGeometry()
168       
169        #Fit the frame size to fit in space
170        width = min(space.width() - (frame.width() - geometry.width()), geometry.width())
171        height = min(space.height() - (frame.height() - geometry.height()), geometry.height())
172       
173        self.resize(width, height)
174       
175        self.addToolBarBreak()
176        orngTabs.constructCategoriesPopup(self)
177        self.createWidgetsToolbar()
178        orngTabs.constructCategoriesPopup(self)
179        self.readShortcuts()
180       
181        def addOnRefreshCallback():
182            self.widgetRegistry = orngRegistry.readCategories()
183            orngTabs.constructCategoriesPopup(self)
184            self.createWidgetsToolbar()
185        orngAddOns.addOnRefreshCallback.append(addOnRefreshCallback)
186
187        # create menu
188        self.initMenu()
189        self.readRecentFiles()
190
191       
192       
193        #move to center if frame not fully contained in space
194        if not space.contains(self.frameGeometry()):
195            x = max(0, space.width() / 2 - width / 2)
196            y = max(0, space.height() / 2 - height / 2)
197           
198            self.move(x, y)
199
200        self.helpWindow = orngHelp.HelpWindow(self)
201        self.reportWindow = OWReport.ReportWindow()
202        self.reportWindow.widgets = self.schema.widgets
203        self.reportWindow.saveDir = self.settings["reportsDir"]
204       
205
206        # did Orange crash the last time we used it? If yes, you will find a temSchema.tmp file
207        if not RedR:
208            if os.path.exists(os.path.join(self.canvasSettingsDir, "tempSchema.tmp")):
209                mb = QMessageBox('%s Canvas' % product, "Your previous %s Canvas session was not closed successfully.\nYou can choose to reload your unsaved work or start a new session.\n\nIf you choose 'Reload', the links will be disabled to prevent reoccurence of the crash.\nYou can enable them by clicking Options/Enable all links." % product, QMessageBox.Information, QMessageBox.Ok | QMessageBox.Default, QMessageBox.Cancel | QMessageBox.Escape, QMessageBox.NoButton)
210                mb.setButtonText(QMessageBox.Ok, "Reload")
211                mb.setButtonText(QMessageBox.Cancel, "New schema")
212                if mb.exec_() == QMessageBox.Ok:
213                    self.schema.loadDocument(os.path.join(self.canvasSettingsDir, "tempSchema.tmp"), freeze=1)
214       
215        if self.schema.widgets == [] and len(sys.argv) > 1 and os.path.exists(sys.argv[-1]) and os.path.splitext(sys.argv[-1])[1].lower() == ".ows":
216            self.schema.loadDocument(sys.argv[-1])
217       
218        # show message box if no numpy
219        qApp.processEvents()
220        try:
221            import numpy
222        except:
223            if QMessageBox.warning(self, '%s Canvas' % product, 'Several widgets now use numpy module, \nthat is not yet installed on this computer. \nDo you wish to download it?', QMessageBox.Ok | QMessageBox.Default, QMessageBox.Cancel | QMessageBox.Escape) == QMessageBox.Ok:
224                import webbrowser
225                webbrowser.open("http://sourceforge.net/projects/numpy/")
226
227    def createWidgetsToolbar(self):
228        if self.widgetsToolBar:
229            self.settings["showWidgetToolbar"] = self.widgetsToolBar.isVisible()
230            if isinstance(self.widgetsToolBar, QToolBar):
231                self.removeToolBar(self.widgetsToolBar)
232            elif isinstance(self.widgetsToolBar, orngTabs.WidgetToolBox):
233                self.settings["toolboxWidth"] = self.widgetsToolBar.toolbox.width()
234                self.removeDockWidget(self.widgetsToolBar)
235            elif isinstance(self.widgetsToolBar, orngTabs.WidgetTree):
236                self.settings["toolboxWidth"] = self.widgetsToolBar.treeWidget.width()
237                self.removeDockWidget(self.widgetsToolBar)
238           
239        if self.settings["widgetListType"] == 0:
240            self.tabs = self.widgetsToolBar = orngTabs.WidgetToolBox(self, self.widgetRegistry)
241            self.addDockWidget(Qt.LeftDockWidgetArea, self.widgetsToolBar)
242        elif self.settings["widgetListType"] in [1, 2]:
243            self.tabs = self.widgetsToolBar = orngTabs.WidgetTree(self, self.widgetRegistry)
244            self.addDockWidget(Qt.LeftDockWidgetArea, self.widgetsToolBar)
245        else:
246            if sys.platform == "darwin":
247                self.setUnifiedTitleAndToolBarOnMac(False)   
248            self.widgetsToolBar = self.addToolBar("Widgets")
249            self.insertToolBarBreak(self.widgetsToolBar)
250            self.tabs = orngTabs.WidgetTabs(self, self.widgetRegistry, self.widgetsToolBar)
251            self.widgetsToolBar.addWidget(self.tabs)
252           
253        if sys.platform == "darwin":
254            self.setUnifiedTitleAndToolBarOnMac(self.settings["widgetListType"] in [0, 1, 2] and self.settings["style"].lower() == "macintosh (aqua)")
255
256        # find widgets and create tab with buttons
257        self.settings["WidgetTabs"] = self.tabs.createWidgetTabs(self.settings["WidgetTabs"], self.widgetRegistry, self.widgetDir, self.picsDir, self.defaultPic)
258        if not self.settings.get("showWidgetToolbar", True):
259            self.widgetsToolBar.hide()
260
261
262    def readShortcuts(self):
263        self.widgetShortcuts = {}
264        shfn = os.path.join(self.canvasSettingsDir, "shortcuts.txt")
265        if os.path.exists(shfn):
266            for t in file(shfn).readlines():
267                key, info = [x.strip() for x in t.split(":")]
268                if len(info) == 0: continue
269                if info[0] == "(" and info[-1] == ")":
270                    cat, widgetName = eval(info)            # new style of shortcuts are of form F: ("Data", "File")
271                else:
272                    cat, widgetName = info.split(" - ")   # old style of shortcuts are of form F: Data - File
273                if self.widgetRegistry.has_key(cat) and self.widgetRegistry[cat].has_key(widgetName):
274                    self.widgetShortcuts[key] = self.widgetRegistry[cat][widgetName]
275
276
277    def initMenu(self):
278        self.menuRecent = QMenu("Recent Schemas", self)
279
280        self.menuFile = QMenu("&File", self)
281        self.menuFile.addAction("New Scheme", self.menuItemNewScheme, QKeySequence.New)
282        self.menuFile.addAction(QIcon(self.file_open), "&Open...", self.menuItemOpen, QKeySequence.Open)
283        self.menuFile.addAction(QIcon(self.file_open), "&Open and Freeze...", self.menuItemOpenFreeze)
284        if RedR:
285            self.menuFile.addAction("Import Schema", self.importSchema)
286        if os.path.exists(os.path.join(self.canvasSettingsDir, "lastSchema.tmp")):
287            self.menuFile.addAction("Reload Last Schema", self.menuItemOpenLastSchema, Qt.CTRL + Qt.Key_R)
288        #self.menuFile.addAction( "&Clear", self.menuItemClear)
289        self.menuFile.addSeparator()
290        self.menuReportID = self.menuFile.addAction("&Report", self.menuItemReport, Qt.CTRL + Qt.ALT + Qt.Key_R)
291        self.menuFile.addSeparator()
292        self.menuSaveID = self.menuFile.addAction(QIcon(self.file_save), "&Save", self.menuItemSave, QKeySequence.Save)
293        self.menuSaveAsID = self.menuFile.addAction("Save &as...", self.menuItemSaveAs)
294        if not RedR:
295            self.menuFile.addAction("&Save as Application (Tabs)...", self.menuItemSaveAsAppTabs)
296            self.menuFile.addAction("&Save as Application (Buttons)...", self.menuItemSaveAsAppButtons)
297        self.menuFile.addSeparator()
298        self.menuFile.addAction(QIcon(self.file_print), "&Print Schema / Save image", self.menuItemPrinter, QKeySequence.Print)
299        self.menuFile.addSeparator()
300        self.menuFile.addMenu(self.menuRecent)
301        self.menuFile.addSeparator()
302        self.menuFile.addAction("E&xit", self.close, Qt.CTRL + Qt.Key_Q)
303
304        self.menuOptions = QMenu("&Options", self)
305        self.menuOptions.addAction("Enable All Links", self.menuItemEnableAll, Qt.CTRL + Qt.Key_E)
306        self.menuOptions.addAction("Disable All Links", self.menuItemDisableAll, Qt.CTRL + Qt.Key_D)
307        self.menuOptions.addSeparator()
308        self.menuOptions.addAction("Show Output Window", self.menuItemShowOutputWindow)
309        self.menuOptions.addAction("Clear Output Window", self.menuItemClearOutputWindow)
310        self.menuOptions.addAction("Save Output Text...", self.menuItemSaveOutputWindow)
311        if RedR:
312            self.menuOptions.addAction("Set to debug mode", self.setDebugMode)
313       
314        # uncomment this only for debugging
315#        self.menuOptions.addSeparator()
316#        self.menuOptions.addAction("Dump widget variables", self.dumpVariables)
317
318        self.menuOptions.addSeparator()
319#        self.menuOptions.addAction( "Channel preferences",  self.menuItemPreferences)
320        #self.menuOptions.addSeparator()
321        self.menuOptions.addAction("&Customize Shortcuts", self.menuItemEditWidgetShortcuts)
322        self.menuOptions.addAction("&Delete Widget Settings", self.menuItemDeleteWidgetSettings)
323        self.menuOptions.addSeparator()
324        self.menuOptions.addAction(sys.platform == "darwin" and "&Preferences..." or "Canvas &Options...", self.menuItemCanvasOptions)
325        self.menuOptions.addAction("&Add-ons...", self.menuItemAddOns)
326
327        localHelp = 0
328        self.menuHelp = QMenu("&Help", self)
329        if os.path.exists(os.path.join(self.orangeDir, r"doc/reference/default.htm")): self.menuHelp.addAction("Orange Help", self.menuOpenLocalOrangeHelp)
330        if os.path.exists(os.path.join(self.orangeDir, r"doc/catalog/index.html")): self.menuHelp.addAction("Orange Widget Catalog", self.menuOpenLocalWidgetCatalog)
331        if os.path.exists(os.path.join(self.orangeDir, r"doc/canvas/default.htm")): self.menuHelp.addAction("Orange Canvas Help", self.menuOpenLocalCanvasHelp)
332
333        self.menuHelp.addAction("Orange Online Widget Catalog", self.menuOpenOnlineOrangeHelp)
334        #self.menuHelp.addAction("Orange Canvas Online Help", self.menuOpenOnlineCanvasHelp)
335
336        if os.path.exists(os.path.join(self.orangeDir, r"updateOrange.py")):
337            self.menuHelp.addSeparator()
338            self.menuHelp.addAction("Check for updates", self.menuCheckForUpdates)
339           
340        self.menuHelp.addSeparator()
341        self.menuHelp.addAction("About Orange", self.menuItemAboutOrange)
342
343        # widget popup menu
344        self.widgetPopup = QMenu("Widget", self)
345        self.openActiveWidgetAction = self.widgetPopup.addAction("Open", self.schema.canvasView.openActiveWidget)
346        self.widgetPopup.addSeparator()
347        self.renameActiveWidgetAction = rename = self.widgetPopup.addAction("&Rename", self.schema.canvasView.renameActiveWidget, Qt.Key_F2)
348        self.removeActiveWidgetAction = delete = self.widgetPopup.addAction("Remove", self.schema.canvasView.removeActiveWidget, Qt.Key_Delete)
349        if sys.platform != "darwin":
350            delete.setShortcuts([Qt.Key_Delete, Qt.CTRL + Qt.Key_Backspace, Qt.CTRL + Qt.Key_Delete])
351        else:
352            delete.setShortcuts([Qt.CTRL + Qt.Key_Backspace, Qt.Key_Delete, Qt.CTRL + Qt.Key_Delete])
353        self.widgetPopup.addSeparator()
354        self.helpActiveWidgetAction = self.widgetPopup.addAction("Help", self.schema.canvasView.helpOnActiveWidget, Qt.Key_F1)
355        self.widgetPopup.setEnabled(0)
356       
357        if sys.platform == "darwin":
358            self.windowPopup = QMenu("Window", self)
359            self.windowPopup.addAction("Minimize", self.showMinimized, Qt.CTRL + Qt.Key_M)
360            self.windowPopup.addAction("Zoom", self.showMaximized, 0)
361
362        self.menuBar = QMenuBar(self)
363        self.menuBar.addMenu(self.menuFile)
364        self.menuBar.addMenu(self.menuOptions)
365        self.menuBar.addMenu(self.widgetPopup)
366       
367        if hasattr(self, "windowPopup"):
368            self.menuBar.addMenu(self.windowPopup)
369           
370        self.menuBar.addMenu(self.menuHelp)
371       
372        self.setMenuBar(self.menuBar)
373       
374    def setDebugMode(self):   # RedR specific
375        if self.output.debugMode:
376            self.output.debugMode = 0
377        else:
378            self.output.debugMode = 1
379    def importSchema(self):   # RedR specific
380        name = QFileDialog.getOpenFileName(self, "Import File", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
381        if name.isEmpty():
382            return
383        self.schema.clear()
384        self.schema.loadDocument(str(name), freeze = 0, importBlank = 1)
385        self.addToRecentMenu(str(name))
386   
387    def openSchema(self, filename):
388        if self.schema.isSchemaChanged() and self.schema.widgets:
389            ret = QMessageBox.warning(self, "Orange Canvas", "Changes to your present schema are not saved.\nSave them?",
390                                      QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, QMessageBox.Save)
391            if ret == QMessageBox.Save:
392                self.schema.saveDocument()
393            elif ret == QMessageBox.Cancel:
394                return
395        self.schema.clear()
396        dirname = os.path.dirname(filename)
397        os.chdir(dirname)
398        self.schema.loadDocument(filename)
399       
400    def menuItemOpen(self):
401        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
402        if name.isEmpty():
403            return
404        self.schema.clear()
405        dirname = os.path.dirname(str(name))
406        os.chdir(dirname)
407        self.schema.loadDocument(str(name), freeze=0)
408        self.addToRecentMenu(str(name))
409
410    def menuItemOpenFreeze(self):
411        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
412        if name.isEmpty():
413            return
414        self.schema.clear()
415        dirname = os.path.dirname(str(name))
416        os.chdir(dirname)
417        self.schema.loadDocument(str(name), freeze=1)
418        self.addToRecentMenu(str(name))
419
420    def menuItemOpenLastSchema(self):
421        fullName = os.path.join(self.canvasSettingsDir, "lastSchema.tmp")
422        if os.path.exists(fullName):
423            self.schema.loadDocument(fullName)
424
425    def menuItemReport(self):
426        self.schema.reportAll()
427       
428    def menuItemSave(self):
429        self.schema.saveDocument()
430       
431    def menuItemSaveAs(self):
432        self.schema.saveDocumentAs()
433
434    def menuItemSaveAsAppButtons(self):
435        self.schema.saveDocumentAsApp(asTabs=0)
436
437    def menuItemSaveAsAppTabs(self):
438        self.schema.saveDocumentAsApp(asTabs=1)
439
440    def menuItemPrinter(self):
441        try:
442            import OWDlgs
443            sizeDlg = OWDlgs.OWChooseImageSizeDlg(self.schema.canvas, defaultName=self.schema.schemaName or "schema", parent=self)
444            sizeDlg.exec_()
445        except:
446            print "Missing file 'OWDlgs.py'. This file should be in OrangeWidgets folder. Unable to print/save image."
447       
448
449    def readRecentFiles(self):
450        self.menuRecent.clear()
451        if not self.settings.has_key("RecentFiles"): return
452        recentDocs = self.settings["RecentFiles"]
453
454        # remove missing recent files
455        for i in range(len(recentDocs) - 1, -1, -1):
456            if not os.path.exists(recentDocs[i]):
457                recentDocs.remove(recentDocs[i])
458
459        recentDocs = recentDocs[:9]
460        self.settings["RecentFiles"] = recentDocs
461
462        for i in range(len(recentDocs)):
463            shortName = "&" + str(i + 1) + " " + os.path.basename(recentDocs[i])
464            self.menuRecent.addAction(shortName, lambda ind=i: self.openRecentFile(ind + 1))
465
466    def openRecentFile(self, index):
467        if len(self.settings["RecentFiles"]) >= index:
468            self.schema.clear()
469            name = self.settings["RecentFiles"][index - 1]
470            dirname = os.path.dirname(name)
471            os.chdir(dirname)
472            self.schema.loadDocument(name)
473            self.addToRecentMenu(name)
474
475    def addToRecentMenu(self, name):
476        recentDocs = []
477        if self.settings.has_key("RecentFiles"):
478            recentDocs = self.settings["RecentFiles"]
479
480        # convert to a valid file name
481        name = os.path.realpath(name)
482
483        if name in recentDocs:
484            recentDocs.remove(name)
485        recentDocs.insert(0, name)
486
487        if len(recentDocs) > 5:
488            recentDocs.remove(recentDocs[5])
489        self.settings["RecentFiles"] = recentDocs
490        self.readRecentFiles()
491
492    def menuItemSelectAll(self):
493        return
494
495    def updateSnapToGrid(self):
496        if self.settings["snapToGrid"]:
497            for widget in self.schema.widgets:
498                widget.setCoords(widget.x(), widget.y())
499            self.schema.canvas.update()
500
501    def menuItemEnableAll(self):
502        self.schema.enableAllLines()
503
504    def menuItemDisableAll(self):
505        self.schema.disableAllLines()
506
507    def menuItemSaveSettings(self):
508        self.menuSaveSettings = not self.menuSaveSettings
509        self.menuOptions.setItemChecked(self.menuSaveSettingsID, self.menuSaveSettings)
510
511    def menuItemNewScheme(self):
512        self.schema.clear()
513
514    def dumpVariables(self):
515        self.schema.dumpWidgetVariables()
516
517    def menuItemShowOutputWindow(self):
518        self.output.show()
519        self.output.raise_()
520        self.output.activateWindow()
521
522    def menuItemClearOutputWindow(self):
523        self.output.textOutput.clear()
524        self.statusBar().showMessage("")
525
526    def menuItemSaveOutputWindow(self):
527        qname = QFileDialog.getSaveFileName(self, "Save Output To File", self.canvasSettingsDir + "/Output.html", "HTML Document (*.html)")
528        if qname.isEmpty(): return
529        name = str(qname)
530
531        text = str(self.output.textOutput.toHtml())
532        #text = text.replace("</nobr>", "</nobr><br>")
533
534        file = open(name, "wt")
535        file.write(text)
536        file.close()
537
538
539    def menuItemShowToolbar(self):
540        self.settings["showToolbar"] = not self.settings.get("showToolbar", True)
541        if self.settings["showToolbar"]: self.toolbar.show()
542        else: self.toolbar.hide()
543
544    def menuItemShowWidgetToolbar(self):
545        self.settings["showWidgetToolbar"] = not self.settings.get("showWidgetToolbar", True)
546        if self.settings["showWidgetToolbar"]: self.widgetsToolBar.show()
547        else: self.widgetsToolBar.hide()
548
549
550    def menuItemEditWidgetShortcuts(self):
551        dlg = orngDlgs.WidgetShortcutDlg(self, self)
552        if dlg.exec_() == QDialog.Accepted:
553            self.widgetShortcuts = dict([(y, x) for x, y in dlg.invDict.items()])
554            shf = file(os.path.join(self.canvasSettingsDir, "shortcuts.txt"), "wt")
555            for k, widgetInfo in self.widgetShortcuts.items():
556                shf.write("%s: %s\n" % (k, (widgetInfo.category, widgetInfo.name)))
557
558    def menuItemDeleteWidgetSettings(self):
559        if QMessageBox.warning(self, 'Orange Canvas', 'Delete all settings?\nNote that for a complete reset there should be no open schema with any widgets.', QMessageBox.Ok | QMessageBox.Default, QMessageBox.Cancel | QMessageBox.Escape) == QMessageBox.Ok:
560            if os.path.exists(self.widgetSettingsDir):
561                for f in os.listdir(self.widgetSettingsDir):
562                    if os.path.splitext(f)[1].lower() == ".ini":
563                        os.remove(os.path.join(self.widgetSettingsDir, f))
564
565    def menuOpenLocalOrangeHelp(self):
566        import webbrowser
567        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/reference/default.htm"))
568
569    def menuOpenLocalWidgetCatalog(self):
570        import webbrowser
571        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/catalog/index.html"))
572
573    def menuOpenLocalCanvasHelp(self):
574        import webbrowser
575        webbrowser.open(os.path.join(self.orangeDir, "doc/canvas/default.htm"))
576
577    def menuOpenOnlineOrangeHelp(self):
578        import webbrowser
579        webbrowser.open("http://www.ailab.si/orange/doc/catalog")
580
581    def menuOpenOnlineCanvasHelp(self):
582        import webbrowser
583        #webbrowser.open("http://www.ailab.si/orange/orangeCanvas") # to be added on the web
584        webbrowser.open("http://www.ailab.si/orange")
585
586    def menuCheckForUpdates(self):
587        import updateOrange
588        self.updateDlg = updateOrange.updateOrangeDlg(None)#, Qt.WA_DeleteOnClose)
589
590    def menuItemAboutOrange(self):
591        dlg = orngDlgs.AboutDlg(self)
592        dlg.exec_()
593
594
595## to see the signals you have to call: self.output.catchException(0); self.output.catchOutput(0)
596## and run orngCanvas.pyw from command line using "python.exe orngCanvas.pyw"
597#    def event(self, e):
598#        eventDict = dict([(0, "None"), (130, "AccessibilityDescription"), (119, "AccessibilityHelp"), (86, "AccessibilityPrepare"), (114, "ActionAdded"), (113, "ActionChanged"), (115, "ActionRemoved"), (99, "ActivationChange"), (121, "ApplicationActivated"), (122, "ApplicationDeactivated"), (36, "ApplicationFontChange"), (37, "ApplicationLayoutDirectionChange"), (38, "ApplicationPaletteChange"), (35, "ApplicationWindowIconChange"), (68, "ChildAdded"), (69, "ChildPolished"), (71, "ChildRemoved"), (40, "Clipboard"), (19, "Close"), (82, "ContextMenu"), (52, "DeferredDelete"), (60, "DragEnter"), (62, "DragLeave"), (61, "DragMove"), (63, "Drop"), (98, "EnabledChange"), (10, "Enter"), (150, "EnterEditFocus"), (124, "EnterWhatsThisMode"), (116, "FileOpen"), (8, "FocusIn"), (9, "FocusOut"), (97, "FontChange"), (159, "GraphicsSceneContextMenu"), (164, "GraphicsSceneDragEnter"), (166, "GraphicsSceneDragLeave"), (165, "GraphicsSceneDragMove"), (167, "GraphicsSceneDrop"), (163, "GraphicsSceneHelp"), (160, "GraphicsSceneHoverEnter"), (162, "GraphicsSceneHoverLeave"), (161, "GraphicsSceneHoverMove"), (158, "GraphicsSceneMouseDoubleClick"), (155, "GraphicsSceneMouseMove"), (156, "GraphicsSceneMousePress"), (157, "GraphicsSceneMouseRelease"), (168, "GraphicsSceneWheel"), (18, "Hide"), (27, "HideToParent"), (127, "HoverEnter"), (128, "HoverLeave"), (129, "HoverMove"), (96, "IconDrag"), (101, "IconTextChange"), (83, "InputMethod"), (6, "KeyPress"), (7, "KeyRelease"), (89, "LanguageChange"), (90, "LayoutDirectionChange"), (76, "LayoutRequest"), (11, "Leave"), (151, "LeaveEditFocus"), (125, "LeaveWhatsThisMode"), (88, "LocaleChange"), (153, "MenubarUpdated"), (43, "MetaCall"), (102, "ModifiedChange"), (4, "MouseButtonDblClick"), (2, "MouseButtonPress"), (3, "MouseButtonRelease"), (5, "MouseMove"), (109, "MouseTrackingChange"), (13, "Move"), (12, "Paint"), (39, "PaletteChange"), (131, "ParentAboutToChange"), (21, "ParentChange"), (75, "Polish"), (74, "PolishRequest"), (123, "QueryWhatsThis"), (14, "Resize"), (117, "Shortcut"), (51, "ShortcutOverride"), (17, "Show"), (26, "ShowToParent"), (50, "SockAct"), (112, "StatusTip"), (100, "StyleChange"), (87, "TabletMove"), (92, "TabletPress"), (93, "TabletRelease"), (171, "TabletEnterProximity"), (172, "TabletLeaveProximity"), (1, "Timer"), (120, "ToolBarChange"), (110, "ToolTip"), (78, "UpdateLater"), (77, "UpdateRequest"), (111, "WhatsThis"), (118, "WhatsThisClicked"), (31, "Wheel"), (132, "WinEventAct"), (24, "WindowActivate"), (103, "WindowBlocked"), (25, "WindowDeactivate"), (34, "WindowIconChange"), (105, "WindowStateChange"), (33, "WindowTitleChange"), (104, "WindowUnblocked"), (126, "ZOrderChange"), (169, "KeyboardLayoutChange"), (170, "DynamicPropertyChange")])
599#        if eventDict.has_key(e.type()):
600#            print str(self.windowTitle()), eventDict[e.type()]
601#        return QMainWindow.event(self, e)
602
603
604    def menuItemCanvasOptions(self):
605        dlg = orngDlgs.CanvasOptionsDlg(self, self)
606
607        if dlg.exec_() == QDialog.Accepted:
608            if self.settings["snapToGrid"] != dlg.settings["snapToGrid"]:
609                self.updateSnapToGrid()
610
611            if self.settings["widgetListType"] != dlg.settings["widgetListType"]:
612                self.settings["widgetListType"] = dlg.settings["widgetListType"]
613                self.createWidgetsToolbar()
614                self.widgetListTypeCB.setCurrentIndex(self.settings["widgetListType"])
615            self.settings.update(dlg.settings)
616            self.updateStyle()
617           
618#            self.widgetSelectedColor = dlg.selectedWidgetIcon.color
619#            self.widgetActiveColor   = dlg.activeWidgetIcon.color
620#            self.lineColor           = dlg.lineIcon.color
621           
622            # update settings in widgets in current documents
623            for widget in self.schema.widgets:
624                widget.instance._useContexts = self.settings["useContexts"]
625                widget.instance._owInfo = self.settings["owInfo"]
626                widget.instance._owWarning = self.settings["owWarning"]
627                widget.instance._owError = self.settings["owError"]
628                widget.instance._owShowStatus = self.settings["owShow"]
629                widget.instance.updateStatusBarState()
630                widget.resetWidgetSize()
631                widget.updateWidgetState()
632               
633            # update tooltips for lines in all documents
634            for line in self.schema.lines:
635                line.showSignalNames = self.settings["showSignalNames"]
636                line.updateTooltip()
637           
638            self.schema.canvasView.repaint()
639       
640#            import orngEnviron, orngRegistry
641#            if dlg.toAdd != []:
642#                for (name, dir) in dlg.toAdd:
643#                    orngEnviron.registerAddOn(name, dir)
644           
645#            if dlg.toRemove != []:
646#                for (catName, cat) in dlg.toRemove:
647#                    addonsToRemove = set()
648#                    for widget in cat.values():
649#                        addonDir = widget.directory
650#                        while os.path.split(addonDir)[1] in ["prototypes", "widgets"]:
651#                            addonDir = os.path.split(addonDir)[0]
652#                        addonName = os.path.split(addonDir)[1]
653#                        addonsToRemove.add( (addonName, addonDir) )
654#                    for addonToRemove in addonsToRemove:
655#                        orngEnviron.registerAddOn(add=False, *addonToRemove)
656#           
657#            if dlg.toAdd != [] or dlg.toRemove != []:
658#                self.widgetRegistry = orngRegistry.readCategories()
659
660            # save tab order settings
661            newTabList = [(str(dlg.tabOrderList.item(i).text()), int(dlg.tabOrderList.item(i).checkState())) for i in range(dlg.tabOrderList.count())]
662            if newTabList != self.settings["WidgetTabs"]:
663                self.settings["WidgetTabs"] = newTabList
664                self.createWidgetsToolbar()
665                orngTabs.constructCategoriesPopup(self)
666
667    def menuItemAddOns(self):
668        dlg = orngDlgs.AddOnManagerDialog(self, self)
669        if dlg.exec_() == QDialog.Accepted:
670            for (id, addOn) in dlg.addOnsToRemove.items():
671                try:
672                    addOn.uninstall(refresh=False)
673                    if id in dlg.addOnsToAdd.items():
674                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
675                        del dlg.addOnsToAdd[id]
676                except Exception, e:
677                    print "Problem %s add-on %s: %s" % ("upgrading" if id in dlg.addOnsToAdd else "removing", addOn.name, e)
678            for (id, addOn) in dlg.addOnsToAdd.items():
679                if id.startswith("registered:"):
680                    try:
681                        orngAddOns.registerAddOn(addOn.name, addOn.directory, refresh=False, systemWide=False)
682                    except Exception, e:
683                        print "Problem registering add-on %s: %s" % (addOn.name, e)
684                else:
685                    try:
686                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
687                    except Exception, e:
688                        print "Problem installing add-on %s: %s" % (addOn.name, e)
689            if len(dlg.addOnsToAdd)+len(dlg.addOnsToRemove)>0:
690                orngAddOns.refreshAddOns(reloadPath=True)
691               
692                   
693
694    def updateStyle(self):
695        QApplication.setStyle(QStyleFactory.create(self.settings["style"]))
696#        qApp.setStyleSheet(" QDialogButtonBox { button-layout: 0; }")       # we want buttons to go in the "windows" direction (Yes, No, Cancel)
697        if self.settings["useDefaultPalette"]:
698            QApplication.setPalette(qApp.style().standardPalette())
699        else:
700            QApplication.setPalette(self.originalPalette)
701
702
703    def setStatusBarEvent(self, text):
704        if text == "" or text == None:
705            self.statusBar().showMessage("")
706            return
707        elif text == "\n": return
708        text = str(text)
709        text = text.replace("<nobr>", ""); text = text.replace("</nobr>", "")
710        text = text.replace("<b>", ""); text = text.replace("</b>", "")
711        text = text.replace("<i>", ""); text = text.replace("</i>", "")
712        text = text.replace("<br>", ""); text = text.replace("&nbsp", "")
713        self.statusBar().showMessage("Last event: " + str(text), 5000)
714
715    # Loads settings from the widget's .ini file
716    def loadSettings(self):
717        self.settings = {"widgetListType": 4, "iconSize": "40 x 40", "toolbarIconSize": 2, "toolboxWidth": 200, 'schemeIconSize': 1,
718                       "snapToGrid": 1, "writeLogFile": 1, "dontAskBeforeClose": 0, "saveWidgetsPosition": 1,
719#                       "widgetSelectedColor": (0, 255, 0), "widgetActiveColor": (0, 0, 255), "lineColor": (0, 255, 0),
720                       "reportsDir": self.defaultReportsDir, "saveSchemaDir": self.canvasSettingsDir, "saveApplicationDir": self.canvasSettingsDir,
721                       "showSignalNames": 1, "useContexts": 1, "enableCanvasDropShadows": 0,
722                       "canvasWidth": 700, "canvasHeight": 600, "useDefaultPalette": 0,
723                       "focusOnCatchException": 1, "focusOnCatchOutput": 0, "printOutputInStatusBar": 1, "printExceptionInStatusBar": 1,
724                       "outputVerbosity": 0, "synchronizeHelp": 1,
725                       "ocShow": 1, "owShow": 0, "ocInfo": 1, "owInfo": 1, "ocWarning": 1, "owWarning": 1, "ocError": 1, "owError": 1,
726                       }
727        if RedR:
728            self.setting.update({"svnSettings": None, "versionNumber": "Version0"})
729        try:
730            filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
731            self.settings.update(cPickle.load(open(filename, "rb")))
732        except:
733            pass
734
735        if not self.settings.has_key("style"):
736            items = [str(n) for n in QStyleFactory.keys()]
737            lowerItems = [str(n).lower() for n in QStyleFactory.keys()]
738            if sys.platform == "darwin" and qVersion() < "4.6": #On Mac OSX full aqua style isn't supported until Qt 4.6
739                currStyle = "cleanlooks"
740            else:
741                currStyle = str(qApp.style().objectName()).lower()
742            self.settings.setdefault("style", items[lowerItems.index(currStyle)])
743
744
745    # Saves settings to this widget's .ini file
746    def saveSettings(self):
747        filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
748        file = open(filename, "wb")
749        if self.settings["widgetListType"] == 1:        # tree view
750            self.settings["treeItemsOpenness"] = dict([(key, self.tabs.tabDict[key].isExpanded()) for key in self.tabs.tabDict.keys()])
751        cPickle.dump(self.settings, file)
752        file.close()
753
754    def closeEvent(self, ce):
755        # save the current width of the toolbox, if we are using it
756        if isinstance(self.widgetsToolBar, orngTabs.WidgetToolBox):
757            self.settings["toolboxWidth"] = self.widgetsToolBar.toolbox.width()
758        self.settings["showWidgetToolbar"] = self.widgetsToolBar.isVisible()
759        self.settings["showToolbar"] = self.toolbar.isVisible()
760        self.settings["reportsDir"] = self.reportWindow.saveDir
761
762        closed = self.schema.close()
763        if closed:
764            self.canvasIsClosing = 1        # output window (and possibly report window also) will check this variable before it will close the window
765            self.output.logFile.close()
766            self.output.hide()
767           
768            ce.accept()
769           
770            self.helpWindow.close()
771            self.reportWindow.close()
772        else:
773            ce.ignore()
774       
775        self.reportWindow.removeTemp()
776       
777        size = self.geometry().size()
778        self.settings["canvasWidth"] = size.width()
779        self.settings["canvasHeight"] = size.height()
780        self.settings["CanvasMainWindowGeometry"] = str(self.saveGeometry())
781       
782        self.saveSettings()
783       
784
785    def setCaption(self, caption=""):
786        if caption:
787            caption = caption.split(".")[0]
788            self.setWindowTitle(caption + " - %s Canvas" % product)
789        else:
790            self.setWindowTitle("%s Canvas" % product)
791   
792    def getWidgetIcon(self, widgetInfo):
793        if self.iconNameToIcon.has_key(widgetInfo.icon):
794            return self.iconNameToIcon[widgetInfo.icon]
795       
796        iconNames = self.getFullWidgetIconName(widgetInfo)
797        iconBackgrounds = self.getFullIconBackgroundName(widgetInfo)
798        icon = QIcon()
799        if len(iconNames) == 1:
800            iconSize = QPixmap(iconNames[0]).width()
801            iconBackgrounds = [name for name in iconBackgrounds if QPixmap(name).width() == iconSize]
802        for name, back in zip(iconNames, iconBackgrounds):
803            image = QPixmap(back).toImage()
804            painter = QPainter(image)
805            painter.drawPixmap(0, 0, QPixmap(name))
806            painter.end()
807            icon.addPixmap(QPixmap.fromImage(image))
808        if iconNames != [self.defaultPic]:
809            self.iconNameToIcon[widgetInfo.icon] = icon
810        return icon
811           
812   
813    def getFullWidgetIconName(self, widgetInfo):
814        iconName = widgetInfo.icon
815        names = []
816        name, ext = os.path.splitext(iconName)
817        for num in [16, 32, 40, 48, 60]:
818            names.append("%s_%d%s" % (name, num, ext))
819           
820        widgetDir = str(widgetInfo.directory)  #os.path.split(self.getFileName())[0]
821        fullPaths = []
822        for paths in [(self.widgetDir, widgetInfo.category), (self.widgetDir,), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
823            for name in names + [iconName]:
824                fname = os.path.join(*paths + (name,))
825                if os.path.exists(fname):
826                    fullPaths.append(fname)
827            if len(fullPaths) > 1 and fullPaths[-1].endswith(iconName):
828                fullPaths.pop()     # if we have the new icons we can remove the default icon
829            if fullPaths != []:
830                return fullPaths
831        return [self.defaultPic]
832   
833    def getFullIconBackgroundName(self, widgetInfo):
834        widgetDir = str(widgetInfo.directory)
835        fullPaths = []
836        for paths in [(widgetDir, "icons"), (self.widgetDir, widgetInfo.category, "icons"), (self.widgetDir, "icons"), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
837            for name in ["background_%d.png" % num for num in [16, 32, 40, 48, 60]]:
838                fname = os.path.join(*paths + (name,))
839#                print fname
840                if os.path.exists(fname):
841                    fullPaths.append(fname)
842            if fullPaths != []:
843                return fullPaths   
844        return [self.defaultBackground]
845   
846class MyStatusBar(QStatusBar):
847    def __init__(self, parent):
848        QStatusBar.__init__(self, parent)
849        self.parentWidget = parent
850
851    def mouseDoubleClickEvent(self, ev):
852        self.parentWidget.menuItemShowOutputWindow()
853       
854       
855class OrangeQApplication(QApplication):
856    def __init__(self, *args):
857        QApplication.__init__(self, *args)
858       
859    #QFileOpenEvent are Mac OSX only
860    if sys.platform == "darwin":
861        def event(self, event):
862            if event.type() == QEvent.FileOpen:
863                file = str(event.file())
864                def send():
865                    if hasattr(qApp, "canvasDlg"):
866                        qApp.canvasDlg.openSchema(file)
867                    else:
868                        QTimer.singleShot(100, send)
869                send()
870            return QApplication.event(self, event)
871       
872#    def notify(self, receiver, event):
873#        eventDict = {0: 'None', 1: 'Timer', 2: 'MouseButtonPress', 3: 'MouseButtonRelease', 4: 'MouseButtonDblClick', 5: 'MouseMove', 6: 'KeyPress', 7: 'KeyRelease', 8: 'FocusIn', 9: 'FocusOut', 10: 'Enter', 11: 'Leave', 12: 'Paint', 13: 'Move', 14: 'Resize', 17: 'Show', 18: 'Hide', 19: 'Close', 21: 'ParentChange', 24: 'WindowActivate', 25: 'WindowDeactivate', 26: 'ShowToParent', 27: 'HideToParent', 31: 'Wheel', 33: 'WindowTitleChange', 34: 'WindowIconChange', 35: 'ApplicationWindowIconChange', 36: 'ApplicationFontChange', 37: 'ApplicationLayoutDirectionChange', 38: 'ApplicationPaletteChange', 39: 'PaletteChange', 40: 'Clipboard', 43: 'MetaCall', 50: 'SockAct', 51: 'ShortcutOverride', 52: 'DeferredDelete', 60: 'DragEnter', 61: 'DragMove', 62: 'DragLeave', 63: 'Drop', 68: 'ChildAdded', 69: 'ChildPolished', 70: 'ChildInserted', 71: 'ChildRemoved', 74: 'PolishRequest', 75: 'Polish', 76: 'LayoutRequest', 77: 'UpdateRequest', 78: 'UpdateLater', 82: 'ContextMenu', 83: 'InputMethod', 86: 'AccessibilityPrepare', 87: 'TabletMove', 88: 'LocaleChange', 89: 'LanguageChange', 90: 'LayoutDirectionChange', 92: 'TabletPress', 93: 'TabletRelease', 94: 'OkRequest', 96: 'IconDrag', 97: 'FontChange', 98: 'EnabledChange', 99: 'ActivationChange', 100: 'StyleChange', 101: 'IconTextChange', 102: 'ModifiedChange', 103: 'WindowBlocked', 104: 'WindowUnblocked', 105: 'WindowStateChange', 109: 'MouseTrackingChange', 110: 'ToolTip', 111: 'WhatsThis', 112: 'StatusTip', 113: 'ActionChanged', 114: 'ActionAdded', 115: 'ActionRemoved', 116: 'FileOpen', 117: 'Shortcut', 118: 'WhatsThisClicked', 119: 'AccessibilityHelp', 120: 'ToolBarChange', 121: 'ApplicationActivate', 122: 'ApplicationDeactivate', 123: 'QueryWhatsThis', 124: 'EnterWhatsThisMode', 125: 'LeaveWhatsThisMode', 126: 'ZOrderChange', 127: 'HoverEnter', 128: 'HoverLeave', 129: 'HoverMove', 130: 'AccessibilityDescription', 131: 'ParentAboutToChange', 132: 'WinEventAct', 150: 'EnterEditFocus', 151: 'LeaveEditFocus', 153: 'MenubarUpdated', 155: 'GraphicsSceneMouseMove', 156: 'GraphicsSceneMousePress', 157: 'GraphicsSceneMouseRelease', 158: 'GraphicsSceneMouseDoubleClick', 159: 'GraphicsSceneContextMenu', 160: 'GraphicsSceneHoverEnter', 161: 'GraphicsSceneHoverMove', 162: 'GraphicsSceneHoverLeave', 163: 'GraphicsSceneHelp', 164: 'GraphicsSceneDragEnter', 165: 'GraphicsSceneDragMove', 166: 'GraphicsSceneDragLeave', 167: 'GraphicsSceneDrop', 168: 'GraphicsSceneWheel', 169: 'KeyboardLayoutChange', 170: 'DynamicPropertyChange', 171: 'TabletEnterProximity', 172: 'TabletLeaveProximity', 173: 'NonClientAreaMouseMove', 174: 'NonClientAreaMouseButtonPress', 175: 'NonClientAreaMouseButtonRelease', 176: 'NonClientAreaMouseButtonDblClick', 177: 'MacSizeChange', 178: 'ContentsRectChange', 181: 'GraphicsSceneResize', 182: 'GraphicsSceneMove', 183: 'CursorChange', 184: 'ToolTipChange', 186: 'GrabMouse', 187: 'UngrabMouse', 188: 'GrabKeyboard', 189: 'UngrabKeyboard'}
874#        import time
875#        try:
876#            if str(receiver.windowTitle()) != "":
877#                print time.strftime("%H:%M:%S"), "%15s" % str(receiver.windowTitle()) + ": ",      # print only events for QWidget classes and up
878#                if eventDict.has_key(event.type()):
879#                    print eventDict[event.type()]
880#                else:
881#                    print "unknown event name (" + str(event.type()) + ")"
882#        except:
883#            pass
884#            #print str(receiver.objectName()),
885#               
886#        return QApplication.notify(self, receiver, event)
887
888
889def main(argv=None):
890    if argv == None:
891        argv = sys.argv
892
893    app = OrangeQApplication(sys.argv)
894    dlg = OrangeCanvasDlg(app)
895    qApp.canvasDlg = dlg
896    dlg.show()
897    for arg in sys.argv[1:]:
898        if arg == "-reload":
899            dlg.menuItemOpenLastSchema()
900    app.exec_()
901    app.closeAllWindows()
902
903if __name__ == "__main__":
904    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.