def __init__(self, main_window, theme=None): """ Constructor Arguments: main_window -- the main_window object Keyword arguments: theme -- the theme to be used or None to use config (default=None) """ self.main_window = main_window if theme == None: self.theme = config.get_config(u"theme") else: self.theme = theme self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) debug.msg(u"theme = '%s' (%s)" % (self.theme, self.theme_folder)) if self.theme_folder == None or not os.path.exists(self.theme_folder): debug.msg(u"theme '%s' does not exist, using 'default'" % theme, \ reason=u"warning") self.theme = u"default" self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) self.theme_info = os.path.join(self.theme_folder, u"__theme__.py") if os.path.exists(self.theme_info): info = imp.load_source(self.theme, self.theme_info) self._qss = path = \ open(os.path.join(self.theme_folder, info.qss)).read() self._icon_map = info.icon_map self._icon_theme = info.icon_theme self.load_icon_map() self.apply_theme(self.main_window)
def qpixmap(self, icon, size=None): """ Get an icon from the theme Arguments: icon -- the icon name Keyword arguments: size -- the size of the icon or None for default (default=None) Returns: A QPixmap """ if size == None: if icon in self.icon_map: name, size = self.icon_map[icon] else: name = icon size = self.default_icon_size else: if icon in self.icon_map: name = self.icon_map[icon][0] else: name = icon return QtGui.QIcon.fromTheme(name, QtGui.QIcon(os.path.join( \ misc.resource(u"theme"), u"fallback.png"))).pixmap(size)
def load_ui(self, ui=None): """ desc: Dynamically loads the ui, if any. keywords: ui: An id for a user-interface file, or None. """ if ui is not None: # If the UI file has been explicitly registered, which is the case # for extensions if hasattr(self, u'experiment') and ui in self.experiment.resources: ui_path = self.experiment.resources[ui] else: # Dot-split the ui id, append a `.ui` extension, and assume it's # relative to the resources/ui subfolder. path_list = [u'ui'] + ui.split(u'.') if hasattr(self, u'experiment'): # If an experiment object is available, use that to find the # resources ... ui_path = self.experiment.resource( os.path.join(*path_list)+u'.ui') else: # ... otherwise use the static resources function. from libopensesame import misc ui_path = misc.resource(os.path.join(*path_list)+u'.ui') debug.msg(u'dynamically loading ui: %s' % ui_path) with open(ui_path) as fd: self.ui = uic.loadUi(fd, self) else: self.ui = None
def resource(self, name): """ Retrieves a file from the resources folder. Arguments: name -- The file name. Returns: A Unicode string with the full path to the file in the resources folder. """ name = self.unistr(name) if self != None: if name in self.resources: return self.resources[name] if os.path.exists(self.get_file(name)): return self.get_file(name) path = misc.resource(name) if path == None: raise Exception( \ u"The resource '%s' could not be found in libopensesame.experiment.resource()" \ % name) return path
def init_cache(self): """ desc: Initializes the webbrowser cache, if available. """ import pickle cache_file = misc.resource(u'webbrowser-cache.pkl') if cache_file is None: self.extension_manager.fire( u'notify', message=_(u'No webbrowser cache available'), category=u'info') self._cache = {} return with open(cache_file) as fd: try: self._cache = pickle.load(fd) except: self._cache = {} return if not isinstance(self._cache, dict): self.extension_manager.fire( u'notify', message=_(u'Webbrowser cache is corrupt'), category=u'warning') self._cache = {} return
def load_ui(self, ui=None): """ desc: Dynamically loads the ui, if any. keywords: ui: An id for a user-interface file, or None. """ if ui is not None: # If the UI file has been explicitly registered, which is the case # for extensions if hasattr(self, u'experiment') and ui in self.experiment.resources: ui_path = self.experiment.resources[ui] else: # Dot-split the ui id, append a `.ui` extension, and assume it's # relative to the resources/ui subfolder. path_list = [u'ui'] + ui.split(u'.') if hasattr(self, u'experiment'): # If an experiment object is available, use that to find the # resources ... ui_path = self.experiment.resource( os.path.join(*path_list) + u'.ui') else: # ... otherwise use the static resources function. from libopensesame import misc ui_path = misc.resource(os.path.join(*path_list) + u'.ui') debug.msg(u'dynamically loading ui: %s' % ui_path) with open(ui_path) as fd: self.ui = uic.loadUi(fd, self) else: self.ui = None
def init_cache(self): """ desc: Initializes the webbrowser cache, if available. """ import pickle cache_file = misc.resource(u'webbrowser-cache.pkl') if cache_file is None: self.extension_manager.fire(u'notify', message=_(u'No webbrowser cache available'), category=u'info') self._cache = {} return with open(cache_file) as fd: try: self._cache = pickle.load(fd) except: self._cache = {} return if not isinstance(self._cache, dict): self.extension_manager.fire(u'notify', message=_(u'Webbrowser cache is corrupt'), category=u'warning') self._cache = {} return
def __init__(self, main_window, theme=None): """ Constructor Arguments: main_window -- the main_window object Keyword arguments: theme -- the theme to be used or None to use config (default=None) """ self.main_window = main_window self.fallback_icon = QtGui.QIcon(os.path.join(misc.resource(u"theme"), u"fallback.png")) if theme is None: self.theme = config.get_config(u"theme") else: self.theme = theme self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) debug.msg(u"theme = '%s' (%s)" % (self.theme, self.theme_folder)) # The theme folder must exist, and contain a file called __theme__.py, # if not, we fall back to the default theme, which is assumed to always # exist. if self.theme_folder is None or not os.path.exists( os.path.join(self.theme_folder, u'__theme__.py')): debug.msg(u"theme '%s' does not exist, using 'default'" % theme, \ reason=u"warning") self.theme = u"default" self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) self.theme_info = os.path.join(self.theme_folder, u"__theme__.py") if os.path.exists(self.theme_info): info = imp.load_source(self.theme, safe_str(self.theme_info, enc=misc.filesystem_encoding())) with open(os.path.join(self.theme_folder, info.qss)) as fd: self._qss = fd.read() self._icon_map = info.icon_map self._icon_theme = info.icon_theme self.load_icon_map() self.apply_theme(self.main_window)
def __init__(self, main_window, theme=None): """ Constructor Arguments: main_window -- the main_window object Keyword arguments: theme -- the theme to be used or None to use config (default=None) """ self.main_window = main_window self.fallback_icon = QtGui.QIcon( os.path.join(misc.resource(u"theme"), u"fallback.png")) if theme is None: self.theme = config.get_config(u"theme") else: self.theme = theme self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) debug.msg(u"theme = '%s' (%s)" % (self.theme, self.theme_folder)) # The theme folder must exist, and contain a file called __theme__.py, # if not, we fall back to the default theme, which is assumed to always # exist. if self.theme_folder is None or not os.path.exists( os.path.join(self.theme_folder, u'__theme__.py')): debug.msg(u"theme '%s' does not exist, using 'default'" % theme, \ reason=u"warning") self.theme = u"default" self.theme_folder = misc.resource(os.path.join(u"theme", \ self.theme)) self.theme_info = os.path.join(self.theme_folder, u"__theme__.py") if os.path.exists(self.theme_info): info = imp.load_source( self.theme, safe_str(self.theme_info, enc=misc.filesystem_encoding())) with safe_open(os.path.join(self.theme_folder, info.qss)) as fd: self._qss = fd.read() self._icon_map = info.icon_map self._icon_theme = info.icon_theme self.load_icon_map() self.apply_theme(self.main_window)
def qicon(self, icon): """ Get an icon from the theme Arguments: icon -- the icon name Returns: A QIcon """ if icon in self.icon_map: name, size = self.icon_map[icon] else: name = icon return QtGui.QIcon.fromTheme(name, QtGui.QIcon(os.path.join( \ misc.resource(u"theme"), u"fallback.png")))
def set_controls(self): """ desc: Updates the controls. """ if self.lock: return self.lock = True self.ui.checkbox_autoresponse.setChecked( self.experiment.auto_response) self.ui.checkbox_toolbar_text.setChecked( self.main_window.ui.toolbar_main.toolButtonStyle() == \ QtCore.Qt.ToolButtonTextUnderIcon) self.ui.checkbox_small_toolbar.setChecked(cfg.toolbar_size == 16) self.ui.combobox_runner.setCurrentIndex( self.ui.combobox_runner.findText(cfg.runner, flags=QtCore.Qt.MatchContains)) # Set the locale combobox self.ui.combobox_locale.addItem(u'[Default]') self.ui.combobox_locale.setCurrentIndex(0) locales = sorted( [ locale[:-3] for locale in os.listdir(misc.resource(u'locale')) if locale != u'translatables.qm' ] + [u'en_US'] ) for i, locale in enumerate(locales): self.ui.combobox_locale.addItem(locale) if cfg.locale == locale: self.ui.combobox_locale.setCurrentIndex(i+1) # Set the style combobox self.ui.combobox_style.addItem(u"[Default]") self.ui.combobox_style.setCurrentIndex(0) for i, style in enumerate(QtWidgets.QStyleFactory.keys()): self.ui.combobox_style.addItem(style) if cfg.style == style: self.ui.combobox_style.setCurrentIndex(i+1) # Set the theme combobox for i, _theme in enumerate(theme.available_themes): self.ui.combobox_theme.addItem(_theme) if cfg.theme == _theme: self.ui.combobox_theme.setCurrentIndex(i+1) self.lock = False
def set_controls(self): """ desc: Updates the controls. """ if self.lock: return self.lock = True self.ui.checkbox_autoresponse.setChecked( self.experiment.auto_response) self.ui.checkbox_toolbar_text.setChecked( self.main_window.ui.toolbar_main.toolButtonStyle() == \ QtCore.Qt.ToolButtonTextUnderIcon) self.ui.checkbox_small_toolbar.setChecked(cfg.toolbar_size == 16) self.ui.combobox_runner.setCurrentIndex( self.ui.combobox_runner.findText(cfg.runner, flags=QtCore.Qt.MatchContains)) # Set the locale combobox self.ui.combobox_locale.addItem(u'[Default]') self.ui.combobox_locale.setCurrentIndex(0) locales = [locale[:-3] \ for locale in os.listdir(misc.resource(u'locale')) \ if locale != u'translatables'] for i, locale in enumerate(locales): self.ui.combobox_locale.addItem(locale) if cfg.locale == locale: self.ui.combobox_locale.setCurrentIndex(i+1) # Set the style combobox self.ui.combobox_style.addItem(u"[Default]") self.ui.combobox_style.setCurrentIndex(0) for i, style in enumerate(QtWidgets.QStyleFactory.keys()): self.ui.combobox_style.addItem(style) if cfg.style == style: self.ui.combobox_style.setCurrentIndex(i+1) # Set the theme combobox for i, _theme in enumerate(theme.available_themes): self.ui.combobox_theme.addItem(_theme) if cfg.theme == _theme: self.ui.combobox_theme.setCurrentIndex(i+1) self.lock = False
def resource(self, name): """ Retrieve a file from the resources folder Arguments: name -- the file name Returns: The full path to the file in the resources folder """ if self != None: if name in self.resources: return self.resources[name] if os.path.exists(self.get_file(name)): return self.get_file(name) path = misc.resource(name) if path == None: raise Exception("The resource '%s' could not be found in libopensesame.experiment.resource()" % name) return path
def resource(self, name): """ Retrieve a file from the resources folder Arguments: name -- the file name Returns: The full path to the file in the resources folder """ if self != None: if name in self.resources: return self.resources[name] if os.path.exists(self.get_file(name)): return self.get_file(name) path = misc.resource(name) if path == None: raise Exception( \ "The resource '%s' could not be found in libopensesame.experiment.resource()" \ % name) return path
def resume_init(self): """Resume GUI initialization""" from libopensesame import misc from libqtopensesame.misc import theme from libqtopensesame.extensions import extension_manager import platform import random # Set some initial variables self.current_path = None self.version = misc.version self.codename = misc.codename self.lock_refresh = False self.unsaved_changes = False # Make sure that QProgEdit doesn't complain about some standard names from QProgEdit import validate validate.addPythonBuiltins([u'exp', u'win', u'self']) # Initialize random number generator random.seed() # Check the filesystem encoding for debugging purposes debug.msg(u'filesystem encoding: %s' % misc.filesystem_encoding()) # Parse the command line self.parse_command_line() # Restore the configuration self.restore_config() # Setup the UI self.load_ui(u'misc.main_window') self.ui.itemtree.setup(self) self.ui.tabwidget.main_window = self # Load a theme self.theme = theme.theme(self, self.options._theme) # Determine the home folder self.home_folder = libopensesame.misc.home_folder() # Create .opensesame folder if it doesn't exist yet if not os.path.exists(os.path.join(self.home_folder, u".opensesame")): os.mkdir(os.path.join(self.home_folder, u".opensesame")) # Set the filter-string for opening and saving files self.file_type_filter = \ u"OpenSesame files (*.opensesame.tar.gz *.opensesame);;OpenSesame script and file pool (*.opensesame.tar.gz);;OpenSesame script (*.opensesame)" self.file_type_filter_script = u"OpenSesame script (*.opensesame)" self.file_type_filter_pool = \ u"OpenSesame script and file pool (*.opensesame.tar.gz)" # Set the window message self.window_message(_(u"Welcome to OpenSesame %s") % self.version) # Set the window icon self.setWindowIcon(self.theme.qicon(u"opensesame")) # Make the connections self.ui.itemtree.structure_change.connect(self.update_overview_area) self.ui.action_quit.triggered.connect(self.close) self.ui.action_new.triggered.connect(self.new_file) self.ui.action_open.triggered.connect(self.open_file) self.ui.action_save.triggered.connect(self.save_file) self.ui.action_save_as.triggered.connect(self.save_file_as) self.ui.action_run.triggered.connect(self.run_experiment) self.ui.action_run_in_window.triggered.connect( self.run_experiment_in_window) self.ui.action_run_quick.triggered.connect(self.run_quick) self.ui.action_enable_auto_response.triggered.connect( self.set_auto_response) self.ui.action_close_current_tab.triggered.connect( self.ui.tabwidget.close_current) self.ui.action_close_all_tabs.triggered.connect( self.ui.tabwidget.close_all) self.ui.action_close_other_tabs.triggered.connect( self.ui.tabwidget.close_other) self.ui.action_onetabmode.triggered.connect( self.ui.tabwidget.toggle_onetabmode) self.ui.action_show_overview.triggered.connect(self.toggle_overview) self.ui.action_show_variable_inspector.triggered.connect( self.refresh_variable_inspector) self.ui.action_show_pool.triggered.connect(self.refresh_pool) self.ui.action_show_stdout.triggered.connect(self.refresh_stdout) self.ui.action_preferences.triggered.connect( self.ui.tabwidget.open_preferences) self.ui.button_help_stdout.clicked.connect( self.ui.tabwidget.open_stdout_help) # Setup the overview area self.ui.dock_overview.show() self.ui.dock_overview.visibilityChanged.connect( \ self.ui.action_show_overview.setChecked) # Setup the variable inspector from libqtopensesame.widgets.variable_inspector import \ variable_inspector self.ui.variable_inspector = variable_inspector(self) self.ui.dock_variable_inspector.hide() self.ui.dock_variable_inspector.visibilityChanged.connect( self.ui.action_show_variable_inspector.setChecked) self.ui.dock_variable_inspector.setWidget(self.ui.variable_inspector) # Setup the file pool from libqtopensesame.widgets.pool_widget import pool_widget self.ui.dock_pool.hide() self.ui.dock_pool.visibilityChanged.connect( self.ui.action_show_pool.setChecked) self.ui.pool_widget = pool_widget(self) self.ui.dock_pool.setWidget(self.ui.pool_widget) # Uncheck the debug window button on debug window close self.ui.dock_stdout.visibilityChanged.connect( \ self.ui.action_show_stdout.setChecked) # Initialize keyboard shortcuts self.ui.shortcut_itemtree = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.itemtree.setFocus) self.ui.shortcut_tabwidget = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.tabwidget.setFocus) self.ui.shortcut_stdout = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.edit_stdout.setFocus) self.ui.shortcut_variables = QtGui.QShortcut( \ QtGui.QKeySequence(), self, \ self.ui.variable_inspector.set_focus()) self.ui.shortcut_pool = QtGui.QShortcut( \ QtGui.QKeySequence(), self, \ self.ui.pool_widget.ui.edit_pool_filter.setFocus) # Create the initial experiment, which is the default template. self.experiment = experiment.experiment(self, u"New experiment", \ open(misc.resource(os.path.join(u"templates", \ u"default.opensesame")), u"r").read()) self.experiment.build_item_tree() # Miscellaneous initialization self.restore_state() self.update_recent_files() self.set_unsaved(False) self.init_custom_fonts() self.ui.variable_inspector.refresh() # Initialize extensions self.extension_manager = extension_manager(self) self.extension_manager.fire(u'startup')
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSesame. If not, see <http://www.gnu.org/licenses/>. """ import sys if "--catch-translatables" in sys.argv: # Automatically catches all strings that require translation from libopensesame import misc import os.path path = misc.resource(os.path.join(u"ts", u"translatables.txt")) def _(s): l = open(path).read().split(u"\n") if s not in l: f = open(path, u"a") f.write(s + u"\n") print u"New translatable: " + s f.close() return s else: # A simple wrapper arround the translate function from PyQt4.QtCore import QCoreApplication
def resume_init(self): """Resume GUI initialization""" from libopensesame import misc from libqtopensesame.misc import theme from libqtopensesame.extensions import extension_manager import platform import random # Set some initial variables self.current_path = None self.version = misc.version self.codename = misc.codename self.lock_refresh = False self.unsaved_changes = False # Make sure that QProgEdit doesn't complain about some standard names from QProgEdit import validate validate.addPythonBuiltins([u'exp', u'win', u'self']) # Initialize random number generator random.seed() # Check the filesystem encoding for debugging purposes debug.msg(u'filesystem encoding: %s' % misc.filesystem_encoding()) # Parse the command line self.parse_command_line() # Restore the configuration self.restore_config() # Setup the UI self.load_ui(u'misc.main_window') self.ui.itemtree.setup(self) self.ui.tabwidget.main_window = self # Load a theme self.theme = theme.theme(self, self.options._theme) # Determine the home folder self.home_folder = libopensesame.misc.home_folder() # Create .opensesame folder if it doesn't exist yet if not os.path.exists(os.path.join(self.home_folder, u".opensesame")): os.mkdir(os.path.join(self.home_folder, u".opensesame")) # Set the filter-string for opening and saving files self.file_type_filter = \ u"OpenSesame files (*.opensesame.tar.gz *.opensesame);;OpenSesame script and file pool (*.opensesame.tar.gz);;OpenSesame script (*.opensesame)" # Set the window message self.window_message(_(u"Welcome to OpenSesame %s") % self.version) # Set the window icon self.setWindowIcon(self.theme.qicon(u"opensesame")) # Make the connections self.ui.itemtree.structure_change.connect(self.update_overview_area) self.ui.action_quit.triggered.connect(self.close) self.ui.action_new.triggered.connect(self.new_file) self.ui.action_open.triggered.connect(self.open_file) self.ui.action_save.triggered.connect(self.save_file) self.ui.action_save_as.triggered.connect(self.save_file_as) self.ui.action_run.triggered.connect(self.run_experiment) self.ui.action_run_in_window.triggered.connect( self.run_experiment_in_window) self.ui.action_run_quick.triggered.connect(self.run_quick) self.ui.action_enable_auto_response.triggered.connect( self.set_auto_response) self.ui.action_close_current_tab.triggered.connect( self.ui.tabwidget.close_current) self.ui.action_close_all_tabs.triggered.connect( self.ui.tabwidget.close_all) self.ui.action_close_other_tabs.triggered.connect( self.ui.tabwidget.close_other) self.ui.action_onetabmode.triggered.connect( self.ui.tabwidget.toggle_onetabmode) self.ui.action_show_overview.triggered.connect(self.toggle_overview) self.ui.action_show_variable_inspector.triggered.connect( self.refresh_variable_inspector) self.ui.action_show_pool.triggered.connect(self.refresh_pool) self.ui.action_show_stdout.triggered.connect(self.refresh_stdout) self.ui.action_preferences.triggered.connect( self.ui.tabwidget.open_preferences) self.ui.button_help_stdout.clicked.connect( self.ui.tabwidget.open_stdout_help) # Setup the overview area self.ui.dock_overview.show() self.ui.dock_overview.visibilityChanged.connect( \ self.ui.action_show_overview.setChecked) # Setup the variable inspector from libqtopensesame.widgets.variable_inspector import \ variable_inspector self.ui.variable_inspector = variable_inspector(self) self.ui.dock_variable_inspector.hide() self.ui.dock_variable_inspector.visibilityChanged.connect( self.ui.action_show_variable_inspector.setChecked) self.ui.dock_variable_inspector.setWidget(self.ui.variable_inspector) # Setup the file pool from libqtopensesame.widgets.pool_widget import pool_widget self.ui.dock_pool.hide() self.ui.dock_pool.visibilityChanged.connect( self.ui.action_show_pool.setChecked) self.ui.pool_widget = pool_widget(self) self.ui.dock_pool.setWidget(self.ui.pool_widget) # Uncheck the debug window button on debug window close self.ui.dock_stdout.visibilityChanged.connect( \ self.ui.action_show_stdout.setChecked) # Initialize keyboard shortcuts self.ui.shortcut_itemtree = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.itemtree.setFocus) self.ui.shortcut_tabwidget = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.tabwidget.setFocus) self.ui.shortcut_stdout = QtGui.QShortcut( \ QtGui.QKeySequence(), self, self.ui.edit_stdout.setFocus) self.ui.shortcut_variables = QtGui.QShortcut( \ QtGui.QKeySequence(), self, \ self.ui.variable_inspector.set_focus()) self.ui.shortcut_pool = QtGui.QShortcut( \ QtGui.QKeySequence(), self, \ self.ui.pool_widget.ui.edit_pool_filter.setFocus) # Create the initial experiment, which is the default template. self.experiment = experiment.experiment(self, u"New experiment", \ open(misc.resource(os.path.join(u"templates", \ u"default.opensesame")), u"r").read()) self.experiment.build_item_tree() # Miscellaneous initialization self.restore_state() self.update_recent_files() self.set_unsaved(False) self.init_custom_fonts() # Initialize extensions self.extension_manager = extension_manager(self) self.extension_manager.fire(u'startup')
def resume_init(self): """Resume GUI initialization""" from libopensesame import misc from libqtopensesame.misc import theme from libqtopensesame.extensions import extension_manager import random # Make sure that icons are shown in context menu, regardless of the # system settings. This is necessary, because Ubuntu doesn't show menu # icons by default. QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus, False) # Add the Qt plugin folders to the library path, if they exists. Where # these folders are depends on the version of Qt4, but these are two # possible locations. qt_plugin_path = os.path.join( os.path.dirname(sys.executable), 'Library', 'plugins') if os.path.isdir(qt_plugin_path): QtCore.QCoreApplication.addLibraryPath(qt_plugin_path) qt_plugin_path = os.path.join( os.path.dirname(sys.executable), 'Library', 'lib', 'qt4', 'plugins') if os.path.isdir(qt_plugin_path): QtCore.QCoreApplication.addLibraryPath(qt_plugin_path) # Do a few things to customize QProgEdit behavior: # - Register the bundled monospace font (Droid Sans Mono) # - Make sure that QProgEdit doesn't complain about some standard names # - Ignore undefined name warnings, which don't play well with # OpenSesame's single workspace QtGui.QFontDatabase.addApplicationFont(misc.resource(u'mono.ttf')) from QProgEdit import validate validate.addPythonBuiltins([u'exp', u'win', u'self']) if hasattr(validate, u'setPyFlakesFilter'): validate.setPyFlakesFilter( lambda msg: msg.message == u'undefined name %r') # Initialize random number generator random.seed() # Check the filesystem encoding for debugging purposes debug.msg(u'filesystem encoding: %s' % misc.filesystem_encoding()) # # Parse the command line # self.parse_command_line() # # # Restore the configuration # self.restore_config() self.set_style() self.set_warnings() # self.set_locale() # Setup the UI self.load_ui(u'misc.main_window') self.theme = theme.theme(self, self.options._theme) self.ui.itemtree.setup(self) self.ui.console.setup(self) self.ui.tabwidget.main_window = self # Determine the home folder self.home_folder = libopensesame.misc.home_folder() # Create .opensesame folder if it doesn't exist yet if not os.path.exists(os.path.join(self.home_folder, u".opensesame")): os.mkdir(os.path.join(self.home_folder, u".opensesame")) # Set the filter-string for opening and saving files self.save_file_filter =u'OpenSesame files (*.osexp)' self.open_file_filter = \ u'OpenSesame files (*.osexp *.opensesame.tar.gz *.opensesame)' # Set the window message self._read_only = False self.window_message(_(u"New experiment")) # Set the window icon self.setWindowIcon(self.theme.qicon(u"opensesame")) # Make the connections self.ui.itemtree.structure_change.connect(self.update_overview_area) self.ui.action_quit.triggered.connect(self.close) self.ui.action_open.triggered.connect(self.open_file) self.ui.action_save.triggered.connect(self.save_file) self.ui.action_save_as.triggered.connect(self.save_file_as) self.ui.action_run.triggered.connect(self.run_experiment) self.ui.action_run_in_window.triggered.connect( self.run_experiment_in_window) self.ui.action_run_quick.triggered.connect(self.run_quick) self.ui.action_enable_auto_response.triggered.connect( self.set_auto_response) self.ui.action_close_current_tab.triggered.connect( self.ui.tabwidget.close_current) self.ui.action_close_all_tabs.triggered.connect( self.ui.tabwidget.close_all) self.ui.action_close_other_tabs.triggered.connect( self.ui.tabwidget.close_other) self.ui.action_onetabmode.triggered.connect( self.ui.tabwidget.toggle_onetabmode) self.ui.action_show_overview.triggered.connect(self.toggle_overview) self.ui.action_show_pool.triggered.connect( self.toggle_pool) self.ui.action_show_stdout.triggered.connect(self.refresh_stdout) self.ui.action_preferences.triggered.connect( self.ui.tabwidget.open_preferences) # Setup console self.ui.button_help_console.clicked.connect( self.ui.tabwidget.open_stdout_help) self.ui.button_reset_console.clicked.connect( self.ui.console.reset) # Setup the overview area self.ui.dock_overview.show() self.ui.dock_overview.visibilityChanged.connect( self.ui.action_show_overview.setChecked) # Setup the file pool from libqtopensesame.widgets.pool_widget import pool_widget self.ui.dock_pool.hide() self.ui.dock_pool.visibilityChanged.connect( self.ui.action_show_pool.setChecked) self.ui.pool_widget = pool_widget(self) self.ui.dock_pool.setWidget(self.ui.pool_widget) # Uncheck the debug window button on debug window close self.ui.dock_stdout.hide() self.ui.dock_stdout.visibilityChanged.connect( self.ui.action_show_stdout.setChecked) # Initialize keyboard shortcuts self.ui.shortcut_itemtree = QtWidgets.QShortcut(QtGui.QKeySequence(), self, self.focus_overview_area) self.ui.shortcut_tabwidget = QtWidgets.QShortcut( QtGui.QKeySequence(), self, self.ui.tabwidget.focus) self.ui.shortcut_stdout = QtWidgets.QShortcut(QtGui.QKeySequence(), self, self.focus_debug_window) self.ui.shortcut_pool = QtWidgets.QShortcut(QtGui.QKeySequence(), self, self.focus_file_pool) # Create the initial experiment, which is the default template. Because # not all backends are supported under Python 3, we use a different # backend for each. if py3: tmpl = u'default-py3.osexp' else: tmpl = u'default.osexp' with safe_open(misc.resource(os.path.join(u'templates', tmpl)), u'r') as fd: self.experiment = experiment.experiment(self, u'New experiment', fd.read()) self.experiment.build_item_tree() self.ui.itemtree.default_fold_state() # Miscellaneous initialization self.restore_state() self.update_recent_files() self.set_unsaved(False) self.init_custom_fonts() # Initialize extensions self.extension_manager = extension_manager(self) self.extension_manager.fire(u'startup')
def opensesame(): import os, sys, platform # Add the folder that contains the OpenSesame modules to the path. This is # generally only necessary if OpenSesame is directly run from source, # instead from an installation. if os.path.exists(os.path.join(os.getcwd(), 'libopensesame')): sys.path.insert(0, os.getcwd()) # Support for multiprocessing when packaged # In OS X the multiprocessing module is horribly broken, but a fixed # version has been released as the 'billiard' module if platform.system() == 'Darwin': # Use normal multirpocessing module from python 3.4 and on if sys.version_info >= (3, 4): from multiprocessing import freeze_support, set_start_method freeze_support() set_start_method('forkserver') else: from billiard import freeze_support, forking_enable freeze_support() forking_enable(0) else: from multiprocessing import freeze_support freeze_support() # Parse the (optional) environment file that contains special paths, etc. from libopensesame.misc import resource, filesystem_encoding, \ parse_environment_file parse_environment_file() # Force the new-style Qt API import sip import qtpy sip.setapi('QString', 2) sip.setapi('QVariant', 2) # Load debug package (this must be after the working directory change) from libopensesame import debug # Do the basic window initialization from qtpy.QtWidgets import QApplication # From Qt 5.6 on, QtWebEngine is the default way to render web pages # QtWebEngineWidgets must be imported before a QCoreApplication instance is created try: from qtpy import QtWebEngineWidgets except ImportError: pass app = QApplication(sys.argv) # Enable High DPI display with PyQt5 if hasattr(qtpy.QtCore.Qt, 'AA_UseHighDpiPixmaps'): app.setAttribute(qtpy.QtCore.Qt.AA_UseHighDpiPixmaps) from libqtopensesame.qtopensesame import qtopensesame opensesame = qtopensesame(app) opensesame.__script__ = __file__ app.processEvents() # Import the remaining modules from qtpy.QtCore import QObject, QLocale, QTranslator import os.path # Load the locale for UI translation. The locale can be specified on the # command line using the --locale parameter locale = QLocale().system().name() for i in range(len(sys.argv) - 1): if sys.argv[i] == '--locale': locale = sys.argv[i + 1] qm = resource(os.path.join(u'locale', locale) + u'.qm') # Say that we're trying to load de_AT, and it is not found, then we'll try # de_DE as fallback. if qm is None: l = locale.split(u'_') if len(l): _locale = l[0] + u'_' + l[0].upper() qm = resource(os.path.join(u'locale', _locale + u'.qm')) if qm is not None: locale = _locale opensesame._locale = locale if qm is not None: debug.msg(u'installing %s translator' % qm) translator = QTranslator() translator.load(qm) app.installTranslator(translator) else: debug.msg(u'no translator found for %s' % locale) # Now that the window is shown, load the remaining modules and resume the # GUI initialization. opensesame.resume_init() opensesame.restore_window_state() opensesame.refresh() opensesame.show() # Added for OS X, otherwise Window will not appear opensesame.raise_() # Exit using the application exit status sys.exit(app.exec_())
def resume_init(self): """Resume GUI initialization""" from libopensesame import misc from libqtopensesame.misc import theme from libqtopensesame.extensions import extension_manager import random # Make sure that icons are shown in context menu, regardless of the # system settings. This is necessary, because Ubuntu doesn't show menu # icons by default. QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus, False) # Do a few things to customize QProgEdit behavior: # - Register the bundled monospace font (Droid Sans Mono) # - Make sure that QProgEdit doesn't complain about some standard names # - Ignore undefined name warnings, which don't play well with # OpenSesame's single workspace QtGui.QFontDatabase.addApplicationFont(misc.resource(u'mono.ttf')) from QProgEdit import validate validate.addPythonBuiltins([u'exp', u'win', u'self']) if hasattr(validate, u'setPyFlakesFilter'): validate.setPyFlakesFilter( lambda msg: msg.message == u'undefined name %r') # Initialize random number generator random.seed() # Check the filesystem encoding for debugging purposes debug.msg(u'filesystem encoding: %s' % misc.filesystem_encoding()) # # Parse the command line # self.parse_command_line() # # # Restore the configuration # self.restore_config() self.set_style() self.set_warnings() # self.set_locale() # Setup the UI self.load_ui(u'misc.main_window') self.theme = theme.theme(self, self.options._theme) self.ui.itemtree.setup(self) self.ui.console.setup(self) self.ui.tabwidget.main_window = self # Determine the home folder self.home_folder = libopensesame.misc.home_folder() # Create .opensesame folder if it doesn't exist yet if not os.path.exists(os.path.join(self.home_folder, u".opensesame")): os.mkdir(os.path.join(self.home_folder, u".opensesame")) # Set the filter-string for opening and saving files self.save_file_filter = u'OpenSesame files (*.osexp)' self.open_file_filter = \ u'OpenSesame files (*.osexp *.opensesame.tar.gz *.opensesame)' # Set the window message self._read_only = False self.window_message(_(u"New experiment")) # Set the window icon self.setWindowIcon(self.theme.qicon(u"opensesame")) # Make the connections self.ui.itemtree.structure_change.connect(self.update_overview_area) self.ui.action_quit.triggered.connect(self.close) self.ui.action_open.triggered.connect(self.open_file) self.ui.action_save.triggered.connect(self.save_file) self.ui.action_save_as.triggered.connect(self.save_file_as) self.ui.action_run.triggered.connect(self.run_experiment) self.ui.action_run_in_window.triggered.connect( self.run_experiment_in_window) self.ui.action_run_quick.triggered.connect(self.run_quick) self.ui.action_kill.triggered.connect(self.kill_experiment) self.ui.action_enable_auto_response.triggered.connect( self.set_auto_response) self.ui.action_close_current_tab.triggered.connect( self.ui.tabwidget.close_current) self.ui.action_close_all_tabs.triggered.connect( self.ui.tabwidget.close_all) self.ui.action_close_other_tabs.triggered.connect( self.ui.tabwidget.close_other) self.ui.action_onetabmode.triggered.connect( self.ui.tabwidget.toggle_onetabmode) self.ui.action_show_overview.triggered.connect(self.toggle_overview) self.ui.action_show_pool.triggered.connect(self.toggle_pool) self.ui.action_show_stdout.triggered.connect(self.refresh_stdout) self.ui.action_preferences.triggered.connect( self.ui.tabwidget.open_preferences) # Setup console self.ui.button_help_console.clicked.connect( self.ui.tabwidget.open_stdout_help) self.ui.button_reset_console.clicked.connect(self.ui.console.reset) # Setup the overview area self.ui.dock_overview.show() self.ui.dock_overview.visibilityChanged.connect( self.ui.action_show_overview.setChecked) # Setup the file pool from libqtopensesame.widgets.pool_widget import pool_widget self.ui.dock_pool.hide() self.ui.dock_pool.visibilityChanged.connect( self.ui.action_show_pool.setChecked) self.ui.pool_widget = pool_widget(self) self.ui.dock_pool.setWidget(self.ui.pool_widget) # Uncheck the debug window button on debug window close self.ui.dock_stdout.hide() self.ui.dock_stdout.visibilityChanged.connect( self.ui.action_show_stdout.setChecked) # Initialize keyboard shortcuts self.ui.shortcut_itemtree = QtWidgets.QShortcut( QtGui.QKeySequence(), self, self.focus_overview_area) self.ui.shortcut_tabwidget = QtWidgets.QShortcut( QtGui.QKeySequence(), self, self.ui.tabwidget.focus) self.ui.shortcut_stdout = QtWidgets.QShortcut(QtGui.QKeySequence(), self, self.focus_debug_window) self.ui.shortcut_pool = QtWidgets.QShortcut(QtGui.QKeySequence(), self, self.focus_file_pool) # Create the initial experiment, which is the default template. Because # not all backends are supported under Python 3, we use a different # backend for each. if py3: tmpl = u'default-py3.osexp' else: tmpl = u'default.osexp' with safe_open(misc.resource(os.path.join(u'templates', tmpl)), u'r') as fd: self.experiment = experiment.experiment(self, u'New experiment', fd.read()) self.experiment.build_item_tree() self.ui.itemtree.default_fold_state() # Miscellaneous initialization self.restore_state() self.update_recent_files() self.set_unsaved(False) self.init_custom_fonts() # Initialize extensions self.extension_manager = extension_manager(self) self.extension_manager.fire(u'startup')
def opensesame(): import os, sys, platform # Add the folder that contains the OpenSesame modules to the path. This is # generally only necessary if OpenSesame is directly run from source, # instead from an installation. if os.path.exists(os.path.join(os.getcwd(), 'libopensesame')): sys.path.insert(0, os.getcwd()) # Support for multiprocessing when packaged # In OS X the multiprocessing module is horribly broken, but a fixed # version has been released as the 'billiard' module if platform.system() == 'Darwin': # Use normal multirpocessing module from python 3.4 and on if sys.version_info >= (3,4): from multiprocessing import freeze_support, set_start_method freeze_support() set_start_method('forkserver') else: from billiard import freeze_support, forking_enable freeze_support() forking_enable(0) else: from multiprocessing import freeze_support freeze_support() # Parse the (optional) environment file that contains special paths, etc. from libopensesame.misc import resource, filesystem_encoding, \ parse_environment_file parse_environment_file() # Force the new-style Qt API import sip import qtpy sip.setapi('QString', 2) sip.setapi('QVariant', 2) # Load debug package (this must be after the working directory change) from libopensesame import debug # Do the basic window initialization from qtpy.QtWidgets import QApplication # From Qt 5.6 on, QtWebEngine is the default way to render web pages # QtWebEngineWidgets must be imported before a QCoreApplication instance is created try: from qtpy import QtWebEngineWidgets except ImportError: pass app = QApplication(sys.argv) # Enable High DPI display with PyQt5 if hasattr(qtpy.QtCore.Qt, 'AA_UseHighDpiPixmaps'): app.setAttribute(qtpy.QtCore.Qt.AA_UseHighDpiPixmaps) from libqtopensesame.qtopensesame import qtopensesame opensesame = qtopensesame(app) opensesame.__script__ = __file__ app.processEvents() # Import the remaining modules from qtpy.QtCore import QObject, QLocale, QTranslator import os.path # Load the locale for UI translation. The locale can be specified on the # command line using the --locale parameter locale = str(QLocale().system().name()) for i in range(len(sys.argv)-1): if sys.argv[i] == '--locale': locale = sys.argv[i+1] opensesame._locale = locale qm = resource(os.path.join(u'locale', locale) + u'.qm') if qm is not None: debug.msg(u'installing %s translator' % qm) translator = QTranslator() translator.load(qm) app.installTranslator(translator) else: debug.msg(u'no translator found for %s' % locale) # Now that the window is shown, load the remaining modules and resume the # GUI initialization. opensesame.resume_init() opensesame.restore_window_state() opensesame.refresh() opensesame.show() # Added for OS X, otherwise Window will not appear opensesame.raise_() # Exit using the application exit status sys.exit(app.exec_())
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSesame. If not, see <http://www.gnu.org/licenses/>. """ __author__ = "Sebastiaan Mathot" __license__ = "GPLv3" import sys if '--catch-translatables' in sys.argv: # Automatically catches all strings that require translation from libopensesame import misc import os.path path = misc.resource(os.path.join('ts', 'translatables.txt')) def _(s): l = open(path).read().split('\n') if s not in l: f = open(path, 'a') f.write(s+'\n') print 'New translatable: '+s f.close() return s else: # A simple wrapper arround the translate function from PyQt4.QtCore import QCoreApplication _ = lambda s: unicode(QCoreApplication.translate('script', s))
GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenSesame. If not, see <http://www.gnu.org/licenses/>. """ __author__ = "Sebastiaan Mathot" __license__ = "GPLv3" import sys if '--catch-translatables' in sys.argv: # Automatically catches all strings that require translation from libopensesame import misc import os.path path = misc.resource(os.path.join('ts', 'translatables.txt')) def _(s): l = open(path).read().split('\n') if s not in l: f = open(path, 'a') f.write(s + '\n') print 'New translatable: ' + s f.close() return s else: # A simple wrapper arround the translate function from PyQt4.QtCore import QCoreApplication _ = lambda s: unicode(QCoreApplication.translate('script', s))