source: orange/orange/OrangeCanvas/orngCanvas.pyw @ 7730:d5d17b58bd8c

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

Construct the category/widget menu popup with add-on categories on first load (Ticket #697).

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        self.createWidgetsToolbar()
177        orngTabs.constructCategoriesPopup(self)
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        if sys.platform != "darwin":
349            delete.setShortcuts([Qt.Key_Delete, Qt.CTRL + Qt.Key_Backspace, Qt.CTRL + Qt.Key_Delete])
350        else:
351            delete.setShortcuts([Qt.CTRL + Qt.Key_Backspace, Qt.Key_Delete, Qt.CTRL + Qt.Key_Delete])
352        self.widgetPopup.addSeparator()
353        self.helpActiveWidgetAction = self.widgetPopup.addAction("Help", self.schema.canvasView.helpOnActiveWidget, Qt.Key_F1)
354        self.widgetPopup.setEnabled(0)
355       
356        if sys.platform == "darwin":
357            self.windowPopup = QMenu("Window", self)
358            self.windowPopup.addAction("Minimize", self.showMinimized, Qt.CTRL + Qt.Key_M)
359            self.windowPopup.addAction("Zoom", self.showMaximized, 0)
360
361        self.menuBar = QMenuBar(self)
362        self.menuBar.addMenu(self.menuFile)
363        self.menuBar.addMenu(self.menuOptions)
364        self.menuBar.addMenu(self.widgetPopup)
365       
366        if hasattr(self, "windowPopup"):
367            self.menuBar.addMenu(self.windowPopup)
368           
369        self.menuBar.addMenu(self.menuHelp)
370       
371        self.setMenuBar(self.menuBar)
372       
373    def setDebugMode(self):   # RedR specific
374        if self.output.debugMode:
375            self.output.debugMode = 0
376        else:
377            self.output.debugMode = 1
378    def importSchema(self):   # RedR specific
379        name = QFileDialog.getOpenFileName(self, "Import File", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
380        if name.isEmpty():
381            return
382        self.schema.clear()
383        self.schema.loadDocument(str(name), freeze = 0, importBlank = 1)
384        self.addToRecentMenu(str(name))
385   
386    def openSchema(self, filename):
387        if self.schema.isSchemaChanged() and self.schema.widgets:
388            ret = QMessageBox.warning(self, "Orange Canvas", "Changes to your present schema are not saved.\nSave them?",
389                                      QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel, QMessageBox.Save)
390            if ret == QMessageBox.Save:
391                self.schema.saveDocument()
392            elif ret == QMessageBox.Cancel:
393                return
394        self.schema.clear()
395        dirname = os.path.dirname(filename)
396        os.chdir(dirname)
397        self.schema.loadDocument(filename)
398       
399    def menuItemOpen(self):
400        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
401        if name.isEmpty():
402            return
403        self.schema.clear()
404        dirname = os.path.dirname(str(name))
405        os.chdir(dirname)
406        self.schema.loadDocument(str(name), freeze=0)
407        self.addToRecentMenu(str(name))
408
409    def menuItemOpenFreeze(self):
410        name = QFileDialog.getOpenFileName(self, "Open Orange Schema", self.settings["saveSchemaDir"], "Orange Widget Scripts (*.ows)")
411        if name.isEmpty():
412            return
413        self.schema.clear()
414        dirname = os.path.dirname(str(name))
415        os.chdir(dirname)
416        self.schema.loadDocument(str(name), freeze=1)
417        self.addToRecentMenu(str(name))
418
419    def menuItemOpenLastSchema(self):
420        fullName = os.path.join(self.canvasSettingsDir, "lastSchema.tmp")
421        if os.path.exists(fullName):
422            self.schema.loadDocument(fullName)
423
424    def menuItemReport(self):
425        self.schema.reportAll()
426       
427    def menuItemSave(self):
428        self.schema.saveDocument()
429       
430    def menuItemSaveAs(self):
431        self.schema.saveDocumentAs()
432
433    def menuItemSaveAsAppButtons(self):
434        self.schema.saveDocumentAsApp(asTabs=0)
435
436    def menuItemSaveAsAppTabs(self):
437        self.schema.saveDocumentAsApp(asTabs=1)
438
439    def menuItemPrinter(self):
440        try:
441            import OWDlgs
442            sizeDlg = OWDlgs.OWChooseImageSizeDlg(self.schema.canvas, defaultName=self.schema.schemaName or "schema", parent=self)
443            sizeDlg.exec_()
444        except:
445            print "Missing file 'OWDlgs.py'. This file should be in OrangeWidgets folder. Unable to print/save image."
446       
447
448    def readRecentFiles(self):
449        self.menuRecent.clear()
450        if not self.settings.has_key("RecentFiles"): return
451        recentDocs = self.settings["RecentFiles"]
452
453        # remove missing recent files
454        for i in range(len(recentDocs) - 1, -1, -1):
455            if not os.path.exists(recentDocs[i]):
456                recentDocs.remove(recentDocs[i])
457
458        recentDocs = recentDocs[:9]
459        self.settings["RecentFiles"] = recentDocs
460
461        for i in range(len(recentDocs)):
462            shortName = "&" + str(i + 1) + " " + os.path.basename(recentDocs[i])
463            self.menuRecent.addAction(shortName, lambda ind=i: self.openRecentFile(ind + 1))
464
465    def openRecentFile(self, index):
466        if len(self.settings["RecentFiles"]) >= index:
467            self.schema.clear()
468            name = self.settings["RecentFiles"][index - 1]
469            dirname = os.path.dirname(name)
470            os.chdir(dirname)
471            self.schema.loadDocument(name)
472            self.addToRecentMenu(name)
473
474    def addToRecentMenu(self, name):
475        recentDocs = []
476        if self.settings.has_key("RecentFiles"):
477            recentDocs = self.settings["RecentFiles"]
478
479        # convert to a valid file name
480        name = os.path.realpath(name)
481
482        if name in recentDocs:
483            recentDocs.remove(name)
484        recentDocs.insert(0, name)
485
486        if len(recentDocs) > 5:
487            recentDocs.remove(recentDocs[5])
488        self.settings["RecentFiles"] = recentDocs
489        self.readRecentFiles()
490
491    def menuItemSelectAll(self):
492        return
493
494    def updateSnapToGrid(self):
495        if self.settings["snapToGrid"]:
496            for widget in self.schema.widgets:
497                widget.setCoords(widget.x(), widget.y())
498            self.schema.canvas.update()
499
500    def menuItemEnableAll(self):
501        self.schema.enableAllLines()
502
503    def menuItemDisableAll(self):
504        self.schema.disableAllLines()
505
506    def menuItemSaveSettings(self):
507        self.menuSaveSettings = not self.menuSaveSettings
508        self.menuOptions.setItemChecked(self.menuSaveSettingsID, self.menuSaveSettings)
509
510    def menuItemNewScheme(self):
511        self.schema.clear()
512
513    def dumpVariables(self):
514        self.schema.dumpWidgetVariables()
515
516    def menuItemShowOutputWindow(self):
517        self.output.show()
518        self.output.raise_()
519        self.output.activateWindow()
520
521    def menuItemClearOutputWindow(self):
522        self.output.textOutput.clear()
523        self.statusBar().showMessage("")
524
525    def menuItemSaveOutputWindow(self):
526        qname = QFileDialog.getSaveFileName(self, "Save Output To File", self.canvasSettingsDir + "/Output.html", "HTML Document (*.html)")
527        if qname.isEmpty(): return
528        name = str(qname)
529
530        text = str(self.output.textOutput.toHtml())
531        #text = text.replace("</nobr>", "</nobr><br>")
532
533        file = open(name, "wt")
534        file.write(text)
535        file.close()
536
537
538    def menuItemShowToolbar(self):
539        self.settings["showToolbar"] = not self.settings.get("showToolbar", True)
540        if self.settings["showToolbar"]: self.toolbar.show()
541        else: self.toolbar.hide()
542
543    def menuItemShowWidgetToolbar(self):
544        self.settings["showWidgetToolbar"] = not self.settings.get("showWidgetToolbar", True)
545        if self.settings["showWidgetToolbar"]: self.widgetsToolBar.show()
546        else: self.widgetsToolBar.hide()
547
548
549    def menuItemEditWidgetShortcuts(self):
550        dlg = orngDlgs.WidgetShortcutDlg(self, self)
551        if dlg.exec_() == QDialog.Accepted:
552            self.widgetShortcuts = dict([(y, x) for x, y in dlg.invDict.items()])
553            shf = file(os.path.join(self.canvasSettingsDir, "shortcuts.txt"), "wt")
554            for k, widgetInfo in self.widgetShortcuts.items():
555                shf.write("%s: %s\n" % (k, (widgetInfo.category, widgetInfo.name)))
556
557    def menuItemDeleteWidgetSettings(self):
558        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:
559            if os.path.exists(self.widgetSettingsDir):
560                for f in os.listdir(self.widgetSettingsDir):
561                    if os.path.splitext(f)[1].lower() == ".ini":
562                        os.remove(os.path.join(self.widgetSettingsDir, f))
563
564    def menuOpenLocalOrangeHelp(self):
565        import webbrowser
566        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/reference/default.htm"))
567
568    def menuOpenLocalWidgetCatalog(self):
569        import webbrowser
570        webbrowser.open("file:///" + os.path.join(self.orangeDir, "doc/catalog/index.html"))
571
572    def menuOpenLocalCanvasHelp(self):
573        import webbrowser
574        webbrowser.open(os.path.join(self.orangeDir, "doc/canvas/default.htm"))
575
576    def menuOpenOnlineOrangeHelp(self):
577        import webbrowser
578        webbrowser.open("http://www.ailab.si/orange/doc/catalog")
579
580    def menuOpenOnlineCanvasHelp(self):
581        import webbrowser
582        #webbrowser.open("http://www.ailab.si/orange/orangeCanvas") # to be added on the web
583        webbrowser.open("http://www.ailab.si/orange")
584
585    def menuCheckForUpdates(self):
586        import updateOrange
587        self.updateDlg = updateOrange.updateOrangeDlg(None)#, Qt.WA_DeleteOnClose)
588
589    def menuItemAboutOrange(self):
590        dlg = orngDlgs.AboutDlg(self)
591        dlg.exec_()
592
593
594## to see the signals you have to call: self.output.catchException(0); self.output.catchOutput(0)
595## and run orngCanvas.pyw from command line using "python.exe orngCanvas.pyw"
596#    def event(self, e):
597#        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")])
598#        if eventDict.has_key(e.type()):
599#            print str(self.windowTitle()), eventDict[e.type()]
600#        return QMainWindow.event(self, e)
601
602
603    def menuItemCanvasOptions(self):
604        dlg = orngDlgs.CanvasOptionsDlg(self, self)
605
606        if dlg.exec_() == QDialog.Accepted:
607            if self.settings["snapToGrid"] != dlg.settings["snapToGrid"]:
608                self.updateSnapToGrid()
609
610            if self.settings["widgetListType"] != dlg.settings["widgetListType"]:
611                self.settings["widgetListType"] = dlg.settings["widgetListType"]
612                self.createWidgetsToolbar()
613                self.widgetListTypeCB.setCurrentIndex(self.settings["widgetListType"])
614            self.settings.update(dlg.settings)
615            self.updateStyle()
616           
617#            self.widgetSelectedColor = dlg.selectedWidgetIcon.color
618#            self.widgetActiveColor   = dlg.activeWidgetIcon.color
619#            self.lineColor           = dlg.lineIcon.color
620           
621            # update settings in widgets in current documents
622            for widget in self.schema.widgets:
623                widget.instance._useContexts = self.settings["useContexts"]
624                widget.instance._owInfo = self.settings["owInfo"]
625                widget.instance._owWarning = self.settings["owWarning"]
626                widget.instance._owError = self.settings["owError"]
627                widget.instance._owShowStatus = self.settings["owShow"]
628                widget.instance.updateStatusBarState()
629                widget.resetWidgetSize()
630                widget.updateWidgetState()
631               
632            # update tooltips for lines in all documents
633            for line in self.schema.lines:
634                line.showSignalNames = self.settings["showSignalNames"]
635                line.updateTooltip()
636           
637            self.schema.canvasView.repaint()
638       
639#            import orngEnviron, orngRegistry
640#            if dlg.toAdd != []:
641#                for (name, dir) in dlg.toAdd:
642#                    orngEnviron.registerAddOn(name, dir)
643           
644#            if dlg.toRemove != []:
645#                for (catName, cat) in dlg.toRemove:
646#                    addonsToRemove = set()
647#                    for widget in cat.values():
648#                        addonDir = widget.directory
649#                        while os.path.split(addonDir)[1] in ["prototypes", "widgets"]:
650#                            addonDir = os.path.split(addonDir)[0]
651#                        addonName = os.path.split(addonDir)[1]
652#                        addonsToRemove.add( (addonName, addonDir) )
653#                    for addonToRemove in addonsToRemove:
654#                        orngEnviron.registerAddOn(add=False, *addonToRemove)
655#           
656#            if dlg.toAdd != [] or dlg.toRemove != []:
657#                self.widgetRegistry = orngRegistry.readCategories()
658
659            # save tab order settings
660            newTabList = [(str(dlg.tabOrderList.item(i).text()), int(dlg.tabOrderList.item(i).checkState())) for i in range(dlg.tabOrderList.count())]
661            if newTabList != self.settings["WidgetTabs"]:
662                self.settings["WidgetTabs"] = newTabList
663                self.createWidgetsToolbar()
664                orngTabs.constructCategoriesPopup(self)
665
666    def menuItemAddOns(self):
667        dlg = orngDlgs.AddOnManagerDialog(self, self)
668        if dlg.exec_() == QDialog.Accepted:
669            for (id, addOn) in dlg.addOnsToRemove.items():
670                try:
671                    addOn.uninstall(refresh=False)
672                    if id in dlg.addOnsToAdd.items():
673                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
674                        del dlg.addOnsToAdd[id]
675                except Exception, e:
676                    print "Problem %s add-on %s: %s" % ("upgrading" if id in dlg.addOnsToAdd else "removing", addOn.name, e)
677            for (id, addOn) in dlg.addOnsToAdd.items():
678                if id.startswith("registered:"):
679                    try:
680                        orngAddOns.registerAddOn(addOn.name, addOn.directory, refresh=False, systemWide=False)
681                    except Exception, e:
682                        print "Problem registering add-on %s: %s" % (addOn.name, e)
683                else:
684                    try:
685                        orngAddOns.installAddOnFromRepo(dlg.addOnsToAdd[id], globalInstall=False, refresh=False)
686                    except Exception, e:
687                        print "Problem installing add-on %s: %s" % (addOn.name, e)
688            if len(dlg.addOnsToAdd)+len(dlg.addOnsToRemove)>0:
689                orngAddOns.refreshAddOns(reloadPath=True)
690               
691                   
692
693    def updateStyle(self):
694        QApplication.setStyle(QStyleFactory.create(self.settings["style"]))
695#        qApp.setStyleSheet(" QDialogButtonBox { button-layout: 0; }")       # we want buttons to go in the "windows" direction (Yes, No, Cancel)
696        if self.settings["useDefaultPalette"]:
697            QApplication.setPalette(qApp.style().standardPalette())
698        else:
699            QApplication.setPalette(self.originalPalette)
700
701
702    def setStatusBarEvent(self, text):
703        if text == "" or text == None:
704            self.statusBar().showMessage("")
705            return
706        elif text == "\n": return
707        text = str(text)
708        text = text.replace("<nobr>", ""); text = text.replace("</nobr>", "")
709        text = text.replace("<b>", ""); text = text.replace("</b>", "")
710        text = text.replace("<i>", ""); text = text.replace("</i>", "")
711        text = text.replace("<br>", ""); text = text.replace("&nbsp", "")
712        self.statusBar().showMessage("Last event: " + str(text), 5000)
713
714    # Loads settings from the widget's .ini file
715    def loadSettings(self):
716        self.settings = {"widgetListType": 4, "iconSize": "40 x 40", "toolbarIconSize": 2, "toolboxWidth": 200, 'schemeIconSize': 1,
717                       "snapToGrid": 1, "writeLogFile": 1, "dontAskBeforeClose": 0, "saveWidgetsPosition": 1,
718#                       "widgetSelectedColor": (0, 255, 0), "widgetActiveColor": (0, 0, 255), "lineColor": (0, 255, 0),
719                       "reportsDir": self.defaultReportsDir, "saveSchemaDir": self.canvasSettingsDir, "saveApplicationDir": self.canvasSettingsDir,
720                       "showSignalNames": 1, "useContexts": 1, "enableCanvasDropShadows": 0,
721                       "canvasWidth": 700, "canvasHeight": 600, "useDefaultPalette": 0,
722                       "focusOnCatchException": 1, "focusOnCatchOutput": 0, "printOutputInStatusBar": 1, "printExceptionInStatusBar": 1,
723                       "outputVerbosity": 0, "synchronizeHelp": 1,
724                       "ocShow": 1, "owShow": 0, "ocInfo": 1, "owInfo": 1, "ocWarning": 1, "owWarning": 1, "ocError": 1, "owError": 1,
725                       }
726        if RedR:
727            self.setting.update({"svnSettings": None, "versionNumber": "Version0"})
728        try:
729            filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
730            self.settings.update(cPickle.load(open(filename, "rb")))
731        except:
732            pass
733
734        if not self.settings.has_key("style"):
735            items = [str(n) for n in QStyleFactory.keys()]
736            lowerItems = [str(n).lower() for n in QStyleFactory.keys()]
737            if sys.platform == "darwin" and qVersion() < "4.6": #On Mac OSX full aqua style isn't supported until Qt 4.6
738                currStyle = "cleanlooks"
739            else:
740                currStyle = str(qApp.style().objectName()).lower()
741            self.settings.setdefault("style", items[lowerItems.index(currStyle)])
742
743
744    # Saves settings to this widget's .ini file
745    def saveSettings(self):
746        filename = os.path.join(self.canvasSettingsDir, "orngCanvas.ini")
747        file = open(filename, "wb")
748        if self.settings["widgetListType"] == 1:        # tree view
749            self.settings["treeItemsOpenness"] = dict([(key, self.tabs.tabDict[key].isExpanded()) for key in self.tabs.tabDict.keys()])
750        cPickle.dump(self.settings, file)
751        file.close()
752
753    def closeEvent(self, ce):
754        # save the current width of the toolbox, if we are using it
755        if isinstance(self.widgetsToolBar, orngTabs.WidgetToolBox):
756            self.settings["toolboxWidth"] = self.widgetsToolBar.toolbox.width()
757        self.settings["showWidgetToolbar"] = self.widgetsToolBar.isVisible()
758        self.settings["showToolbar"] = self.toolbar.isVisible()
759        self.settings["reportsDir"] = self.reportWindow.saveDir
760
761        closed = self.schema.close()
762        if closed:
763            self.canvasIsClosing = 1        # output window (and possibly report window also) will check this variable before it will close the window
764            self.output.logFile.close()
765            self.output.hide()
766           
767            ce.accept()
768           
769            self.helpWindow.close()
770            self.reportWindow.close()
771        else:
772            ce.ignore()
773       
774        self.reportWindow.removeTemp()
775       
776        size = self.geometry().size()
777        self.settings["canvasWidth"] = size.width()
778        self.settings["canvasHeight"] = size.height()
779        self.settings["CanvasMainWindowGeometry"] = str(self.saveGeometry())
780       
781        self.saveSettings()
782       
783
784    def setCaption(self, caption=""):
785        if caption:
786            caption = caption.split(".")[0]
787            self.setWindowTitle(caption + " - %s Canvas" % product)
788        else:
789            self.setWindowTitle("%s Canvas" % product)
790   
791    def getWidgetIcon(self, widgetInfo):
792        if self.iconNameToIcon.has_key(widgetInfo.icon):
793            return self.iconNameToIcon[widgetInfo.icon]
794       
795        iconNames = self.getFullWidgetIconName(widgetInfo)
796        iconBackgrounds = self.getFullIconBackgroundName(widgetInfo)
797        icon = QIcon()
798        if len(iconNames) == 1:
799            iconSize = QPixmap(iconNames[0]).width()
800            iconBackgrounds = [name for name in iconBackgrounds if QPixmap(name).width() == iconSize]
801        for name, back in zip(iconNames, iconBackgrounds):
802            image = QPixmap(back).toImage()
803            painter = QPainter(image)
804            painter.drawPixmap(0, 0, QPixmap(name))
805            painter.end()
806            icon.addPixmap(QPixmap.fromImage(image))
807        if iconNames != [self.defaultPic]:
808            self.iconNameToIcon[widgetInfo.icon] = icon
809        return icon
810           
811   
812    def getFullWidgetIconName(self, widgetInfo):
813        iconName = widgetInfo.icon
814        names = []
815        name, ext = os.path.splitext(iconName)
816        for num in [16, 32, 40, 48, 60]:
817            names.append("%s_%d%s" % (name, num, ext))
818           
819        widgetDir = str(widgetInfo.directory)  #os.path.split(self.getFileName())[0]
820        fullPaths = []
821        for paths in [(self.widgetDir, widgetInfo.category), (self.widgetDir,), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
822            for name in names + [iconName]:
823                fname = os.path.join(*paths + (name,))
824                if os.path.exists(fname):
825                    fullPaths.append(fname)
826            if len(fullPaths) > 1 and fullPaths[-1].endswith(iconName):
827                fullPaths.pop()     # if we have the new icons we can remove the default icon
828            if fullPaths != []:
829                return fullPaths
830        return [self.defaultPic]
831   
832    def getFullIconBackgroundName(self, widgetInfo):
833        widgetDir = str(widgetInfo.directory)
834        fullPaths = []
835        for paths in [(widgetDir, "icons"), (self.widgetDir, widgetInfo.category, "icons"), (self.widgetDir, "icons"), (self.picsDir,), tuple(), (widgetDir,), (widgetDir, "icons")]:
836            for name in ["background_%d.png" % num for num in [16, 32, 40, 48, 60]]:
837                fname = os.path.join(*paths + (name,))
838#                print fname
839                if os.path.exists(fname):
840                    fullPaths.append(fname)
841            if fullPaths != []:
842                return fullPaths   
843        return [self.defaultBackground]
844   
845class MyStatusBar(QStatusBar):
846    def __init__(self, parent):
847        QStatusBar.__init__(self, parent)
848        self.parentWidget = parent
849
850    def mouseDoubleClickEvent(self, ev):
851        self.parentWidget.menuItemShowOutputWindow()
852       
853       
854class OrangeQApplication(QApplication):
855    def __init__(self, *args):
856        QApplication.__init__(self, *args)
857       
858    #QFileOpenEvent are Mac OSX only
859    if sys.platform == "darwin":
860        def event(self, event):
861            if event.type() == QEvent.FileOpen:
862                file = str(event.file())
863                def send():
864                    if hasattr(qApp, "canvasDlg"):
865                        qApp.canvasDlg.openSchema(file)
866                    else:
867                        QTimer.singleShot(100, send)
868                send()
869            return QApplication.event(self, event)
870       
871#    def notify(self, receiver, event):
872#        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'}
873#        import time
874#        try:
875#            if str(receiver.windowTitle()) != "":
876#                print time.strftime("%H:%M:%S"), "%15s" % str(receiver.windowTitle()) + ": ",      # print only events for QWidget classes and up
877#                if eventDict.has_key(event.type()):
878#                    print eventDict[event.type()]
879#                else:
880#                    print "unknown event name (" + str(event.type()) + ")"
881#        except:
882#            pass
883#            #print str(receiver.objectName()),
884#               
885#        return QApplication.notify(self, receiver, event)
886
887
888def main(argv=None):
889    if argv == None:
890        argv = sys.argv
891
892    app = OrangeQApplication(sys.argv)
893    dlg = OrangeCanvasDlg(app)
894    qApp.canvasDlg = dlg
895    dlg.show()
896    for arg in sys.argv[1:]:
897        if arg == "-reload":
898            dlg.menuItemOpenLastSchema()
899    app.exec_()
900    app.closeAllWindows()
901
902if __name__ == "__main__":
903    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.