source: orange/orange/OrangeCanvas/orngCanvas.pyw @ 7144:8623e6d112e9

Revision 7144:8623e6d112e9, 47.0 KB checked in by ales_erjavec <ales.erjavec@…>, 3 years ago (diff)
  • Loading data files from the local directory (from where the schema file was loaded) if saved path does not exist.
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        self.readShortcuts()
179       
180        def addOnRefreshCallback():
181            self.widgetRegistry = orngRegistry.readCategories()
182            orngTabs.constructCategoriesPopup(self)
183            self.createWidgetsToolbar()
184        orngAddOns.addOnRefreshCallback.append(addOnRefreshCallback)
185
186        # create menu
187        self.initMenu()
188        self.readRecentFiles()
189
190       
191       
192        #move to center if frame not fully contained in space
193        if not space.contains(self.frameGeometry()):
194            x = max(0, space.width() / 2 - width / 2)
195            y = max(0, space.height() / 2 - height / 2)
196           
197            self.move(x, y)
198
199        self.helpWindow = orngHelp.HelpWindow(self)
200        self.reportWindow = OWReport.ReportWindow()
201        self.reportWindow.widgets = self.schema.widgets
202        self.reportWindow.saveDir = self.settings["reportsDir"]
203       
204
205        # did Orange crash the last time we used it? If yes, you will find a temSchema.tmp file
206        if not RedR:
207            if os.path.exists(os.path.join(self.canvasSettingsDir, "tempSchema.tmp")):
208                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)
209                mb.setButtonText(QMessageBox.Ok, "Reload")
210                mb.setButtonText(QMessageBox.Cancel, "New schema")
211                if mb.exec_() == QMessageBox.Ok:
212                    self.schema.loadDocument(os.path.join(self.canvasSettingsDir, "tempSchema.tmp"), freeze=1)
213       
214        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":
215            self.schema.loadDocument(sys.argv[-1])
216       
217        # show message box if no numpy
218        qApp.processEvents()
219        try:
220            import numpy
221        except:
222            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:
223                import webbrowser
224                webbrowser.open("http://sourceforge.net/projects/numpy/")
225
226    def createWidgetsToolbar(self):
227        if self.widgetsToolBar:
228            self.settings["showWidgetToolbar"] = self.widgetsToolBar.isVisible()
229            if isinstance(self.widgetsToolBar, QToolBar):
230                self.removeToolBar(self.widgetsToolBar)
231            elif isinstance(self.widgetsToolBar, orngTabs.WidgetToolBox):
232                self.settings["toolboxWidth"] = self.widgetsToolBar.toolbox.width()
233                self.removeDockWidget(self.widgetsToolBar)
234            elif isinstance(self.widgetsToolBar, orngTabs.WidgetTree):
235                self.settings["toolboxWidth"] = self.widgetsToolBar.treeWidget.width()
236                self.removeDockWidget(self.widgetsToolBar)
237           
238        if self.settings["widgetListType"] == 0:
239            self.tabs = self.widgetsToolBar = orngTabs.WidgetToolBox(self, self.widgetRegistry)
240            self.addDockWidget(Qt.LeftDockWidgetArea, self.widgetsToolBar)
241        elif self.settings["widgetListType"] in [1, 2]:
242            self.tabs = self.widgetsToolBar = orngTabs.WidgetTree(self, self.widgetRegistry)
243            self.addDockWidget(Qt.LeftDockWidgetArea, self.widgetsToolBar)
244        else:
245            if sys.platform == "darwin":
246                self.setUnifiedTitleAndToolBarOnMac(False)   
247            self.widgetsToolBar = self.addToolBar("Widgets")
248            self.insertToolBarBreak(self.widgetsToolBar)
249            self.tabs = orngTabs.WidgetTabs(self, self.widgetRegistry, self.widgetsToolBar)
250            self.widgetsToolBar.addWidget(self.tabs)
251           
252        if sys.platform == "darwin":
253            self.setUnifiedTitleAndToolBarOnMac(self.settings["widgetListType"] in [0, 1, 2] and self.settings["style"].lower() == "macintosh (aqua)")
254
255        # find widgets and create tab with buttons
256        self.settings["WidgetTabs"] = self.tabs.createWidgetTabs(self.settings["WidgetTabs"], self.widgetRegistry, self.widgetDir, self.picsDir, self.defaultPic)
257        if not self.settings.get("showWidgetToolbar", True):
258            self.widgetsToolBar.hide()
259
260
261    def readShortcuts(self):
262        self.widgetShortcuts = {}
263        shfn = os.path.join(self.canvasSettingsDir, "shortcuts.txt")
264        if os.path.exists(shfn):
265            for t in file(shfn).readlines():
266                key, info = [x.strip() for x in t.split(":")]
267                if len(info) == 0: continue
268                if info[0] == "(" and info[-1] == ")":
269                    cat, widgetName = eval(info)            # new style of shortcuts are of form F: ("Data", "File")
270                else:
271                    cat, widgetName = info.split(" - ")   # old style of shortcuts are of form F: Data - File
272                if self.widgetRegistry.has_key(cat) and self.widgetRegistry[cat].has_key(widgetName):
273                    self.widgetShortcuts[key] = self.widgetRegistry[cat][widgetName]
274
275
276    def initMenu(self):
277        self.menuRecent = QMenu("Recent Schemas", self)
278
279        self.menuFile = QMenu("&File", self)
280        self.menuFile.addAction("New Scheme", self.menuItemNewScheme, QKeySequence.New)
281        self.menuFile.addAction(QIcon(self.file_open), "&Open...", self.menuItemOpen, QKeySequence.Open)
282        self.menuFile.addAction(QIcon(self.file_open), "&Open and Freeze...", self.menuItemOpenFreeze)
283        if RedR:
284            self.menuFile.addAction("Import Schema", self.importSchema)
285        if os.path.exists(os.path.join(self.canvasSettingsDir, "lastSchema.tmp")):
286            self.menuFile.addAction("Reload Last Schema", self.menuItemOpenLastSchema, Qt.CTRL + Qt.Key_R)
287        #self.menuFile.addAction( "&Clear", self.menuItemClear)
288        self.menuFile.addSeparator()
289        self.menuReportID = self.menuFile.addAction("&Report", self.menuItemReport, Qt.CTRL + Qt.ALT + Qt.Key_R)
290        self.menuFile.addSeparator()
291        self.menuSaveID = self.menuFile.addAction(QIcon(self.file_save), "&Save", self.menuItemSave, QKeySequence.Save)
292        self.menuSaveAsID = self.menuFile.addAction("Save &as...", self.menuItemSaveAs)
293        if not RedR:
294            self.menuFile.addAction("&Save as Application (Tabs)...", self.menuItemSaveAsAppTabs)
295            self.menuFile.addAction("&Save as Application (Buttons)...", self.menuItemSaveAsAppButtons)
296        self.menuFile.addSeparator()
297        self.menuFile.addAction(QIcon(self.file_print), "&Print Schema / Save image", self.menuItemPrinter, QKeySequence.Print)
298        self.menuFile.addSeparator()
299        self.menuFile.addMenu(self.menuRecent)
300        self.menuFile.addSeparator()
301        self.menuFile.addAction("E&xit", self.close, Qt.CTRL + Qt.Key_Q)
302
303        self.menuOptions = QMenu("&Options", self)
304        self.menuOptions.addAction("Enable All Links", self.menuItemEnableAll, Qt.CTRL + Qt.Key_E)
305        self.menuOptions.addAction("Disable All Links", self.menuItemDisableAll, Qt.CTRL + Qt.Key_D)
306        self.menuOptions.addSeparator()
307        self.menuOptions.addAction("Show Output Window", self.menuItemShowOutputWindow)
308        self.menuOptions.addAction("Clear Output Window", self.menuItemClearOutputWindow)
309        self.menuOptions.addAction("Save Output Text...", self.menuItemSaveOutputWindow)
310        if RedR:
311            self.menuOptions.addAction("Set to debug mode", self.setDebugMode)
312       
313        # uncomment this only for debugging
314#        self.menuOptions.addSeparator()
315#        self.menuOptions.addAction("Dump widget variables", self.dumpVariables)
316
317        self.menuOptions.addSeparator()
318#        self.menuOptions.addAction( "Channel preferences",  self.menuItemPreferences)
319        #self.menuOptions.addSeparator()
320        self.menuOptions.addAction("&Customize Shortcuts", self.menuItemEditWidgetShortcuts)
321        self.menuOptions.addAction("&Delete Widget Settings", self.menuItemDeleteWidgetSettings)
322        self.menuOptions.addSeparator()
323        self.menuOptions.addAction(sys.platform == "darwin" and "&Preferences..." or "Canvas &Options...", self.menuItemCanvasOptions)
324        self.menuOptions.addAction("&Add-ons...", self.menuItemAddOns)
325
326        localHelp = 0
327        self.menuHelp = QMenu("&Help", self)
328        if os.path.exists(os.path.join(self.orangeDir, r"doc/reference/default.htm")): self.menuHelp.addAction("Orange Help", self.menuOpenLocalOrangeHelp)
329        if os.path.exists(os.path.join(self.orangeDir, r"doc/catalog/index.html")): self.menuHelp.addAction("Orange Widget Catalog", self.menuOpenLocalWidgetCatalog)
330        if os.path.exists(os.path.join(self.orangeDir, r"doc/canvas/default.htm")): self.menuHelp.addAction("Orange Canvas Help", self.menuOpenLocalCanvasHelp)
331
332        self.menuHelp.addAction("Orange Online Widget Catalog", self.menuOpenOnlineOrangeHelp)
333        #self.menuHelp.addAction("Orange Canvas Online Help", self.menuOpenOnlineCanvasHelp)
334
335        if os.path.exists(os.path.join(self.orangeDir, r"updateOrange.py")):
336            self.menuHelp.addSeparator()
337            self.menuHelp.addAction("Check for updates", self.menuCheckForUpdates)
338           
339        self.menuHelp.addSeparator()
340        self.menuHelp.addAction("About Orange", self.menuItemAboutOrange)
341
342        # widget popup menu
343        self.widgetPopup = QMenu("Widget", self)
344        self.openActiveWidgetAction = self.widgetPopup.addAction("Open", self.schema.canvasView.openActiveWidget)
345        self.widgetPopup.addSeparator()
346        self.renameActiveWidgetAction = rename = self.widgetPopup.addAction("&Rename", self.schema.canvasView.renameActiveWidget, Qt.Key_F2)
347        self.removeActiveWidgetAction = delete = self.widgetPopup.addAction("Remove", self.schema.canvasView.removeActiveWidget, Qt.Key_Delete)
348        delete.setShortcuts([Qt.Key_Delete, Qt.CTRL + Qt.Key_Backspace, Qt.CTRL + Qt.Key_Delete])
349        self.widgetPopup.addSeparator()
350        self.helpActiveWidgetAction = self.widgetPopup.addAction("Help", self.schema.canvasView.helpOnActiveWidget, Qt.Key_F1)
351        self.widgetPopup.setEnabled(0)
352       
353        if sys.platform == "darwin":
354            self.windowPopup = QMenu("Window", self)
355            self.windowPopup.addAction("Minimize", self.showMinimized, Qt.CTRL + Qt.Key_M)
356            self.windowPopup.addAction("Zoom", self.showMaximized, 0)
357
358        self.menuBar = QMenuBar(self)
359        self.menuBar.addMenu(self.menuFile)
360        self.menuBar.addMenu(self.menuOptions)
361        self.menuBar.addMenu(self.widgetPopup)
362       
363        if hasattr(self, "windowPopup"):
364            self.menuBar.addMenu(self.windowPopup)
365           
366        self.menuBar.addMenu(self.menuHelp)
367       
368        self.setMenuBar(self.menuBar)
369       
370    def setDebugMode(self):   # RedR specific
371        if self.output.debugMode:
372            self.output.debugMode = 0
373        else:
374            self.output.debugMode = 1
375    def importSchema(self):   # RedR specific
376        name = QFileDialog.getOpenFileName(self, "Import File", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
377        if name.isEmpty():
378            return
379        self.schema.clear()
380        self.schema.loadDocument(str(name), freeze = 0, importBlank = 1)
381        self.addToRecentMenu(str(name))
382   
383    def openSchema(self, filename):
384        if self.schema.isSchemaChanged() and self.schema.widgets:
385            ret = QMessageBox.warning(self, "Orange Canvas", "Changes to your present schema are not saved.\nSave them?",
386                                      QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, QMessageBox.Save)
387            if ret == QMessageBox.Save:
388                self.schema.saveDocument()
389            elif ret == QMessageBox.Cancel:
390                return
391        self.schema.clear()
392        dirname = os.path.dirname(filename)
393        os.chdir(dirname)
394        self.schema.loadDocument(filename)
395       
396    def menuItemOpen(self):
397        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
398        if name.isEmpty():
399            return
400        self.schema.clear()
401        dirname = os.path.dirname(str(name))
402        os.chdir(dirname)
403        self.schema.loadDocument(str(name), freeze=0)
404        self.addToRecentMenu(str(name))
405
406    def menuItemOpenFreeze(self):
407        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
408        if name.isEmpty():
409            return
410        self.schema.clear()
411        dirname = os.path.dirname(str(name))
412        os.chdir(dirname)
413        self.schema.loadDocument(str(name), freeze=1)
414        self.addToRecentMenu(str(name))
415
416    def menuItemOpenLastSchema(self):
417        fullName = os.path.join(self.canvasSettingsDir, "lastSchema.tmp")
418        if os.path.exists(fullName):
419            self.schema.loadDocument(fullName)
420
421    def menuItemReport(self):
422        self.schema.reportAll()
423       
424    def menuItemSave(self):
425        self.schema.saveDocument()
426       
427    def menuItemSaveAs(self):
428        self.schema.saveDocumentAs()
429
430    def menuItemSaveAsAppButtons(self):
431        self.schema.saveDocumentAsApp(asTabs=0)
432
433    def menuItemSaveAsAppTabs(self):
434        self.schema.saveDocumentAsApp(asTabs=1)
435
436    def menuItemPrinter(self):
437        try:
438            import OWDlgs
439            sizeDlg = OWDlgs.OWChooseImageSizeDlg(self.schema.canvas, defaultName=self.schema.schemaName or "schema", parent=self)
440            sizeDlg.exec_()
441        except:
442            print "Missing file 'OWDlgs.py'. This file should be in OrangeWidgets folder. Unable to print/save image."
443       
444
445    def readRecentFiles(self):
446        self.menuRecent.clear()
447        if not self.settings.has_key("RecentFiles"): return
448        recentDocs = self.settings["RecentFiles"]
449
450        # remove missing recent files
451        for i in range(len(recentDocs) - 1, -1, -1):
452            if not os.path.exists(recentDocs[i]):
453                recentDocs.remove(recentDocs[i])
454
455        recentDocs = recentDocs[:9]
456        self.settings["RecentFiles"] = recentDocs
457
458        for i in range(len(recentDocs)):
459            shortName = "&" + str(i + 1) + " " + os.path.basename(recentDocs[i])
460            self.menuRecent.addAction(shortName, lambda ind=i: self.openRecentFile(ind + 1))
461
462    def openRecentFile(self, index):
463        if len(self.settings["RecentFiles"]) >= index:
464            self.schema.clear()
465            name = self.settings["RecentFiles"][index - 1]
466            dirname = os.path.dirname(name)
467            os.chdir(dirname)
468            self.schema.loadDocument(name)
469            self.addToRecentMenu(name)
470
471    def addToRecentMenu(self, name):
472        recentDocs = []
473        if self.settings.has_key("RecentFiles"):
474            recentDocs = self.settings["RecentFiles"]
475
476        # convert to a valid file name
477        name = os.path.realpath(name)
478
479        if name in recentDocs:
480            recentDocs.remove(name)
481        recentDocs.insert(0, name)
482
483        if len(recentDocs) > 5:
484            recentDocs.remove(recentDocs[5])
485        self.settings["RecentFiles"] = recentDocs
486        self.readRecentFiles()
487
488    def menuItemSelectAll(self):
489        return
490
491    def updateSnapToGrid(self):
492        if self.settings["snapToGrid"]:
493            for widget in self.schema.widgets:
494                widget.setCoords(widget.x(), widget.y())
495            self.schema.canvas.update()
496
497    def menuItemEnableAll(self):
498        self.schema.enableAllLines()
499
500    def menuItemDisableAll(self):
501        self.schema.disableAllLines()
502
503    def menuItemSaveSettings(self):
504        self.menuSaveSettings = not self.menuSaveSettings
505        self.menuOptions.setItemChecked(self.menuSaveSettingsID, self.menuSaveSettings)
506
507    def menuItemNewScheme(self):
508        self.schema.clear()
509
510    def dumpVariables(self):
511        self.schema.dumpWidgetVariables()
512
513    def menuItemShowOutputWindow(self):
514        self.output.show()
515        self.output.raise_()
516        self.output.activateWindow()
517
518    def menuItemClearOutputWindow(self):
519        self.output.textOutput.clear()
520        self.statusBar().showMessage("")
521
522    def menuItemSaveOutputWindow(self):
523        qname = QFileDialog.getSaveFileName(self, "Save Output To File", self.canvasSettingsDir + "/Output.html", "HTML Document (*.html)")
524        if qname.isEmpty(): return
525        name = str(qname)
526
527        text = str(self.output.textOutput.toHtml())
528        #text = text.replace("</nobr>", "</nobr><br>")
529
530        file = open(name, "wt")
531        file.write(text)
532        file.close()
533
534
535    def menuItemShowToolbar(self):
536        self.settings["showToolbar"] = not self.settings.get("showToolbar", True)
537        if self.settings["showToolbar"]: self.toolbar.show()
538        else: self.toolbar.hide()
539
540    def menuItemShowWidgetToolbar(self):
541        self.settings["showWidgetToolbar"] = not self.settings.get("showWidgetToolbar", True)
542        if self.settings["showWidgetToolbar"]: self.widgetsToolBar.show()
543        else: self.widgetsToolBar.hide()
544
545
546    def menuItemEditWidgetShortcuts(self):
547        dlg = orngDlgs.WidgetShortcutDlg(self, self)
548        if dlg.exec_() == QDialog.Accepted:
549            self.widgetShortcuts = dict([(y, x) for x, y in dlg.invDict.items()])
550            shf = file(os.path.join(self.canvasSettingsDir, "shortcuts.txt"), "wt")
551            for k, widgetInfo in self.widgetShortcuts.items():
552                shf.write("%s: %s\n" % (k, (widgetInfo.category, widgetInfo.name)))
553
554    def menuItemDeleteWidgetSettings(self):
555        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:
556            if os.path.exists(self.widgetSettingsDir):
557                for f in os.listdir(self.widgetSettingsDir):
558                    if os.path.splitext(f)[1].lower() == ".ini":
559                        os.remove(os.path.join(self.widgetSettingsDir, f))
560
561    def menuOpenLocalOrangeHelp(self):
562        import webbrowser
563        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/reference/default.htm"))
564
565    def menuOpenLocalWidgetCatalog(self):
566        import webbrowser
567        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/catalog/index.html"))
568
569    def menuOpenLocalCanvasHelp(self):
570        import webbrowser
571        webbrowser.open(os.path.join(self.orangeDir, "doc/canvas/default.htm"))
572
573    def menuOpenOnlineOrangeHelp(self):
574        import webbrowser
575        webbrowser.open("http://www.ailab.si/orange/doc/catalog")
576
577    def menuOpenOnlineCanvasHelp(self):
578        import webbrowser
579        #webbrowser.open("http://www.ailab.si/orange/orangeCanvas") # to be added on the web
580        webbrowser.open("http://www.ailab.si/orange")
581
582    def menuCheckForUpdates(self):
583        import updateOrange
584        self.updateDlg = updateOrange.updateOrangeDlg(None)#, Qt.WA_DeleteOnClose)
585
586    def menuItemAboutOrange(self):
587        dlg = orngDlgs.AboutDlg(self)
588        dlg.exec_()
589
590
591## to see the signals you have to call: self.output.catchException(0); self.output.catchOutput(0)
592## and run orngCanvas.pyw from command line using "python.exe orngCanvas.pyw"
593#    def event(self, e):
594#        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")])
595#        if eventDict.has_key(e.type()):
596#            print str(self.windowTitle()), eventDict[e.type()]
597#        return QMainWindow.event(self, e)
598
599
600    def menuItemCanvasOptions(self):
601        dlg = orngDlgs.CanvasOptionsDlg(self, self)
602
603        if dlg.exec_() == QDialog.Accepted:
604            if self.settings["snapToGrid"] != dlg.settings["snapToGrid"]:
605                self.updateSnapToGrid()
606
607            if self.settings["widgetListType"] != dlg.settings["widgetListType"]:
608                self.settings["widgetListType"] = dlg.settings["widgetListType"]
609                self.createWidgetsToolbar()
610                self.widgetListTypeCB.setCurrentIndex(self.settings["widgetListType"])
611            self.settings.update(dlg.settings)
612            self.updateStyle()
613           
614#            self.widgetSelectedColor = dlg.selectedWidgetIcon.color
615#            self.widgetActiveColor   = dlg.activeWidgetIcon.color
616#            self.lineColor           = dlg.lineIcon.color
617           
618            # update settings in widgets in current documents
619            for widget in self.schema.widgets:
620                widget.instance._useContexts = self.settings["useContexts"]
621                widget.instance._owInfo = self.settings["owInfo"]
622                widget.instance._owWarning = self.settings["owWarning"]
623                widget.instance._owError = self.settings["owError"]
624                widget.instance._owShowStatus = self.settings["owShow"]
625                widget.instance.updateStatusBarState()
626                widget.resetWidgetSize()
627                widget.updateWidgetState()
628               
629            # update tooltips for lines in all documents
630            for line in self.schema.lines:
631                line.showSignalNames = self.settings["showSignalNames"]
632                line.updateTooltip()
633           
634            self.schema.canvasView.repaint()
635       
636#            import orngEnviron, orngRegistry
637#            if dlg.toAdd != []:
638#                for (name, dir) in dlg.toAdd:
639#                    orngEnviron.registerAddOn(name, dir)
640           
641#            if dlg.toRemove != []:
642#                for (catName, cat) in dlg.toRemove:
643#                    addonsToRemove = set()
644#                    for widget in cat.values():
645#                        addonDir = widget.directory
646#                        while os.path.split(addonDir)[1] in ["prototypes", "widgets"]:
647#                            addonDir = os.path.split(addonDir)[0]
648#                        addonName = os.path.split(addonDir)[1]
649#                        addonsToRemove.add( (addonName, addonDir) )
650#                    for addonToRemove in addonsToRemove:
651#                        orngEnviron.registerAddOn(add=False, *addonToRemove)
652#           
653#            if dlg.toAdd != [] or dlg.toRemove != []:
654#                self.widgetRegistry = orngRegistry.readCategories()
655
656            # save tab order settings
657            newTabList = [(str(dlg.tabOrderList.item(i).text()), int(dlg.tabOrderList.item(i).checkState())) for i in range(dlg.tabOrderList.count())]
658            if newTabList != self.settings["WidgetTabs"]:
659                self.settings["WidgetTabs"] = newTabList
660                self.createWidgetsToolbar()
661                orngTabs.constructCategoriesPopup(self)
662
663    def menuItemAddOns(self):
664        dlg = orngDlgs.AddOnManagerDialog(self, self)
665        if dlg.exec_() == QDialog.Accepted:
666            for (id, addOn) in dlg.addOnsToRemove.items():
667                try:
668                    addOn.uninstall(refresh=False)
669                    if id in dlg.addOnsToAdd.items():
670                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
671                        del dlg.addOnsToAdd[id]
672                except Exception, e:
673                    print "Problem %s add-on %s: %s" % ("upgrading" if id in dlg.addOnsToAdd else "removing", addOn.name, e)
674            for (id, addOn) in dlg.addOnsToAdd.items():
675                if id.startswith("registered:"):
676                    try:
677                        orngAddOns.registerAddOn(addOn.name, addOn.directory, refresh=False, systemWide=False)
678                    except Exception, e:
679                        print "Problem registering add-on %s: %s" % (addOn.name, e)
680                else:
681                    try:
682                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
683                    except Exception, e:
684                        print "Problem installing add-on %s: %s" % (addOn.name, e)
685            if len(dlg.addOnsToAdd)+len(dlg.addOnsToRemove)>0:
686                orngAddOns.refreshAddOns(reloadPath=True)
687               
688                   
689
690    def updateStyle(self):
691        QApplication.setStyle(QStyleFactory.create(self.settings["style"]))
692#        qApp.setStyleSheet(" QDialogButtonBox { button-layout: 0; }")       # we want buttons to go in the "windows" direction (Yes, No, Cancel)
693        if self.settings["useDefaultPalette"]:
694            QApplication.setPalette(qApp.style().standardPalette())
695        else:
696            QApplication.setPalette(self.originalPalette)
697
698
699    def setStatusBarEvent(self, text):
700        if text == "" or text == None:
701            self.statusBar().showMessage("")
702            return
703        elif text == "\n": return
704        text = str(text)
705        text = text.replace("<nobr>", ""); text = text.replace("</nobr>", "")
706        text = text.replace("<b>", ""); text = text.replace("</b>", "")
707        text = text.replace("<i>", ""); text = text.replace("</i>", "")
708        text = text.replace("<br>", ""); text = text.replace("&nbsp", "")
709        self.statusBar().showMessage("Last event: " + str(text), 5000)
710
711    # Loads settings from the widget's .ini file
712    def loadSettings(self):
713        self.settings = {"widgetListType": 4, "iconSize": "40 x 40", "toolbarIconSize": 2, "toolboxWidth": 200, 'schemeIconSize': 1,
714                       "snapToGrid": 1, "writeLogFile": 1, "dontAskBeforeClose": 1, "saveWidgetsPosition": 1,
715#                       "widgetSelectedColor": (0, 255, 0), "widgetActiveColor": (0, 0, 255), "lineColor": (0, 255, 0),
716                       "reportsDir": self.defaultReportsDir, "saveSchemaDir": self.canvasSettingsDir, "saveApplicationDir": self.canvasSettingsDir,
717                       "showSignalNames": 1, "useContexts": 1, "enableCanvasDropShadows": 0,
718                       "canvasWidth": 700, "canvasHeight": 600, "useDefaultPalette": 0,
719                       "focusOnCatchException": 1, "focusOnCatchOutput": 0, "printOutputInStatusBar": 1, "printExceptionInStatusBar": 1,
720                       "outputVerbosity": 0, "synchronizeHelp": 1,
721                       "ocShow": 1, "owShow": 0, "ocInfo": 1, "owInfo": 1, "ocWarning": 1, "owWarning": 1, "ocError": 1, "owError": 1,
722                       }
723        if RedR:
724            self.setting.update({"svnSettings": None, "versionNumber": "Version0"})
725        try:
726            filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
727            self.settings.update(cPickle.load(open(filename, "rb")))
728        except:
729            pass
730
731        if not self.settings.has_key("style"):
732            items = [str(n) for n in QStyleFactory.keys()]
733            lowerItems = [str(n).lower() for n in QStyleFactory.keys()]
734            if sys.platform == "darwin" and qVersion() < "4.6": #On Mac OSX full aqua style isn't supported until Qt 4.6
735                currStyle = "cleanlooks"
736            else:
737                currStyle = str(qApp.style().objectName()).lower()
738            self.settings.setdefault("style", items[lowerItems.index(currStyle)])
739
740
741    # Saves settings to this widget's .ini file
742    def saveSettings(self):
743        filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
744        file = open(filename, "wb")
745        if self.settings["widgetListType"] == 1:        # tree view
746            self.settings["treeItemsOpenness"] = dict([(key, self.tabs.tabDict[key].isExpanded()) for key in self.tabs.tabDict.keys()])
747        cPickle.dump(self.settings, file)
748        file.close()
749
750    def closeEvent(self, ce):
751        # save the current width of the toolbox, if we are using it
752        if isinstance(self.widgetsToolBar, orngTabs.WidgetToolBox):
753            self.settings["toolboxWidth"] = self.widgetsToolBar.toolbox.width()
754        self.settings["showWidgetToolbar"] = self.widgetsToolBar.isVisible()
755        self.settings["showToolbar"] = self.toolbar.isVisible()
756        self.settings["reportsDir"] = self.reportWindow.saveDir
757
758        closed = self.schema.close()
759        if closed:
760            self.canvasIsClosing = 1        # output window (and possibly report window also) will check this variable before it will close the window
761            self.output.logFile.close()
762            self.output.hide()
763           
764            ce.accept()
765           
766            self.helpWindow.close()
767            self.reportWindow.close()
768        else:
769            ce.ignore()
770       
771        self.reportWindow.removeTemp()
772       
773        size = self.geometry().size()
774        self.settings["canvasWidth"] = size.width()
775        self.settings["canvasHeight"] = size.height()
776        self.settings["CanvasMainWindowGeometry"] = str(self.saveGeometry())
777       
778        self.saveSettings()
779       
780
781    def setCaption(self, caption=""):
782        if caption:
783            caption = caption.split(".")[0]
784            self.setWindowTitle(caption + " - %s Canvas" % product)
785        else:
786            self.setWindowTitle("%s Canvas" % product)
787   
788    def getWidgetIcon(self, widgetInfo):
789        if self.iconNameToIcon.has_key(widgetInfo.icon):
790            return self.iconNameToIcon[widgetInfo.icon]
791       
792        iconNames = self.getFullWidgetIconName(widgetInfo)
793        iconBackgrounds = self.getFullIconBackgroundName(widgetInfo)
794        icon = QIcon()
795        if len(iconNames) == 1:
796            iconSize = QPixmap(iconNames[0]).width()
797            iconBackgrounds = [name for name in iconBackgrounds if QPixmap(name).width() == iconSize]
798        for name, back in zip(iconNames, iconBackgrounds):
799            image = QPixmap(back).toImage()
800            painter = QPainter(image)
801            painter.drawPixmap(0, 0, QPixmap(name))
802            painter.end()
803            icon.addPixmap(QPixmap.fromImage(image))
804        if iconNames != [self.defaultPic]:
805            self.iconNameToIcon[widgetInfo.icon] = icon
806        return icon
807           
808   
809    def getFullWidgetIconName(self, widgetInfo):
810        iconName = widgetInfo.icon
811        names = []
812        name, ext = os.path.splitext(iconName)
813        for num in [16, 32, 40, 48, 60]:
814            names.append("%s_%d%s" % (name, num, ext))
815           
816        widgetDir = str(widgetInfo.directory)  #os.path.split(self.getFileName())[0]
817        fullPaths = []
818        for paths in [(self.widgetDir, widgetInfo.category), (self.widgetDir,), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
819            for name in names + [iconName]:
820                fname = os.path.join(*paths + (name,))
821                if os.path.exists(fname):
822                    fullPaths.append(fname)
823            if len(fullPaths) > 1 and fullPaths[-1].endswith(iconName):
824                fullPaths.pop()     # if we have the new icons we can remove the default icon
825            if fullPaths != []:
826                return fullPaths
827        return [self.defaultPic]
828   
829    def getFullIconBackgroundName(self, widgetInfo):
830        widgetDir = str(widgetInfo.directory)
831        fullPaths = []
832        for paths in [(widgetDir, "icons"), (self.widgetDir, widgetInfo.category, "icons"), (self.widgetDir, "icons"), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
833            for name in ["background_%d.png" % num for num in [16, 32, 40, 48, 60]]:
834                fname = os.path.join(*paths + (name,))
835#                print fname
836                if os.path.exists(fname):
837                    fullPaths.append(fname)
838            if fullPaths != []:
839                return fullPaths   
840        return [self.defaultBackground]
841   
842class MyStatusBar(QStatusBar):
843    def __init__(self, parent):
844        QStatusBar.__init__(self, parent)
845        self.parentWidget = parent
846
847    def mouseDoubleClickEvent(self, ev):
848        self.parentWidget.menuItemShowOutputWindow()
849       
850       
851class OrangeQApplication(QApplication):
852    def __init__(self, *args):
853        QApplication.__init__(self, *args)
854       
855    #QFileOpenEvent are Mac OSX only
856    if sys.platform == "darwin":
857        def event(self, event):
858            if event.type() == QEvent.FileOpen:
859                file = str(event.file())
860                def send():
861                    if hasattr(qApp, "canvasDlg"):
862                        qApp.canvasDlg.openSchema(file)
863                    else:
864                        QTimer.singleShot(100, send)
865                send()
866            return QApplication.event(self, event)
867       
868#    def notify(self, receiver, event):
869#        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'}
870#        import time
871#        try:
872#            if str(receiver.windowTitle()) != "":
873#                print time.strftime("%H:%M:%S"), "%15s" % str(receiver.windowTitle()) + ": ",      # print only events for QWidget classes and up
874#                if eventDict.has_key(event.type()):
875#                    print eventDict[event.type()]
876#                else:
877#                    print "unknown event name (" + str(event.type()) + ")"
878#        except:
879#            pass
880#            #print str(receiver.objectName()),
881#               
882#        return QApplication.notify(self, receiver, event)
883
884
885def main(argv=None):
886    if argv == None:
887        argv = sys.argv
888
889    app = OrangeQApplication(sys.argv)
890    dlg = OrangeCanvasDlg(app)
891    qApp.canvasDlg = dlg
892    dlg.show()
893    for arg in sys.argv[1:]:
894        if arg == "-reload":
895            dlg.menuItemOpenLastSchema()
896    app.exec_()
897    app.closeAllWindows()
898
899if __name__ == "__main__":
900    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.