Beispiel #1
0
    def fetchPsychoPy(self, v='latest'):
        msg = _translate("Attempting to fetch PsychoPy %s...")
        self.statusMessage.SetLabel(msg % self.latest['version'])
        info = ""
        if v == 'latest':
            v = self.latest['version']

        # open page
        URL = "https://github.com/psychopy/psychopy/releases/download/%s/PsychoPy-%s.zip"
        page = urllib.request.urlopen(URL % v)
        # download in chunks so that we can monitor progress and abort mid-way
        chunk = 4096
        read = 0
        fileSize = int(page.info()['Content-Length'])
        buffer = io.StringIO()
        self.progressBar.SetRange(fileSize)
        while read < fileSize:
            ch = page.read(chunk)
            buffer.write(ch)
            read += chunk
            self.progressBar.SetValue(read)
            txt = _translate(
                "Fetched %(done)i of %(total)i kb of PsychoPy-%(version)s.zip")
            msg = txt % {'done': read // 1000,
                         'total': fileSize // 1000, 'version': v}
            self.statusMessage.SetLabel(msg)
            self.Update()
        info += _translate('Successfully downloaded PsychoPy-%s.zip') % v
        page.close()
        zfile = zipfile.ZipFile(buffer)
        # buffer.close()
        return zfile, info
Beispiel #2
0
 def check(self, parent):
     """checks namespace, return error-msg (str), enable (bool)
     """
     control = self.GetWindow()
     newName = control.GetValue()
     msg, OK = '', True  # until we find otherwise
     if newName == '':
         msg = _translate("Missing name")
         OK = False
     else:
         namespace = parent.frame.exp.namespace
         used = namespace.exists(newName)
         sameAsOldName = bool(newName == parent.params['name'].val)
         if used and not sameAsOldName:
             msg = _translate("That name is in use (by %s). Try another name.") % used
             OK = False
         elif not namespace.isValid(newName):  # valid as a var name
             msg = _translate("Name must be alpha-numeric or _, no spaces")
             OK = False
         # warn but allow, chances are good that its actually ok
         elif namespace.isPossiblyDerivable(newName):
             msg = _translate(namespace.isPossiblyDerivable(newName))
             OK = True
     parent.warningsDict['name'] = msg
     return msg, OK
Beispiel #3
0
    def __init__(self, parent, ID, app):
        """Latest is optional extra. If not given it will be fetched.
        """
        self.app = app
        # get latest version info if poss
        if app.updater in [False, None]:
            # user has turned off check for updates in prefs so check now
            app.updater = updater = Updater(app=self.app)
            # don't need a warning - we'll provide one ourselves
            self.latest = updater.getLatestInfo(warnMsg=False)
        else:
            self.latest = app.updater.latest
        self.runningVersion = app.updater.runningVersion
        wx.Dialog.__init__(self, parent, ID,
                           title=_translate('PsychoPy Updates'),
                           size=(100, 200))

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        # set the actual content of status msg later in self.updateStatus()
        self.statusMessage = wx.StaticText(
            self, -1, "msg", style=wx.ALIGN_CENTER)
        mainSizer.Add(self.statusMessage, flag=wx.EXPAND | wx.ALL, border=5)
        # ctrls for auto-update from web
        msg = _translate(" Auto-update (will fetch latest version)")
        self.useLatestBtn = wx.RadioButton(self, -1, msg,
                                           style=wx.RB_GROUP)
        self.Bind(wx.EVT_RADIOBUTTON, self.onRadioSelect, self.useLatestBtn)
        self.progressBar = wx.Gauge(self, -1, 100, size=(250, 25))
        mainSizer.Add(self.useLatestBtn,
                      flag=wx.ALIGN_LEFT | wx.ALL, border=5)
        mainSizer.Add(self.progressBar, flag=wx.EXPAND | wx.ALL, border=5)
        # ctrls for updating from specific zip file
        msg = _translate(" Use zip file below (download a PsychoPy release "
                         "file ending .zip)")
        self.useZipBtn = wx.RadioButton(self, -1, msg)
        self.Bind(wx.EVT_RADIOBUTTON, self.onRadioSelect, self.useZipBtn)
        self.fileBrowseCtrl = wx.lib.filebrowsebutton.FileBrowseButton(
            self, -1, size=(450, -1), changeCallback=self.onFileBrowse,
            fileMask='*.zip')
        mainSizer.Add(self.useZipBtn, flag=wx.ALIGN_LEFT | wx.ALL, border=5)
        mainSizer.Add(self.fileBrowseCtrl,
                      flag=wx.ALIGN_LEFT | wx.ALL, border=5)
        # ctrls for buttons (install/cancel)
        self.installBtn = wx.Button(self, -1, _translate('Install'))
        self.Bind(wx.EVT_BUTTON, self.onInstall, self.installBtn)
        self.installBtn.SetDefault()
        self.cancelBtn = wx.Button(self, -1, _translate('Close'))
        self.Bind(wx.EVT_BUTTON, self.onCancel, self.cancelBtn)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.installBtn, flag=wx.ALIGN_RIGHT)
        btnSizer.Add(self.cancelBtn, flag=wx.ALIGN_RIGHT | wx.LEFT, border=5)
        mainSizer.Add(btnSizer, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)

        self.SetSizerAndFit(mainSizer)
        self.SetAutoLayout(True)

        # positioning and sizing
        self.updateStatus()
        self.Center()
        self.ShowModal()
Beispiel #4
0
 def onLogin(self, event):
     """
     Check credentials and login
     """
     if not havePyosf:
         dialogs.MessageDialog(parent=self.parent, type='Warning',
                               title=_translate("pyosf not found"),
                               message=_translate("You need pyosf to "
                                       "log in to Open Science Framework"),
                               )
         return None
     username = self.username.GetValue()
     pword = self.password.GetValue()
     rememberMe = bool(self.rememberMe.GetValue())
     try:
         session = pyosf.Session(username=username,
                                 password=pword, remember_me=rememberMe)
         self.app.osf_session = session
         self.updateStatus(_translate("Successful authentication"),
                           color=(0, 170, 0))
         time.sleep(0.5)
         self.Destroy()
     except pyosf.AuthError:
         self.updateStatus(_translate("Failed to Authenticate. "
                           "Check username/password"), color=(255, 0, 0))
 def setPrefsFromCtrls(self):
     # extract values, adjust as needed:
     # a) strip() to remove whitespace
     # b) case-insensitive match for Cmd+ at start of string
     # c) reverse-map locale display names to canonical names (ja_JP)
     re_cmd2ctrl = re.compile('^Cmd\+', re.I)
     for sectionName in self.prefsCfg:
         for prefName in self.prefsSpec[sectionName]:
             if prefName in ['version']:  # any other prefs not to show?
                 continue
             ctrlName = sectionName + '.' + prefName
             ctrl = self.ctrls[ctrlName]
             thisPref = ctrl.getValue()
             # remove invisible trailing whitespace:
             if hasattr(thisPref, 'strip'):
                 thisPref = thisPref.strip()
             # regularize the display format for keybindings
             if sectionName == 'keyBindings':
                 thisPref = thisPref.replace(' ', '')
                 thisPref = '+'.join([part.capitalize()
                                      for part in thisPref.split('+')])
                 if platform.system() == 'Darwin':
                     # key-bindings were displayed as 'Cmd+O', revert to
                     # 'Ctrl+O' internally
                     thisPref = re_cmd2ctrl.sub('Ctrl+', thisPref)
             self.prefsCfg[sectionName][prefName] = thisPref
             # make sure list values are converted back to lists (from str)
             if self.prefsSpec[sectionName][prefName].startswith('list'):
                 try:
                     # if thisPref is not a null string, do eval() to get a
                     # list.
                     if thisPref == '' or type(thisPref) == list:
                         newVal = thisPref
                     else:
                         newVal = eval(thisPref)
                 except Exception:
                     # if eval() failed, show warning dialog and return
                     try:
                         pLabel = _localized[prefName]
                         sLabel = _localized[sectionName]
                     except Exception:
                         pLabel = prefName
                         sLabel = sectionName
                     txt = _translate(
                         'Invalid value in "%(pref)s" ("%(section)s" Tab)')
                     msg = txt % {'pref': pLabel, 'section': sLabel}
                     title = _translate('Error')
                     warnDlg = dialogs.MessageDialog(parent=self,
                                                     message=msg,
                                                     type='Info',
                                                     title=title)
                     resp = warnDlg.ShowModal()
                     return
                 if type(newVal) != list:
                     self.prefsCfg[sectionName][prefName] = [newVal]
                 else:
                     self.prefsCfg[sectionName][prefName] = newVal
     self.app.prefs.saveUserPrefs()  # includes a validation
 def save(self, event=None):
     """save header + row x col data to a pickle file
     """
     self.getData(True)  # update self.data
     adjustedNames = False
     for i, paramName in enumerate(self.data[0]):
         newName = paramName
         # ensure its legal as a var name, including namespace check:
         if self.parent:
             msg, enable = self.parent._checkName(name=paramName)
             if msg:  # msg not empty means a namespace issue
                 newName = self.parent.exp.namespace.makeValid(
                     paramName, prefix='param')
                 adjustedNames = True
         elif not valid_var_re.match(paramName):
             msg, enable = _translate(
                 "Name must be alpha-numeric or _, no spaces"), False
             newName = _nonalphanumeric_re.sub('_', newName)
             adjustedNames = True
         else:
             msg, enable = "", True
         # try to ensure its unique:
         while newName in self.data[0][:i]:
             adjustedNames = True
             newName += 'x'  # might create a namespace conflict?
         self.data[0][i] = newName
         self.header[i].SetValue(newName)  # displayed value
     if adjustedNames:
         self.tmpMsg.SetLabel(_translate(
             'Param name(s) adjusted to be legal. Look ok?'))
         return False
     if hasattr(self, 'fileName') and self.fileName:
         fname = self.fileName
     else:
         self.newFile = True
         fname = self.defaultFileName
     if self.newFile or not os.path.isfile(fname):
         fullPath = gui.fileSaveDlg(initFilePath=os.path.split(fname)[0],
                                    initFileName=os.path.basename(fname),
                                    allowed="Pickle files (*.pkl)|*.pkl")
     else:
         fullPath = fname
     if fullPath:  # None if user canceled
         if not fullPath.endswith('.pkl'):
             fullPath += '.pkl'
         f = open(fullPath, 'w')
         pickle.dump(self.data, f)
         f.close()
         self.fileName = fullPath
         self.newFile = False
         # ack, sometimes might want relative path
         if self.parent:
             self.parent.conditionsFile = fullPath
     return True
Beispiel #7
0
 def onOpenFile(self, event):
     """Open project file from dialog
     """
     dlg = wx.FileDialog(parent=None,
                         message=_translate("Open local project file"),
                         style=wx.FD_OPEN,
                         wildcard=_translate(
                         "Project files (*.psyproj)|*.psyproj"))
     if dlg.ShowModal() == wx.ID_OK:
         projFile = dlg.GetPath()
         self.openProj(projFile)
Beispiel #8
0
def getProject(filename):
    """Will try to find (locally synced) pavlovia Project for the filename
    """
    try:
        git
        haveGit = True
    except ImportError:
        haveGit = False
    if not haveGit:
        logging.error(
            "You need to install git to connect with Pavlovia projects")
        return None
    gitRoot = getGitRoot(filename)
    if gitRoot in knownProjects:
        return knownProjects[gitRoot]
    elif gitRoot:
        # Existing repo but not in our knownProjects. Investigate
        logging.info("Investigating repo at {}".format(gitRoot))
        localRepo = git.Repo(gitRoot)
        proj = None
        for remote in localRepo.remotes:
            for url in remote.urls:
                if "gitlab.pavlovia.org/" in url:
                    namespaceName = url.split('gitlab.pavlovia.org/')[1]
                    namespaceName = namespaceName.replace('.git', '')
                    pavSession = getCurrentSession()
                    if pavSession.user:
                        proj = pavSession.getProject(namespaceName,
                                                     repo=localRepo)
                        if proj.pavlovia == 0:
                            logging.warning(
                                    _translate(
                                        "We found a repository pointing to {} "
                                        "but ") +
                                    _translate("no project was found there ("
                                               "deleted?)")
                                    .format(url))

                    else:
                        logging.warning(
                                _translate(
                                    "We found a repository pointing to {} "
                                    "but ") +
                                _translate(
                                    "no user is logged in for us to check "
                                    "it")
                                .format(url))
                    return proj
        if proj == None:
            logging.warning("We found a repository at {} but it "
                            "doesn't point to gitlab.pavlovia.org. "
                            "You could create that as a remote to "
                            "sync from PsychoPy.".format(gitRoot))
Beispiel #9
0
 def getLatestInfo(self, warnMsg=False):
     # open page
     latest = getLatestVersionInfo()
     if latest == -1:
         m1 = _translate("Couldn't connect to psychopy.org to check for "
                         "updates. \n")
         m2 = _translate("Check internet settings (and proxy setting in "
                         "PsychoPy Preferences).")
         confirmDlg = dialogs.MessageDialog(
             parent=None, message=m1 + m2, type='Info',
             title=_translate('PsychoPy updates'))
         confirmDlg.ShowModal()
     return latest
Beispiel #10
0
 def onInsertRoutineSelect(self, event):
     """User has selected a routine to be entered so bring up the
     entrypoint marker and await mouse button press.
     see self.insertRoutine() for further info
     """
     self.mode = 'routine'
     self.btnInsertRoutine.SetLabel(_translate('CANCEL Insert'))
     self.btnInsertRoutine.SetLabelColor(**self.labelTextRed)
     self.frame.SetStatusText(_translate(
         'Click where you want to insert the Routine, or CANCEL insert.'))
     self.insertingRoutine = self.routinesFromID[event.GetId()]
     x = self.getNearestGapPoint(0)
     self.drawEntryPoints([x])
Beispiel #11
0
 def updateUserProjs(self):
     if self.app.osf_session.user_id is None:
         self.myProjectsPanel.setContents(
             _translate("No user logged in. \n\n"
             "Go to menu item Projects>Users>"))
     else:
         self.myProjectsPanel.setContents(
             _translate("Searching projects for user {} ...")
             .format(self.app.osf_session.username))
         self.Update()
         wx.Yield()
         myProjs = self.app.osf_session.find_user_projects()
         self.myProjectsPanel.setContents(myProjs)
Beispiel #12
0
    def check(self, parent):
        """Checks python syntax of code snippets, and for self-reference.

        Note: code snippets simply use existing names in the namespace,
        like from condition-file headers. They do not add to the
        namespace (unlike Name fields).

        Code snippets in param fields will often be user-defined
        vars, especially condition names. Can also be expressions like
        random(1,100). Hard to know what will be problematic.
        But its always the case that self-reference is wrong.
        """
        # first check if there's anything to validate (and return if not)
        control = self.GetWindow()
        if not hasattr(control, 'GetValue'):
            return '', True
        val = control.GetValue()  # same as parent.params[self.fieldName].val
        if not isinstance(val, basestring):
            return '', True

        field = self.fieldName
        msg, OK = '', True  # until we find otherwise
        codeWanted = psychopy.experiment.utils.unescapedDollarSign_re.search(val)
        isCodeField = bool(parent.params[self.fieldName].valType == 'code')
        if codeWanted or isCodeField:
            # get var names from val, check against namespace:
            code = experiment.getCodeFromParamStr(val)
            try:
                names = compile(code, '', 'eval').co_names
            except SyntaxError:
                # empty '' compiles to a syntax error, ignore
                if not code.strip() == '':
                    msg = _translate('Python syntax error in field `{}`:  {}')
                    msg = msg.format(self.displayName, code)
                    OK = False
            else:
                # namespace = parent.frame.exp.namespace
                # parent.params['name'].val is not in namespace for new params
                # and is not fixed as .val until dialog closes. Use getvalue()
                # to handle dynamic changes to Name field:
                if 'name' in parent.paramCtrls:  # some components don't have names
                    parentName = parent.paramCtrls['name'].getValue()
                    for name in names:
                        # `name` means a var name within a compiled code snippet
                        if name == parentName:
                            msg = _translate(
                                'Python var `{}` in `{}` is same as Name')
                            msg = msg.format(name, self.displayName)
                            OK = False
        parent.warningsDict[field] = msg
        return msg, OK
Beispiel #13
0
    def __init__(self, project, parent, *args, **kwargs):
        wx.Dialog.__init__(self, parent, *args, **kwargs)
        self.parent = parent
        self.project = project
        existingName = project.name
        msgText = _translate("points to a remote that doesn't exist (deleted?).")
        msgText += (" "+_translate("What shall we do?"))
        msg = wx.StaticText(self, label="{} {}".format(existingName, msgText))
        choices = [_translate("(Re)create a project"),
                   "{} ({})".format(_translate("Point to an different location"),
                                    _translate("not yet supported")),
                   _translate("Forget the local git repository (deletes history keeps files)")]
        self.radioCtrl = wx.RadioBox(self, label='RadioBox', choices=choices,
                                     majorDimension=1)
        self.radioCtrl.EnableItem(1, False)
        self.radioCtrl.EnableItem(2, False)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(wx.Button(self, id=wx.ID_OK, label=_translate("OK")),
                      1, wx.ALL | wx.ALIGN_RIGHT, 5)
        buttonSizer.Add(wx.Button(self, id=wx.ID_CANCEL, label=_translate("Cancel")),
                      1, wx.ALL | wx.ALIGN_RIGHT, 5)
        mainSizer.Add(msg, 1, wx.ALL, 5)
        mainSizer.Add(self.radioCtrl, 1, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
        mainSizer.Add(buttonSizer, 1, wx.ALL | wx.ALIGN_RIGHT, 1)

        self.SetSizer(mainSizer)
        self.Layout()
Beispiel #14
0
    def addPavloviaTools(self, buttons=[]):
        rc = self.frame.app.prefs.paths['resources']

        info = {}
        info['pavloviaRun'] = {
            'emblem': 'run16.png',
            'func': self.frame.onPavloviaRun,
            'label': _translate('Run online'),
            'tip': _translate('Run the study online (with pavlovia.org)')}
        info['pavloviaSync'] = {
            'emblem': 'sync_green16.png',
            'func': self.frame.onPavloviaSync,
            'label': _translate('Sync online'),
            'tip': _translate('Sync with web project (at pavlovia.org)')}
        info['pavloviaSearch'] = {
            'emblem': 'magnifier16.png',
            'func': self.onPavloviaSearch,
            'label': _translate('Search Pavlovia.org'),
            'tip': _translate('Find existing studies online (at pavlovia.org)')}
        info['pavloviaUser'] = {
            'emblem': 'user22.png',
            'func': self.onPavloviaUser,
            'label': _translate('Log in to Pavlovia'),
            'tip': _translate('Log in to (or create user at) Pavlovia.org')}
        info['pavloviaProject'] = {
            'emblem': 'info16.png',
            'func': self.onPavloviaProject,
            'label': _translate('View project'),
            'tip': _translate('View details of this project')}

        if not buttons:  # allows panels to select subsets
            buttons = info.keys()

        for buttonName in buttons:
            emblem = info[buttonName]['emblem']
            btnFunc = info[buttonName]['func']
            label = info[buttonName]['label']
            tip = info[buttonName]['tip']
            btnImage = icons.combineImageEmblem(
                    main=join(rc, 'globe%i.png' % self.tbSize),
                    emblem=join(rc, emblem), pos='bottom_right')

            if 'phoenix' in wx.PlatformInfo:
                self.btnHandles[buttonName] = self.toolbar.AddTool(
                        wx.ID_ANY, label, btnImage, tip)
            else:
                self.btnHandles[buttonName] = self.toolbar.AddSimpleTool(
                        wx.ID_ANY, btnImage, label, tip)

            self.toolbar.Bind(wx.EVT_TOOL, btnFunc, self.btnHandles[buttonName])
Beispiel #15
0
    def __init__(self, parent, id, project, *args, **kwargs):
        wx.Panel.__init__(self, parent, id, *args, **kwargs)
        self.project = project

        self.sizer = wx.FlexGridSizer(rows=2, cols=2, vgap=5, hgap=5)
        self.sizer.AddGrowableCol(1)

        upLabel = wx.StaticText(self, -1, _translate("Uploading:"))
        self.upProg = wx.Gauge(self, -1, range=1, size=(200, -1))
        downLabel = wx.StaticText(self, -1, _translate("Downloading:"))
        self.downProg = wx.Gauge(self, -1, range=1, size=(200, -1))
        self.sizer.AddMany([upLabel, self.upProg,
                            downLabel, self.downProg])
        self.SetSizerAndFit(self.sizer)
Beispiel #16
0
 def removeComponent(self, component, compID):
     """Remove either a Routine or a Loop from the Flow
     """
     flow = self.frame.exp.flow
     if component.getType() == 'Routine':
         # check whether this will cause a collapsed loop
         # prev and next elements on flow are a loop init/end
         prevIsLoop = nextIsLoop = False
         if compID > 0:  # there is at least one preceding
             prevIsLoop = (flow[compID - 1]).getType() == 'LoopInitiator'
         if len(flow) > (compID + 1):  # there is at least one more compon
             nextIsLoop = (flow[compID + 1]).getType() == 'LoopTerminator'
         if prevIsLoop and nextIsLoop:
             # because flow[compID+1] is a terminator
             loop = flow[compID + 1].loop
             msg = _translate('The "%s" Loop is about to be deleted as '
                              'well (by collapsing). OK to proceed?')
             title = _translate('Impending Loop collapse')
             warnDlg = dialogs.MessageDialog(
                 parent=self.frame, message=msg % loop.params['name'],
                 type='Warning', title=title)
             resp = warnDlg.ShowModal()
             if resp in [wx.ID_CANCEL, wx.ID_NO]:
                 return  # abort
             elif resp == wx.ID_YES:
                 # make recursive calls to this same method until success
                 # remove the loop first
                 self.removeComponent(loop, compID)
                 # because the loop has been removed ID is now one less
                 self.removeComponent(component, compID - 1)
                 return  # have done the removal in final successful call
     # remove name from namespace only if it's a loop;
     # loops exist only in the flow
     elif 'conditionsFile' in component.params:
         conditionsFile = component.params['conditionsFile'].val
         if conditionsFile and conditionsFile not in ['None', '']:
             try:
                 trialList, fieldNames = data.importConditions(
                     conditionsFile, returnFieldNames=True)
                 for fname in fieldNames:
                     self.frame.exp.namespace.remove(fname)
             except Exception:
                 msg = ("Conditions file %s couldn't be found so names not"
                        " removed from namespace")
                 logging.debug(msg % conditionsFile)
         self.frame.exp.namespace.remove(component.params['name'].val)
     # perform the actual removal
     flow.removeComponent(component, id=compID)
     self.draw()
Beispiel #17
0
    def __init__(self, title=_translate('PsychoPy Dialog'),
                 pos=None, size=None, style=None,
                 labelButtonOK=_translate(" OK "),
                 labelButtonCancel=_translate(" Cancel "),
                 screen=-1):

        global app  # avoid recreating for every gui
        app = ensureQtApp()
        QtWidgets.QDialog.__init__(self, None, Qt.WindowTitleHint)

        self.inputFields = []
        self.inputFieldTypes = []
        self.inputFieldNames = []
        self.data = []
        self.irow = 0
        self.pos = pos
        # QtWidgets.QToolTip.setFont(QtGui.QFont('SansSerif', 10))

        # add buttons for OK and Cancel
        self.buttonBox = QtWidgets.QDialogButtonBox(Qt.Horizontal,
                                                    parent=self)
        self.okbutton = QtWidgets.QPushButton(labelButtonOK,
                                              parent=self)
        self.cancelbutton = QtWidgets.QPushButton(labelButtonCancel,
                                                  parent=self)
        self.buttonBox.addButton(self.okbutton,
                                 QtWidgets.QDialogButtonBox.ActionRole)
        self.buttonBox.addButton(self.cancelbutton,
                                 QtWidgets.QDialogButtonBox.ActionRole)
        self.okbutton.clicked.connect(self.accept)
        self.cancelbutton.clicked.connect(self.reject)

        if style:
            raise RuntimeWarning("Dlg does not currently support the "
                                 "style kwarg.")
        self.size = size
        self.screen = screen
        # self.labelButtonOK = labelButtonOK
        # self.labelButtonCancel = labelButtonCancel

        self.layout = QtWidgets.QGridLayout()
        self.layout.setColumnStretch(1, 1)
        self.layout.setSpacing(10)
        self.layout.setColumnMinimumWidth(1, 250)

        self.setLayout(self.layout)

        self.setWindowTitle(title)
Beispiel #18
0
 def update(self, status=None):
     """Update to a particular status if given or deduce status msg if not
     """
     if status is None:
         if not self.OSFproject:
             status = _translate("No remote project set")
             self.syncButton.Enable(False)
         elif not self.localPath or not self.localPath.GetLabel():
             status = _translate("No local folder to sync with")
             self.syncButton.Enable(False)
         else:
             status = _translate("Ready")
             self.syncButton.Enable(True)
     self.status.SetLabel(_translate("Status: ") + status)
     self.Layout()
     self.Update()
Beispiel #19
0
 def preview(self, event=None):
     self.getData(typeSelected=True)
     # in theory, self.data is also ok, because fixed
     previewData = self.data[:]
     # is supposed to never change anything, but bugs would be very subtle
     DlgConditions(previewData, parent=self.parent,
                   title=_translate('PREVIEW'), fixed=True)
Beispiel #20
0
 def makeFileMenu(self):
     fileMenu = wx.Menu()
     app = wx.GetApp()
     keyCodes = app.keys
     # add items to file menu
     fileMenu.Append(wx.ID_CLOSE,
                     _translate("&Close View\t%s") % keyCodes['close'],
                     _translate("Close current window"))
     self.Bind(wx.EVT_MENU, self.closeFrame, id=wx.ID_CLOSE)
     # -------------quit
     fileMenu.AppendSeparator()
     fileMenu.Append(wx.ID_EXIT,
                     _translate("&Quit\t%s") % keyCodes['quit'],
                     _translate("Terminate the program"))
     self.Bind(wx.EVT_MENU, app.quit, id=wx.ID_EXIT)
     return fileMenu
Beispiel #21
0
    def __init__(self, app, parent=None, style=None,
                 pos=wx.DefaultPosition, project=None):
        if style is None:
            style = (wx.DEFAULT_DIALOG_STYLE | wx.CENTER |
                     wx.TAB_TRAVERSAL | wx.RESIZE_BORDER)
        if project:
            title = project.title
        else:
            title = _translate("Project info")
        self.frameType = 'ProjectInfo'
        wx.Dialog.__init__(self, parent, -1, title=title, style=style,
                           size=(700, 500), pos=pos)
        self.app = app
        self.project = project
        self.parent = parent

        # on the right
        self.detailsPanel = DetailsPanel(parent=self, project=self.project)
        self.mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.mainSizer.Add(self.detailsPanel, 1, wx.EXPAND | wx.ALL, 5)
        self.SetSizerAndFit(self.mainSizer)

        if self.parent:
            self.CenterOnParent()
        self.Layout()
Beispiel #22
0
    def __do_layout(self):
        for paramName in self.order:
            if paramName.lower() != 'name':
                guikey = paramName.replace(' ', '_')
                paramGuiDict = self.codeGuiElements.get(guikey)
                asizer = paramGuiDict.setdefault(
                    guikey + '_sizer', wx.BoxSizer(wx.VERTICAL))
                asizer.Add(paramGuiDict.get(
                    guikey + '_codebox'), 1, wx.EXPAND, 0)
                paramGuiDict.get(guikey + '_panel').SetSizer(asizer)
                tabLabel = _translate(paramName)
                # Add a visual indicator when tab contains code
                if self.params.get(guikey.replace('_',' ')).val:
                    tabLabel += ' *'
                self.codeSections.AddPage(paramGuiDict.get(
                    guikey + '_panel'), tabLabel)

        nameSizer = wx.BoxSizer(wx.HORIZONTAL)
        nameSizer.Add(self.nameLabel, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 10)
        nameSizer.Add(self.componentName,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                      border=10, proportion=1)
        nameSizer.Add(self.nameOKlabel, 0, wx.ALL, 10)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        mainSizer.Add(nameSizer)
        mainSizer.Add(self.codeSections, 1, wx.EXPAND | wx.ALL, 10)
        buttonSizer.Add(self.helpButton, 0, wx.RIGHT, 10)
        buttonSizer.Add(self.okButton, 0, wx.LEFT, 10)
        buttonSizer.Add(self.cancelButton, 0, 0, 0)
        mainSizer.Add(buttonSizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.SetSizer(mainSizer)
        self.Layout()
        self.Center()
Beispiel #23
0
def noGitWarning(parent):
    """Raise a simpler warning dialog that the user needs to install git first"""
    dlg = wx.Dialog(parent=parent, style=wx.ICON_ERROR | wx.OK | wx.STAY_ON_TOP)

    errorBitmap = wx.ArtProvider.GetBitmap(
        wx.ART_ERROR, wx.ART_MESSAGE_BOX
    )
    errorBitmapCtrl = wx.StaticBitmap(dlg, -1)
    errorBitmapCtrl.SetBitmap(errorBitmap)

    msg = wx.StaticText(dlg, label=_translate("You need to install git to use Pavlovia projects"))
    link = wxhl.HyperlinkCtrl(dlg, url="https://git-scm.com/")
    OK = wx.Button(dlg, wx.ID_OK, label="OK")

    msgsSizer = wx.BoxSizer(wx.VERTICAL)
    msgsSizer.Add(msg, 1, flag=wx.ALIGN_RIGHT | wx.ALL | wx.EXPAND, border=5)
    msgsSizer.Add(link, 1, flag=wx.ALIGN_RIGHT | wx.ALL | wx.EXPAND, border=5)
    msgsAndIcon = wx.BoxSizer(wx.HORIZONTAL)
    msgsAndIcon.Add(errorBitmapCtrl, 0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
    msgsAndIcon.Add(msgsSizer, 1, flag=wx.ALIGN_RIGHT | wx.ALL | wx.EXPAND, border=5)

    mainSizer = wx.BoxSizer(wx.VERTICAL)
    mainSizer.Add(msgsAndIcon, 0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
    mainSizer.Add(OK, 0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
    
    dlg.SetSizerAndFit(mainSizer)
    dlg.Layout()
    dlg.ShowModal()
Beispiel #24
0
def setLocalPath(parent, project=None, path=""):
    """Open a DirDialog and set the project local folder to that specified

    Returns
    ----------

    None for no change and newPath if this has changed from previous
    """
    if path:
        origPath = path
    elif project and 'localRoot' in project:
        origPath = project.localRoot
    else:
        origPath = ""
    # create the dialog
    dlg = wx.DirDialog(
            parent,
            defaultPath=origPath,
            message=_translate(
                    "Choose/create the root location for the synced project"))
    if dlg.ShowModal() == wx.ID_OK:
        newPath = dlg.GetPath()
        if os.path.isfile(newPath):
            newPath = os.path.split(newPath)[0]
        if newPath != origPath:
            if project:
                project.localRoot = newPath
        return newPath
Beispiel #25
0
 def onInsertRoutine(self, evt):
     """For when the insert Routine button is pressed - bring up
     dialog and present insertion point on flow line.
     see self.insertRoutine() for further info
     """
     if self.mode.startswith('loopPoint'):
         self.clearMode()
     elif self.mode == 'routine':
         # clicked again with label now being "Cancel..."
         self.clearMode()
         return
     self.frame.SetStatusText(_translate(
         "Select a Routine to insert (Esc to exit)"))
     menu = wx.Menu()
     self.routinesFromID = {}
     id = wx.NewIdRef()
     menu.Append(id, '(new)')
     self.routinesFromID[id] = '(new)'
     menu.Bind(wx.EVT_MENU, self.insertNewRoutine, id=id)
     for routine in self.frame.exp.routines:
         id = wx.NewIdRef()
         menu.Append(id, routine)
         self.routinesFromID[id] = routine
         menu.Bind(wx.EVT_MENU, self.onInsertRoutineSelect, id=id)
     btnPos = self.btnInsertRoutine.GetRect()
     menuPos = (btnPos[0], btnPos[1] + btnPos[3])
     self.PopupMenu(menu, menuPos)
     menu.Bind(wx.EVT_MENU_CLOSE, self.clearMode)
     menu.Destroy()  # destroy to avoid mem leak
Beispiel #26
0
 def setLoopPoint1(self, evt=None):
     """Someone pushed the insert loop button.
     Fetch the dialog
     """
     if self.mode == 'routine':
         self.clearMode()
     # clicked again, label is "Cancel..."
     elif self.mode.startswith('loopPoint'):
         self.clearMode()
         return
     self.btnInsertLoop.SetLabel(_translate('CANCEL insert'))
     self.btnInsertLoop.SetLabelColor(**self.labelTextRed)
     self.mode = 'loopPoint1'
     self.frame.SetStatusText(_translate(
         'Click where you want the loop to start/end, or CANCEL insert.'))
     x = self.getNearestGapPoint(0)
     self.drawEntryPoints([x])
Beispiel #27
0
 def clearMode(self, event=None):
     """If we were in middle of doing something (like inserting routine)
     then end it, allowing user to cancel
     """
     self.mode = 'normal'
     self.insertingRoutine = None
     for id in self.entryPointIDlist:
         self.pdc.RemoveId(id)
     self.entryPointPosList = []
     self.entryPointIDlist = []
     self.gapsExcluded = []
     self.draw()
     self.frame.SetStatusText("")
     self.btnInsertRoutine.SetLabel(_translate('Insert Routine'))
     self.btnInsertLoop.SetLabel(_translate('Insert Loop'))
     self.btnInsertRoutine.SetLabelColor(**self.labelTextBlack)
     self.btnInsertLoop.SetLabelColor(**self.labelTextBlack)
Beispiel #28
0
 def doAutoInstall(self, v='latest'):
     if v == 'latest':
         v = self.latest['version']
     msg = _translate("Downloading PsychoPy v%s") % v
     self.statusMessage.SetLabel(msg)
     try:
         zipFile, info = self.fetchPsychoPy(v)
     except Exception:
         msg = _translate('Failed to fetch PsychoPy release.\n'
                          'Check proxy setting in preferences')
         self.statusMessage.SetLabel(msg)
         return -1
     self.statusMessage.SetLabel(info)
     self.Fit()
     # got a download - try to install it
     info = self.installZipFile(zipFile, v)
     return info
Beispiel #29
0
 def onBrowseLocalFolder(self, evt):
     self.localFolder = setLocalPath(self, self.project)
     if self.localFolder:
         self.localFolderCtrl.SetLabel(
             label=_translate("Local root: {}").format(self.localFolder))
     self.localFolderCtrl.Wrap(self.GetSize().width)
     self.Layout()
     self.parent.Raise()
Beispiel #30
0
 def __init__(self, *args, **kwargs):
     wx.Frame.__init__(self, *args, **kwargs)
     self.Center()
     # set up menu bar
     self.menuBar = wx.MenuBar()
     self.fileMenu = self.makeFileMenu()
     self.menuBar.Append(self.fileMenu, _translate('&File'))
     self.SetMenuBar(self.menuBar)
Beispiel #31
0
    def __init__(self,
                 app,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=defaultStyle):
        wx.Dialog.__init__(
            self, None, title=_translate("Log in to Open Science Framework"))
        self.session = app.osf_session
        self.app = app

        self.fieldsSizer = wx.GridBagSizer(vgap=5, hgap=5)

        if web.haveInternetAccess():
            self.status = wx.StaticText(self,
                                        label=_translate("Status: Ready"))
        else:
            self.status = wx.StaticText(self,
                                        label=_translate("No internet access"))
        self.fieldsSizer.Add(self.status,
                             pos=(0, 0),
                             span=(1, 2),
                             flag=wx.ALIGN_CENTER,
                             border=10)

        # user info
        self.fieldsSizer.Add(wx.StaticText(
            self, label=_translate("OSF Username (email)")),
                             pos=(1, 0),
                             flag=wx.ALIGN_RIGHT)
        self.username = wx.TextCtrl(self)
        self.username.SetToolTip(
            wx.ToolTip(
                _translate("Your username on OSF "
                           "(the email address you used)")))
        self.fieldsSizer.Add(self.username, pos=(1, 1), flag=wx.ALIGN_LEFT)
        # pass info
        self.fieldsSizer.Add(wx.StaticText(self, label=_translate("Password")),
                             pos=(2, 0),
                             flag=wx.ALIGN_RIGHT)
        self.password = wx.TextCtrl(self,
                                    style=wx.TE_PASSWORD | wx.TE_PROCESS_ENTER)
        self.password.SetToolTip(
            wx.ToolTip(
                _translate("Your password on OSF "
                           "(will be checked securely with https)")))
        self.fieldsSizer.Add(self.password, pos=(2, 1), flag=wx.ALIGN_LEFT)
        # remember me
        self.fieldsSizer.Add(wx.StaticText(self,
                                           label=_translate("Remember me")),
                             pos=(3, 0),
                             flag=wx.ALIGN_RIGHT)
        self.rememberMe = wx.CheckBox(self, True)
        self.rememberMe.SetToolTip(
            _translate("We won't store your password - "
                       "just an authorisation token"))
        self.fieldsSizer.Add(self.rememberMe, pos=(3, 1), flag=wx.ALIGN_LEFT)

        # buttons (Log in, Cancel)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.cancelBtn = wx.Button(self, wx.ID_CANCEL, _translate('Cancel'))
        self.Bind(wx.EVT_BUTTON, self.onCancel, id=wx.ID_CANCEL)
        btnSizer.Add(self.cancelBtn, wx.ALIGN_RIGHT)

        self.okBtn = wx.Button(self, wx.ID_OK, _translate("Login"))
        self.okBtn.SetDefault()
        self.Bind(wx.EVT_BUTTON, self.onLogin, id=wx.ID_OK)
        btnSizer.Add(self.okBtn, wx.ALIGN_RIGHT)

        self.main_sizer = wx.BoxSizer(wx.VERTICAL)
        self.main_sizer.Add(self.fieldsSizer, 0, wx.ALL, 5)
        self.main_sizer.Add(btnSizer, 0, wx.ALL | wx.ALIGN_RIGHT, 5)
        self.SetSizerAndFit(self.main_sizer)
Beispiel #32
0
    def rename(self):
        """Rename a file or directory."""
        if os.path.isdir(self.selectedItem.abspath):  # rename a directory
            dlg = wx.TextEntryDialog(
                self,
                _translate('Rename folder `{}` to:').format(self.selectedItem.name),
                _translate('Rename Folder'), self.selectedItem.name)

            if dlg.ShowModal() == wx.ID_OK:
                newName = dlg.GetValue()
                try:
                    os.rename(self.selectedItem.abspath,
                              os.path.join(self.selectedItem.basename, newName))
                except OSError:
                    dlg2 = wx.MessageDialog(
                        self,
                        _translate("Cannot rename `{}` to `{}`.").format(
                            self.selectedItem.name, newName),
                        style=wx.ICON_ERROR | wx.OK)
                    dlg2.ShowModal()
                    dlg2.Destroy()
                    dlg.Destroy()
                    return

                self.gotoDir(self.currentPath)  # refresh

                for idx, item in enumerate(self.dirData):
                    abspath = os.path.join(self.currentPath, newName)
                    if item.abspath == abspath:
                        self.fileList.Select(idx, True)
                        self.fileList.EnsureVisible(idx)
                        self.selectedItem = self.dirData[idx]
                        self.fileList.SetFocus()
                        break

            dlg.Destroy()
        elif os.path.isfile(self.selectedItem.abspath):  # rename a directory
            dlg = wx.TextEntryDialog(
                self,
                _translate('Rename file `{}` to:').format(self.selectedItem.name),
                _translate('Rename file'), self.selectedItem.name)

            if dlg.ShowModal() == wx.ID_OK:
                newName = dlg.GetValue()

                try:
                    newPath = os.path.join(self.selectedItem.basename, newName)
                    os.rename(self.selectedItem.abspath,
                              newPath)
                except OSError:
                    dlgError = wx.MessageDialog(
                        self,
                        _translate("Cannot rename `{}` to `{}`.").format(
                            self.selectedItem.name, newName),
                        style=wx.ICON_ERROR | wx.OK)
                    dlgError.ShowModal()
                    dlgError.Destroy()
                    dlg.Destroy()
                    return

                self.gotoDir(self.currentPath)  # refresh

                for idx, item in enumerate(self.dirData):
                    if newPath == item.abspath:
                        self.fileList.Select(idx, True)
                        self.fileList.EnsureVisible(idx)
                        self.selectedItem = self.dirData[idx]
                        self.fileList.SetFocus()
                        break

            dlg.Destroy()
Beispiel #33
0
    def populatePrefs(self):
        """Populate pages with property items for each preference."""
        # clear pages
        for sectionName in self.prefsSpec.keys():
            prefsSection = self.prefsCfg[sectionName]
            specSection = self.prefsSpec[sectionName]

            for prefName in specSection:
                if prefName in ['version']:  # any other prefs not to show?
                    continue
                # allowModuleImports pref is handled by generateSpec.py
                # NB if something is in prefs but not in spec then it won't be
                # shown (removes outdated prefs)
                thisPref = prefsSection[prefName]
                thisSpec = specSection[prefName]

                # for keybindings replace Ctrl with Cmd on Mac
                if platform.system() == 'Darwin' and \
                        sectionName == 'keyBindings':
                    if thisSpec.startswith('string'):
                        thisPref = thisPref.replace('Ctrl+', 'Cmd+')

                # can we translate this pref?
                try:
                    pLabel = _localized[prefName]
                except Exception:
                    pLabel = prefName

                # get tooltips from comment lines from the spec, as parsed by
                # configobj
                helpText = ''
                hints = self.prefsSpec[sectionName].comments[prefName]  # a list
                if len(hints):
                    # use only one comment line, from right above the pref
                    hint = hints[-1].lstrip().lstrip('#').lstrip()
                    helpText = _translate(hint)

                if type(thisPref) == bool:
                    # only True or False - use a checkbox
                    self.proPrefs.addBoolItem(
                        sectionName, pLabel, prefName, thisPref,
                        helpText=helpText)

                # # properties for fonts, dropdown gives a list of system fonts
                elif prefName in ('codeFont', 'commentFont', 'outputFont'):
                    try:
                        default = self.fontList.index(thisPref)
                    except ValueError:
                        default = 0
                    self.proPrefs.addEnumItem(
                            sectionName,
                            pLabel,
                            prefName,
                            labels=self.fontList,
                            values=[i for i in range(len(self.fontList))],
                            value=default, helpText=helpText)
                elif prefName == 'locale':
                    thisPref = self.app.prefs.app['locale']
                    locales = self.app.localization.available
                    try:
                        default = locales.index(thisPref)
                    except ValueError:
                        # default to US english
                        default = locales.index('en_US')
                    self.proPrefs.addEnumItem(
                            sectionName,
                            pLabel,
                            prefName,
                            labels=[_localized[i] for i in locales],
                            values=[i for i in range(len(locales))],
                            value=default, helpText=helpText)
                # # single directory
                elif prefName in ('unpackedDemosDir',):
                    self.proPrefs.addDirItem(
                        sectionName, pLabel, prefName, thisPref,
                        helpText=helpText)
                # single file
                elif prefName in ('flac',):
                    self.proPrefs.addFileItem(
                        sectionName, pLabel, prefName, thisPref,
                        helpText=helpText)
                # # audio latency mode for the PTB driver
                elif prefName == 'audioLatencyMode':
                    # get the labels from above
                    labels = []
                    for val, labl in audioLatencyLabels.items():
                        labels.append(u'{}: {}'.format(val, labl))

                    # get the options from the config file spec
                    vals = thisSpec.replace("option(", "").replace("'", "")
                    # item -1 is 'default=x' from spec
                    vals = vals.replace(", ", ",").split(',')

                    try:
                        # set the field to the value in the pref
                        default = int(thisPref)
                    except ValueError:
                        try:
                            # use first if default not in list
                            default = int(vals[-1].strip('()').split('=')[1])
                        except (IndexError, TypeError, ValueError):
                            # no default
                            default = 0

                    self.proPrefs.addEnumItem(
                            sectionName,
                            pLabel,
                            prefName,
                            labels=labels,
                            values=[i for i in range(len(labels))],
                            value=default, helpText=helpText)
                # # option items are given a dropdown, current value is shown
                # # in the box
                elif thisSpec.startswith('option') or prefName == 'audioDevice':
                    if prefName == 'audioDevice':
                        options = self.audioDevNames
                        try:
                            default = self.audioDevNames.index(
                                self.audioDevDefault)
                        except ValueError:
                            default = 0
                    else:
                        vals = thisSpec.replace("option(", "").replace("'", "")
                        # item -1 is 'default=x' from spec
                        vals = vals.replace(", ", ",").split(',')
                        options = vals[:-1]
                        try:
                            # set the field to the value in the pref
                            default = options.index(thisPref)
                        except ValueError:
                            try:
                                # use first if default not in list
                                default = vals[-1].strip('()').split('=')[1]
                            except IndexError:
                                # no default
                                default = 0

                    labels = []  # display only
                    for opt in options:
                        try:
                            labels.append(_localized[opt])
                        except Exception:
                            labels.append(opt)

                    self.proPrefs.addEnumItem(
                            sectionName,
                            pLabel,
                            prefName,
                            labels=labels,
                            values=[i for i in range(len(labels))],
                            value=default, helpText=helpText)
                # # lists are given a property that can edit and reorder items
                elif thisSpec.startswith('list'):  # list
                    self.proPrefs.addStringArrayItem(
                        sectionName, pLabel, prefName,
                        [str(i) for i in thisPref], helpText)
                # integer items
                elif thisSpec.startswith('integer'):  # integer
                    self.proPrefs.addIntegerItem(
                        sectionName, pLabel, prefName, thisPref, helpText)
                # # all other items just use a string field
                else:
                    self.proPrefs.addStringItem(
                        sectionName, pLabel, prefName, thisPref, helpText)

        self.proPrefs.populateGrid()
Beispiel #34
0
    def __init__(self,
                 exp,
                 parentName,
                 name='image',
                 image='',
                 mask='',
                 interpolate='linear',
                 units='from exp settings',
                 color='$[1,1,1]',
                 colorSpace='rgb',
                 pos=(0, 0),
                 size=(0.5, 0.5),
                 ori=0,
                 texRes='128',
                 flipVert=False,
                 flipHoriz=False,
                 startType='time (s)',
                 startVal=0.0,
                 stopType='duration (s)',
                 stopVal=1.0,
                 startEstim='',
                 durationEstim=''):
        super(ImageComponent, self).__init__(exp,
                                             parentName,
                                             name=name,
                                             units=units,
                                             color=color,
                                             colorSpace=colorSpace,
                                             pos=pos,
                                             size=size,
                                             ori=ori,
                                             startType=startType,
                                             startVal=startVal,
                                             stopType=stopType,
                                             stopVal=stopVal,
                                             startEstim=startEstim,
                                             durationEstim=durationEstim)
        self.type = 'Image'
        self.targets = ['PsychoPy', 'PsychoJS']
        self.url = "https://www.psychopy.org/builder/components/image.html"
        self.exp.requirePsychopyLibs(['visual'])
        # params
        self.order += [
            'image',  # Basic tab
            'mask',
            'texture resolution',  # Texture tab
        ]

        msg = _translate(
            "The image to be displayed - a filename, including path")
        self.params['image'] = Param(
            image,
            valType='file',
            inputType="file",
            allowedTypes=[],
            categ='Basic',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized["image"])

        msg = _translate(
            "An image to define the alpha mask through which the image is "
            "seen - gauss, circle, None or a filename (including path)")
        self.params['mask'] = Param(
            mask,
            valType='str',
            inputType="file",
            allowedTypes=[],
            categ='Texture',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized["mask"])

        msg = _translate("Resolution of the mask if one is used.")
        self.params['texture resolution'] = Param(
            texRes,
            valType='num',
            inputType="choice",
            categ='Texture',
            allowedVals=['32', '64', '128', '256', '512'],
            updates='constant',
            allowedUpdates=[],
            hint=msg,
            label=_localized["texture resolution"])

        msg = _translate(
            "How should the image be interpolated if/when rescaled")
        self.params['interpolate'] = Param(interpolate,
                                           valType='str',
                                           inputType="choice",
                                           allowedVals=['linear', 'nearest'],
                                           categ='Texture',
                                           updates='constant',
                                           allowedUpdates=[],
                                           hint=msg,
                                           label=_localized["interpolate"])

        msg = _translate(
            "Should the image be flipped vertically (top to bottom)?")
        self.params['flipVert'] = Param(flipVert,
                                        valType='bool',
                                        inputType="bool",
                                        categ='Layout',
                                        updates='constant',
                                        allowedUpdates=[],
                                        hint=msg,
                                        label=_localized["flipVert"])

        msg = _translate(
            "Should the image be flipped horizontally (left to right)?")
        self.params['flipHoriz'] = Param(flipHoriz,
                                         valType='bool',
                                         inputType="bool",
                                         categ='Layout',
                                         updates='constant',
                                         allowedUpdates=[],
                                         hint=msg,
                                         label=_localized["flipHoriz"])

        del self.params['fillColor']
        del self.params['borderColor']
Beispiel #35
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file was generated by generateHints.py.
# Following strings are used to localize hints in Preference Dialog of
# the PsychoPy application.
# Rebuild this file if comments in *.spec files are modified.

from __future__ import absolute_import, print_function
from psychopy.localization import _translate

# baseNoArch.spec,[general],line25
_translate("which system to use as a backend for drawing")

# baseNoArch.spec,[general],line27
_translate("the default units for windows and visual stimuli")

# baseNoArch.spec,[general],line29
_translate("full screen is best for accurate timing")

# baseNoArch.spec,[general],line31
_translate("enable subjects to use the mouse and GUIs during experiments")

# baseNoArch.spec,[general],line33
_translate("'version' is for internal usage, not for the user")

# baseNoArch.spec,[general],line35
_translate("Add paths here to your custom Python modules")

# baseNoArch.spec,[general],line37
_translate("choice of audio library")
Beispiel #36
0
    def __init__(self, parent=None, message='', type='Warning', title=None,
                 timeout=None):
        # select and localize a title
        if not title:
            title = type
        labels = {'Warning': _translate('Warning'),
                  'Info': _translate('Info'),
                  'Query': _translate('Query')}
        try:
            label = labels[title]
        except Exception:
            label = title
        wx.Dialog.__init__(self, parent, -1, title=label)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(wx.StaticText(self, -1, message), flag=wx.ALL, border=15)
        # add buttons
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        if type == 'Warning':  # we need Yes,No,Cancel
            self.yesBtn = wx.Button(self, wx.ID_YES, _translate('Yes'))
            self.yesBtn.SetDefault()
            self.cancelBtn = wx.Button(
                self, wx.ID_CANCEL, _translate('Cancel'))
            self.noBtn = wx.Button(self, wx.ID_NO, _translate('No'))
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_CANCEL)
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_YES)
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_NO)
#            self.Bind(wx.EVT_CLOSE, self.onEscape)
            btnSizer.Add(self.cancelBtn, 0,
                         wx.ALL | wx.LEFT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
            btnSizer.AddStretchSpacer()
            btnSizer.Add(self.noBtn, 0,
                         wx.ALL | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
            btnSizer.Add(self.yesBtn, 0,
                         wx.ALL | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
        elif type == 'Query':  # we need Yes,No
            self.yesBtn = wx.Button(self, wx.ID_YES, _translate('Yes'))
            self.yesBtn.SetDefault()
            self.noBtn = wx.Button(self, wx.ID_NO, _translate('No'))
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_YES)
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_NO)
#            self.Bind(wx.EVT_CLOSE, self.onEscape)
            btnSizer.Add(self.noBtn, 0,
                         wx.ALL | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
            btnSizer.Add(self.yesBtn, 0,
                         wx.ALL | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
        elif type == 'Info':  # just an OK button
            self.okBtn = wx.Button(self, wx.ID_OK, _translate('OK'))
            self.okBtn.SetDefault()
            self.Bind(wx.EVT_BUTTON, self.onButton, id=wx.ID_OK)
            btnSizer.Add(self.okBtn, 0,
                         wx.ALL | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                         border=3)
        else:
            raise NotImplementedError('Message type %s unknown' % type)
        # configure sizers and fit
        sizer.Add(btnSizer,
                  flag=wx.ALL | wx.EXPAND, border=5)
        self.Center()
        self.SetSizerAndFit(sizer)
        self.timeout = timeout
Beispiel #37
0
 def __init__(self, exp, name, nReps='50', stairType='simple',
              switchStairs='random',
              conditions=(), conditionsFile='', endPoints=(0, 1),
              isTrials=True):
     """
     @param name: name of the loop e.g. trials
     @type name: string
     @param nReps: number of reps (for all conditions)
     @type nReps:int
     """
     super(MultiStairHandler, self).__init__()
     self.type = 'MultiStairHandler'
     self.exp = exp
     self.order = ['name']  # make name come first
     self.params = {}
     self.params['name'] = Param(
         name, valType='code',
         label=_localized['Name'],
         hint=_translate("Name of this loop"))
     self.params['nReps'] = Param(
         nReps, valType='code',
         label=_localized['nReps'],
         hint=_translate("(Minimum) number of trials in *each* staircase"))
     self.params['stairType'] = Param(
         stairType, valType='str',
         allowedVals=['simple', 'QUEST', 'quest'],
         label=_localized['stairType'],
         hint=_translate("How to select the next staircase to run"))
     self.params['switchMethod'] = Param(
         switchStairs, valType='str',
         allowedVals=['random', 'sequential', 'fullRandom'],
         label=_localized['switchMethod'],
         hint=_translate("How to select the next staircase to run"))
     # these two are really just for making the dialog easier (they won't
     # be used to generate code)
     self.params['loopType'] = Param(
         'staircase', valType='str',
         allowedVals=['random', 'sequential', 'fullRandom', 'staircase',
                      'interleaved staircases'],
         label=_localized['loopType'],
         hint=_translate("How should the next trial value(s) be chosen?"))
     self.params['endPoints'] = Param(
         list(endPoints), valType='num',
         label=_localized['endPoints'],
         hint=_translate('Where to loop from and to (see values currently'
                         ' shown in the flow view)'))
     self.params['conditions'] = Param(
         list(conditions), valType='str', updates=None,
         allowedUpdates=None,
         label=_localized['conditions'],
         hint=_translate("A list of dictionaries describing the "
                         "differences between each staircase"))
     self.params['conditionsFile'] = Param(
         conditionsFile, valType='str', updates=None, allowedUpdates=None,
         label=_localized['conditions'],
         hint=_translate("An xlsx or csv file specifying the parameters "
                         "for each condition"))
     self.params['isTrials'] = Param(
         isTrials, valType='bool', updates=None, allowedUpdates=None,
         label=_localized["Is trials"],
         hint=_translate("Indicates that this loop generates TRIALS, "
                         "rather than BLOCKS of trials or stimuli within "
                         "a trial. It alters how data files are output"))
     pass  # don't initialise at start of exp, create when needed
Beispiel #38
0
 def __init__(self, exp, name, loopType='random', nReps=5,
              conditions=(), conditionsFile='', endPoints=(0, 1),
              randomSeed='', selectedRows='', isTrials=True):
     """
     @param name: name of the loop e.g. trials
     @type name: string
     @param loopType:
     @type loopType: string ('rand', 'seq')
     @param nReps: number of reps (for all conditions)
     @type nReps:int
     @param conditions: list of different trial conditions to be used
     @type conditions: list (of dicts?)
     @param conditionsFile: filename of the .csv file that
         contains conditions info
     @type conditions: string (filename)
     """
     super(TrialHandler, self).__init__()
     self.type = 'TrialHandler'
     self.exp = exp
     self.order = ['name']  # make name come first (others don't matter)
     self.params = {}
     self.params['name'] = Param(
         name, valType='code', updates=None, allowedUpdates=None,
         label=_localized['Name'],
         hint=_translate("Name of this loop"))
     self.params['nReps'] = Param(
         nReps, valType='code', updates=None, allowedUpdates=None,
         label=_localized['nReps'],
         hint=_translate("Number of repeats (for each condition)"))
     self.params['conditions'] = Param(
         list(conditions), valType='str',
         updates=None, allowedUpdates=None,
         label=_localized['conditions'],
         hint=_translate("A list of dictionaries describing the "
                         "parameters in each condition"))
     self.params['conditionsFile'] = Param(
         conditionsFile, valType='str', updates=None, allowedUpdates=None,
         label=_localized['conditions'],
         hint=_translate("Name of a file specifying the parameters for "
                         "each condition (.csv, .xlsx, or .pkl). Browse "
                         "to select a file. Right-click to preview file "
                         "contents, or create a new file."))
     self.params['endPoints'] = Param(
         list(endPoints), valType='num', updates=None, allowedUpdates=None,
         label=_localized['endPoints'],
         hint=_translate("The start and end of the loop (see flow "
                         "timeline)"))
     self.params['Selected rows'] = Param(
         selectedRows, valType='str',
         updates=None, allowedUpdates=None,
         label=_localized['Selected rows'],
         hint=_translate("Select just a subset of rows from your condition"
                         " file (the first is 0 not 1!). Examples: 0, "
                         "0:5, 5:-1"))
     # NB staircase is added for the sake of the loop properties dialog:
     self.params['loopType'] = Param(
         loopType, valType='str',
         allowedVals=['random', 'sequential', 'fullRandom',
                      'staircase', 'interleaved staircases'],
         label=_localized['loopType'],
         hint=_translate("How should the next condition value(s) be "
                         "chosen?"))
     self.params['random seed'] = Param(
         randomSeed, valType='code', updates=None, allowedUpdates=None,
         label=_localized['random seed'],
         hint=_translate("To have a fixed random sequence provide an "
                         "integer of your choosing here. Leave blank to "
                         "have a new random sequence on each run of the "
                         "experiment."))
     self.params['isTrials'] = Param(
         isTrials, valType='bool', updates=None, allowedUpdates=None,
         label=_localized["Is trials"],
         hint=_translate("Indicates that this loop generates TRIALS, "
                         "rather than BLOCKS of trials or stimuli within "
                         "a trial. It alters how data files are output"))
Beispiel #39
0
 def __init__(self, exp, name, nReps='50', startVal='', nReversals='',
              nUp=1, nDown=3, minVal=0, maxVal=1,
              stepSizes='[4,4,2,2,1]', stepType='db', endPoints=(0, 1),
              isTrials=True):
     """
     @param name: name of the loop e.g. trials
     @type name: string
     @param nReps: number of reps (for all conditions)
     @type nReps:int
     """
     super(StairHandler, self).__init__()
     self.type = 'StairHandler'
     self.exp = exp
     self.order = ['name']  # make name come first (others don't matter)
     self.children = []
     self.params = {}
     self.params['name'] = Param(
         name, valType='code',
         hint=_translate("Name of this loop"),
         label=_localized['Name'])
     self.params['nReps'] = Param(
         nReps, valType='code',
         label=_localized['nReps'],
         hint=_translate("(Minimum) number of trials in the staircase"))
     self.params['start value'] = Param(
         startVal, valType='code',
         label=_localized['start value'],
         hint=_translate("The initial value of the parameter"))
     self.params['max value'] = Param(
         maxVal, valType='code',
         label=_localized['max value'],
         hint=_translate("The maximum value the parameter can take"))
     self.params['min value'] = Param(
         minVal, valType='code',
         label=_localized['min value'],
         hint=_translate("The minimum value the parameter can take"))
     self.params['step sizes'] = Param(
         stepSizes, valType='code',
         label=_localized['step sizes'],
         hint=_translate("The size of the jump at each step (can change"
                         " on each 'reversal')"))
     self.params['step type'] = Param(
         stepType, valType='str', allowedVals=['lin', 'log', 'db'],
         label=_localized['step type'],
         hint=_translate("The units of the step size (e.g. 'linear' will"
                         " add/subtract that value each step, whereas "
                         "'log' will ad that many log units)"))
     self.params['N up'] = Param(
         nUp, valType='code',
         label=_localized['N up'],
         hint=_translate("The number of 'incorrect' answers before the "
                         "value goes up"))
     self.params['N down'] = Param(
         nDown, valType='code',
         label=_localized['N down'],
         hint=_translate("The number of 'correct' answers before the "
                         "value goes down"))
     self.params['N reversals'] = Param(
         nReversals, valType='code',
         label=_localized['N reversals'],
         hint=_translate("Minimum number of times the staircase must "
                         "change direction before ending"))
     # these two are really just for making the dialog easier (they won't
     # be used to generate code)
     self.params['loopType'] = Param(
         'staircase', valType='str',
         allowedVals=['random', 'sequential', 'fullRandom', 'staircase',
                      'interleaved staircases'],
         label=_localized['loopType'],
         hint=_translate("How should the next trial value(s) be chosen?"))
     # NB this is added for the sake of the loop properties dialog
     self.params['endPoints'] = Param(
         list(endPoints), valType='num',
         label=_localized['endPoints'],
         hint=_translate('Where to loop from and to (see values currently'
                         ' shown in the flow view)'))
     self.params['isTrials'] = Param(
         isTrials, valType='bool', updates=None, allowedUpdates=None,
         label=_localized["Is trials"],
         hint=_translate("Indicates that this loop generates TRIALS, "
                         "rather than BLOCKS of trials or stimuli within"
                         " a trial. It alters how data files are output"))
Beispiel #40
0
    def __init__(self, parent, id, size=(400, 300), *args, **kwargs):
        BaseFrame.__init__(self,
                           parent=None,
                           id=id,
                           size=size,
                           *args,
                           **kwargs)
        self.frameType = 'project'
        self.app = wx.GetApp()
        self.app.trackFrame(self)
        self.OSFproject = None
        self.project = None
        self.syncStatus = None

        # title
        self.title = wx.StaticText(self,
                                   -1,
                                   _translate("No project opened"),
                                   style=wx.BOLD | wx.ALIGN_CENTER)
        font = wx.Font(18, family=wx.NORMAL, style=wx.NORMAL, weight=wx.BOLD)
        self.title.SetFont(font)
        self.title.SetMinSize((300, -1))
        self.title.Wrap(300)
        # name box
        nameBox = wx.StaticBox(self, -1,
                               _translate("Name (for PsychoPy use):"))
        nameSizer = wx.StaticBoxSizer(nameBox, wx.VERTICAL)
        self.nameCtrl = wx.TextCtrl(self, -1, "", style=wx.TE_LEFT)
        nameSizer.Add(self.nameCtrl, flag=wx.EXPAND | wx.ALL, border=5)
        # local files
        localsBox = wx.StaticBox(self, -1, _translate("Local Info"))
        localsSizer = wx.StaticBoxSizer(localsBox, wx.VERTICAL)
        localBrowseBtn = wx.Button(self, -1, _translate("Browse..."))
        localBrowseBtn.Bind(wx.EVT_BUTTON, self.onBrowseLocal)
        self.localPath = wx.StaticText(self, -1, "")
        filesSizer = wx.BoxSizer(wx.HORIZONTAL)
        filesSizer.Add(wx.StaticText(self, -1, _translate("Local files:")))
        filesSizer.Add(localBrowseBtn, flag=wx.ALL, border=5)
        localsSizer.Add(filesSizer, flag=wx.ALL, border=5)
        localsSizer.Add(self.localPath,
                        flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                        proportion=1,
                        border=5)

        # sync controls
        syncBox = wx.StaticBox(self, -1, _translate("Sync"))
        self.syncButton = wx.Button(self, -1, _translate("Sync Now"))
        self.syncButton.Bind(wx.EVT_BUTTON, self.onSyncBtn)
        self.syncStatus = SyncStatusPanel(self, id=-1, project=self.project)
        self.status = wx.StaticText(self, -1, "put status updates here")
        syncSizer = wx.StaticBoxSizer(syncBox, wx.VERTICAL)
        syncSizer.Add(self.syncButton,
                      flag=wx.EXPAND | wx.ALL,
                      proportion=1,
                      border=5)
        syncSizer.Add(self.syncStatus,
                      flag=wx.EXPAND | wx.ALL,
                      proportion=1,
                      border=5)
        syncSizer.Add(self.status,
                      flag=wx.EXPAND | wx.ALL,
                      proportion=1,
                      border=5)

        projBox = wx.StaticBox(self, -1, _translate("Project Info"))
        projSizer = wx.StaticBoxSizer(projBox, wx.VERTICAL)
        self.projDetails = DetailsPanel(parent=self, noTitle=True)
        projSizer.Add(self.projDetails,
                      flag=wx.EXPAND | wx.ALL,
                      proportion=1,
                      border=5)
        # mainSizer with title, then two columns
        self.mainSizer = wx.BoxSizer(wx.VERTICAL)
        self.mainSizer.Add(self.title,
                           flag=wx.ALIGN_CENTER | wx.ALL,
                           border=20)

        # set contents for left and right sizers
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        leftSizer.Add(projSizer,
                      flag=wx.EXPAND | wx.ALL,
                      proportion=1,
                      border=5)
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer.Add(nameSizer,
                       flag=wx.EXPAND | wx.ALL,
                       proportion=0,
                       border=5)
        rightSizer.Add(localsSizer,
                       flag=wx.EXPAND | wx.ALL,
                       proportion=0,
                       border=5)
        rightSizer.Add(syncSizer, flag=wx.ALL, border=5)

        columnSizer = wx.BoxSizer(wx.HORIZONTAL)
        columnSizer.Add(leftSizer,
                        border=5,
                        flag=wx.EXPAND | wx.ALL,
                        proportion=1)
        columnSizer.Add(rightSizer,
                        border=5,
                        flag=wx.EXPAND | wx.ALL,
                        proportion=1)
        self.mainSizer.Add(columnSizer,
                           proportion=1,
                           flag=wx.EXPAND | wx.ALL,
                           border=5)

        self.SetSizerAndFit(self.mainSizer)
        self.SetAutoLayout(True)
        self.update()

        self.app.trackFrame(self)
        self.Show()
Beispiel #41
0
    def __init__(self,
                 parent=None,
                 id=wx.ID_ANY,
                 project=None,
                 localRoot="",
                 *args,
                 **kwargs):

        wx.Dialog.__init__(self, parent, id, *args, **kwargs)
        panel = wx.Panel(self, wx.ID_ANY, style=wx.TAB_TRAVERSAL)
        # when a project is successfully created these will be populated
        if hasattr(parent, 'filename'):
            self.filename = parent.filename
        else:
            self.filename = None
        self.project = project  # type: pavlovia.PavloviaProject
        self.projInfo = None
        self.parent = parent

        if project:
            # edit existing project
            self.isNew = False
            if project.localRoot and not localRoot:
                localRoot = project.localRoot
        else:
            self.isNew = True

        # create the controls
        nameLabel = wx.StaticText(panel, -1, _translate("Name:"))
        self.nameBox = wx.TextCtrl(panel, -1, size=(400, -1))
        # Path can contain only letters, digits, '_', '-' and '.'.
        # Cannot start with '-', end in '.git' or end in '.atom']
        pavSession = pavlovia.getCurrentSession()

        try:
            username = pavSession.user.username
        except AttributeError as e:
            raise pavlovia.NoUserError(
                "{}: Tried to create project with no user logged in.".format(
                    e))

        gpChoices = [username]
        gpChoices.extend(pavSession.listUserGroups())
        groupLabel = wx.StaticText(panel, -1, _translate("Group/owner:"))
        self.groupBox = wx.Choice(panel, -1, size=(400, -1), choices=gpChoices)

        descrLabel = wx.StaticText(panel, -1, _translate("Description:"))
        self.descrBox = wx.TextCtrl(panel,
                                    -1,
                                    size=(400, 200),
                                    style=wx.TE_MULTILINE | wx.SUNKEN_BORDER)

        localLabel = wx.StaticText(panel, -1, _translate("Local folder:"))
        self.localBox = wx.TextCtrl(panel, -1, size=(400, -1), value=localRoot)
        self.btnLocalBrowse = wx.Button(panel, wx.ID_ANY,
                                        _translate("Browse..."))
        self.btnLocalBrowse.Bind(wx.EVT_BUTTON, self.onBrowseLocal)
        localPathSizer = wx.BoxSizer(wx.HORIZONTAL)
        localPathSizer.Add(self.localBox)
        localPathSizer.Add(self.btnLocalBrowse)

        tagsLabel = wx.StaticText(panel, -1,
                                  _translate("Tags (comma separated):"))
        self.tagsBox = wx.TextCtrl(panel,
                                   -1,
                                   size=(400, 100),
                                   value="PsychoPy, Builder, Coder",
                                   style=wx.TE_MULTILINE | wx.SUNKEN_BORDER)
        publicLabel = wx.StaticText(panel, -1, _translate("Public:"))
        self.publicBox = wx.CheckBox(panel, -1)

        # buttons
        if self.isNew:
            buttonMsg = _translate("Create project on Pavlovia")
        else:
            buttonMsg = _translate("Submit changes to Pavlovia")
        updateBtn = wx.Button(panel, -1, buttonMsg)
        updateBtn.Bind(wx.EVT_BUTTON, self.submitChanges)
        cancelBtn = wx.Button(panel, -1, _translate("Cancel"))
        cancelBtn.Bind(wx.EVT_BUTTON, self.onCancel)
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        if sys.platform == "win32":
            btns = [updateBtn, cancelBtn]
        else:
            btns = [cancelBtn, updateBtn]
        btnSizer.AddMany(btns)

        # do layout
        fieldsSizer = wx.FlexGridSizer(cols=2, rows=6, vgap=5, hgap=5)
        fieldsSizer.AddMany([(nameLabel, 0, wx.ALIGN_RIGHT), self.nameBox,
                             (groupLabel, 0, wx.ALIGN_RIGHT), self.groupBox,
                             (localLabel, 0, wx.ALIGN_RIGHT), localPathSizer,
                             (descrLabel, 0, wx.ALIGN_RIGHT), self.descrBox,
                             (tagsLabel, 0, wx.ALIGN_RIGHT), self.tagsBox,
                             (publicLabel, 0, wx.ALIGN_RIGHT), self.publicBox])

        border = wx.BoxSizer(wx.VERTICAL)
        border.Add(fieldsSizer, 0, wx.ALL, 5)
        border.Add(btnSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5)
        panel.SetSizerAndFit(border)
        self.Fit()
Beispiel #42
0
    def __init__(self,
                 app,
                 pos=wx.DefaultPosition,
                 size=wx.DefaultSize,
                 style=defaultStyle):
        title = _translate("Search OSF (Open Science Framework)")
        self.frameType = 'OSFsearch'
        BaseFrame.__init__(self, None, -1, title, pos, size, style)
        self.app = app
        self.currentOSFProject = None

        # to show detail of current selection
        self.detailsPanel = DetailsPanel(parent=self)

        # create list of my projects (no search?)
        self.myProjectsPanel = ProjectListPanel(self, self.detailsPanel)

        # create list of searchable public projects
        self.publicProjectsPanel = ProjectListPanel(self, self.detailsPanel)
        self.publicProjectsPanel.setContents('')

        # sizers: on the left we have search boxes
        leftSizer = wx.BoxSizer(wx.VERTICAL)
        leftSizer.Add(wx.StaticText(self, -1, _translate("My Projects")),
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        leftSizer.Add(self.myProjectsPanel,
                      proportion=1,
                      flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
                      border=10)
        searchSizer = wx.BoxSizer(wx.HORIZONTAL)
        searchSizer.Add(wx.StaticText(self, -1, _translate("Search Public:")))
        self.searchTextCtrl = wx.TextCtrl(self,
                                          -1,
                                          "",
                                          style=wx.TE_PROCESS_ENTER)
        self.searchTextCtrl.Bind(wx.EVT_TEXT_ENTER, self.onSearch)
        searchSizer.Add(self.searchTextCtrl, flag=wx.EXPAND)
        leftSizer.Add(searchSizer)
        tagsSizer = wx.BoxSizer(wx.HORIZONTAL)
        tagsSizer.Add(wx.StaticText(self, -1, _translate("Tags:")))
        self.tagsTextCtrl = wx.TextCtrl(self,
                                        -1,
                                        "psychopy,",
                                        style=wx.TE_PROCESS_ENTER)
        self.tagsTextCtrl.Bind(wx.EVT_TEXT_ENTER, self.onSearch)
        tagsSizer.Add(self.tagsTextCtrl, flag=wx.EXPAND)
        leftSizer.Add(tagsSizer)
        leftSizer.Add(self.publicProjectsPanel,
                      proportion=1,
                      flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
                      border=10)

        # sizers: on the right we have detail
        rightSizer = wx.BoxSizer(wx.VERTICAL)
        rightSizer.Add(wx.StaticText(self, -1, _translate("Project Info")),
                       flag=wx.ALL,
                       border=5)
        self.syncButton = wx.Button(self, -1, _translate("Sync..."))
        self.syncButton.Enable(False)
        rightSizer.Add(self.syncButton, flag=wx.ALL, border=5)
        self.syncButton.Bind(wx.EVT_BUTTON, self.onSyncButton)
        rightSizer.Add(self.detailsPanel,
                       proportion=1,
                       flag=wx.EXPAND | wx.ALL,
                       border=10)

        self.mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.mainSizer.Add(leftSizer, flag=wx.EXPAND, proportion=1, border=5)
        self.mainSizer.Add(rightSizer, flag=wx.EXPAND, proportion=1, border=5)
        self.SetSizerAndFit(self.mainSizer)

        aTable = wx.AcceleratorTable([
            (0, wx.WXK_ESCAPE, wx.ID_CANCEL),
        ])
        self.SetAcceleratorTable(aTable)
        self.Show()  # show the window before doing search/updates
        self.updateUserProjs()  # update the info in myProjectsPanel
Beispiel #43
0
    def _getXMLparam(self, params, paramNode, componentNode=None):
        """params is the dict of params of the builder component
        (e.g. stimulus) into which the parameters will be inserted
        (so the object to store the params should be created first)
        paramNode is the parameter node fetched from the xml file
        """
        name = paramNode.get('name')
        valType = paramNode.get('valType')
        val = paramNode.get('val')
        # many components need web char newline replacement
        if not name == 'advancedParams':
            val = val.replace("&#10;", "\n")

        # custom settings (to be used when
        if valType == 'fixedList':  # convert the string to a list
            try:
                params[name].val = eval('list({})'.format(val))
            except NameError:  # if val is a single string it will look like variable
                params[name].val = [val]
        elif name == 'storeResponseTime':
            return  # deprecated in v1.70.00 because it was redundant
        elif name == 'nVertices':  # up to 1.85 there was no shape param
            # if no shape param then use "n vertices" only
            if _findParam('shape', componentNode) is None:
                if val == '2':
                    params['shape'].val = "line"
                elif val == '3':
                    params['shape'].val = "triangle"
                elif val == '4':
                    params['shape'].val = "rectangle"
                else:
                    params['shape'].val = "regular polygon..."
            params['nVertices'].val = val
        elif name == 'startTime':  # deprecated in v1.70.00
            params['startType'].val = "{}".format('time (s)')
            params['startVal'].val = "{}".format(val)
            return  # times doesn't need to update its type or 'updates' rule
        elif name == 'forceEndTrial':  # deprecated in v1.70.00
            params['forceEndRoutine'].val = bool(val)
            return  # forceEndTrial doesn't need to update type or 'updates'
        elif name == 'forceEndTrialOnPress':  # deprecated in v1.70.00
            params['forceEndRoutineOnPress'].val = bool(val)
            return  # forceEndTrial doesn't need to update  type or 'updates'
        elif name == 'forceEndRoutineOnPress':
            if val == 'True':
                val = "any click"
            elif val == 'False':
                val = "never"
            params['forceEndRoutineOnPress'].val = val
            return
        elif name == 'trialList':  # deprecated in v1.70.00
            params['conditions'].val = eval(val)
            return  # forceEndTrial doesn't need to update  type or 'updates'
        elif name == 'trialListFile':  # deprecated in v1.70.00
            params['conditionsFile'].val = "{}".format(val)
            return  # forceEndTrial doesn't need to update  type or 'updates'
        elif name == 'duration':  # deprecated in v1.70.00
            params['stopType'].val = u'duration (s)'
            params['stopVal'].val = "{}".format(val)
            return  # times doesn't need to update its type or 'updates' rule
        elif name == 'allowedKeys' and valType == 'str':  # changed v1.70.00
            # ynq used to be allowed, now should be 'y','n','q' or
            # ['y','n','q']
            if len(val) == 0:
                newVal = val
            elif val[0] == '$':
                newVal = val[1:]  # they were using code (which we can reuse)
            elif val.startswith('[') and val.endswith(']'):
                # they were using code (slightly incorrectly!)
                newVal = val[1:-1]
            elif val in ['return', 'space', 'left', 'right', 'escape']:
                newVal = val  # they were using code
            else:
                # convert string to list of keys then represent again as a
                # string!
                newVal = repr(list(val))
            params['allowedKeys'].val = newVal
            params['allowedKeys'].valType = 'code'
        elif name == 'correctIf':  # deprecated in v1.60.00
            corrIf = val
            corrAns = corrIf.replace(
                'resp.keys==unicode(', '').replace(')', '')
            params['correctAns'].val = corrAns
            name = 'correctAns'  # then we can fetch other aspects below
        elif 'olour' in name:  # colour parameter was Americanised v1.61.00
            name = name.replace('olour', 'olor')
            params[name].val = val
        elif name == 'times':  # deprecated in v1.60.00
            times = eval('%s' % val)
            params['startType'].val = "{}".format('time (s)')
            params['startVal'].val = "{}".format(times[0])
            params['stopType'].val = "{}".format('time (s)')
            params['stopVal'].val = "{}".format(times[1])
            return  # times doesn't need to update its type or 'updates' rule
        elif name in ('Before Experiment', 'Begin Experiment', 'Begin Routine', 'Each Frame',
                      'End Routine', 'End Experiment',
                      'Before JS Experiment', 'Begin JS Experiment', 'Begin JS Routine', 'Each JS Frame',
                      'End JS Routine', 'End JS Experiment'):
            # up to version 1.78.00 and briefly in 2021.1.0-1.1 these were 'code'
            params[name].val = val
            params[name].valType = 'extendedCode'
            return  # so that we don't update valType again below
        elif name == 'Saved data folder':
            # deprecated in 1.80 for more complete data filename control
            params[name] = Param(
                val, valType='code', allowedTypes=[],
                hint=_translate("Name of the folder in which to save data"
                                " and log files (blank defaults to the "
                                "builder pref)"),
                categ='Data')
        elif name == 'channel':  # was incorrectly set to be valType='str' until 3.1.2
            params[name].val = val
            params[name].valType = 'code'  # override
        elif 'val' in list(paramNode.keys()):
            if val == 'window units':  # changed this value in 1.70.00
                params[name].val = 'from exp settings'
            # in v1.80.00, some RatingScale API and Param fields were changed
            # Try to avoid a KeyError in these cases so can load the expt
            elif name in ('choiceLabelsAboveLine', 'lowAnchorText',
                          'highAnchorText'):
                # not handled, just ignored; want labels=[lowAnchor,
                # highAnchor]
                return
            elif name == 'customize_everything':
                # Try to auto-update the code:
                v = val  # python code, not XML
                v = v.replace('markerStyle', 'marker').replace(
                    'customMarker', 'marker')
                v = v.replace('stretchHoriz', 'stretch').replace(
                    'displaySizeFactor', 'size')
                v = v.replace('textSizeFactor', 'textSize')
                v = v.replace('ticksAboveLine=False', 'tickHeight=-1')
                v = v.replace('showScale=False', 'scale=None').replace(
                    'allowSkip=False', 'skipKeys=None')
                v = v.replace('showAnchors=False', 'labels=None')
                # lowAnchorText highAnchorText will trigger obsolete error
                # when run the script
                params[name].val = v
            elif name == 'storeResponseTime':
                return  # deprecated in v1.70.00 because it was redundant
            elif name == 'Resources':
                # if the xml import hasn't automatically converted from string?
                if type(val) == str:
                    resources = data.utils.listFromString(val)
                if self.psychopyVersion == '2020.2.5':
                    # in 2020.2.5 only, problems were:
                    #   a) resources list was saved as a string and
                    #   b) with wrong root folder
                    resList = []
                    for resourcePath in resources:
                        # doing this the blunt way but should we check for existence?
                        resourcePath = resourcePath.replace("../", "")  # it was created using wrong root
                        resourcePath = resourcePath.replace("\\", "/")  # created using windows \\
                        resList.append(resourcePath)
                    resources = resList  # push our new list back to resources
                params[name].val = resources
            else:
                if name in params:
                    params[name].val = val
                else:
                    # we found an unknown parameter (probably from the future)
                    params[name] = Param(
                        val, valType=paramNode.get('valType'), inputType="inv",
                        allowedTypes=[], label=_translate(name),
                        hint=_translate(
                            "This parameter is not known by this version "
                            "of PsychoPy. It might be worth upgrading, otherwise "
                            "press the X button to remove this parameter."))
                    params[name].allowedTypes = paramNode.get('allowedTypes')
                    if params[name].allowedTypes is None:
                        params[name].allowedTypes = []
                    if name not in legacyParams + ['JS libs', 'OSF Project ID']:
                        # don't warn people if we know it's OK (e.g. for params
                        # that have been removed
                        msg = _translate(
                            "Parameter %r is not known to this version of "
                            "PsychoPy but has come from your experiment file "
                            "(saved by a future version of PsychoPy?). This "
                            "experiment may not run correctly in the current "
                            "version.")
                        logging.warn(msg % name)
                        logging.flush()

        # get the value type and update rate
        if 'valType' in list(paramNode.keys()):
            params[name].valType = paramNode.get('valType')
            # compatibility checks:
            if name in ['allowedKeys'] and paramNode.get('valType') == 'str':
                # these components were changed in v1.70.00
                params[name].valType = 'code'
            elif name == 'Selected rows':
                # changed in 1.81.00 from 'code' to 'str': allow string or var
                params[name].valType = 'str'
            # conversions based on valType
            if params[name].valType == 'bool':
                params[name].val = eval("%s" % params[name].val)
        if 'updates' in list(paramNode.keys()):
            params[name].updates = paramNode.get('updates')
Beispiel #44
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import, print_function

from os import path
from psychopy.experiment.components import BaseComponent, Param, getInitVals

from psychopy.localization import _translate

# the absolute path to the folder containing this path
thisFolder = path.abspath(path.dirname(__file__))
iconFile = path.join(thisFolder, 'image.png')
tooltip = _translate('Image: present images (bmp, jpg, tif...)')

# only use _localized values for label values, nothing functional:
_localized = {
    'image': _translate('Image'),
    'ipd': _translate('IPD'),
    'mask': _translate('Mask'),
    'texture resolution': _translate('Texture resolution'),
    'flipVert': _translate('Flip vertically'),
    'flipHoriz': _translate('Flip horizontally'),
    'interpolate': _translate('Interpolate')
}


class VRDisplayComponent(BaseComponent):
    """An event class for presenting image-based stimuli"""
    categories = ['Stimuli']
Beispiel #45
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# This file was generated by generateAlertmsg.py.
# Following strings are used to localize alerts.
# Rebuild this file if alert messages in *.yaml files are modified.

from __future__ import absolute_import, print_function
from psychopy.localization import _translate

# Alert 2115
_translate(
    "Your stimulus size exceeds the {dimension} dimension of your window.")

# Alert 2120
_translate(
    "Your stimulus size is smaller than 1 pixel ({dimension} dimension).")

# Alert 2155
_translate(
    "Your stimulus position exceeds the {dimension} dimension of your window.")

# Alert 3110
_translate(
    "Your stimulus {type} time of {time} is less than a screen refresh for a {Hz}Hz monitor."
)

# Alert 3115
_translate(
    "Your stimulus {type} time of {time} seconds cannot be accurately presented for {time} on a {Hz}Hz monitor."
)
Beispiel #46
0
def getProject(filename):
    """Will try to find (locally synced) pavlovia Project for the filename
    """
    if not haveGit:
        raise exceptions.DependencyError(
            "gitpython and a git installation required for getProject()")

    gitRoot = getGitRoot(filename)
    if gitRoot in knownProjects:
        return knownProjects[gitRoot]
    elif gitRoot:
        # Existing repo but not in our knownProjects. Investigate
        logging.info("Investigating repo at {}".format(gitRoot))
        localRepo = git.Repo(gitRoot)
        proj = None
        for remote in localRepo.remotes:
            for url in remote.urls:
                if "gitlab.pavlovia.org" in url:
                    # could be 'https://gitlab.pavlovia.org/NameSpace/Name.git'
                    # or may be '[email protected]:NameSpace/Name.git'
                    namespaceName = url.split('gitlab.pavlovia.org')[1]
                    # remove the first char (: or /)
                    if namespaceName[0] in ['/', ':']:
                        namespaceName = namespaceName[1:]
                    # remove the .git at the end if present
                    namespaceName = namespaceName.replace('.git', '')
                    pavSession = getCurrentSession()
                    if not pavSession.user:
                        nameSpace = namespaceName.split('/')[0]
                        if nameSpace in knownUsers:  # Log in if user is known
                            login(nameSpace, rememberMe=True)
                        else:  # Check whether project repo is found in any of the known users accounts
                            for user in knownUsers:
                                try:
                                    login(user)
                                except requests.exceptions.ConnectionError:
                                    break
                                foundProject = False
                                for repo in pavSession.findUserProjects():
                                    if namespaceName in repo['id']:
                                        foundProject = True
                                        logging.info(
                                            "Logging in as {}".format(user))
                                        break
                                if not foundProject:
                                    logging.warning(
                                        "Could not find {namespace} in your Pavlovia accounts. "
                                        "Logging in as {user}.".format(
                                            namespace=namespaceName,
                                            user=user))
                    if pavSession.user:
                        proj = pavSession.getProject(namespaceName,
                                                     repo=localRepo)
                        if proj.pavlovia and proj.pavlovia.get_id() == 0:
                            logging.warning(
                                _translate(
                                    "We found a repository pointing to {} "
                                    "but no project was found there (deleted?)"
                                ).format(url))
                    else:
                        logging.warning(
                            _translate(
                                "We found a repository pointing to {} "
                                "but no user is logged in for us to check it".
                                format(url)))
                    return proj

        if proj == None:
            logging.warning("We found a repository at {} but it "
                            "doesn't point to gitlab.pavlovia.org. "
                            "You could create that as a remote to "
                            "sync from PsychoPy.".format(gitRoot))
Beispiel #47
0
    def __init__(self,
                 app,
                 pos=wx.DefaultPosition,
                 size=dlgSize,
                 style=defaultStyle):
        title = _translate("PsychoPy Preferences")
        wx.Dialog.__init__(self, None, -1, title, pos, size, style)
        self.app = app
        self.Center()
        self.prefsCfg = self.app.prefs.userPrefsCfg
        self.prefsSpec = self.app.prefs.prefsSpec
        sizer = wx.BoxSizer(wx.VERTICAL)

        line = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL)
        lineStyle = wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP
        sizer.Add(line, 0, lineStyle, 5)

        # notebook, flatnotebook or something else?

        self.nb = fnb.FlatNotebook(self,
                                   style=fnb.FNB_NO_X_BUTTON
                                   | fnb.FNB_NO_NAV_BUTTONS)
        # self.nb = wx.Notebook(self)  # notebook not nice with lots of pages

        self.ctrls = {}
        sectionOrdering = [
            'general', 'app', 'builder', 'coder', 'hardware', 'connections',
            'keyBindings'
        ]
        for section in sectionOrdering:
            prefsPage = self.makePrefPage(parent=self.nb,
                                          sectionName=section,
                                          prefsSection=self.prefsCfg[section],
                                          specSection=self.prefsSpec[section])
            self.nb.AddPage(prefsPage, _localized[section])
        self.nb.SetSelection(self.app.prefs.pageCurrent)
        sizer.Add(self.nb, 1, wx.EXPAND)

        aTable = wx.AcceleratorTable([
            (wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL),
            (wx.ACCEL_NORMAL, wx.WXK_RETURN, wx.ID_OK),
        ])
        self.SetAcceleratorTable(aTable)

        # create buttons
        line = wx.StaticLine(self, -1, size=(20, -1), style=wx.LI_HORIZONTAL)
        sizer.Add(line, 0,
                  wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.RIGHT | wx.TOP, 5)
        btnsizer = wx.StdDialogButtonSizer()
        # ok
        btn = wx.Button(self, wx.ID_OK, _translate('OK'))
        btn.SetHelpText(
            _translate("Save prefs (in all sections) and close "
                       "window"))
        btn.Bind(wx.EVT_BUTTON, self.onOK)
        btn.SetDefault()
        btnsizer.AddButton(btn)
        # cancel
        btn = wx.Button(self, wx.ID_CANCEL, _translate('Cancel'))
        btn.SetHelpText(_translate("Cancel any changes (to any panel)"))
        btn.Bind(wx.EVT_BUTTON, self.onCancel)
        btnsizer.AddButton(btn)
        # help
        btn = wx.Button(self, wx.ID_HELP, _translate('Help'))
        btn.SetHelpText(_translate("Get help on prefs"))
        btn.Bind(wx.EVT_BUTTON, self.onHelp)
        btnsizer.AddButton(btn)
        btnsizer.Realize()
        # add buttons to dlg
        sizer.Add(btnsizer, 0, wx.BOTTOM | wx.ALL, 5)

        self.SetSizerAndFit(sizer)
        self.SetAutoLayout(True)
        sizer.Fit(self)
Beispiel #48
0
from . import dialogs
from psychopy import localization
from psychopy.localization import _translate
from pkg_resources import parse_version
from psychopy import sound
from psychopy.app.utils import getSystemFonts
import collections

# this will be overridden by the size of the scrolled panel making the prefs
dlgSize = (600, 500)

# labels mappings for display:
_localized = {
    # section labels:
    'general': _translate('General'),
    'app': _translate('App'),
    'builder': "Builder",  # not localized
    'coder': "Coder",  # not localized
    'hardware': _translate('Hardware'),
    'connections': _translate('Connections'),
    'keyBindings': _translate('Key bindings'),
    # pref labels:
    'winType': _translate("window type"),
    'units': _translate("units"),
    'fullscr': _translate("full-screen"),
    'allowGUI': _translate("allow GUI"),
    'paths': _translate('paths'),
    'audioLib': _translate("audio library"),
    'audioDriver': _translate("audio driver"),
    'audioDevice': _translate("audio device"),
Beispiel #49
0
    def applyPrefs(self):
        """Write preferences to the current configuration."""
        if not self.proPrefs.isModified():
            return

        if platform.system() == 'Darwin':
            re_cmd2ctrl = re.compile('^Cmd\+', re.I)

        for sectionName in self.prefsSpec:
            for prefName in self.prefsSpec[sectionName]:
                if prefName in ['version']:  # any other prefs not to show?
                    continue

                thisPref = self.proPrefs.getPrefVal(sectionName, prefName)
                # handle special cases
                if prefName in ('codeFont', 'commentFont', 'outputFont'):
                    self.prefsCfg[sectionName][prefName] = \
                        self.fontList[thisPref]
                    continue
                elif prefName == 'audioDevice':
                    self.prefsCfg[sectionName][prefName] = \
                        self.audioDevNames[thisPref]
                    continue
                elif prefName == 'locale':
                    # fake spec -> option: use available locale info not spec file
                    self.app.prefs.app['locale'] = \
                        self.app.localization.available[thisPref]
                    self.prefsCfg[sectionName][prefName] = \
                        self.app.localization.available[thisPref]
                    continue

                # remove invisible trailing whitespace:
                if hasattr(thisPref, 'strip'):
                    thisPref = thisPref.strip()
                # regularize the display format for keybindings
                if sectionName == 'keyBindings':
                    thisPref = thisPref.replace(' ', '')
                    thisPref = '+'.join([part.capitalize()
                                         for part in thisPref.split('+')])
                    if platform.system() == 'Darwin':
                        # key-bindings were displayed as 'Cmd+O', revert to
                        # 'Ctrl+O' internally
                        thisPref = re_cmd2ctrl.sub('Ctrl+', thisPref)
                self.prefsCfg[sectionName][prefName] = thisPref

                # make sure list values are converted back to lists (from str)
                if self.prefsSpec[sectionName][prefName].startswith('list'):
                    try:
                        # if thisPref is not a null string, do eval() to get a
                        # list.
                        if thisPref == '' or type(thisPref) == list:
                            newVal = thisPref
                        else:
                            newVal = eval(thisPref)
                    except Exception:
                        # if eval() failed, show warning dialog and return
                        try:
                            pLabel = _localized[prefName]
                            sLabel = _localized[sectionName]
                        except Exception:
                            pLabel = prefName
                            sLabel = sectionName
                        txt = _translate(
                            'Invalid value in "%(pref)s" ("%(section)s" Tab)')
                        msg = txt % {'pref': pLabel, 'section': sLabel}
                        title = _translate('Error')
                        warnDlg = dialogs.MessageDialog(parent=self,
                                                        message=msg,
                                                        type='Info',
                                                        title=title)
                        resp = warnDlg.ShowModal()
                        return
                    if type(newVal) != list:
                        self.prefsCfg[sectionName][prefName] = [newVal]
                    else:
                        self.prefsCfg[sectionName][prefName] = newVal
                elif self.prefsSpec[sectionName][prefName].startswith('option'):
                    vals = self.prefsSpec[sectionName][prefName].replace(
                        "option(", "").replace("'", "")
                    # item -1 is 'default=x' from spec
                    options = vals.replace(", ", ",").split(',')[:-1]
                    self.prefsCfg[sectionName][prefName] = options[thisPref]

        self.app.prefs.saveUserPrefs()  # includes a validation
        # maybe then go back and set GUI from prefs again, because validation
        # may have changed vals?
        # > sure, why not? - mdc
        self.populatePrefs()

        # after validation, update the UI
        self.updateCoderUI()
Beispiel #50
0
    def __init__(self,
                 parent,
                 noTitle=False,
                 style=wx.VSCROLL | wx.NO_BORDER,
                 project={}):

        scrlpanel.ScrolledPanel.__init__(self, parent, -1, style=style)
        self.parent = parent
        self.project = project  # type: pavlovia.PavloviaProject
        self.noTitle = noTitle
        self.localFolder = ''
        self.syncPanel = None

        if not noTitle:
            self.title = wx.StaticText(parent=self,
                                       id=-1,
                                       label="",
                                       style=wx.ALIGN_CENTER)
            font = wx.Font(18, wx.DECORATIVE, wx.NORMAL, wx.BOLD)
            self.title.SetFont(font)

        # if we've synced before we should know the local location
        self.localFolderCtrl = wx.StaticText(parent=self,
                                             id=wx.ID_ANY,
                                             label=_translate("Local root: "))
        self.browseLocalBtn = wx.Button(parent=self,
                                        id=wx.ID_ANY,
                                        label=_translate("Browse..."))
        self.browseLocalBtn.Bind(wx.EVT_BUTTON, self.onBrowseLocalFolder)

        # remote attributes
        self.url = wxhl.HyperLinkCtrl(
            parent=self,
            id=-1,
            label="https://pavlovia.org",
            URL="https://pavlovia.org",
        )
        self.description = wx.StaticText(
            parent=self,
            id=-1,
            label=_translate("Select a project for details"))
        self.tags = wx.StaticText(parent=self, id=-1, label="")
        self.visibility = wx.StaticText(parent=self, id=-1, label="")

        self.syncButton = wx.Button(self, -1, _translate("Sync..."))
        self.syncButton.Enable(False)
        self.syncButton.Bind(wx.EVT_BUTTON, self.onSyncButton)
        self.syncPanel = sync.SyncStatusPanel(parent=self, id=wx.ID_ANY)

        # layout
        # sizers: on the right we have detail
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        # self.sizer.Add(wx.StaticText(self, -1, _translate("Project Info")),
        #                flag=wx.ALL,
        #                border=5)
        if not noTitle:
            self.sizer.Add(self.title, border=5, flag=wx.ALL | wx.CENTER)
        self.sizer.Add(self.url, border=5, flag=wx.ALL | wx.CENTER)
        self.sizer.Add(self.localFolderCtrl, border=5,
                       flag=wx.ALL | wx.EXPAND),
        self.sizer.Add(self.browseLocalBtn, border=5, flag=wx.ALL | wx.LEFT)
        self.sizer.Add(self.tags, border=5, flag=wx.ALL | wx.EXPAND)
        self.sizer.Add(self.visibility, border=5, flag=wx.ALL | wx.EXPAND)
        self.sizer.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL),
                       flag=wx.ALL | wx.EXPAND)
        self.sizer.Add(self.description, border=10, flag=wx.ALL | wx.EXPAND)

        self.sizer.Add(wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL),
                       flag=wx.ALL | wx.EXPAND)
        self.sizer.Add(self.syncButton, flag=wx.ALL | wx.RIGHT, border=5)
        self.sizer.Add(self.syncPanel,
                       border=5,
                       proportion=1,
                       flag=wx.ALL | wx.RIGHT | wx.EXPAND)

        if self.project:
            self.setProject(self.project)
            self.syncPanel.setStatus(_translate("Ready to sync"))
        else:
            self.syncPanel.setStatus(
                _translate("This file doesn't belong to a project yet"))

        self.SetAutoLayout(True)
        self.SetSizerAndFit(self.sizer)
        self.SetupScrolling()
        self.Bind(wx.EVT_SIZE, self.onResize)
Beispiel #51
0
    def onInit(self, showSplash=True, testMode=False):
        """This is launched immediately *after* the app initialises with wx
        :Parameters:

          testMode: bool
        """
        self.SetAppName('PsychoPy3')

        if False:
            # show splash screen
            splashFile = os.path.join(self.prefs.paths['resources'],
                                      'psychopySplash.png')
            splashImage = wx.Image(name=splashFile)
            splashImage.ConvertAlphaToMask()
            splash = AS.AdvancedSplash(
                None,
                bitmap=splashImage.ConvertToBitmap(),
                timeout=3000,
                agwStyle=AS.AS_TIMEOUT | AS.AS_CENTER_ON_SCREEN,
            )  # transparency?
            w, h = splashImage.GetSize()
            splash.SetTextPosition((int(w - 130), h - 20))
            splash.SetText(_translate("Loading libraries..."))
            wx.Yield()
        else:
            splash = None

        # SLOW IMPORTS - these need to be imported after splash screen starts
        # but then that they end up being local so keep track in self
        if splash:
            splash.SetText(_translate("Loading PsychoPy3..."))
            wx.Yield()
        from psychopy.compatibility import checkCompatibility
        # import coder and builder here but only use them later
        from psychopy.app import coder, builder, dialogs

        if '--firstrun' in sys.argv:
            del sys.argv[sys.argv.index('--firstrun')]
            self.firstRun = True
        if 'lastVersion' not in self.prefs.appData:
            # must be before 1.74.00
            last = self.prefs.appData['lastVersion'] = '1.73.04'
            self.firstRun = True
        else:
            last = self.prefs.appData['lastVersion']

        if self.firstRun and not self.testMode:
            pass

        # setup links for URLs
        # on a mac, don't exit when the last frame is deleted, just show menu
        if sys.platform == 'darwin':
            self.menuFrame = MenuFrame(parent=None, app=self)
        # get preferred view(s) from prefs and previous view
        if self.prefs.app['defaultView'] == 'last':
            mainFrame = self.prefs.appData['lastFrame']
        else:
            # configobjValidate should take care of this situation
            allowed = ['last', 'coder', 'builder', 'both']
            if self.prefs.app['defaultView'] in allowed:
                mainFrame = self.prefs.app['defaultView']
            else:
                self.prefs.app['defaultView'] = 'both'
                mainFrame = 'both'
        # fetch prev files if that's the preference
        if self.prefs.coder['reloadPrevFiles']:
            scripts = self.prefs.appData['coder']['prevFiles']
        else:
            scripts = []
        appKeys = list(self.prefs.appData['builder'].keys())
        if self.prefs.builder['reloadPrevExp'] and ('prevFiles' in appKeys):
            exps = self.prefs.appData['builder']['prevFiles']
        else:
            exps = []

        # then override the prev files by command options and passed files
        if len(sys.argv) > 1:
            if sys.argv[1] == __name__:
                # program was executed as "python.exe psychopyApp.py %1'
                args = sys.argv[2:]
            else:
                # program was executed as "psychopyApp.py %1'
                args = sys.argv[1:]
            # choose which frame to start with
            if args[0] in ['builder', '--builder', '-b']:
                mainFrame = 'builder'
                args = args[1:]  # can remove that argument
            elif args[0] in ['coder', '--coder', '-c']:
                mainFrame = 'coder'
                args = args[1:]  # can remove that argument
            # did we get .py or .psyexp files?
            elif args[0][-7:] == '.psyexp':
                mainFrame = 'builder'
                exps = [args[0]]
            elif args[0][-3:] == '.py':
                mainFrame = 'coder'
                scripts = [args[0]]
        else:
            args = []

        self.dpi = int(wx.GetDisplaySize()[0] /
                       float(wx.GetDisplaySizeMM()[0]) * 25.4)
        if not (50 < self.dpi < 120):
            self.dpi = 80  # dpi was unreasonable, make one up

        if sys.platform == 'win32':
            # wx.SYS_DEFAULT_GUI_FONT is default GUI font in Win32
            self._mainFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
        else:
            self._mainFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT)

        try:
            self._codeFont = wx.SystemSettings.GetFont(wx.SYS_ANSI_FIXED_FONT)
        except wx._core.wxAssertionError:
            # if no SYS_ANSI_FIXED_FONT then try generic FONTFAMILY_MODERN
            self._codeFont = wx.Font(self._mainFont.GetPointSize(),
                                     wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL,
                                     wx.FONTWEIGHT_NORMAL)
        self._codeFont.SetFaceName(self.prefs.coder['codeFont'])

        # removed Aug 2017: on newer versions of wx (at least on mac)
        # this looks too big
        # if hasattr(self._mainFont, 'Larger'):
        #     # Font.Larger is available since wyPython version 2.9.1
        #     # PsychoPy still supports 2.8 (see ensureMinimal above)
        #     self._mainFont = self._mainFont.Larger()
        #     self._codeFont.SetPointSize(
        #         self._mainFont.GetPointSize())  # unify font size

        # create both frame for coder/builder as necess
        if splash:
            splash.SetText(_translate("  Creating frames..."))
        if mainFrame in ['both', 'coder']:
            self.showCoder(fileList=scripts)
        if mainFrame in ['both', 'builder']:
            self.showBuilder(fileList=exps)

        # send anonymous info to www.psychopy.org/usage.php
        # please don't disable this, it's important for PsychoPy's development
        self._latestAvailableVersion = None
        self.updater = None
        self.news = None
        self.tasks = None

        prefsConn = self.prefs.connections

        ok, msg = checkCompatibility(last, self.version, self.prefs, fix=True)
        # tell the user what has changed
        if not ok and not self.firstRun and not self.testMode:
            title = _translate("Compatibility information")
            dlg = dialogs.MessageDialog(parent=None,
                                        message=msg,
                                        type='Info',
                                        title=title)
            dlg.ShowModal()

        if (self.prefs.app['showStartupTips'] and not self.testMode
                and not blockTips):
            tipFile = os.path.join(self.prefs.paths['resources'],
                                   _translate("tips.txt"))
            tipIndex = self.prefs.appData['tipIndex']
            if parse_version(wx.__version__) >= parse_version('4.0.0a1'):
                tp = wx.adv.CreateFileTipProvider(tipFile, tipIndex)
                showTip = wx.adv.ShowTip(None, tp)
            else:
                tp = wx.CreateFileTipProvider(tipFile, tipIndex)
                showTip = wx.ShowTip(None, tp)

            self.prefs.appData['tipIndex'] = tp.GetCurrentTip()
            self.prefs.saveAppData()
            self.prefs.app['showStartupTips'] = showTip
            self.prefs.saveUserPrefs()

        self.Bind(wx.EVT_IDLE, self.onIdle)

        # doing this once subsequently enables the app to open & switch among
        # wx-windows on some platforms (Mac 10.9.4) with wx-3.0:
        v = parse_version
        if sys.platform == 'darwin':
            if v('3.0') <= v(wx.version()) < v('4.0'):
                _Showgui_Hack()  # returns ~immediately, no display
                # focus stays in never-land, so bring back to the app:
                if mainFrame in ['both', 'builder']:
                    self.showBuilder()
                else:
                    self.showCoder()
        # after all windows are created (so errors flushed) create output
        self._appLoaded = True
        if self.coder:
            self.coder.setOutputWindow()  # takes control of sys.stdout
        return True
Beispiel #52
0
    def __init__(self,
                 exp,
                 parentName,
                 name='',
                 units='from exp settings',
                 color='$[1,1,1]',
                 borderColor="",
                 fillColor="",
                 pos=(0, 0),
                 size=(0, 0),
                 ori=0,
                 colorSpace='rgb',
                 opacity=1,
                 startType='time (s)',
                 startVal='',
                 stopType='duration (s)',
                 stopVal='',
                 startEstim='',
                 durationEstim='',
                 saveStartStop=True,
                 syncScreenRefresh=True):

        super(BaseVisualComponent,
              self).__init__(exp,
                             parentName,
                             name,
                             startType=startType,
                             startVal=startVal,
                             stopType=stopType,
                             stopVal=stopVal,
                             startEstim=startEstim,
                             durationEstim=durationEstim,
                             saveStartStop=saveStartStop,
                             syncScreenRefresh=syncScreenRefresh)

        self.exp.requirePsychopyLibs(['visual'
                                      ])  # needs this psychopy lib to operate

        msg = _translate("Units of dimensions for this stimulus")
        self.params['units'] = Param(units,
                                     valType='str',
                                     categ='Layout',
                                     allowedVals=[
                                         'from exp settings', 'deg', 'cm',
                                         'pix', 'norm', 'height', 'degFlatPos',
                                         'degFlat'
                                     ],
                                     hint=msg,
                                     label=_localized['units'])

        msg = _translate(
            "Foreground color of this stimulus (e.g. $[1,1,0], red );"
            " Right-click to bring up a color-picker (rgb only)")
        self.params['color'] = Param(
            color,
            valType='str',
            allowedTypes=[],
            categ='Appearance',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['color'])

        msg = _translate("In what format (color space) have you specified "
                         "the foreground color? (rgb, dkl, lms, hsv)")
        self.params['colorSpace'] = Param(
            colorSpace,
            valType='str',
            categ='Appearance',
            allowedVals=['rgb', 'dkl', 'lms', 'hsv'],
            updates='constant',
            hint=msg,
            label=_localized['colorSpace'])

        msg = _translate("Fill color of this stimulus (e.g. $[1,1,0], red );"
                         " Right-click to bring up a color-picker (rgb only)")
        self.params['fillColor'] = Param(
            fillColor,
            valType='str',
            allowedTypes=[],
            categ='Appearance',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['fillColor'])

        msg = _translate("In what format (color space) have you specified "
                         "the fill color? (rgb, dkl, lms, hsv)")
        self.params['fillColorSpace'] = Param(
            colorSpace,
            valType='str',
            categ='Appearance',
            allowedVals=['rgb', 'dkl', 'lms', 'hsv'],
            updates='constant',
            hint=msg,
            label=_localized['fillColorSpace'])

        msg = _translate("Color of this stimulus (e.g. $[1,1,0], red );"
                         " Right-click to bring up a color-picker (rgb only)")
        self.params['borderColor'] = Param(
            borderColor,
            valType='str',
            allowedTypes=[],
            categ='Appearance',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['borderColor'])

        msg = _translate("In what format (color space) have you specified "
                         "the border color? (rgb, dkl, lms, hsv)")
        self.params['borderColorSpace'] = Param(
            colorSpace,
            valType='str',
            categ='Appearance',
            allowedVals=['rgb', 'dkl', 'lms', 'hsv'],
            updates='constant',
            hint=msg,
            label=_localized['borderColorSpace'])

        msg = _translate("Opacity of the stimulus (1=opaque, 0=fully "
                         "transparent, 0.5=translucent)")
        self.params['opacity'] = Param(
            opacity,
            valType='code',
            allowedTypes=[],
            categ='Appearance',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['opacity'])

        msg = _translate("Position of this stimulus (e.g. [1,2] )")
        self.params['pos'] = Param(
            pos,
            valType='code',
            allowedTypes=[],
            categ='Layout',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['pos'])

        msg = _translate("Size of this stimulus (either a single value or "
                         "x,y pair, e.g. 2.5, [1,2] ")
        self.params['size'] = Param(
            size,
            valType='code',
            allowedTypes=[],
            categ='Layout',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=msg,
            label=_localized['size'])

        self.params['ori'] = Param(
            ori,
            valType='code',
            allowedTypes=[],
            categ='Layout',
            updates='constant',
            allowedUpdates=['constant', 'set every repeat', 'set every frame'],
            hint=_translate("Orientation of this stimulus (in deg)"),
            label=_localized['ori'])

        self.params['syncScreenRefresh'].readOnly = True
Beispiel #53
0
    def makeTools(self):

        iconCache = self.app.iconCache
        iconSize = 16
        # Load in icons for toolbars
        # Redraw toolbar buttons
        self.newFolderTool = iconCache.makeBitmapButton(
                self,
                filename='foldernew',
                name='foldernew',
                label=_translate(
                        'New Folder'),
                toolbar=self.toolBar,
                tip=_translate(
                        "Create a new folder in the current folder"),
                size=iconSize)
        self.renameTool = iconCache.makeBitmapButton(
                self, filename='rename',
                name='rename',
                label=_translate('Rename'),
                toolbar=self.toolBar,
                tip=_translate(
                        "Rename the selected folder or file"),
                size=iconSize)
        self.deleteTool = iconCache.makeBitmapButton(
                self, filename='delete',
                name='delete',
                label=_translate('Delete'),
                toolbar=self.toolBar,
                tip=_translate(
                        "Delete the selected folder or file"),
                size=iconSize)
        self.gotoTool = iconCache.makeBitmapButton(
                self, filename='goto',
                name='goto',
                label=_translate('Goto'),
                toolbar=self.toolBar,
                tip=_translate(
                        "Jump to another folder"),
                size=iconSize,
                tbKind=wx.ITEM_DROPDOWN)
        # create the dropdown menu for goto
        self.gotoMenu = wx.Menu()
        item = self.gotoMenu.Append(
            wx.ID_ANY,
            _translate("Browse ..."),
            _translate("Browse the file system for a directory to open"))
        self.Bind(wx.EVT_MENU, self.OnBrowse, id=item.GetId())
        self.gotoMenu.AppendSeparator()
        item = self.gotoMenu.Append(
            wx.ID_ANY,
            _translate("Current working directory"),
            _translate("Open the current working directory"))
        self.Bind(wx.EVT_MENU, self.OnGotoCWD, id=item.GetId())
        item = self.gotoMenu.Append(
            wx.ID_ANY,
            _translate("Editor file location"),
            _translate("Open the directory the current editor file is located"))
        self.Bind(wx.EVT_MENU, self.OnGotoFileLocation, id=item.GetId())
        # Bind toolbar buttons
        self.Bind(wx.EVT_TOOL, self.OnBrowse, self.gotoTool)
        self.Bind(aui.EVT_AUITOOLBAR_TOOL_DROPDOWN, self.OnGotoMenu, self.gotoTool)
        self.Bind(wx.EVT_TOOL, self.OnNewFolderTool, self.newFolderTool)
        self.Bind(wx.EVT_TOOL, self.OnDeleteTool, self.deleteTool)
        self.Bind(wx.EVT_TOOL, self.OnRenameTool, self.renameTool)
        self.gotoTool.SetDropdownMenu(self.gotoMenu)

        # Realise
        self.toolBar.Realize()
Beispiel #54
0
    def __init__(self,
                 exp,
                 parentName,
                 name='',
                 startType='time (s)',
                 startVal='',
                 stopType='duration (s)',
                 stopVal='',
                 startEstim='',
                 durationEstim='',
                 saveStartStop=True,
                 syncScreenRefresh=False,
                 disabled=False):
        self.type = 'Base'
        self.exp = exp  # so we can access the experiment if necess
        self.parentName = parentName  # to access the routine too if needed

        self.params = {}
        self.depends = []  # allows params to turn each other off/on
        """{
         "dependsOn": "shape",
         "condition": "=='n vertices",
         "param": "n vertices",
         "true": "enable",  # what to do with param if condition is True
         "false": "disable",  # permitted: hide, show, enable, disable
         }"""

        msg = _translate(
            "Name of this component (alpha-numeric or _, no spaces)")
        self.params['name'] = Param(name,
                                    valType='code',
                                    categ='Basic',
                                    hint=msg,
                                    label=_localized['name'])

        msg = _translate("How do you want to define your start point?")
        self.params['startType'] = Param(
            startType,
            valType='str',
            categ='Basic',
            allowedVals=['time (s)', 'frame N', 'condition'],
            hint=msg,
            label=_localized['startType'])

        msg = _translate("How do you want to define your end point?")
        self.params['stopType'] = Param(stopType,
                                        valType='str',
                                        categ='Basic',
                                        allowedVals=[
                                            'duration (s)',
                                            'duration (frames)', 'time (s)',
                                            'frame N', 'condition'
                                        ],
                                        hint=msg,
                                        label=_localized['stopType'])

        self.params['startVal'] = Param(
            startVal,
            valType='code',
            allowedTypes=[],
            categ='Basic',
            hint=_translate("When does the component start?"),
            label=_localized['startVal'])

        self.params['stopVal'] = Param(
            stopVal,
            valType='code',
            allowedTypes=[],
            categ='Basic',
            updates='constant',
            allowedUpdates=[],
            hint=_translate("When does the component end? (blank is endless)"),
            label=_localized['stopVal'])

        msg = _translate("(Optional) expected start (s), purely for "
                         "representing in the timeline")
        self.params['startEstim'] = Param(startEstim,
                                          valType='code',
                                          allowedTypes=[],
                                          categ='Basic',
                                          hint=msg,
                                          label=_localized['startEstim'])

        msg = _translate("(Optional) expected duration (s), purely for "
                         "representing in the timeline")
        self.params['durationEstim'] = Param(durationEstim,
                                             valType='code',
                                             allowedTypes=[],
                                             categ='Basic',
                                             hint=msg,
                                             label=_localized['durationEstim'])

        msg = _translate("Store the onset/offset times in the data file "
                         "(as well as in the log file).")
        self.params['saveStartStop'] = Param(
            saveStartStop,
            valType='bool',
            allowedTypes=[],
            categ='Data',
            hint=msg,
            label=_translate('Save onset/offset times'))

        msg = _translate("Synchronize times with screen refresh (good for "
                         "visual stimuli and responses based on them)")
        self.params['syncScreenRefresh'] = Param(
            syncScreenRefresh,
            valType='bool',
            allowedTypes=[],
            hint=msg,
            categ="Data",
            label=_translate('Sync timing with screen refresh'))

        msg = _translate("Disable this component")
        self.params['disabled'] = Param(disabled,
                                        valType='bool',
                                        allowedTypes=[],
                                        hint=msg,
                                        categ="Testing",
                                        label=_translate('Disable component'))

        self.order = ['name']  # name first, then timing, then others
Beispiel #55
0
    def __init__(self,
                 frame,
                 title,
                 params,
                 order,
                 helpUrl=None,
                 suppressTitles=True,
                 size=wx.DefaultSize,
                 style=_style,
                 editing=False,
                 depends=[],
                 timeout=None):

        # translate title
        localizedTitle = title.replace(' Properties',
                                       _translate(' Properties'))
        wx.Dialog.__init__(self,
                           None,
                           -1,
                           localizedTitle,
                           size=size,
                           style=style)
        self.frame = frame
        self.app = frame.app
        self.helpUrl = helpUrl
        self.params = params  # dict
        self.order = order
        self.title = title
        self.timeout = timeout
        self.warningsDict = {}  # to store warnings for all fields
        # keep localized title to update dialog's properties later.
        self.localizedTitle = localizedTitle
        self.codeBoxes = {}
        self.tabs = OrderedDict()

        if not editing and 'name' in self.params:
            # then we're adding a new component so ensure a valid name:
            makeValid = self.frame.exp.namespace.makeValid
            self.params['name'].val = makeValid(params['name'].val)

        agwStyle = flatnotebook.FNB_NO_X_BUTTON
        if hasattr(flatnotebook, "FNB_NAV_BUTTONS_WHEN_NEEDED"):
            # not available in wxPython 2.8
            agwStyle |= flatnotebook.FNB_NAV_BUTTONS_WHEN_NEEDED
        if hasattr(flatnotebook, "FNB_NO_TAB_FOCUS"):
            # not available in wxPython 2.8.10
            agwStyle |= flatnotebook.FNB_NO_TAB_FOCUS
        self.codeNotebook = flatnotebook.FlatNotebook(self,
                                                      wx.ID_ANY,
                                                      style=agwStyle)

        openToPage = None
        tabN = -1
        for paramN, paramName in enumerate(self.order):
            param = self.params.get(paramName)
            if paramName == 'name':
                self.nameLabel = wx.StaticText(self, wx.ID_ANY,
                                               _translate(param.label))
                _style = wx.TE_PROCESS_ENTER | wx.TE_PROCESS_TAB
                self.componentName = wx.TextCtrl(self,
                                                 wx.ID_ANY,
                                                 str(param.val),
                                                 style=_style)
                self.componentName.SetToolTip(
                    wx.ToolTip(_translate(param.hint)))
                self.componentName.SetValidator(validators.NameValidator())
                self.nameOKlabel = wx.StaticText(self,
                                                 -1,
                                                 '',
                                                 style=wx.ALIGN_RIGHT)
                self.nameOKlabel.SetForegroundColour(wx.RED)
            elif paramName == 'Code Type':
                # Create code type choice menu
                _codeTypes = self.params['Code Type'].allowedVals
                _selectedCodeType = self.params['Code Type'].val
                _selectedCodeTypeIndex = _codeTypes.index(_selectedCodeType)
                self.codeTypeMenu = wx.Choice(self, choices=_codeTypes)
                # If user does not have metapensiero but codetype is auto-js, revert to (Py?)
                if not hasMetapensiero and _selectedCodeType.lower(
                ) == 'auto->js':
                    _selectedCodeTypeIndex -= 1
                # Set selection to value stored in self params
                self.codeTypeMenu.SetSelection(_selectedCodeTypeIndex)
                self.codeTypeMenu.Bind(wx.EVT_CHOICE, self.onCodeChoice)
                self.codeTypeName = wx.StaticText(self, wx.ID_ANY,
                                                  _translate(param.label))
            else:
                codeType = ["Py",
                            "JS"]["JS"
                                  in paramName]  # Give CodeBox a code type
                tabName = paramName.replace("JS ", "")
                if tabName in self.tabs:
                    _panel = self.tabs[tabName]
                else:
                    _panel = wx.Panel(self.codeNotebook, wx.ID_ANY)
                    self.tabs[tabName] = _panel
                    tabN += 1

                self.codeBoxes[paramName] = CodeBox(_panel,
                                                    wx.ID_ANY,
                                                    pos=wx.DefaultPosition,
                                                    style=0,
                                                    prefs=self.app.prefs,
                                                    params=params,
                                                    codeType=codeType)
                self.codeBoxes[paramName].AddText(param.val)
                self.codeBoxes[paramName].Bind(
                    wx.EVT_KEY_UP, self.onKeyUp)  # For real time translation

                if len(param.val.strip()) and openToPage is None:
                    # index of first non-blank page
                    openToPage = tabN

        if self.helpUrl is not None:
            self.helpButton = wx.Button(self, wx.ID_HELP, _translate(" Help "))
            tip = _translate("Go to online help about this component")
            self.helpButton.SetToolTip(wx.ToolTip(tip))
        self.okButton = wx.Button(self, wx.ID_OK, _translate(" OK "))
        self.okButton.SetDefault()
        self.cancelButton = wx.Button(self, wx.ID_CANCEL,
                                      _translate(" Cancel "))
        self.__set_properties()
        self.__do_layout()
        if openToPage is None:
            openToPage = 0
        self.codeNotebook.SetSelection(openToPage)
        self.Update()
        self.Bind(wx.EVT_BUTTON, self.helpButtonHandler, self.helpButton)

        if self.timeout:
            timeout = wx.CallLater(self.timeout, self.onEnter)
            timeout.Start()
        # do show and process return
        ret = self.ShowModal()

        if ret == wx.ID_OK:
            self.checkName()
            self.OK = True
            self.params = self.getParams()  # get new vals from dlg
            self.Validate()
        else:
            self.OK = False
Beispiel #56
0
    def __init__(self, app, parent=None, pos=wx.DefaultPosition, style=None):
        if style is None:
            style = (wx.DEFAULT_DIALOG_STYLE | wx.CENTER | wx.TAB_TRAVERSAL
                     | wx.RESIZE_BORDER)
        title = _translate("Search for projects online")
        self.frameType = 'ProjectSearch'
        wx.Dialog.__init__(self,
                           parent,
                           -1,
                           title=title,
                           style=style,
                           size=(700, 500))
        self.app = app
        self.project = None
        self.parent = parent
        # info about last search (NB None means no search but [] or '' means empty)
        self.lastSearchStr = None
        self.lastSearchOwn = None
        self.lastSearchGp = None
        self.lastSearchPub = None

        # self.mainPanel = wx.Panel(self, wx.ID_ANY)
        self.searchLabel = wx.StaticText(self, wx.ID_ANY,
                                         _translate('Search:'))
        self.searchCtrl = wx.TextCtrl(self, wx.ID_ANY)
        self.searchCtrl.Bind(wx.EVT_BUTTON, self.onSearch)
        self.searchBtn = wx.Button(self, wx.ID_ANY, _translate("Search"))
        self.searchBtn.Bind(wx.EVT_BUTTON, self.onSearch)
        self.searchBtn.SetDefault()

        self.searchInclPublic = wx.CheckBox(self, wx.ID_ANY, label="Public")
        self.searchInclPublic.Bind(wx.EVT_CHECKBOX, self.onSearch)
        self.searchInclPublic.SetValue(True)

        self.searchInclGroup = wx.CheckBox(self, wx.ID_ANY, label="My groups")
        self.searchInclGroup.Bind(wx.EVT_CHECKBOX, self.onSearch)
        self.searchInclGroup.SetValue(True)

        self.searchBuilderOnly = wx.CheckBox(self,
                                             wx.ID_ANY,
                                             label="Only Builder")
        self.searchBuilderOnly.Bind(wx.EVT_CHECKBOX, self.onSearch)
        # then the search results
        self.searchResults = ProjectListCtrl(self)

        # on the right
        self.detailsPanel = DetailsPanel(parent=self)

        # sizers layout
        self.searchBtnSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.searchBtnSizer.Add(self.searchCtrl, 1, wx.EXPAND | wx.ALL, 5)
        self.searchBtnSizer.Add(self.searchBtn, 0, wx.EXPAND | wx.ALL, 5)
        self.optionsSizer = wx.WrapSizer()
        self.optionsSizer.AddMany([
            self.searchInclGroup, self.searchInclPublic, self.searchBuilderOnly
        ])

        self.leftSizer = wx.BoxSizer(wx.VERTICAL)
        self.leftSizer.Add(self.searchLabel, 0, wx.EXPAND | wx.ALL, 5)
        self.leftSizer.Add(self.optionsSizer)
        self.leftSizer.Add(self.searchBtnSizer, 0, wx.EXPAND | wx.ALL, 5)
        self.leftSizer.Add(self.searchResults, 1, wx.EXPAND | wx.ALL, 5)

        self.mainSizer = wx.BoxSizer(wx.HORIZONTAL)
        self.mainSizer.Add(self.leftSizer, 1, wx.EXPAND | wx.ALL, 5)
        self.mainSizer.Add(self.detailsPanel, 1, wx.EXPAND | wx.ALL, 5)

        self.SetSizer(self.mainSizer)
        if self.parent:
            self.CenterOnParent()
Beispiel #57
0
import numpy as np
import platform
import codecs
from pkg_resources import parse_version

if parse_version(wx.__version__) < parse_version('2.9'):
    tmpApp = wx.PySimpleApp()
else:
    tmpApp = wx.App(False)
from psychopy.localization import _translate
from psychopy import (info, data, visual, gui, core, __version__,
                      prefs, event, constants)

# set values, using a form that poedit can discover:
_localized = {
    'Benchmark': _translate('Benchmark'),
    'benchmark version': _translate('benchmark version'),
    'full-screen': _translate('full-screen'),
    'dots_circle': _translate('dots_circle'),
    'dots_square': _translate('dots_square'),
    'available memory': _translate('available memory'),
    'python version': _translate('python version'),
    'locale': _translate('locale'),
    'Visual': _translate('Visual'),
    'openGL version': _translate('openGL version'),
    'openGL vendor': _translate('openGL vendor'),
    'screen size': _translate('screen size'),
    'have shaders': _translate('have shaders'),
    'refresh stability (SD)': _translate('refresh stability (SD)'),
    'no dropped frames': _translate('no dropped frames'),
    'pyglet avbin': _translate('pyglet avbin'),
Beispiel #58
0
Discover all _localized strings from all Builder components, etc.

Mainly used by validators.py -- need access to _translate()d field names.
"""
from __future__ import absolute_import, print_function

import copy
import os
import glob
from psychopy.localization import _localized as _localizedBase
from psychopy.localization import _translate

_localizedDialogs = {
    # strings for all allowedVals (from all components) go here:
    # interpolation
    'linear': _translate('linear'),
    'nearest': _translate('nearest'),
    # color spaces not translated:
    'rgb': 'rgb', 'dkl': 'dkl', 'lms': 'lms', 'hsv': 'hsv',
    'last key': _translate('last key'),
    'first key': _translate('first key'),
    'all keys': _translate('all keys'),
    'nothing': _translate('nothing'),
    'last button': _translate('last button'),
    'first button': _translate('first button'),
    'all buttons': _translate('all buttons'),
    'final': _translate('final'),
    'on click': _translate('on click'),
    'every frame': _translate('every frame'),
    'never': _translate('never'),
    'from exp settings': _translate('from exp settings'),
Beispiel #59
0
    def __init__(self, parent):
        wx.Menu.__init__(self)
        self.parent = parent
        ProjectsMenu.app = parent.app
        keys = self.app.keys
        # from prefs fetch info about prev usernames and projects
        ProjectsMenu.appData = self.app.prefs.appData['projects']

        global projHistory
        self.projHistory = projHistory  # so we can treat as local from here
        global usersList
        self.userList = usersList

        item = self.Append(wx.ID_ANY, _translate("Tell me more..."))
        parent.Bind(wx.EVT_MENU, self.onAbout, id=item.GetId())
        if not havePyosf:
            self.Append(wx.ID_ANY,
                        _translate("Requires pyosf (not installed)"))
            ProjectsMenu.knownUsers = {}
        else:
            if self.app.osf_session is None:
                # create a default (anonymous) session with osf
                self.app.osf_session = pyosf.Session()

            ProjectsMenu.knownUsers = pyosf.TokenStorage()  # a dict name:token

        # sub-menu to open previous or new projects
        self.projsSubMenu = wx.Menu()
        item = self.projsSubMenu.Append(
            wx.ID_ANY,
            _translate("From file...\t{}").format(keys['projectsOpen']))
        parent.Bind(wx.EVT_MENU, self.onOpenFile, id=item.GetId())
        self.projsSubMenu.AppendSeparator()
        self.projHistory.UseMenu(self.projsSubMenu)
        try:
            self.projHistory.AddFilesToMenu(self.projsSubMenu)
        except:
            self.projHistory.AddFilesToThisMenu(self.projsSubMenu)
        parent.Bind(wx.EVT_MENU_RANGE,
                    self.onProjFromHistory,
                    id=self.projHistory.idBase,
                    id2=self.projHistory.idBase + 9)
        self.AppendSubMenu(self.projsSubMenu, _translate("Open"))

        # sub-menu for usernames and login
        self.userMenu = wx.Menu()
        # if a user was previously logged in then set them as current
        if ProjectsMenu.appData['user'] and \
                ProjectsMenu.appData['user'] in self.knownUsers:
            self.setUser(ProjectsMenu.appData['user'])
        for name in self.knownUsers:
            self.addToSubMenu(name, self.userMenu, self.onSetUser)
        self.userMenu.AppendSeparator()
        item = self.userMenu.Append(
            wx.ID_ANY,
            _translate("Log in...\t{}").format(keys['projectsLogIn']))
        parent.Bind(wx.EVT_MENU, self.onLogIn, id=item.GetId())
        self.AppendSubMenu(self.userMenu, _translate("User"))

        # search
        item = self.Append(
            wx.ID_ANY,
            _translate("Search OSF\t{}").format(keys['projectsFind']))
        parent.Bind(wx.EVT_MENU, self.onSearch, id=item.GetId())

        # new
        item = self.Append(
            wx.ID_ANY,
            _translate("New...\t{}").format(keys['projectsNew']))
        parent.Bind(wx.EVT_MENU, self.onNew, id=item.GetId())
Beispiel #60
0
def syncProject(parent, project=None, closeFrameWhenDone=False):
    """A function to sync the current project (if there is one)

    Returns
    -----------
        1 for success
        0 for fail
        -1 for cancel at some point in the process
    """
    if not pavlovia.haveGit:
        noGitWarning(parent)
        return 0

    isCoder = hasattr(parent, 'currentDoc')

    # Test and reject sync from invalid folders
    if isCoder:
        currentPath = os.path.dirname(parent.currentDoc.filename)
    else:
        currentPath = os.path.dirname(parent.filename)

    currentPath = os.path.normcase(os.path.expanduser(currentPath))
    invalidFolders = [
        os.path.normcase(os.path.expanduser('~/Desktop')),
        os.path.normcase(os.path.expanduser('~/My Documents'))
    ]

    if currentPath in invalidFolders:
        wx.MessageBox(
            ("You cannot sync projects from:\n\n"
             "  - Desktop\n"
             "  - My Documents\n\n"
             "Please move your project files to another folder, and try again."
             ), "Project Sync Error", wx.ICON_QUESTION | wx.OK)
        return -1

    if not project and "BuilderFrame" in repr(parent):
        # try getting one from the frame
        project = parent.project  # type: pavlovia.PavloviaProject

    if not project:  # ask the user to create one

        # if we're going to create a project we need user to be logged in
        pavSession = pavlovia.getCurrentSession()
        try:
            username = pavSession.user.username
        except:
            username = logInPavlovia(parent)
        if not username:
            return -1  # never logged in

        # create project dialog
        msg = _translate("This file doesn't belong to any existing project.")
        style = wx.OK | wx.CANCEL | wx.CENTER
        dlg = wx.MessageDialog(parent=parent, message=msg, style=style)
        dlg.SetOKLabel(_translate("Create a project"))
        if dlg.ShowModal() == wx.ID_OK:
            if isCoder:
                if parent.currentDoc:
                    localRoot = os.path.dirname(parent.currentDoc.filename)
                else:
                    localRoot = ''
            else:
                localRoot = os.path.dirname(parent.filename)
            # open the project editor (with no project to create one)
            editor = ProjectEditor(parent=parent, localRoot=localRoot)
            if editor.ShowModal() == wx.ID_OK:
                project = editor.project
            else:
                project = None
        else:
            return -1  # user pressed cancel

    if not project:  # we did our best for them. Give up!
        return 0

    # if project.localRoot doesn't exist, or is empty
    if 'localRoot' not in project or not project.localRoot:
        # we first need to choose a location for the repository
        setLocalPath(parent, project)
        parent.Raise()  # make sure that frame is still visible

    #check that the project does exist remotely
    if not project.pavlovia:
        # project didn't exist at Pavlovia (deleted?)
        recreatorDlg = ProjectRecreator(parent=parent, project=project)
        ok = recreatorDlg.ShowModal()
        if ok > 0:
            project = recreatorDlg.project
        else:
            logging.error("Failed to recreate project to sync with")
            return 0

    # a sync will be necessary so set the target to Runner stdout
    parent.app.showRunner()
    syncFrame = parent.app.runner.stdOut

    if project._newRemote:
        # new remote so this will be a first push
        if project.getRepo(forceRefresh=True) is None:
            # no local repo yet so create one
            project.newRepo(syncFrame)
        # add the local files and commit them
        ok = showCommitDialog(parent=parent,
                              project=project,
                              initMsg="First commit",
                              infoStream=syncFrame)
        if ok == -1:  # cancelled
            syncFrame.Destroy()
            return -1
        syncFrame.setStatus("Pushing files to Pavlovia")
        wx.Yield()
        time.sleep(0.001)
        # git push -u origin master
        try:
            project.firstPush(infoStream=syncFrame)
            project._newRemote = False
        except Exception as e:
            closeFrameWhenDone = False
            syncFrame.statusAppend(traceback.format_exc())
    else:
        # existing remote which we should sync (or clone)
        try:
            ok = project.getRepo(syncFrame)
            if not ok:
                closeFrameWhenDone = False
        except Exception as e:
            closeFrameWhenDone = False
            syncFrame.statusAppend(traceback.format_exc())
        # check for anything to commit before pull/push
        outcome = showCommitDialog(parent, project, infoStream=syncFrame)
        # 0=nothing to do, 1=OK, -1=cancelled
        if outcome == -1:  # user cancelled
            return -1
        try:
            status = project.sync(syncFrame)
            if status == -1:
                syncFrame.statusAppend("Couldn't sync")
        except Exception:  # not yet sure what errors might occur
            # send the error to panel
            syncFrame.statusAppend(traceback.format_exc())
            return 0

    wx.Yield()
    project._lastKnownSync = time.time()
    if closeFrameWhenDone:
        pass

    return 1