source: orange/Orange/OrangeCanvas/main.py @ 11256:26cf194aab3c

Revision 11256:26cf194aab3c, 8.5 KB checked in by Ales Erjavec <ales.erjavec@…>, 15 months ago (diff)

Update from the new settings after the settings dialog is closed.

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