source: orange/Orange/OrangeCanvas/main.py @ 11518:25344bdd7781

Revision 11518:25344bdd7781, 9.6 KB checked in by Ales Erjavec <ales.erjavec@…>, 11 months ago (diff)

Changed the main window default size.

Line 
1"""
2Orange Canvas main entry point
3
4"""
5
6import os
7import sys
8import gc
9import re
10import logging
11import optparse
12import cPickle
13from contextlib import nested
14
15import pkg_resources
16
17from PyQt4.QtGui import QFont, QColor
18from PyQt4.QtCore import Qt, QRect, QDir
19
20from Orange import OrangeCanvas
21from Orange.OrangeCanvas.application.application import CanvasApplication
22from Orange.OrangeCanvas.application.canvasmain import CanvasMainWindow
23from Orange.OrangeCanvas.application.outputview import TextStream, ExceptHook
24
25from Orange.OrangeCanvas.gui.splashscreen import SplashScreen, QPixmap
26from Orange.OrangeCanvas.config import cache_dir
27from Orange.OrangeCanvas import config
28from Orange.OrangeCanvas.utils.redirect import redirect_stdout, redirect_stderr
29from Orange.OrangeCanvas.utils.qtcompat import QSettings
30
31from Orange.OrangeCanvas.registry import qt
32from Orange.OrangeCanvas.registry import WidgetRegistry, set_global_registry
33from Orange.OrangeCanvas.registry import cache
34
35log = logging.getLogger(__name__)
36
37
38def running_in_ipython():
39    try:
40        __IPYTHON__
41        return True
42    except NameError:
43        return False
44
45
46def fix_win_pythonw_std_stream():
47    """
48    On windows when running without a console (using pythonw.exe) the
49    std[err|out] file descriptors are invalid and start throwing exceptions
50    when their buffer is flushed (`http://bugs.python.org/issue706263`_)
51
52    """
53    if sys.platform == "win32" and \
54            os.path.basename(sys.executable) == "pythonw.exe":
55        if sys.stdout.fileno() < 0:
56            sys.stdout = open(os.devnull, "wb")
57        if sys.stderr.fileno() < 0:
58            sys.stderr = open(os.devnull, "wb")
59
60
61def main(argv=None):
62    if argv is None:
63        argv = sys.argv[1:]
64
65    usage = "usage: %prog [options] [scheme_file]"
66    parser = optparse.OptionParser(usage=usage)
67
68    parser.add_option("--no-discovery",
69                      action="store_true",
70                      help="Don't run widget discovery "
71                           "(use full cache instead)")
72
73    parser.add_option("--force-discovery",
74                      action="store_true",
75                      help="Force full widget discovery "
76                           "(invalidate cache)")
77    parser.add_option("--no-welcome",
78                      action="store_true",
79                      help="Don't show welcome dialog.")
80    parser.add_option("--no-splash",
81                      action="store_true",
82                      help="Don't show splash screen.")
83    parser.add_option("-l", "--log-level",
84                      help="Logging level (0, 1, 2, 3, 4)",
85                      type="int", default=1)
86    parser.add_option("--no-redirect",
87                      action="store_true",
88                      help="Do not redirect stdout/err to canvas output view.")
89    parser.add_option("--style",
90                      help="QStyle to use",
91                      type="str", default=None)
92    parser.add_option("--stylesheet",
93                      help="Application level CSS style sheet to use",
94                      type="str", default="orange.qss")
95    parser.add_option("--qt",
96                      help="Additional arguments for QApplication",
97                      type="str", default=None)
98
99    (options, args) = parser.parse_args(argv)
100
101    levels = [logging.CRITICAL,
102              logging.ERROR,
103              logging.WARN,
104              logging.INFO,
105              logging.DEBUG]
106
107    logging.basicConfig(level=levels[options.log_level])
108
109    fix_win_pythonw_std_stream()
110
111    log.info("Starting 'Orange Canvas' application.")
112
113    qt_argv = ["orange-canvas"]
114
115    if options.style is not None:
116        qt_argv += ["-style", options.style]
117
118    if options.qt is not None:
119        qt_argv += options.qt.split()
120
121    log.debug("Starting CanvasApplicaiton with argv = %r.", qt_argv)
122    app = CanvasApplication(qt_argv)
123
124    # Note: config.init must be called after the QApplication constructor
125    config.init()
126    settings = QSettings()
127
128    stylesheet = options.stylesheet
129    stylesheet_string = None
130
131    if stylesheet != "none":
132        if os.path.isfile(stylesheet):
133            stylesheet_string = open(stylesheet, "rb").read()
134        else:
135            if not os.path.splitext(stylesheet)[1]:
136                # no extension
137                stylesheet = os.path.extsep.join([stylesheet, "qss"])
138
139            pkg_name = OrangeCanvas.__name__
140            resource = "styles/" + stylesheet
141
142            if pkg_resources.resource_exists(pkg_name, resource):
143                stylesheet_string = \
144                    pkg_resources.resource_string(pkg_name, resource)
145
146                base = pkg_resources.resource_filename(pkg_name, "styles")
147
148                pattern = re.compile(
149                    r"^\s@([a-zA-Z0-9_]+?)\s*:\s*([a-zA-Z0-9_/]+?);\s*$",
150                    flags=re.MULTILINE
151                )
152
153                matches = pattern.findall(stylesheet_string)
154
155                for prefix, search_path in matches:
156                    QDir.addSearchPath(prefix, os.path.join(base, search_path))
157                    log.info("Adding search path %r for prefix, %r",
158                             search_path, prefix)
159
160                stylesheet_string = pattern.sub("", stylesheet_string)
161
162            else:
163                log.info("%r style sheet not found.", stylesheet)
164
165    if stylesheet_string is not None:
166        app.setStyleSheet(stylesheet_string)
167
168    # Add the default canvas_icons search path
169    dirpath = os.path.abspath(os.path.dirname(OrangeCanvas.__file__))
170    QDir.addSearchPath("canvas_icons", os.path.join(dirpath, "icons"))
171
172    canvas_window = CanvasMainWindow()
173
174    if not options.force_discovery:
175        reg_cache = cache.registry_cache()
176    else:
177        reg_cache = None
178
179    widget_discovery = qt.QtWidgetDiscovery(cached_descriptions=reg_cache)
180
181    widget_registry = qt.QtWidgetRegistry()
182
183    widget_discovery.found_category.connect(
184        widget_registry.register_category
185    )
186    widget_discovery.found_widget.connect(
187        widget_registry.register_widget
188    )
189
190    want_splash = \
191        settings.value("startup/show-splash-screen", True, type=bool) and \
192        not options.no_splash
193
194    if want_splash:
195        pm = QPixmap(pkg_resources.resource_filename(
196                        __name__, "icons/orange-splash-screen.png")
197                     )
198        # Text rectangle in which to fit the message.
199        rect = QRect(88, 193, 200, 20)
200        splash_screen = SplashScreen(pixmap=pm, textRect=rect)
201        splash_screen.setFont(QFont("Helvetica", 12))
202        color = QColor("#FFD39F")
203
204        def show_message(message):
205            splash_screen.showMessage(message, color=color)
206
207        widget_discovery.discovery_start.connect(splash_screen.show)
208        widget_discovery.discovery_process.connect(show_message)
209        widget_discovery.discovery_finished.connect(splash_screen.hide)
210
211    log.info("Running widget discovery process.")
212
213    cache_filename = os.path.join(cache_dir(), "widget-registry.pck")
214    if options.no_discovery:
215        widget_registry = cPickle.load(open(cache_filename, "rb"))
216        widget_registry = qt.QtWidgetRegistry(widget_registry)
217    else:
218        widget_discovery.run(config.widgets_entry_points())
219        # Store cached descriptions
220        cache.save_registry_cache(widget_discovery.cached_descriptions)
221        cPickle.dump(WidgetRegistry(widget_registry),
222                     open(cache_filename, "wb"))
223    set_global_registry(widget_registry)
224    canvas_window.set_widget_registry(widget_registry)
225    canvas_window.show()
226
227    want_welcome = \
228        settings.value("startup/show-welcome-screen", True, type=bool) \
229        and not options.no_welcome
230
231    canvas_window.raise_()
232
233    if want_welcome and not args:
234        # Process events to make sure the canvas_window layout has
235        # a chance to activate (the welcome dialog is modal and will
236        # block the event queue)
237        app.processEvents()
238        canvas_window.welcome_dialog()
239
240    elif args:
241        log.info("Loading a scheme from the command line argument %r",
242                 args[0])
243        canvas_window.load_scheme(args[0])
244
245    stdout_redirect = \
246        settings.value("output/redirect-stdout", True, type=bool)
247
248    stderr_redirect = \
249        settings.value("output/redirect-stderr", True, type=bool)
250
251    # cmd line option overrides settings / no redirect is possible
252    # under ipython
253    if options.no_redirect or running_in_ipython():
254        stderr_redirect = stdout_redirect = False
255
256    output_view = canvas_window.output_view()
257
258    if stdout_redirect:
259        stdout = TextStream()
260        stdout.stream.connect(output_view.write)
261        # also connect to original fd
262        stdout.stream.connect(sys.stdout.write)
263    else:
264        stdout = sys.stdout
265
266    if stderr_redirect:
267        error_writer = output_view.formated(color=Qt.red)
268        stderr = TextStream()
269        stderr.stream.connect(error_writer.write)
270        # also connect to original fd
271        stderr.stream.connect(sys.stderr.write)
272    else:
273        stderr = sys.stderr
274
275    if stderr_redirect:
276        sys.excepthook = ExceptHook()
277        sys.excepthook.handledException.connect(output_view.parent().show)
278
279    with nested(redirect_stdout(stdout), redirect_stderr(stderr)):
280        log.info("Entering main event loop.")
281        try:
282            status = app.exec_()
283        except BaseException:
284            log.error("Error in main event loop.", exc_info=True)
285
286    canvas_window.deleteLater()
287    app.processEvents()
288    app.flush()
289    del canvas_window
290
291    # Collect any cycles before deleting the QApplication instance
292    gc.collect()
293
294    del app
295    return status
296
297
298if __name__ == "__main__":
299    sys.exit(main())
Note: See TracBrowser for help on using the repository browser.