Пример #1
0
    def set_rect(self, rect):
        """
		desc:
			Sets the widget geometry.

		arguments:
			rect:
				desc:	A (left, top, width, height) tuple.
				type:	tuple
		"""

        self.rect = rect
        _path = safe_str(self.path, enc=misc.filesystem_encoding())
        if not os.path.isfile(_path):
            raise osexception(u'"%s" does not exist' % _path)
        if self.adjust:
            x, y, w, h = self.rect
            try:
                img = Image.open(_path)
                img_w, img_h = img.size
            except:
                try:
                    import pygame
                    img = pygame.image.load(_path)
                except:
                    raise osexception(
                        u'Failed to open image "%s". Perhaps the file is not an image, or the image format is not supported.'
                        % self.path)
                img_w, img_h = img.get_size()
            scale_x = 1. * w / img_w
            scale_y = 1. * h / img_h
            self.scale = min(scale_x, scale_y)
        else:
            self.scale = 1
        Widget.set_rect(self, rect)
Пример #2
0
    def image(self, fname, center=True, x=None, y=None, scale=None):

        _fname = safe_str(fname, enc=misc.filesystem_encoding())
        if not os.path.isfile(_fname):
            raise osexception(u'"%s" does not exist' % fname)
        try:
            surface = pygame.image.load(_fname)
        except pygame.error:
            raise osexception(u"'%s' is not a supported image format" % fname)
        if scale is not None:
            try:
                surface = pygame.transform.smoothscale(
                    surface, (int(surface.get_width() * scale), int(surface.get_height() * scale))
                )
            except:
                debug.msg(u"smooth scaling failed for '%s'" % fname, reason=u"warning")
                surface = pygame.transform.scale(
                    surface, (int(surface.get_width() * scale), int(surface.get_height() * scale))
                )
        size = surface.get_size()
        x, y = self.to_xy(x, y)
        if center:
            x -= size[0] / 2
            y -= size[1] / 2
        self.surface.blit(surface, (x, y))
Пример #3
0
	def __init__(self, experiment, folder=None):

		"""
		visible: False

		desc:
			Constructor.

		arguments:
			experiment:
				desc:	The experiment object.
				type:	experiment

		keywords:
			folder:
				desc:	The folder to use for the file pool, or `None` to create
						a new temporary folder.
				type:	[str, unicode, NoneType]
		"""

		self.experiment = experiment
		if folder is None:
			# On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
			# This is resolved by passing the dir explicitly as a Unicode
			# string. This fix has been adapted from:
			# - <http://bugs.python.org/issue1681974>
			self.__folder__ = tempfile.mkdtemp(suffix=u'.opensesame_pool',
				dir=safe_decode(tempfile.gettempdir(),
				enc=misc.filesystem_encoding()))
			debug.msg(u'creating new pool folder')
		else:
			debug.msg(u'reusing existing pool folder')
			self.__folder__ = folder
		debug.msg(u'pool folder is \'%s\'' % self.__folder__)
Пример #4
0
	def __init__(self, plugin_file=None):

		"""
		Constructor.

		Arguments:
		plugin_file		-- The path to the plugin script. (default=None)
		"""

		if plugin_file != None:
			# The __file__ variable is generally a str, which will cause unicode
			# errors. Therefore, convert this here if necessary.
			if isinstance(plugin_file, str):
				plugin_file = plugin_file.decode(misc.filesystem_encoding())
			# These lines makes sure that the icons and help file are recognized
			# by OpenSesame.
			self.plugin_folder = os.path.dirname(plugin_file)
			self.experiment.resources[u'%s.png' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.png' % self.item_type)
			self.experiment.resources[u'%s_large.png' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s_large.png' \
				% self.item_type)
			self.experiment.resources[u'%s.html' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.html' \
				% self.item_type)
			self.experiment.resources[u'%s.md' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.md' \
				% self.item_type)
		self.lock = False
		qtitem.qtitem.__init__(self)
Пример #5
0
	def set_rect(self, rect):

		"""
		desc:
			Sets the widget geometry.

		arguments:
			rect:
				desc:	A (left, top, width, height) tuple.
				type:	tuple
		"""

		self.rect = rect
		_path = safe_str(self.path, enc=misc.filesystem_encoding())
		if self.adjust:
			x, y, w, h = self.rect
			try:
				img = Image.open(_path)
				img_w, img_h = img.size
			except:
				try:
					import pygame
					img = pygame.image.load(_path)
				except:
					raise osexception(
						u'Failed to open image "%s". Perhaps the file is not an image, or the image format is not supported.' \
						% self.path)
				img_w, img_h = img.get_size()
			scale_x = 1.*w/img_w
			scale_y = 1.*h/img_h
			self.scale = min(scale_x, scale_y)
		else:
			self.scale = 1
Пример #6
0
	def __getitem__(self, path):

		"""
		visible: False

		desc: |
			Returns the full path to a file.

		arguments:
			path:
				desc:	A filename. This can be any type, but will be coerced
						to `unicode` if it is not `unicode`.

		returns:
			desc:	The full path to the file.
			type:	unicode
		"""

		path = safe_decode(path)
		if path.strip() == u'':
			raise osexception(u'Cannot get empty filename from file pool.')
		for folder in self.folders(include_experiment_path=True):
			_path = os.path.normpath(os.path.join(folder, path))
			if os.path.exists(safe_str(_path, enc=misc.filesystem_encoding())):
				return _path
		return os.path.normpath(path)
Пример #7
0
    def __init__(self, plugin_file=None):
        """
		Constructor.

		Arguments:
		plugin_file		-- The path to the plugin script. (default=None)
		"""

        if plugin_file != None:
            # The __file__ variable is generally a str, which will cause unicode
            # errors. Therefore, convert this here if necessary.
            if isinstance(plugin_file, str):
                plugin_file = plugin_file.decode(misc.filesystem_encoding())
            # These lines makes sure that the icons and help file are recognized
            # by OpenSesame.
            self.plugin_folder = os.path.dirname(plugin_file)
            self.experiment.resources[u'%s.png' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s.png' % self.item_type)
            self.experiment.resources[u'%s_large.png' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s_large.png' \
             % self.item_type)
            self.experiment.resources[u'%s.html' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s.html' \
             % self.item_type)
            self.experiment.resources[u'%s.md' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s.md' \
             % self.item_type)
        self.lock = False
        qtitem.qtitem.__init__(self)
Пример #8
0
    def image(self, fname, center=True, x=None, y=None, scale=None):

        _fname = safe_str(fname, enc=misc.filesystem_encoding())
        if not os.path.isfile(_fname):
            raise osexception(u'"%s" does not exist' % fname)
        try:
            surface = pygame.image.load(_fname)
        except pygame.error:
            raise osexception(u"'%s' is not a supported image format" % fname)
        if scale is not None:
            try:
                surface = pygame.transform.smoothscale(
                    surface, (int(surface.get_width() * scale),
                              int(surface.get_height() * scale)))
            except:
                debug.msg(u"smooth scaling failed for '%s'" % fname,
                          reason=u"warning")
                surface = pygame.transform.scale(
                    surface, (int(surface.get_width() * scale),
                              int(surface.get_height() * scale)))
        size = surface.get_size()
        x, y = self.to_xy(x, y)
        if center:
            x -= size[0] / 2
            y -= size[1] / 2
        self.surface.blit(surface, (x, y))
Пример #9
0
	def image(self, fname, center=True, x=None, y=None, scale=None):

		# If the filename is a str, we first decode it to unicode
		if isinstance(fname, str):
			_fname = fname.decode(self.experiment.encoding)
		# Next, we encode the filename to a str in the filesystem encoding
		_fname = fname.encode(misc.filesystem_encoding())
		try:
			surface = pygame.image.load(_fname)
		except pygame.error as e:
			raise osexception(
				u"'%s' is not a supported image format" % fname)
		if scale != None:
			try:
				surface = pygame.transform.smoothscale(surface,
					(int(surface.get_width()*scale),
					int(surface.get_height()*scale)))
			except:
				debug.msg(u"smooth scaling failed for '%s'" % fname,
					reason=u"warning")
				surface = pygame.transform.scale(surface,
					(int(surface.get_width()*scale),
					int(surface.get_height()*scale)))
		size = surface.get_size()
		if x == None:
			x = self.xcenter()
		if y == None:
			y = self.ycenter()
		if center:
			x -= size[0] / 2
			y -= size[1] / 2
		self.surface.blit(surface, (x, y))
Пример #10
0
	def _read_tarfile(self, format):
		
		"""
		visible: False
		
		desc:
			Reads a tar or targz archive.
			
		arguments:
			format:
				desc:	The format to be used for tarfile.open().
				type:	str
		"""
		
		self._experiment_path = os.path.dirname(self._src)
		tar = tarfile.open(self._src, format)
		for name in tar.getnames():	
			# Tar doesn't return unicode in Python 2
			uname = safe_decode(name)
			folder, fname = os.path.split(uname)			
			# Ignore everything except the pool folder
			if folder != u'pool':
				continue
			# Filenames are encoded with U+XXXX notation in the archive. This is
			# necessary to deal with absence of good unicode support in .tar.gz.
			fname = self._syntax.from_ascii(fname)
			pool_folder = safe_str(self._pool.folder(),
				enc=misc.filesystem_encoding())
			from_name = safe_str(os.path.join(self._pool.folder(), uname),
				enc=misc.filesystem_encoding())
			to_name = safe_str(os.path.join(self._pool.folder(), fname),
				enc=misc.filesystem_encoding())
			tar.extract(name, pool_folder)
			os.rename(from_name, to_name)
			os.rmdir(os.path.join(self._pool.folder(), folder))
		# Temporarily extract the script file to the file pool, and remove it
		# right away
		script_path = os.path.join(self._pool.folder(), u'script.opensesame')
		tar.extract(u'script.opensesame', self._pool.folder())
		with safe_open(script_path, universal_newline_mode) as fd:
			self._script = fd.read()
		os.remove(script_path)
Пример #11
0
	def open(self, src):

		"""
		If the path exists, open the file, extract the pool and return the
		contents of the script.opensesame. Otherwise just return the input
		string, because it probably was a definition to begin with.

		Arguments:
		src		--	A definition string or a file to be opened.

		Returns:
		A unicode defition string.
		"""

		# If the path is not a path at all, but a string containing
		# the script, return it. Also, convert the path back to Unicode before
		# returning.
		if not os.path.exists(src):
			debug.msg(u'opening from unicode string')
			self.experiment_path = None
			if isinstance(src, unicode):
				return src
			return src.decode(self.encoding, u'replace')
		# If the file is a regular text script,
		# read it and return it
		ext = u'.opensesame.tar.gz'
		if src[-len(ext):] != ext:
			debug.msg(u'opening .opensesame file')
			self.experiment_path = os.path.dirname(src)
			return self.unsanitize(open(src, u'rU').read())
		debug.msg(u"opening .opensesame.tar.gz file")
		# If the file is a .tar.gz archive, extract the pool to the pool folder
		# and return the contents of opensesame.script.
		tar = tarfile.open(src, u'r:gz')
		for name in tar.getnames():
			# Here, all paths except name are Unicode. In addition, fname is
			# Unicode unsanitized, because the files as saved are Unicode
			# sanitized (see save()).
			uname = name.decode(self.encoding)
			folder, fname = os.path.split(uname)
			fname = self.unsanitize(fname)
			if folder == u"pool":
				debug.msg(u"extracting '%s'" % uname)
				tar.extract(name, self.pool_folder.encode( \
					misc.filesystem_encoding()))
				os.rename(os.path.join(self.pool_folder, uname), \
					os.path.join(self.pool_folder, fname))
				os.rmdir(os.path.join(self.pool_folder, folder))
		script_path = os.path.join(self.pool_folder, u"script.opensesame")
		tar.extract(u"script.opensesame", self.pool_folder)
		script = self.unsanitize(open(script_path, u"rU").read())
		os.remove(script_path)
		self.experiment_path = os.path.dirname(src)
		return script
Пример #12
0
def import_plugin(plugin):
    """
	Imports plugin module
	
	Arguments:
	plugin -- the name of the plugin
	"""

    import imp
    plugin = str(plugin)
    for tmpl in src_templates:
        if os.path.exists(os.path.join(plugin_folder(plugin), tmpl % plugin)):
            path = os.path.join(plugin_folder(plugin), tmpl % plugin).encode( \
             misc.filesystem_encoding())
            return imp.load_source(plugin, path)
    for tmpl in bytecode_templates:
        if os.path.exists(os.path.join(plugin_folder(plugin), tmpl % plugin)):
            path = os.path.join(plugin_folder(plugin), tmpl % plugin).encode( \
             misc.filesystem_encoding())
            return imp.load_compiled(plugin, path)
Пример #13
0
def plugin_folders(only_existing=True, _type=u'plugins'):
    """
	desc:
		Returns a list of plugin folders.

	keywords:
		only_existing:
			desc:	Specifies if only existing folders should be returned.
			type:	bool
		_type:
			desc:	Indicates whether runtime plugins ('plugins') or GUI
					extensions ('extensions') should be listed.
			type:	[str, unicode]

	returns:
		desc:	A list of folders.
		type:	list
	"""

    l = []

    # For all platforms, the plugins folder relative to the working directory
    # should be searched
    path = os.path.join(os.getcwdu(), _type)
    if not only_existing or os.path.exists(path):
        l.append(path)

    if os.name == u'posix' and u'HOME' in os.environ:
        # Regular Linux distributions. TODO: How well does this apply to Mac OS?
        path = os.path.join(os.environ[u'HOME'], u'.opensesame', _type)
        if not only_existing or os.path.exists(path):
            l.append(path)
        path = u'/usr/share/opensesame/%s' % _type
        if not only_existing or os.path.exists(path):
            l.append(path)

    elif os.name == u'posix' and u'HOME' not in os.environ:
        # Android can be recognized by the fact that the HOME variable is not
        # available. We can simply use the relative path `plugins`, which will
        # (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
        path = _type
        if not only_existing or os.path.exists(path):
            l.append(path)

    elif os.name == u'nt':
        # Windows
        path = os.path.join(
            os.environ[u'APPDATA'].decode(misc.filesystem_encoding()),
            u'.opensesame', _type)
        if not only_existing or os.path.exists(path):
            l.append(path)

    return l
Пример #14
0
def import_plugin(plugin):

	"""
	Imports plugin module

	Arguments:
	plugin -- the name of the plugin
	"""

	import imp
	plugin = str(plugin)
	for tmpl in src_templates:
		if os.path.exists(os.path.join(plugin_folder(plugin), tmpl % plugin)):
			path = os.path.join(plugin_folder(plugin), tmpl % plugin).encode( \
				misc.filesystem_encoding())
			return imp.load_source(plugin, path)
	for tmpl in bytecode_templates:
		if os.path.exists(os.path.join(plugin_folder(plugin), tmpl % plugin)):
			path = os.path.join(plugin_folder(plugin), tmpl % plugin).encode( \
				misc.filesystem_encoding())
			return imp.load_compiled(plugin, path)
Пример #15
0
def plugin_folders(only_existing=True, _type=u'plugins'):

	"""
	desc:
		Returns a list of plugin folders.

	keywords:
		only_existing:
			desc:	Specifies if only existing folders should be returned.
			type:	bool
		_type:
			desc:	Indicates whether runtime plugins ('plugins') or GUI
					extensions ('extensions') should be listed.
			type:	[str, unicode]

	returns:
		desc:	A list of folders.
		type:	list
	"""

	l = []

	# For all platforms, the plugins folder relative to the working directory
	# should be searched
	path = os.path.join(os.getcwdu(), _type)
	if not only_existing or os.path.exists(path):
		l.append(path)

	if os.name == u'posix' and u'HOME' in os.environ:
		# Regular Linux distributions. TODO: How well does this apply to Mac OS?
		path = os.path.join(os.environ[u'HOME'], u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)
		path = u'/usr/share/opensesame/%s' % _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'posix' and u'HOME' not in os.environ:
		# Android can be recognized by the fact that the HOME variable is not
		# available. We can simply use the relative path `plugins`, which will
		# (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
		path = _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'nt':
		# Windows
		path = os.path.join(os.environ[u'APPDATA'].decode(
			misc.filesystem_encoding()), u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)

	return l
Пример #16
0
    def _init_pyqt(self, exp):

        global app, font_database

        # 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):
            QCoreApplication.addLibraryPath(
                safe_decode(qt_plugin_path, enc=misc.filesystem_encoding()))
        qt_plugin_path = os.path.join(os.path.dirname(sys.executable),
                                      'Library', 'lib', 'qt4', 'plugins')
        if os.path.isdir(qt_plugin_path):
            QCoreApplication.addLibraryPath(
                safe_decode(qt_plugin_path, enc=misc.filesystem_encoding()))
        # If no instance of QApplication exists, a segmentation fault seems to always
        # occur. So we create one.
        if QCoreApplication.instance() is None:
            app = QApplication([])
        # Register the fonts bundled with OpenSesame
        if font_database is None:
            font_database = QFontDatabase()
            for font in FONTS:
                try:
                    path = exp.resource(font + u'.ttf')
                except:
                    warnings.warn(u'Font %s not found' % font)
                    continue
                font_id = font_database.addApplicationFont(path)
                if font_id < 0:
                    warnings.warn(u'Failed to load font %s' % font)
                    continue
                font_families = font_database.applicationFontFamilies(font_id)
                if not font_families:
                    warnings.warn(u'Font %s contains no families' % font)
                    continue
                font_substitutions.append((font_families[0], font))
Пример #17
0
def set_paths():

    from qtpy import QtCore
    from libopensesame import misc
    # 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())
    # 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(
            safe_decode(qt_plugin_path, enc=misc.filesystem_encoding()))
    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(
            safe_decode(qt_plugin_path, enc=misc.filesystem_encoding()))
Пример #18
0
def import_plugin(plugin, _type=u'plugins'):
    """
	Imports plugin module

	Arguments:
	plugin -- the name of the plugin
	"""

    import imp
    plugin = str(plugin)
    folder = plugin_folder(plugin, _type=_type)
    for tmpl in src_templates:
        if os.path.exists(os.path.join(folder, tmpl % plugin)):
            path = os.path.join(folder, tmpl % plugin)
            if not py3:
                path = safe_encode(path, enc=misc.filesystem_encoding())
            return imp.load_source(plugin, path)
    for tmpl in bytecode_templates:
        if os.path.exists(os.path.join(folder, tmpl % plugin)):
            path = os.path.join(folder, tmpl % plugin)
            if not py3:
                path = safe_encode(path, enc=misc.filesystem_encoding())
            return imp.load_compiled(plugin, path)
Пример #19
0
def import_plugin(plugin, _type=u'plugins'):

	"""
	Imports plugin module

	Arguments:
	plugin -- the name of the plugin
	"""

	import imp
	plugin = str(plugin)
	folder = plugin_folder(plugin, _type=_type)
	for tmpl in src_templates:
		if os.path.exists(os.path.join(folder, tmpl % plugin)):
			path = os.path.join(folder, tmpl % plugin)
			if not py3:
				path = safe_encode(path, enc=misc.filesystem_encoding())
			return imp.load_source(plugin, path)
	for tmpl in bytecode_templates:
		if os.path.exists(os.path.join(folder, tmpl % plugin)):
			path = os.path.join(folder, tmpl % plugin)
			if not py3:
				path = safe_encode(path, enc=misc.filesystem_encoding())
			return imp.load_compiled(plugin, path)
Пример #20
0
    def event_startup(self):
        """
		desc:
			Called on startup.
		"""

        # Open an experiment if it has been specified as a command line argument
        # and suppress the new wizard in that case.
        if len(sys.argv) >= 2 and os.path.isfile(sys.argv[1]):
            path = safe_decode(sys.argv[1],
                               enc=misc.filesystem_encoding(),
                               errors=u'ignore')
            self.main_window.open_file(path=path)
            return
        self.activate()
Пример #21
0
	def event_startup(self):

		"""
		desc:
			Called on startup.
		"""

		# Open an experiment if it has been specified as a command line argument
		# and suppress the new wizard in that case.
		if len(sys.argv) >= 2 and os.path.isfile(sys.argv[1]):
			path = safe_decode(sys.argv[1], enc=misc.filesystem_encoding(),
				errors=u'ignore')
			self.main_window.open_file(path=path)
			return
		self.activate()
Пример #22
0
    def render(self):
        """
		desc:
			Draws the widget.
		"""

        _path = safe_str(self.path, enc=misc.filesystem_encoding())
        if not os.path.exists(_path):
            raise osexception(
                u'No valid path has been specified in image widget')
        x, y, w, h = self.rect
        x += w / 2
        y += h / 2
        self.form.canvas.image(_path, x=x, y=y, scale=self.scale, center=True)
        if self.frame:
            self.draw_frame(self.rect)
Пример #23
0
def plugin_folders(only_existing=True):

	"""
	Returns a list of plugin folders.

	Keywords arguments:
	only_existing	--	Specifies if only existing folders should be returned.
						(default=True)

	Returns:
	A list of folders.
	"""

	l = []

	# For all platforms, the plugins folder relative to the working directory
	# should be searched
	path = os.path.join(os.getcwdu(), u'plugins')
	if not only_existing or os.path.exists(path):
		l.append(path)

	if os.name == u'posix' and u'HOME' in os.environ:
		# Regular Linux distributions. TODO: How well does this apply to Mac OS?
		path = os.path.join(os.environ[u'HOME'], u'.opensesame', u'plugins')
		if not only_existing or os.path.exists(path):
			l.append(path)
		path = u'/usr/share/opensesame/plugins'
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'posix' and u'HOME' not in os.environ:
		# Android can be recognized by the fact that the HOME variable is not
		# available. We can simply use the relative path `plugins`, which will
		# (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
		path = u'plugins'
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'nt':
		# Windows
		path = os.path.join(os.environ[u'APPDATA'].decode( \
			misc.filesystem_encoding()), u'.opensesame', u'plugins')
		if not only_existing or os.path.exists(path):
			l.append(path)

	return l
Пример #24
0
def plugin_folders(only_existing=True):
    """
	Returns a list of plugin folders.
	
	Keywords arguments:
	only_existing	--	Specifies if only existing folders should be returned.
						(default=True)
	
	Returns:
	A list of folders.
	"""

    l = []

    # For all platforms, the plugins folder relative to the working directory
    # should be searched
    path = os.path.join(os.getcwdu(), u'plugins')
    if not only_existing or os.path.exists(path):
        l.append(path)

    if os.name == u'posix' and u'HOME' in os.environ:
        # Regular Linux distributions. TODO: How well does this apply to Mac OS?
        path = os.path.join(os.environ[u'HOME'], u'.opensesame', u'plugins')
        if not only_existing or os.path.exists(path):
            l.append(path)
        path = u'/usr/share/opensesame/plugins'
        if not only_existing or os.path.exists(path):
            l.append(path)

    elif os.name == u'posix' and u'HOME' not in os.environ:
        # Android can be recognized by the fact that the HOME variable is not
        # available. We can simply use the relative path `plugins`, which will
        # (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
        path = u'plugins'
        if not only_existing or os.path.exists(path):
            l.append(path)

    elif os.name == u'nt':
        # Windows
        path = os.path.join(os.environ[u'APPDATA'].decode( \
         misc.filesystem_encoding()), u'.opensesame', u'plugins')
        if not only_existing or os.path.exists(path):
            l.append(path)

    return l
Пример #25
0
	def render(self):

		"""
		desc:
			Draws the widget.
		"""

		_path = safe_str(self.path, enc=misc.filesystem_encoding())
		if not os.path.exists(_path):
			raise osexception(
				u'No valid path has been specified in image widget')
		x, y, w, h = self.rect
		x += w/2
		y += h/2
		self.form.canvas.image(_path, x=x, y=y, scale=self.scale,
			center=True)
		if self.frame:
			self.draw_frame(self.rect)
Пример #26
0
    def _init_canvas_elements(self):
        """
		desc:
			Initializes all canvas elements.
		"""

        _path = safe_str(self.path, enc=misc.filesystem_encoding())
        if not os.path.exists(_path):
            raise osexception(
                u'No valid path has been specified in image widget')
        x, y, w, h = self.rect
        x += w / 2
        y += h / 2
        print(_path)
        self.canvas.add_element(
            ImageElement(_path, x=x, y=y, scale=self.scale,
                         center=True).construct(self.canvas))
        if self.frame:
            self._update_frame(self.rect)
Пример #27
0
	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)
Пример #28
0
    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)
Пример #29
0
    def __init__(self, experiment, src, **playback_args):

        if src is not None:
            if isinstance(src, basestring):
                if not os.path.exists(src):
                    raise osexception( \
                     u"openexp._sampler.legacy.__init__() the file '%s' does not exist" \
                     % src)
                if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
                    raise osexception( \
                     u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" \
                     % src)
                # The mixer chokes on unicode pathnames that contain special
                # characters. To avoid this we convert to str with the
                # filesystem encoding. (Python 2 only).
                if not py3 and isinstance(src, str):
                    import sys
                    src = src.encode(misc.filesystem_encoding())
            self.sound = mixer.Sound(src)
        sampler.sampler.__init__(self, experiment, src, **playback_args)
        self.keyboard = keyboard(experiment)
Пример #30
0
	def __init__(self, experiment, src, **playback_args):

		if src is not None:
			if isinstance(src, basestring):
				if not os.path.exists(src):
					raise osexception( \
						u"openexp._sampler.legacy.__init__() the file '%s' does not exist" \
						% src)
				if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
					raise osexception( \
						u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" \
						% src)
				# The mixer chokes on unicode pathnames that contain special
				# characters. To avoid this we convert to str with the
				# filesystem encoding. (Python 2 only).
				if not py3 and isinstance(src, str):
					import sys
					src = src.encode(misc.filesystem_encoding())
			self.sound = mixer.Sound(src)
		sampler.sampler.__init__(self, experiment, src, **playback_args)
		self.keyboard = keyboard(experiment)
Пример #31
0
	def __init__(self, plugin_file=None):

		"""
		desc:
			Constructor.

		arguments:
			plugin_file:	The location of the plugin script file.
		"""

		if plugin_file is not None:
			# The __file__ variable is generally a str, which will cause unicode
			# errors. Therefore, convert this here if necessary.
			plugin_file = safe_decode(plugin_file,
				enc=misc.filesystem_encoding())
			# These lines makes sure that the icons and help file are recognized
			# by OpenSesame.
			self.plugin_folder = os.path.dirname(plugin_file)
			self.experiment.resources[u'%s.html' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.html' \
				% self.item_type)
			self.experiment.resources[u'%s.md' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.md' \
				% self.item_type)
			# Install a translation file if there is one. Most plugins have
			# their translations as part of the OpenSesame main translations.
			# However, separate plugins can bring their own translation.
			translation_file = os.path.join(self.plugin_folder, u'resources',
				u'locale', u'%s.qm' % self.main_window._locale)
			if os.path.exists(translation_file):
				translator = QtCore.QTranslator()
				translator.load(translation_file)
				QtCore.QCoreApplication.installTranslator(translator)
			self.init_item_icon()
		else:
			self.qicon = None
		self.lock = False
		qtitem.qtitem.__init__(self)
Пример #32
0
	def __init__(self, experiment, src):

		"""<DOC>
		Initializes the sampler with a specified file.

		Arguments:
		experiment -- An instance of libopensesame.experiment.experiment.
		src -- A path to a .wav or .ogg file.

		Example:
		>>> from openexp.sampler import sampler
		>>> src = exp.get_file('my_sound.ogg')
		>>> my_sampler = sampler(exp, src)
		</DOC>"""

		if src != None:
			if not os.path.exists(src):
				raise osexception( \
					u"openexp._sampler.legacy.__init__() the file '%s' does not exist" \
					% src)
			if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
				raise osexception( \
					u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" \
					% src)
			# The mixer chokes on unicode pathnames that contain special
			# characters. To avoid this we convert to str with the filesystem
			# encoding.
			if isinstance(src, unicode):
				import sys
				src = src.encode(misc.filesystem_encoding())
			self.sound = mixer.Sound(src)

		self.experiment = experiment
		self.keyboard = keyboard(experiment)
		self._stop_after = 0
		self._fade_in = 0
		self._volume = 1.0
Пример #33
0
    def __init__(self, experiment, src):

        if src != None:
            if isinstance(src, basestring):
                if not os.path.exists(src):
                    raise osexception( \
                     u"openexp._sampler.legacy.__init__() the file '%s' does not exist" \
                     % src)
                if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
                    raise osexception( \
                     u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" \
                     % src)
                # The mixer chokes on unicode pathnames that contain special
                # characters. To avoid this we convert to str with the filesystem
                # encoding.
                if isinstance(src, unicode):
                    import sys
                    src = src.encode(misc.filesystem_encoding())
            self.sound = mixer.Sound(src)
        self.experiment = experiment
        self.keyboard = keyboard(experiment)
        self._stop_after = 0
        self._fade_in = 0
        self._volume = 1.0
Пример #34
0
	def __init__(self, plugin_file=None):

		"""
		Constructor.

		Arguments:
		plugin_file		-- The path to the plugin script. (default=None)
		"""

		if plugin_file is not None:
			# The __file__ variable is generally a str, which will cause unicode
			# errors. Therefore, convert this here if necessary.
			plugin_file = safe_decode(plugin_file,
				enc=misc.filesystem_encoding())
			# These lines makes sure that the icons and help file are recognized
			# by OpenSesame.
			self.plugin_folder = os.path.dirname(plugin_file)
			icon16 = os.path.join(
				self.plugin_folder, u'%s.png' % self.item_type)
			icon32 = os.path.join(
				self.plugin_folder, u'%s_large.png' % self.item_type)
			self.experiment.resources[u'%s.png' % self.item_type] = icon16
			self.experiment.resources[u'%s_large.png' % self.item_type] = icon32
			self.experiment.resources[u'%s.html' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.html' \
				% self.item_type)
			self.experiment.resources[u'%s.md' % self.item_type] = \
				os.path.join(self.plugin_folder, u'%s.md' \
				% self.item_type)
			self.qicon = QtGui.QIcon()
			self.qicon.addFile(icon16, QtCore.QSize(16,16))
			self.qicon.addFile(icon32, QtCore.QSize(32,32))
		else:
			self.qicon = None
		self.lock = False
		qtitem.qtitem.__init__(self)
Пример #35
0
    def __init__(self, plugin_file=None):
        """
		Constructor.

		Arguments:
		plugin_file		-- The path to the plugin script. (default=None)
		"""

        if plugin_file is not None:
            # The __file__ variable is generally a str, which will cause unicode
            # errors. Therefore, convert this here if necessary.
            plugin_file = safe_decode(plugin_file,
                                      enc=misc.filesystem_encoding())
            # These lines makes sure that the icons and help file are recognized
            # by OpenSesame.
            self.plugin_folder = os.path.dirname(plugin_file)
            icon16 = os.path.join(self.plugin_folder,
                                  u'%s.png' % self.item_type)
            icon32 = os.path.join(self.plugin_folder,
                                  u'%s_large.png' % self.item_type)
            self.experiment.resources[u'%s.png' % self.item_type] = icon16
            self.experiment.resources[u'%s_large.png' %
                                      self.item_type] = icon32
            self.experiment.resources[u'%s.html' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s.html' \
             % self.item_type)
            self.experiment.resources[u'%s.md' % self.item_type] = \
             os.path.join(self.plugin_folder, u'%s.md' \
             % self.item_type)
            self.qicon = QtGui.QIcon()
            self.qicon.addFile(icon16, QtCore.QSize(16, 16))
            self.qicon.addFile(icon32, QtCore.QSize(32, 32))
        else:
            self.qicon = None
        self.lock = False
        qtitem.qtitem.__init__(self)
Пример #36
0
	def __init__(self, experiment, src):

		if src != None:
			if isinstance(src, basestring):
				if not os.path.exists(src):
					raise osexception( \
						u"openexp._sampler.legacy.__init__() the file '%s' does not exist" \
						% src)
				if os.path.splitext(src)[1].lower() not in (".ogg", ".wav"):
					raise osexception( \
						u"openexp._sampler.legacy.__init__() the file '%s' is not an .ogg or .wav file" \
						% src)
				# The mixer chokes on unicode pathnames that contain special
				# characters. To avoid this we convert to str with the filesystem
				# encoding.
				if isinstance(src, unicode):
					import sys
					src = src.encode(misc.filesystem_encoding())
			self.sound = mixer.Sound(src)
		self.experiment = experiment
		self.keyboard = keyboard(experiment)
		self._stop_after = 0
		self._fade_in = 0
		self._volume = 1.0
Пример #37
0
"""

from libopensesame import item, generic_response, exceptions, debug, misc
from libqtopensesame import qtplugin
from libqtopensesame.misc import _
from openexp.keyboard import keyboard
import imp
import os
import os.path
from PyQt4 import QtGui, QtCore, uic

# First try to load libboks from source, from the plug-in folder. If this fails,
# try a plain import statement.
try:
	libboks = imp.load_source(u'libboks', os.path.join(os.path.dirname( \
		__file__).decode(misc.filesystem_encoding()), u'libboks.py'))
except:
	import libboks

class boks(item.item, generic_response.generic_response):

	"""A plug-in for using the Boks"""
	
	description = u'Collects input from a boks'
	
	def __init__(self, name, experiment, script=None):

		"""
		Constructor.

		Arguments:
Пример #38
0
    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')
Пример #39
0
    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')
Пример #40
0
	def open(self, src):

		"""
		desc: |
			Opens a file from a source, which can be any of the following:

			- A definition string
			- The name of a plain-text file
			- The name of a .tar.gz archive, which contains the script and the
			  file pool.

		arguments:
			src:	The source.

		returns:
			desc:	A defition string.
			type:	str
		"""

		# If the path is not a path at all, but a string containing
		# the script, return it. Also, convert the path back to Unicode before
		# returning.
		if not os.path.exists(src):
			debug.msg(u'opening from unicode string')
			self.experiment_path = None
			return safe_decode(src, errors=u'replace')
		try:
			tar = tarfile.open(src, u'r:gz')
		except tarfile.ReadError:
			# If the file wasn't a .tar.gz, then it must be a plain-text file
			debug.msg(u"opening plain-text experiment")
			with open(src, universal_newline_mode) as fd:
				return safe_decode(fd.read())
		debug.msg(u"opening .tar.gz archive")
		# If the file is a .tar.gz archive, extract the pool to the pool folder
		# and return the contents of opensesame.script.
		tar = tarfile.open(src, u'r:gz')
		for name in tar.getnames():
			# Here, all paths except name are Unicode. In addition, fname is
			# Unicode from_asciid, because the files as saved are Unicode
			# sanitized (see save()).
			uname = safe_decode(name)
			folder, fname = os.path.split(uname)
			fname = self._syntax.from_ascii(fname)
			if folder == u"pool":
				# NOTE: When merging into `ising`, this needs to be ported to
				# the py3compat system, and Python 3 compatibility needs to be
				# checked.
				debug.msg(u"extracting '%s'" % uname)
				pool_folder = safe_str(self.pool.folder(),
					enc=misc.filesystem_encoding())
				from_name = safe_str(os.path.join(self.pool.folder(), uname),
					enc=misc.filesystem_encoding())
				to_name = safe_str(os.path.join(self.pool.folder(), fname),
					enc=misc.filesystem_encoding())
				tar.extract(name, pool_folder)
				os.rename(from_name, to_name)
				os.rmdir(os.path.join(self.pool.folder(), folder))
		script_path = os.path.join(self.pool.folder(), u"script.opensesame")
		tar.extract(u"script.opensesame", self.pool.folder())
		with open(script_path, universal_newline_mode) as fd:
			script = safe_decode(fd.read())
		os.remove(script_path)
		self.experiment_path = os.path.dirname(src)
		return script
Пример #41
0
	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')
Пример #42
0
    def open(self, src):
        """
		desc: |
			Opens a file from a source, which can be any of the following:

			- A definition string
			- The name of a plain-text file
			- The name of a .tar.gz archive, which contains the script and the
			  file pool.

		arguments:
			src:	The source.

		returns:
			desc:	A defition string.
			type:	str
		"""

        # If the path is not a path at all, but a string containing
        # the script, return it. Also, convert the path back to Unicode before
        # returning.
        if not os.path.exists(src):
            debug.msg(u'opening from unicode string')
            self.experiment_path = None
            return safe_decode(src, errors=u'replace')
        try:
            tar = tarfile.open(src, u'r:gz')
        except tarfile.ReadError:
            # If the file wasn't a .tar.gz, then it must be a plain-text file
            debug.msg(u"opening plain-text experiment")
            with open(src, universal_newline_mode) as fd:
                return safe_decode(fd.read())
        debug.msg(u"opening .tar.gz archive")
        # If the file is a .tar.gz archive, extract the pool to the pool folder
        # and return the contents of opensesame.script.
        tar = tarfile.open(src, u'r:gz')
        for name in tar.getnames():
            # Here, all paths except name are Unicode. In addition, fname is
            # Unicode from_asciid, because the files as saved are Unicode
            # sanitized (see save()).
            uname = safe_decode(name)
            folder, fname = os.path.split(uname)
            fname = self._syntax.from_ascii(fname)
            if folder == u"pool":
                # NOTE: When merging into `ising`, this needs to be ported to
                # the py3compat system, and Python 3 compatibility needs to be
                # checked.
                debug.msg(u"extracting '%s'" % uname)
                pool_folder = safe_str(self.pool.folder(),
                                       enc=misc.filesystem_encoding())
                from_name = safe_str(os.path.join(self.pool.folder(), uname),
                                     enc=misc.filesystem_encoding())
                to_name = safe_str(os.path.join(self.pool.folder(), fname),
                                   enc=misc.filesystem_encoding())
                tar.extract(name, pool_folder)
                os.rename(from_name, to_name)
                os.rmdir(os.path.join(self.pool.folder(), folder))
        script_path = os.path.join(self.pool.folder(), u"script.opensesame")
        tar.extract(u"script.opensesame", self.pool.folder())
        with open(script_path, universal_newline_mode) as fd:
            script = safe_decode(fd.read())
        os.remove(script_path)
        self.experiment_path = os.path.dirname(src)
        return script
Пример #43
0
	def __init__(self, name=u'experiment', string=None, pool_folder=None,
		experiment_path=None, fullscreen=False, auto_response=False,
		logfile=u'defaultlog.csv', subject_nr=0, items=None, workspace=None,
		resources={}):

		"""
		desc:
			Constructor. The experiment is created automatically be OpenSesame
			and you will generally not need to create it yourself.

		keywords:
			name:
				desc:	The name of the experiment.
				type:	[str, unicode]
			string:
				desc:	A string containing the experiment definition, the
						name of an OpenSesame experiment file, or `None` to
						create a blank experiment.
				type:	[str, unicode, NoneType]
			pool_folder:
				desc:	A specific folder to be used for the file pool, or
						`None` to use a new temporary folder.
				type:	[str, unicode, NoneType]
			experiment_path:
				desc:	The path of the experiment file. This will need to
						be specified even if a filename was passed using the
						`string` keyword.
				type:	[str, unicode, NoneType]
			fullscreen:
				desc:	Indicates whether the experiment should be executed in
						fullscreen.
				type:	bool
			auto_response:
				desc:	Indicates whether auto-response mode should be enabled.
				type:	bool
			logfile:
				desc:	The logfile path.
				type:	[unicode, str]
			subject_nr:
				desc:	The subject number.
				type:	int
			items:
				desc:	An `item_store` object to be used for storing items
						internally, or `None` to create a new item store.
				type:	[item_store, NoneType]
			workspace:
				desc:	A `python_workspace` object to be used for executing
						custom Python code, or `None` to create a new workspace.
				type:	[python_workspace, NoneType]
			resources:
				desc:	A dictionary with names as keys and paths as values.
						This serves as a look-up table for resources.
				type:	dict
		"""

		global pool_folders

		if items == None:
			self.items = item_store(self)
		else:
			self.items = items
		if workspace == None:
			self.python_workspace = python_workspace(self)
		else:
			self.python_workspace = workspace
		self.running = False
		self.auto_response = auto_response
		self.plugin_folder = u'plugins'
		self.start_response_interval = None
		self.cleanup_functions = []
		self.restart = False
		self.title = u'My Experiment'
		self.transparent_variables = u'no'
		self.bidi = u'no'
		self.resources = resources

		# Set default variables
		self.start = u'experiment'

		# Sound parameters
		self.sound_freq = 48000
		self.sound_sample_size = -16 # Negative values mean signed
		self.sound_channels = 2
		self.sound_buf_size = 1024

		# Backend parameters
		self.canvas_backend = u'xpyriment'
		self.keyboard_backend = u'legacy'
		self.mouse_backend = u'xpyriment'
		self.sampler_backend = u'legacy'
		self.synth_backend = u'legacy'

		# Save the date and time, and the version of OpenSesame
		self.datetime = time.strftime(u'%c').decode(self.encoding, u'ignore')
		self.opensesame_version = misc.version
		self.opensesame_codename = misc.codename

		# Display parameters
		self.width = 1024
		self.height = 768
		self.background = u'black'
		self.foreground = u'white'
		self.fullscreen = fullscreen

		# Font parameters
		self.font_size = 18
		self.font_family = u'mono'
		self.font_italic = u'no'
		self.font_bold = u'no'
		self.font_underline = u'no'

		# Logfile parameters
		self._log = None
		self.logfile = logfile

		# This is some duplication of the option parser in qtopensesame,
		# but nevertheless keep it so we don't need qtopensesame
		self.debug = debug.enabled
		self._stack = debug.stack

		# Pool folder
		if pool_folder == None:
			# On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
			# This is resolved by passing the dir explicitly as a Unicode
			# string. This fix has been adapted from:
			# - <http://bugs.python.org/issue1681974>
			self.pool_folder = tempfile.mkdtemp(suffix= \
				u'.opensesame_pool', dir=tempfile.gettempdir().decode( \
				encoding=misc.filesystem_encoding()))
			pool_folders.append(self.pool_folder)
			debug.msg(u'creating new pool folder')
		else:
			debug.msg(u'reusing existing pool folder')
			self.pool_folder = pool_folder
		debug.msg(u'pool folder is \'%s\'' % self.pool_folder)

		string = self.open(string)
		item.item.__init__(self, name, self, string)

		# Default subject info
		self.set_subject(subject_nr)
		# Restore experiment path
		if experiment_path != None:
			self.fallback_pool_folder = os.path.join(experiment_path,
				u'__pool__')
			if os.path.exists(self.fallback_pool_folder):
				debug.msg(u'Using fallback pool folder: %s' \
					% self.fallback_pool_folder)
			else:
				self.fallback_pool_folder = None
			self.experiment_path = experiment_path
		else:
			self.fallback_pool_folder = None
Пример #44
0
def plugin_folders(only_existing=True, _type=u'plugins'):

	"""
	desc:
		Returns a list of plugin folders.

	keywords:
		only_existing:
			desc:	Specifies if only existing folders should be returned.
			type:	bool
		_type:
			desc:	Indicates whether runtime plugins ('plugins') or GUI
					extensions ('extensions') should be listed.
			type:	[str, unicode]

	returns:
		desc:	A list of folders.
		type:	list
	"""

	l = []

	# Build a list of default plugin/ extension folders
	for folder in misc.base_folders:
		path = os.path.join(folder, u'opensesame_%s' % _type)
		if os.path.exists(path):
			l.append(path)

	# Get the environment variables
	if _type == u'plugins':
		key = u'OPENSESAME_PLUGIN_PATH'
	else:
		key = u'OPENSESAME_EXTENSION_PATH'
	if key in os.environ:
		for path in os.environ[key].split(';'):
			path = safe_decode(path, enc=misc.filesystem_encoding())
			if os.path.exists(path):
				l.append(path)

	if os.name == u'posix' and u'HOME' in os.environ:
		# Regular Linux distributions. TODO: How well does this apply to Mac OS?
		path = os.path.join(os.environ[u'HOME'], u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)
		path = u'/usr/share/opensesame/%s' % _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'posix' and u'HOME' not in os.environ:
		# Android can be recognized by the fact that the HOME variable is not
		# available. We can simply use the relative path `plugins`, which will
		# (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
		path = _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'nt':
		# Windows
		path = os.path.join(safe_decode(os.environ[u'APPDATA'],
			enc=misc.filesystem_encoding()), u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)

	return l
Пример #45
0
def plugin_folders(only_existing=True, _type=u'plugins'):

	"""
	desc:
		Returns a list of plugin folders.

	keywords:
		only_existing:
			desc:	Specifies if only existing folders should be returned.
			type:	bool
		_type:
			desc:	Indicates whether runtime plugins ('plugins') or GUI
					extensions ('extensions') should be listed.
			type:	[str, unicode]

	returns:
		desc:	A list of folders.
		type:	list
	"""

	l = []

	# Build a list of default plugin/ extension folders
	for folder in misc.base_folders:
		path = os.path.join(folder, u'opensesame_%s' % _type)
		if os.path.exists(path):
			l.append(path)

	# Get the environment variables
	if _type == u'plugins':
		key = u'OPENSESAME_PLUGIN_PATH'
	else:
		key = u'OPENSESAME_EXTENSION_PATH'
	if key in os.environ:
		for path in os.environ[key].split(';'):
			path = safe_decode(path, enc=misc.filesystem_encoding())
			if os.path.exists(path):
				l.insert(0, path)

	if os.name == u'posix' and u'HOME' in os.environ:
		# Regular Linux distributions. TODO: How well does this apply to Mac OS?
		path = os.path.join(os.environ[u'HOME'], u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)
		path = u'/usr/share/opensesame/%s' % _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'posix' and u'HOME' not in os.environ:
		# Android can be recognized by the fact that the HOME variable is not
		# available. We can simply use the relative path `plugins`, which will
		# (always?) point to `/data/data/nl.cogsci.nl/opensesame/files/plugins`
		path = _type
		if not only_existing or os.path.exists(path):
			l.append(path)

	elif os.name == u'nt':
		# Windows
		path = os.path.join(safe_decode(os.environ[u'APPDATA'],
			enc=misc.filesystem_encoding()), u'.opensesame', _type)
		if not only_existing or os.path.exists(path):
			l.append(path)

	return l
=======
>>>>>>> 61437b7728a64a89e660f1dc0b55af5677e65dfe
		# This is some duplication of the option parser in qtopensesame,
		# but nevertheless keep it so we don't need qtopensesame
		self.debug = debug.enabled
		self._stack = debug.stack

		# Pool folder
		if pool_folder == None:
			# On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
			# This is resolved by passing the dir explicitly as a Unicode
			# string. This fix has been adapted from:
			# - <http://bugs.python.org/issue1681974>
			self.pool_folder = tempfile.mkdtemp(suffix= \
				u'.opensesame_pool', dir=tempfile.gettempdir().decode( \
				encoding=misc.filesystem_encoding()))
			pool_folders.append(self.pool_folder)
			debug.msg(u'creating new pool folder')
		else:
			debug.msg(u'reusing existing pool folder')
			self.pool_folder = pool_folder
		debug.msg(u'pool folder is \'%s\'' % self.pool_folder)

		string = self.open(string)
		item.item.__init__(self, name, self, string)
		
		# Default subject info
		self.set_subject(subject_nr)
		# Restore experiment path
		if experiment_path != None:
			self.experiment_path = experiment_path
Пример #47
0
	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')
Пример #48
0
    def __init__(self,
                 name=u'experiment',
                 string=None,
                 pool_folder=None,
                 experiment_path=None,
                 fullscreen=False,
                 auto_response=False,
                 logfile=u'defaultlog.csv',
                 subject_nr=0,
                 items=None,
                 workspace=None,
                 resources={}):
        """
		desc:
			Constructor. The experiment is created automatically be OpenSesame
			and you will generally not need to create it yourself.

		keywords:
			name:
				desc:	The name of the experiment.
				type:	[str, unicode]
			string:
				desc:	A string containing the experiment definition, the
						name of an OpenSesame experiment file, or `None` to
						create a blank experiment.
				type:	[str, unicode, NoneType]
			pool_folder:
				desc:	A specific folder to be used for the file pool, or
						`None` to use a new temporary folder.
				type:	[str, unicode, NoneType]
			experiment_path:
				desc:	The path of the experiment file. This will need to
						be specified even if a filename was passed using the
						`string` keyword.
				type:	[str, unicode, NoneType]
			fullscreen:
				desc:	Indicates whether the experiment should be executed in
						fullscreen.
				type:	bool
			auto_response:
				desc:	Indicates whether auto-response mode should be enabled.
				type:	bool
			logfile:
				desc:	The logfile path.
				type:	[unicode, str]
			subject_nr:
				desc:	The subject number.
				type:	int
			items:
				desc:	An `item_store` object to be used for storing items
						internally, or `None` to create a new item store.
				type:	[item_store, NoneType]
			workspace:
				desc:	A `python_workspace` object to be used for executing
						custom Python code, or `None` to create a new workspace.
				type:	[python_workspace, NoneType]
			resources:
				desc:	A dictionary with names as keys and paths as values.
						This serves as a look-up table for resources.
				type:	dict
		"""

        global pool_folders

        if items == None:
            self.items = item_store(self)
        else:
            self.items = items
        if workspace == None:
            self.python_workspace = python_workspace(self)
        else:
            self.python_workspace = workspace
        self.running = False
        self.auto_response = auto_response
        self.plugin_folder = u'plugins'
        self.start_response_interval = None
        self.cleanup_functions = []
        self.restart = False
        self.title = u'My Experiment'
        self.transparent_variables = u'no'
        self.bidi = u'no'
        self.resources = resources

        # Set default variables
        self.start = u'experiment'

        # Sound parameters
        self.sound_freq = 48000
        self.sound_sample_size = -16  # Negative values mean signed
        self.sound_channels = 2
        self.sound_buf_size = 1024

        # Backend parameters
        self.canvas_backend = u'xpyriment'
        self.keyboard_backend = u'legacy'
        self.mouse_backend = u'xpyriment'
        self.sampler_backend = u'legacy'
        self.synth_backend = u'legacy'

        # Save the date and time, and the version of OpenSesame
        self.datetime = time.strftime(u'%c').decode(self.encoding, u'ignore')
        self.opensesame_version = misc.version
        self.opensesame_codename = misc.codename

        # Display parameters
        self.width = 1024
        self.height = 768
        self.background = u'black'
        self.foreground = u'white'
        self.fullscreen = fullscreen

        # Font parameters
        self.font_size = 18
        self.font_family = u'mono'
        self.font_italic = u'no'
        self.font_bold = u'no'
        self.font_underline = u'no'

        # Logfile parameters
        self._log = None
        self.logfile = logfile

        # This is some duplication of the option parser in qtopensesame,
        # but nevertheless keep it so we don't need qtopensesame
        self.debug = debug.enabled
        self._stack = debug.stack

        # Pool folder
        if pool_folder == None:
            # On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
            # This is resolved by passing the dir explicitly as a Unicode
            # string. This fix has been adapted from:
            # - <http://bugs.python.org/issue1681974>
            self.pool_folder = tempfile.mkdtemp(suffix= \
             u'.opensesame_pool', dir=tempfile.gettempdir().decode( \
             encoding=misc.filesystem_encoding()))
            pool_folders.append(self.pool_folder)
            debug.msg(u'creating new pool folder')
        else:
            debug.msg(u'reusing existing pool folder')
            self.pool_folder = pool_folder
        debug.msg(u'pool folder is \'%s\'' % self.pool_folder)

        string = self.open(string)
        item.item.__init__(self, name, self, string)

        # Default subject info
        self.set_subject(subject_nr)
        # Restore experiment path
        if experiment_path != None:
            self.fallback_pool_folder = os.path.join(experiment_path,
                                                     u'__pool__')
            if os.path.exists(self.fallback_pool_folder):
                debug.msg(u'Using fallback pool folder: %s' \
                 % self.fallback_pool_folder)
            else:
                self.fallback_pool_folder = None
            self.experiment_path = experiment_path
        else:
            self.fallback_pool_folder = None
Пример #49
0
	def __init__(self, name=u'experiment', string=None, pool_folder=None, experiment_path=None, fullscreen=False, auto_response=False, logfile=u'defaultlog.csv', subject_nr=0):

		"""<DOC>
		Constructor. The experiment is created automatically be OpenSesame and #
		you will generally not need to create it yourself.

		Keyword arguments:
		name 			--	The name of the experiment. (default=u'experiment')
		string 			--	A string containing the experiment definition. #
							(default=None)
		pool_folder		--	A specific folder to be used for the file pool. #
							(default=None)
		experiment_path	--	The path of the experiment file. (default=None)
		fullscreen		--	Indicates whether the experiment should be #
							executed in fullscreen. (default=False)
		auto_response	--	Indicates whether auto-response mode should be #
							enabled. (default=False)
		logfile			--	The logfile path. (default=u'defaultlog.csv')
		subject_nr		--	The subject number. (default=0)
		</DOC>"""

		global pool_folders

		self.items = {}
		self.running = False
		self.auto_response = auto_response
		self.plugin_folder = u'plugins'
		self.start_response_interval = None
		self.cleanup_functions = []
		self.restart = False
		self.title = u'My Experiment'
		self.transparent_variables = u'no'
		self.bidi = u'no'

		# Set default variables
		self.start = u'experiment'

		# Sound parameters
		self.sound_freq = 48000
		self.sound_sample_size = -16 # Negative values mean signed
		self.sound_channels = 2
		self.sound_buf_size = 512
		self.resources = {}

		# Backend parameters
		self.canvas_backend = u'xpyriment'
		self.keyboard_backend = u'legacy'
		self.mouse_backend = u'xpyriment'
		self.sampler_backend = u'legacy'
		self.synth_backend = u'legacy'

		# Save the date and time, and the version of OpenSesame
		self.datetime = time.strftime(u'%c').decode(self.encoding, u'ignore')
		self.opensesame_version = misc.version
		self.opensesame_codename = misc.codename

		# Display parameters
		self.width = 1024
		self.height = 768
		self.background = u'black'
		self.foreground = u'white'
		self.fullscreen = fullscreen

		# Font parameters
		self.font_size = 18
		self.font_family = u'mono'
		self.font_italic = u'no'
		self.font_bold = u'no'
		self.font_underline = u'no'

		# Logfile parameters
		self._log = None
		self.logfile = logfile

		# This is some duplication of the option parser in qtopensesame,
		# but nevertheless keep it so we don't need qtopensesame
		self.debug = debug.enabled
		self._stack = debug.stack

		# Pool folder
		if pool_folder == None:
			# On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
			# This is resolved by passing the dir explicitly as a Unicode
			# string. This fix has been adapted from:
			# - <http://bugs.python.org/issue1681974>
			self.pool_folder = tempfile.mkdtemp(suffix= \
				u'.opensesame_pool', dir=tempfile.gettempdir().decode( \
				encoding=misc.filesystem_encoding()))
			pool_folders.append(self.pool_folder)
			debug.msg(u'creating new pool folder')
		else:
			debug.msg(u'reusing existing pool folder')
			self.pool_folder = pool_folder
		debug.msg(u'pool folder is \'%s\'' % self.pool_folder)

		string = self.open(string)
		item.item.__init__(self, name, self, string)

		# Default subject info
		self.set_subject(subject_nr)
		# Restore experiment path
		if experiment_path != None:
			self.experiment_path = experiment_path
Пример #50
0
    def __init__(self, name=u'experiment', string=None, pool_folder=None):
        """<DOC>
		Constructor. The experiment is created automatically be OpenSesame and #
		you will generally not need to create it yourself.

		Keyword arguments:
		name 		--	The name of the experiment. (default='experiment')
		string 		--	A string containing the experiment definition. #
						(default=None)
		pool_folder	--	A specific folder to be used for the file pool. #
						(default=None)
		</DOC>"""

        global pool_folders

        self.items = {}
        self.running = False
        self.auto_response = False
        self.plugin_folder = u'plugins'
        self.start_response_interval = None
        self.cleanup_functions = []
        self.restart = False
        self.experiment_path = None
        self.title = u'My Experiment'
        self.transparent_variables = u'no'

        # Set default variables
        self.coordinates = u'relative'  # DEPRECATED
        self.compensation = 0  # DEPRECATED
        self.start = u'experiment'

        # Sound parameters
        self.sound_freq = 48000
        self.sound_sample_size = -16  # Negative values mean signed
        self.sound_channels = 2
        self.sound_buf_size = 512
        self.resources = {}

        # Backend parameters
        self.canvas_backend = u'xpyriment'
        self.keyboard_backend = u'legacy'
        self.mouse_backend = u'xpyriment'
        self.sampler_backend = u'legacy'
        self.synth_backend = u'legacy'

        # Display parameters
        self.width = 1024
        self.height = 768
        self.background = u'black'
        self.foreground = u'white'
        self.fullscreen = False

        # Font parameters
        self.font_size = 18
        self.font_family = u'mono'
        self.font_italic = u'no'
        self.font_bold = u'no'
        self.font_underline = u'no'

        # Logfile parameters
        self._log = None
        self.logfile = None

        # This is a dummy variable for backwards compatibility. The logfile
        # encoding is always utf-8, and this variable doesn't do anything.
        self.logfile_codec = u'utf-8'  # DEPRECATED

        # Default subject info
        self.subject_nr = 0
        self.subject_parity = u'even'

        # This is some duplication of the option parser in qtopensesame,
        # but nevertheless keep it so we don't need qtopensesame
        self.debug = debug.enabled
        self._stack = debug.stack

        # Pool folder
        if pool_folder == None:
            # On some systems tempfile.mkdtemp() triggers a UnicodeDecodeError.
            # This is resolved by passing the dir explicitly as a Unicode
            # string. This fix has been adapted from:
            # - <http://bugs.python.org/issue1681974>
            self.pool_folder = tempfile.mkdtemp(suffix= \
             u'.opensesame_pool', dir=tempfile.gettempdir().decode( \
             encoding=misc.filesystem_encoding()))
            pool_folders.append(self.pool_folder)
            debug.msg(u'creating new pool folder')
        else:
            debug.msg(u'reusing existing pool folder')
            self.pool_folder = pool_folder
        debug.msg(u'pool folder is \'%s\'' % self.pool_folder)

        string = self.open(string)
        item.item.__init__(self, name, self, string)
Пример #51
0
	def get_logfile(self, quick=False, subject_nr=0):

		"""
		Gets the logfile for the current session, either by falling back to a
		default value ('quickrun.csv') or through a pop-up dialogue.

		Keyword arguments:
		quick		--	Indicates whether we are quickrunning the experiment.
						(default=False)
		subject_nr	--	Indicates the subject number, which is used to
						suggest a logfile. (default=0)

		Returns:
		A pathname for the logfile or None if no logfile was chosen (i.e. the
		dialogue was cancelled).
		"""

		remember_logfile = True
		if quick:
			logfile = os.path.join(cfg.default_logfile_folder,
				cfg.quick_run_logfile)
			try:
				open(logfile, u'w').close()
			except:
				import tempfile
				from libopensesame import misc
				debug.msg(u'Failed to open %s' % logfile)
				logfile = os.path.join(safe_decode(tempfile.gettempdir(),
					enc=misc.filesystem_encoding()), safe_decode(
					tempfile.gettempprefix(),
					enc=misc.filesystem_encoding())+u'quickrun.csv')
				debug.msg(u'Using temporary file %s' % logfile)
				remember_logfile = False
		else:
			# Suggested filename
			suggested_path = os.path.join(cfg.default_logfile_folder,
				u'subject-%d.csv' % subject_nr)
			# Get the data file
			csv_filter = u'Comma-separated values (*.csv)'
			logfile = QtWidgets.QFileDialog.getSaveFileName( \
				self.main_window.ui.centralwidget, \
				_(u"Choose location for logfile (press 'escape' for default location)"), \
				suggested_path, filter=csv_filter)
			# In PyQt5, the QFileDialog.getOpenFileName returns a tuple instead of
			# a string, of which the first position contains the path.
			if isinstance(logfile,tuple):
				logfile = logfile[0]
			# An empty string indicates that the dialogue was cancelled, in
			# which case we fall back to a default location.
			if logfile == u'':
				logfile = os.path.join(cfg.default_logfile_folder,
					u'defaultlog.csv')
			# If a logfile was provided, but it did not have a proper extension,
			# we add a `.csv` extension.
			else:
				if os.path.splitext(logfile)[1].lower() not in \
					self.valid_logfile_extensions:
					logfile += self.default_logfile_extension
		# If the logfile is not writable, inform the user and cancel.
		try:
			open(logfile, u'w').close()
		except:
			self.main_window.experiment.notify( \
				_(u"The logfile '%s' is not writable. Please choose another location for the logfile.") \
				% logfile)
			return None
		if remember_logfile:
			# Remember the logfile folder for the next run
			cfg.default_logfile_folder = os.path.dirname(logfile)
		return logfile
Пример #52
0
    def get_logfile(self, quick=False, subject_nr=0):

        """
		Gets the logfile for the current session, either by falling back to a
		default value ('quickrun.csv') or through a pop-up dialogue.

		Keyword arguments:
		quick		--	Indicates whether we are quickrunning the experiment.
						(default=False)
		subject_nr	--	Indicates the subject number, which is used to
						suggest a logfile. (default=0)

		Returns:
		A pathname for the logfile or None if no logfile was chosen (i.e. the
		dialogue was cancelled).
		"""

        remember_logfile = True
        if quick:
            logfile = os.path.join(
                config.get_config(u"default_logfile_folder"), config.get_config(u"quick_run_logfile")
            )
            try:
                open(logfile, u"w").close()
            except:
                import tempfile
                from libopensesame import misc

                debug.msg(u"Failed to open %s" % logfile)
                logfile = os.path.join(
                    tempfile.gettempdir().decode(misc.filesystem_encoding()),
                    tempfile.gettempprefix().decode(misc.filesystem_encoding()) + u"quickrun.csv",
                )
                debug.msg(u"Using temporary file %s" % logfile)
                remember_logfile = False
        else:
            # Suggested filename
            suggested_path = os.path.join(config.get_config(u"default_logfile_folder"), u"subject-%d.csv" % subject_nr)
            # Get the data file
            csv_filter = u"Comma-separated values (*.csv)"
            logfile = unicode(
                QtGui.QFileDialog.getSaveFileName(
                    self.main_window.ui.centralwidget,
                    _(u"Choose location for logfile (press 'escape' for default location)"),
                    suggested_path,
                    filter=csv_filter,
                )
            )
            # An empty string indicates that the dialogue was cancelled, in
            # which case we fall back to a default location.
            if logfile == u"":
                logfile = os.path.join(config.get_config("default_logfile_folder"), u"defaultlog.csv")
                # If a logfile was provided, but it did not have a proper extension,
                # we add a `.csv` extension.
            else:
                if os.path.splitext(logfile)[1].lower() not in self.valid_logfile_extensions:
                    logfile += self.default_logfile_extension
                    # If the logfile is not writable, inform the user and cancel.
        try:
            open(logfile, u"w").close()
        except:
            self.main_window.experiment.notify(
                _(u"The logfile '%s' is not writable. Please choose another location for the logfile.") % logfile
            )
            return None
        if remember_logfile:
            # Remember the logfile folder for the next run
            config.set_config("default_logfile_folder", os.path.dirname(logfile))
        return logfile