source: orange/Orange/OrangeCanvas/main.py @ 11250:3b499a088cfc

Revision 11250:3b499a088cfc, 8.0 KB checked in by Ales Erjavec <ales.erjavec@…>, 18 months ago (diff)

Added user settings/preferences dialog.

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