def setProject(self, project, localRoot=''): if not isinstance(project, pavlovia.PavloviaProject): project = pavlovia.getCurrentSession().getProject(project) if project is None: return # we're done self.project = project if not self.noTitle: # use the id (namespace/name) but give space around / self.title.SetLabel(project.id.replace("/", " / ")) # url self.url.SetLabel(self.project.web_url) self.url.SetURL(self.project.web_url) # public / private if hasattr(project.attributes, 'description') and project.attributes['description']: self.description.SetLabel(project.attributes['description']) else: self.description.SetLabel('') if not hasattr(project, 'visibility'): visib = _translate("User not logged in!") elif project.visibility in ['public', 'internal']: visib = "Public" else: visib = "Private" self.visibility.SetLabel(_translate("Visibility: {}").format(visib)) # do we have a local location? localFolder = project.localRoot if not localFolder: localFolder = _translate("<not yet synced>") self.localFolderCtrl.SetLabel( _translate("Local root: {}").format(localFolder)) # Check permissions: login, fork or sync perms = project.permissions # we've got the permissions value so use it if not pavlovia.getCurrentSession().user: self.syncButton.SetLabel(_translate('Log in to sync...')) elif not perms or perms < pavlovia.permissions['developer']: self.syncButton.SetLabel(_translate('Fork + sync...')) else: self.syncButton.SetLabel(_translate('Sync...')) self.syncButton.Enable(True) # now we have a project we should enable while None in project.tags: project.tags.remove(None) self.tags.SetLabel(_translate("Tags:") + " " + ", ".join(project.tags)) # call onResize to get correct wrapping of description box and title self.onResize()
def setProject(self, project, localRoot=''): if not isinstance(project, pavlovia.PavloviaProject): project = pavlovia.getCurrentSession().getProject(project) if project is None: return # we're done self.project = project if not self.noTitle: # use the id (namespace/name) but give space around / self.title.SetLabel(project.id.replace("/", " / ")) # url self.url.SetLabel(self.project.web_url) self.url.SetURL(self.project.web_url) # public / private if hasattr(project.attributes, 'description') and project.attributes['description']: self.description.SetLabel(project.attributes['description']) else: self.description.SetLabel('') if not hasattr(project, 'visibility'): visib = _translate("User not logged in!") elif project.visibility in ['public', 'internal']: visib = "Public" else: visib = "Private" self.visibility.SetLabel(_translate("Visibility: {}").format(visib)) # do we have a local location? localFolder = project.localRoot if not localFolder: localFolder = _translate("<not yet synced>") self.localFolderCtrl.SetLabel(_translate("Local root: {}").format(localFolder)) # Check permissions: login, fork or sync perms = project.permissions # we've got the permissions value so use it if not pavlovia.getCurrentSession().user: self.syncButton.SetLabel(_translate('Log in to sync...')) elif not perms or perms < pavlovia.permissions['developer']: self.syncButton.SetLabel(_translate('Fork + sync...')) else: self.syncButton.SetLabel(_translate('Sync...')) self.syncButton.Enable(True) # now we have a project we should enable while None in project.tags: project.tags.remove(None) self.tags.SetLabel(_translate("Tags:") + " " + ", ".join(project.tags)) # call onResize to get correct wrapping of description box and title self.onResize()
def __init__(self, project, *args, **kwargs): wx.Dialog.__init__(self, *args, **kwargs) existingName = project.name session = pavlovia.getCurrentSession() groups = [session.user.username] groups.extend(session.listUserGroups()) msg = wx.StaticText(self, label="Where shall we fork to?") groupLbl = wx.StaticText(self, label="Group:") self.groupField = wx.Choice(self, choices=groups) nameLbl = wx.StaticText(self, label="Project name:") self.nameField = wx.TextCtrl(self, value=project.name) fieldsSizer = wx.FlexGridSizer(cols=2, rows=2, vgap=5, hgap=5) fieldsSizer.AddMany([groupLbl, self.groupField, nameLbl, self.nameField]) buttonSizer = wx.BoxSizer(wx.HORIZONTAL) buttonSizer.Add(wx.Button(self, id=wx.ID_OK, label="OK")) buttonSizer.Add(wx.Button(self, id=wx.ID_CANCEL, label="Cancel")) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(msg, 1, wx.ALL, 5) mainSizer.Add(fieldsSizer, 1, wx.ALL, 5) mainSizer.Add(buttonSizer, 1, wx.ALL | wx.ALIGN_RIGHT, 5) self.SetSizerAndFit(mainSizer) self.Layout()
def __init__(self, project, *args, **kwargs): wx.Dialog.__init__(self, *args, **kwargs) existingName = project.name session = pavlovia.getCurrentSession() groups = [session.user.username] groups.extend(session.listUserGroups()) msg = wx.StaticText(self, label="Where shall we fork to?") groupLbl = wx.StaticText(self, label="Group:") self.groupField = wx.Choice(self, choices=groups) nameLbl = wx.StaticText(self, label="Project name:") self.nameField = wx.TextCtrl(self, value=project.name) fieldsSizer = wx.FlexGridSizer(cols=2, rows=2, vgap=5, hgap=5) fieldsSizer.AddMany( [groupLbl, self.groupField, nameLbl, self.nameField]) buttonSizer = wx.BoxSizer(wx.HORIZONTAL) buttonSizer.Add(wx.Button(self, id=wx.ID_OK, label="OK")) buttonSizer.Add(wx.Button(self, id=wx.ID_CANCEL, label="Cancel")) mainSizer = wx.BoxSizer(wx.VERTICAL) mainSizer.Add(msg, 1, wx.ALL, 5) mainSizer.Add(fieldsSizer, 1, wx.ALL, 5) mainSizer.Add(buttonSizer, 1, wx.ALL | wx.ALIGN_RIGHT, 5) self.SetSizerAndFit(mainSizer) self.Layout()
def onSearch(self, evt=None): opts = self.getSearchOptions() searchStr = self.searchCtrl.GetValue() newSearch = (searchStr != self.lastSearchStr) self.lastSearchStr = newSearch session = pavlovia.getCurrentSession() # search own if newSearch: try: self.lastSearchOwn = session.gitlab.projects.list( owned=True, search=searchStr) except requests.exceptions.ConnectionError: print("Failed to establish a new connection: No internet?") return None # search my groups if opts['inclGroup'] and (newSearch or self.lastSearchGp is None): # group projects: owned=False, membership=True self.lastSearchGp = session.gitlab.projects.list(owned=False, membership=True, search=searchStr) elif not opts[ 'inclGroup']: # set to None (to indicate non-search not simply empty result) self.lastSearchGp = None elif opts['inclGroup'] and not newSearch: pass # we have last search and we need it so do nothing else: print( "ERROR: During Pavlovia search we found opts['inclGroup']={}, newSearch={}" .format(opts['inclGroup'], newSearch)) # search public if opts['inclPublic'] and (newSearch or self.lastSearchPub is None): self.lastSearchPub = session.gitlab.projects.list(owned=False, membership=False, search=searchStr) elif not opts[ 'inclPublic']: # set to None (to indicate non-search not simply empty result) self.lastSearchPub = None elif opts['inclPublic'] and not newSearch: pass # we have last search and we need it so do nothing else: print( "ERROR: During Pavlovia search we found opts['inclPublic']={}, newSearch={}" .format(opts['inclPublic'], newSearch)) projs = copy.copy(self.lastSearchOwn) if opts['inclGroup']: projs.extend(self.lastSearchGp) if opts['inclPublic']: projs.extend(self.lastSearchPub) projs = getUniqueByID(projs) projs = [pavlovia.PavloviaProject(proj) for proj in projs if proj.id] self.searchResults.setContents(projs) self.searchResults.Update() self.Layout()
def __init__(self, parent, user=None, loginOnly=False, logoutOnly=False, style=style, *args, **kwargs): # create the dialog wx.Dialog.__init__(self, parent, style=style, *args, **kwargs) # create browser window for authentication self.browser = wx.html2.WebView.New(self) self.loginOnly = loginOnly self.logoutOnly = logoutOnly self.tokenInfo = {} # do layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.browser, 1, wx.EXPAND, 10) self.SetSizer(sizer) if loginOnly: self.SetSize((600, 600)) else: self.SetSize((700, 600)) self.CenterOnParent() # check there is a user (or log them in) if not user: self.user = pavlovia.getCurrentSession().user if not user: self.login() if not user: return None
def __init__(self, parent, user=None, loginOnly=False, logoutOnly=False, style=style, *args, **kwargs): # create the dialog wx.Dialog.__init__(self, parent, style=style, *args, **kwargs) # create browser window for authentication self.browser = wx.html2.WebView.New(self) self.loginOnly = loginOnly self.logoutOnly = logoutOnly self.tokenInfo = {} # do layout sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self.browser, 1, wx.EXPAND, 10) self.SetSizer(sizer) if loginOnly: self.SetSize((600, 600)) else: self.SetSize((700, 600)) self.CenterOnParent() # check there is a user (or log them in) if not user: self.user = pavlovia.getCurrentSession().user if not user: self.login() if not user: return None
def setUser(self, user): if user == PavloviaMenu.currentUser: return # nothing to do here. Move along please. PavloviaMenu.currentUser = user PavloviaMenu.appData['pavloviaUser'] = user if user in pavlovia.knownUsers: token = pavlovia.knownUsers[user]['token'] try: pavlovia.getCurrentSession().setToken(token) except requests.exceptions.ConnectionError: logging.warning("Tried to log in to Pavlovia but no network " "connection") return else: self.onLogInPavlovia() if self.searchDlg: self.searchDlg.updateUserProjs()
def setUser(self, user): if user == PavloviaMenu.currentUser: return # nothing to do here. Move along please. PavloviaMenu.currentUser = user PavloviaMenu.appData['pavloviaUser'] = user if user in pavlovia.knownUsers: token = pavlovia.knownUsers[user]['token'] try: pavlovia.getCurrentSession().setToken(token) except requests.exceptions.ConnectionError: logging.warning("Tried to log in to Pavlovia but no network " "connection") return else: self.onLogInPavlovia() if self.searchDlg: self.searchDlg.updateUserProjs()
def onSearch(self, evt=None): opts = self.getSearchOptions() searchStr = self.searchCtrl.GetValue() newSearch = (searchStr!=self.lastSearchStr) self.lastSearchStr = newSearch session = pavlovia.getCurrentSession() # search own if newSearch: try: self.lastSearchOwn = session.gitlab.projects.list(owned=True, search=searchStr) except requests.exceptions.ConnectionError: print("Failed to establish a new connection: No internet?") return None # search my groups if opts['inclGroup'] and (newSearch or self.lastSearchGp is None): # group projects: owned=False, membership=True self.lastSearchGp = session.gitlab.projects.list( owned=False, membership=True, search=searchStr) elif not opts['inclGroup']: # set to None (to indicate non-search not simply empty result) self.lastSearchGp = None elif opts['inclGroup'] and not newSearch: pass # we have last search and we need it so do nothing else: print("ERROR: During Pavlovia search we found opts['inclGroup']={}, newSearch={}" .format(opts['inclGroup'], newSearch)) # search public if opts['inclPublic'] and (newSearch or self.lastSearchPub is None): self.lastSearchPub = session.gitlab.projects.list(owned=False, membership=False, search=searchStr) elif not opts['inclPublic']: # set to None (to indicate non-search not simply empty result) self.lastSearchPub = None elif opts['inclPublic'] and not newSearch: pass # we have last search and we need it so do nothing else: print("ERROR: During Pavlovia search we found opts['inclPublic']={}, newSearch={}" .format(opts['inclPublic'], newSearch)) projs = copy.copy(self.lastSearchOwn) if opts['inclGroup']: projs.extend(self.lastSearchGp) if opts['inclPublic']: projs.extend(self.lastSearchPub) projs = getUniqueByID(projs) projs = [pavlovia.PavloviaProject(proj) for proj in projs if proj.id] self.searchResults.setContents(projs) self.searchResults.Update() self.Layout()
def onSyncButton(self, event): try: git haveGit = True except ImportError: haveGit = False if not haveGit: noGitWarning(parent=self.parent) return if self.project is None: raise AttributeError("User pressed the sync button with no " "current project existing.") # log in first if needed if not pavlovia.getCurrentSession().user: logInPavlovia(parent=self.parent) return # fork first if needed perms = self.project.permissions if not perms or perms < pavlovia.permissions['developer']: # specifying the group to fork to has no effect so don't use it # dlg = ForkDlg(parent=self.parent, project=self.project) # if dlg.ShowModal() == wx.ID_CANCEL: # return # else: # newGp = dlg.groupField.GetStringSelection() # newName = dlg.nameField.GetValue() fork = self.project.forkTo() # logged-in user self.setProject(fork.id) # if project.localRoot doesn't exist, or is empty if 'localRoot' not in self.project or not self.project.localRoot: # we first need to choose a location for the repository newPath = setLocalPath(self, self.project) if newPath: self.localFolderCtrl.SetLabel( label=_translate("Local root: {}").format(newPath)) self.project.local = newPath self.Layout() self.Raise() syncPanel = sync.SyncStatusPanel(parent=self, id=wx.ID_ANY) self.sizer.Add(syncPanel, border=5, flag=wx.ALL | wx.RIGHT) self.sizer.Layout() progHandler = sync.ProgressHandler(syncPanel=syncPanel) wx.Yield() self.project.sync(syncPanel=syncPanel, progressHandler=progHandler) syncPanel.Destroy() self.sizer.Layout() self.parent.Raise()
def onSyncButton(self, event): try: git haveGit = True except ImportError: haveGit = False if not haveGit: noGitWarning(parent=self.parent) return if self.project is None: raise AttributeError("User pressed the sync button with no " "current project existing.") # log in first if needed if not pavlovia.getCurrentSession().user: logInPavlovia(parent=self.parent) return # fork first if needed perms = self.project.permissions if not perms or perms < pavlovia.permissions['developer']: # specifying the group to fork to has no effect so don't use it # dlg = ForkDlg(parent=self.parent, project=self.project) # if dlg.ShowModal() == wx.ID_CANCEL: # return # else: # newGp = dlg.groupField.GetStringSelection() # newName = dlg.nameField.GetValue() fork = self.project.forkTo() # logged-in user self.setProject(fork.id) # if project.localRoot doesn't exist, or is empty if 'localRoot' not in self.project or not self.project.localRoot: # we first need to choose a location for the repository newPath = setLocalPath(self, self.project) if newPath: self.localFolderCtrl.SetLabel( label=_translate("Local root: {}").format(newPath)) self.project.local = newPath self.Layout() self.Raise() syncPanel = sync.SyncStatusPanel(parent=self, id=wx.ID_ANY) self.sizer.Add(syncPanel, border=5, flag=wx.ALL | wx.RIGHT) self.sizer.Layout() progHandler = sync.ProgressHandler(syncPanel=syncPanel) wx.Yield() self.project.sync(syncPanel=syncPanel, progressHandler=progHandler) syncPanel.Destroy() self.sizer.Layout() self.parent.Raise()
def logInPavlovia(parent, event=None): """Opens the built-in browser dialog to login to pavlovia Returns ------- None (user closed window without logging on) or a gitlab.User object """ # check known users list dlg = PavloviaMiniBrowser(parent=parent, loginOnly=True) dlg.ShowModal() # with loginOnly=True this will EndModal once logged in if dlg.tokenInfo: token = dlg.tokenInfo['token'] pavlovia.login(token, rememberMe=True) # log in to the current pavlovia session return pavlovia.getCurrentSession().user
def logInPavlovia(parent, event=None): """Opens the built-in browser dialog to login to pavlovia Returns ------- None (user closed window without logging on) or a gitlab.User object """ # check known users list dlg = PavloviaMiniBrowser(parent=parent, loginOnly=True) dlg.ShowModal() # with loginOnly=True this will EndModal once logged in if dlg.tokenInfo: token = dlg.tokenInfo['token'] pavlovia.login(token, rememberMe=True) # log in to the current pavlovia session return pavlovia.getCurrentSession().user
def onNew(self, event): """Create a new project """ if pavlovia.getCurrentSession().user.username: projEditor = ProjectEditor() if projEditor.ShowModal() == wx.ID_OK: self.parent.project = projEditor.project # do a first sync as well syncProject(parent=self.parent, project=projEditor.project) else: infoDlg = dialogs.MessageDialog(parent=None, type='Info', message=_translate( "You need to log in" " to create a project")) infoDlg.Show()
def onSelectUser(evt): # Get user from menu id = evt.Id menu = evt.EventObject user = menu.users[id] # Logout pavlovia.logout() # Log back in as new user pavlovia.login(user['username']) # Update view self.user = pavlovia.getCurrentSession().user # Update cache prefs.appData['projects']['pavloviaUser'] = user['username'] self.Layout() # update the size of the button self.Fit()
def onNew(self, event): """Create a new project """ # Get session session = pavlovia.getCurrentSession() # If logged in, create project if session.user: dlg = sync.CreateDlg(self.parent, user=session.user) dlg.ShowModal() # Otherwise, prompt user to log in else: infoDlg = dialogs.MessageDialog(parent=None, type='Info', message=_translate( "You need to log in" " to create a project")) infoDlg.Show()
def submitChanges(self, evt=None): session = pavlovia.getCurrentSession() if not session.user: user = logInPavlovia(parent=self.parent) if not session.user: return # get current values name = self.nameBox.GetValue() namespace = self.groupBox.GetStringSelection() descr = self.descrBox.GetValue() visibility = self.publicBox.GetValue() # tags need splitting and then tagsList = self.tagsBox.GetValue().split(',') tags = [thisTag.strip() for thisTag in tagsList] localRoot = self.localBox.GetValue() if not localRoot: localRoot = setLocalPath(self.parent, project=None, path="") # then create/update if self.isNew: project = session.createProject(name=name, description=descr, tags=tags, visibility=visibility, localRoot=localRoot, namespace=namespace) self.project = project self.project._newRemote = True else: # we're changing metadata of an existing project. Don't sync self.project.pavlovia.name = name self.project.pavlovia.description = descr self.project.tags = tags self.project.visibility = visibility self.project.localRoot = localRoot self.project.save() # pushes changed metadata to gitlab self.project._newRemote = False self.EndModal(wx.ID_OK) pavlovia.knownProjects.save() self.project.getRepo(forceRefresh=True) self.parent.project = self.project
def onSyncButton(self, event): if not pavlovia.haveGit: noGitWarning(parent=self.parent) return 0 if self.project is None: raise AttributeError("User pressed the sync button with no " "current project existing.") # log in first if needed if not pavlovia.getCurrentSession().user: logInPavlovia(parent=self.parent) return # fork first if needed perms = self.project.permissions if not perms or perms < pavlovia.permissions['developer']: # specifying the group to fork to has no effect so don't use it # dlg = ForkDlg(parent=self.parent, project=self.project) # if dlg.ShowModal() == wx.ID_CANCEL: # return # else: # newGp = dlg.groupField.GetStringSelection() # newName = dlg.nameField.GetValue() fork = self.project.forkTo() # logged-in user self.setProject(fork.id) # if project.localRoot doesn't exist, or is empty if 'localRoot' not in self.project or not self.project.localRoot: # we first need to choose a location for the repository newPath = setLocalPath(self, self.project) if newPath: self.localFolderCtrl.SetLabel( label=_translate("Local root: {}").format(newPath)) self.project.local = newPath self.Layout() self.Raise() self.syncPanel.setStatus(_translate("Synchronizing...")) self.project.sync(infoStream=self.syncPanel.infoStream) self.parent.Raise()
def submitChanges(self, evt=None): session = pavlovia.getCurrentSession() if not session.user: user = logInPavlovia(parent=self.parent) if not session.user: return # get current values name = self.nameBox.GetValue() namespace = self.groupBox.GetStringSelection() descr = self.descrBox.GetValue() visibility = self.publicBox.GetValue() # tags need splitting and then tagsList = self.tagsBox.GetValue().split(',') tags = [thisTag.strip() for thisTag in tagsList] localRoot = self.localBox.GetValue() if not localRoot: localRoot = setLocalPath(self.parent, project=None, path="") # then create/update if self.isNew: project = session.createProject(name=name, description=descr, tags=tags, visibility=visibility, localRoot=localRoot, namespace=namespace) self.project = project self.project._newRemote = True else: # we're changing metadata of an existing project. Don't sync self.project.pavlovia.name = name self.project.pavlovia.description = descr self.project.tags = tags self.project.visibility = visibility self.project.localRoot = localRoot self.project.save() # pushes changed metadata to gitlab self.project._newRemote = False self.EndModal(wx.ID_OK) pavlovia.knownProjects.save() self.project.getRepo(forceRefresh=True) self.parent.project = self.project
def onSyncButton(self, event): if not pavlovia.haveGit: noGitWarning(parent=self.parent) return 0 if self.project is None: raise AttributeError("User pressed the sync button with no " "current project existing.") # log in first if needed if not pavlovia.getCurrentSession().user: logInPavlovia(parent=self.parent) return # fork first if needed perms = self.project.permissions if not perms or perms < pavlovia.permissions['developer']: # specifying the group to fork to has no effect so don't use it # dlg = ForkDlg(parent=self.parent, project=self.project) # if dlg.ShowModal() == wx.ID_CANCEL: # return # else: # newGp = dlg.groupField.GetStringSelection() # newName = dlg.nameField.GetValue() fork = self.project.forkTo() # logged-in user self.setProject(fork.id) # if project.localRoot doesn't exist, or is empty if 'localRoot' not in self.project or not self.project.localRoot: # we first need to choose a location for the repository newPath = setLocalPath(self, self.project) if newPath: self.localFolderCtrl.SetLabel( label=_translate("Local root: {}").format(newPath)) self.project.local = newPath self.Layout() self.Raise() self.syncPanel.setStatus(_translate("Synchronizing...")) self.project.sync(infoStream=self.syncPanel.infoStream) self.parent.Raise()
def __init__(self, parent=None, id=wx.ID_ANY, style=defStyle, *args, **kwargs): wx.Dialog.__init__(self, parent, id, *args, style=style, **kwargs) self.SetWindowStyle(wx.STAY_ON_TOP) # this will be a modal dialog panel = wx.Panel(self, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.parent = parent pavSession = pavlovia.getCurrentSession() if pavSession.user: pavSession.gitlab.auth() self.user = pavSession.user else: self.user = logInPavlovia(parent=parent) if not self.user: return # they were given a login but cancelled if type(self.user) != pavlovia.User: self.user = pavlovia.User(gitlabData=self.user) # create the controls userField = wxhl.HyperLinkCtrl(panel, id=wx.ID_ANY, label=self.user.url, URL=self.user.url) logoutBtn = wx.Button(panel, label="Logout") logoutBtn.Bind(wx.EVT_BUTTON, self.onLogout) nameLabel = wx.StaticText(panel, id=wx.ID_ANY, label=_translate("Full name:")) self.nameField = wx.StaticText(panel, wx.ID_ANY, self.user.name) if self.user.avatar: userBitmap = wx.Bitmap(self.user.avatar) else: userBitmap = wx.Bitmap(os.path.join(resources, "user128invisible.png")) # self.avatarBtn = wx.Button(panel, wx.ID_ANY, name="Avatar") # self.avatarBtn.SetBitmap(userBitmap) self.avatarBtn = wx.BitmapButton(panel, wx.ID_ANY, bitmap=userBitmap, name="Avatar") # self.avatarBtn.SetBitmap(userBitmap) org = self.user.organization or "" orgLabel = wx.StaticText(panel, wx.ID_ANY, _translate("Organization:")) self.orgField = wx.StaticText(panel, wx.ID_ANY, org, size=(300, -1)) bio = self.user.bio or "" self.bioLabel = wx.StaticText(panel, wx.ID_ANY, _translate("Bio (250 chrs):")) self.bioField = wx.StaticText(panel, wx.ID_ANY, bio, style=wx.TE_MULTILINE) # submit/cancel buttonMsg = _translate("OK") updateBtn = wx.Button(panel, id=wx.ID_OK, label=buttonMsg) updateBtn.Bind(wx.EVT_BUTTON, self.submitChanges) # cancelBtn = wx.Button(panel, id=wx.ID_CANCEL, label=_translate("Cancel")) # cancelBtn.Bind(wx.EVT_BUTTON, self.onCancel) # layout userAndLogout = wx.BoxSizer(wx.VERTICAL) userAndLogout.Add(userField, 1, wx.ALL | wx.CENTER | wx.ALIGN_CENTER_VERTICAL, 5) userAndLogout.Add(logoutBtn, 0, wx.ALL | wx.CENTER | wx.ALIGN_CENTER_VERTICAL , 5) topRow = wx.BoxSizer(wx.HORIZONTAL) topRow.Add(userAndLogout, 1, wx.ALL | wx.CENTER, 5) topRow.Add(self.avatarBtn, 0, wx.ALL | wx.RIGHT, 5) fieldsSizer = wx.FlexGridSizer(cols=2, rows=5, vgap=10, hgap=10) fieldsSizer.AddMany([ (nameLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.nameField,0, wx.EXPAND), (orgLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.orgField,0, wx.EXPAND), (self.bioLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.bioField, 1, wx.EXPAND), ]) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add(updateBtn, flag=wx.ALIGN_RIGHT) border = wx.BoxSizer(wx.VERTICAL) border.Add(topRow, 0, wx.ALL| wx.EXPAND, 5) border.Add(fieldsSizer, 1, wx.ALL | wx.EXPAND, 10) border.Add(btnSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5) panel.SetSizerAndFit(border) self.Fit()
def __init__(self, parent, size=(600, 300), style=wx.NO_BORDER): wx.Panel.__init__(self, parent, -1, size=size, style=style) self.parent = parent self.SetBackgroundColour("white") self.session = pavlovia.getCurrentSession() # Setup sizer self.contentBox = wx.BoxSizer() self.SetSizer(self.contentBox) self.sizer = wx.BoxSizer(wx.VERTICAL) self.contentBox.Add(self.sizer, proportion=1, border=12, flag=wx.ALL | wx.EXPAND) # Head sizer self.headSizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(self.headSizer, border=0, flag=wx.EXPAND) # Icon self.icon = wx.lib.statbmp.GenStaticBitmap(self, ID=wx.ID_ANY, bitmap=icons.ButtonIcon( stem="user_none", size=128).bitmap, size=(128, 128)) self.icon.SetBackgroundColour("#f2f2f2") self.headSizer.Add(self.icon, border=6, flag=wx.ALL) # Title sizer self.titleSizer = wx.BoxSizer(wx.VERTICAL) self.headSizer.Add(self.titleSizer, proportion=1, flag=wx.EXPAND) # Full name self.fullName = wx.StaticText(self, size=(-1, -1), label="---", style=wx.ST_ELLIPSIZE_END) self.fullName.SetFont( wx.Font(24, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)) self.fullName.Bind(wx.EVT_TEXT, self.updateUser) self.titleSizer.Add(self.fullName, border=6, flag=wx.ALL | wx.EXPAND) # Organisation self.organisation = wx.StaticText(self, size=(-1, -1), label="---", style=wx.ST_ELLIPSIZE_END) self.organisation.SetFont( wx.Font(12, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_ITALIC, wx.FONTWEIGHT_NORMAL)) self.titleSizer.Add(self.organisation, border=6, flag=wx.ALL | wx.EXPAND) # Spacer self.titleSizer.AddStretchSpacer(1) # Button sizer self.btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.titleSizer.Add(self.btnSizer, border=6, flag=wx.TOP | wx.BOTTOM | wx.EXPAND) # Spacer self.btnSizer.AddStretchSpacer(1) # Pavlovia link self.link = wxhl.HyperLinkCtrl( self, -1, label="", URL="https://gitlab.pavlovia.org/", ) self.link.SetBackgroundColour(self.GetBackgroundColour()) self.btnSizer.Add(self.link, border=6, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL) # Edit self.edit = wx.Button(self, label=chr(int("270E", 16)), size=(24, -1)) self.edit.Bind(wx.EVT_BUTTON, self.onEdit) self.btnSizer.Add(self.edit, border=3, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL) # Switch user self.switch = wx.Button(self, label=_translate("Switch User")) self.switch.SetBitmap( icons.ButtonIcon(stem="view-refresh", size=16).bitmap) self.switch.Bind(wx.EVT_BUTTON, self.onSwitchUser) self.btnSizer.Add(self.switch, border=3, flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER_VERTICAL) # Login self.login = wx.Button(self, label=_translate("Login")) self.login.SetBitmap( icons.ButtonIcon(stem="person_off", size=16).bitmap) self.login.Bind(wx.EVT_BUTTON, self.onLogin) self.btnSizer.Add(self.login, border=3, flag=wx.LEFT | wx.EXPAND) # Logout self.logout = wx.Button(self, label=_translate("Logout")) self.logout.SetBitmap( icons.ButtonIcon(stem="person_off", size=16).bitmap) self.logout.Bind(wx.EVT_BUTTON, self.onLogout) self.btnSizer.Add(self.logout, border=3, flag=wx.LEFT | wx.EXPAND) # Sep self.sizer.Add(wx.StaticLine(self, -1), border=6, flag=wx.EXPAND | wx.ALL) # Bio self.description = wx.StaticText(self, size=(-1, -1), label="", style=wx.TE_MULTILINE) self.sizer.Add(self.description, proportion=1, border=6, flag=wx.ALL | wx.EXPAND) # Populate self.user = self.user
def __init__(self, parent=None, id=wx.ID_ANY, style=defStyle, *args, **kwargs): wx.Dialog.__init__(self, parent, id, *args, style=style, **kwargs) self.SetWindowStyle(wx.STAY_ON_TOP) # this will be a modal dialog panel = wx.Panel(self, wx.ID_ANY, style=wx.TAB_TRAVERSAL) self.parent = parent self.app = wx.GetApp() pavSession = pavlovia.getCurrentSession() if pavSession.user: pavSession.gitlab.auth() self.user = pavSession.user else: self.user = logInPavlovia(parent=parent) if not self.user: return # they were given a login but cancelled if type(self.user) != pavlovia.User: self.user = pavlovia.User(gitlabData=self.user) # create the controls userField = wxhl.HyperLinkCtrl(panel, id=wx.ID_ANY, label=self.user.url, URL=self.user.url) logoutBtn = wx.Button(panel, label="Logout") logoutBtn.Bind(wx.EVT_BUTTON, self.onLogout) nameLabel = wx.StaticText(panel, id=wx.ID_ANY, label=_translate("Full name:")) self.nameField = wx.StaticText(panel, wx.ID_ANY, self.user.name) bitmapFile = self.user.avatar or "user128invisible.png" self.avatarBtn = self.app.iconCache.makeBitmapButton( parent=panel, filename=bitmapFile, label=self.user.name, name=self.user.name) org = self.user.organization or "" orgLabel = wx.StaticText(panel, wx.ID_ANY, _translate("Organization:")) self.orgField = wx.StaticText(panel, wx.ID_ANY, org, size=(300, -1)) bio = self.user.bio or "" self.bioLabel = wx.StaticText(panel, wx.ID_ANY, _translate("Bio (250 chrs):")) self.bioField = wx.StaticText(panel, wx.ID_ANY, bio, style=wx.TE_MULTILINE) # submit/cancel buttonMsg = _translate("OK") updateBtn = wx.Button(panel, id=wx.ID_OK, label=buttonMsg) updateBtn.Bind(wx.EVT_BUTTON, self.submitChanges) # cancelBtn = wx.Button(panel, id=wx.ID_CANCEL, label=_translate("Cancel")) # cancelBtn.Bind(wx.EVT_BUTTON, self.onCancel) # layout userAndLogout = wx.BoxSizer(wx.VERTICAL) userAndLogout.Add(userField, 1, wx.ALL | wx.CENTER, 5) userAndLogout.Add(logoutBtn, 0, wx.ALL | wx.CENTER, 5) topRow = wx.BoxSizer(wx.HORIZONTAL) topRow.Add(userAndLogout, 1, wx.ALL | wx.CENTER, 5) topRow.Add(self.avatarBtn, 0, wx.ALL | wx.RIGHT, 5) fieldsSizer = wx.FlexGridSizer(cols=2, rows=5, vgap=10, hgap=10) fieldsSizer.AddMany([ (nameLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.nameField, 0, wx.EXPAND), (orgLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.orgField, 0, wx.EXPAND), (self.bioLabel, 0, wx.ALIGN_RIGHT | wx.ALIGN_CENTER_VERTICAL), (self.bioField, 1, wx.EXPAND), ]) btnSizer = wx.BoxSizer(wx.HORIZONTAL) btnSizer.Add(updateBtn) border = wx.BoxSizer(wx.VERTICAL) border.Add(topRow, 0, wx.ALL | wx.EXPAND, 5) border.Add(fieldsSizer, 1, wx.ALL | wx.EXPAND, 10) border.Add(btnSizer, 0, wx.ALIGN_RIGHT | wx.ALL, 5) panel.SetSizerAndFit(border) self.Fit()
def syncProject(parent, project, file="", 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 """ # Error catch logged out session = pavlovia.getCurrentSession() if not session or not session.user: # If not logged in, prompt to login dlg = wx.MessageDialog(None, message=_translate( "You are not logged in to Pavlovia. Please log in to sync project." ), style=wx.ICON_AUTH_NEEDED | wx.OK | wx.CANCEL) dlg.SetOKLabel(_translate("Login...")) if dlg.ShowModal() == wx.ID_OK: # If they click Login, open login screen user = functions.logInPavlovia(None) # If they cancelled out of login screen, cancel sync if not user: return else: # If they cancel out of login prompt, cancel sync return # If not in a project, make one if project is None: msgDlg = wx.MessageDialog(parent, message=_translate("This file doesn't belong to any existing project."), style=wx.OK | wx.CANCEL | wx.CENTER) msgDlg.SetOKLabel(_translate("Create a project")) if msgDlg.ShowModal() == wx.ID_OK: # Get start path and name from builder/coder if possible if file: file = Path(file) name = file.stem path = file.parent else: name = path = "" # Open dlg to create new project createDlg = sync.CreateDlg(parent, user=pavlovia.getCurrentSession().user, name=name, path=path) if createDlg.ShowModal() == wx.ID_OK and createDlg.project is not None: project = createDlg.project else: return else: return # If no local root or dead local root, prompt to make one if not project.localRoot or not Path(project.localRoot).is_dir(): defaultRoot = Path(file).parent if not project.localRoot: # If there is no local root at all, prompt user to make one msg = _translate("Project root folder is not yet specified, specify project root now?") elif not Path(project.localRoot).is_dir(): # If there is a local root but the folder is gone, prompt user to change it msg = _translate("Project root folder does not exist, change project root now?") # Ask user if they want to dlg = wx.MessageDialog(parent, message=msg, style=wx.OK | wx.CANCEL) # Get response if dlg.ShowModal() == wx.ID_OK: # Attempt to get folder of current file if file and defaultRoot.is_dir(): # If we have a reference to the current folder, use it project.localRoot = defaultRoot else: # Otherwise, ask designer to specify manually dlg = wx.DirDialog(parent, message=_translate("Specify folder..."), defaultPath=str(defaultRoot)) if dlg.ShowModal() == wx.ID_OK: project.localRoot = str(dlg.GetPath()) else: # If cancelled, cancel sync return else: # If they don't want to specify, cancel sync return # Assign project to parent frame parent.project = project # If there is (now) a project, do sync if project is not None: # Show sync dlg dlg = sync.SyncDialog(parent, project) # Commit changes committed = functions.showCommitDialog(parent, project, initMsg="", infoStream=dlg.status) # Cancel sync if commit cancelled if committed == -1: dlg.status.write(_translate( "\n" "Sync cancelled by user." )) dlg.OKbtn.Enable(True) return # Do sync dlg.sync()
def session(self): # Cache session if not cached if not hasattr(self, "_session"): self._session = pavlovia.getCurrentSession() # Return cached session return self._session
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: 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) btnSizer.AddMany([updateBtn, cancelBtn]) # 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()
def syncProject(parent, project, file="", 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 in a project, make one if project is None: msgDlg = wx.MessageDialog( parent, message=_translate( "This file doesn't belong to any existing project."), style=wx.OK | wx.CANCEL | wx.CENTER) msgDlg.SetOKLabel(_translate("Create a project")) if msgDlg.ShowModal() == wx.ID_OK: # Get start path and name from builder/coder if possible if file: file = Path(file) name = file.stem path = file.parent else: name = path = "" # Open dlg to create new project createDlg = sync.CreateDlg(parent, user=pavlovia.getCurrentSession().user, name=name, path=path) if createDlg.ShowModal( ) == wx.ID_OK and createDlg.project is not None: project = createDlg.project else: return else: return # If no local root, prompt to make one if not project.localRoot: defaultRoot = Path(file).parent # Ask user if they want to dlg = wx.MessageDialog( parent, message=_translate( "Project root folder is not yet specified, specify one now?"), style=wx.YES_NO) # Open folder picker if dlg.ShowModal() == wx.ID_YES: dlg = wx.DirDialog(parent, message=_translate("Specify folder..."), defaultPath=str(defaultRoot)) if dlg.ShowModal() == wx.ID_OK: localRoot = Path(dlg.GetPath()) project.localRoot = str(localRoot) else: # If cancelled, cancel sync return else: # If they don't want to specify, cancel sync return # Assign project to parent frame parent.project = project # If there is (now) a project, do sync if project is not None: dlg = sync.SyncDialog(parent, project) functions.showCommitDialog(parent, project, initMsg="", infoStream=dlg.status) dlg.sync()
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') 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 can create syncFrame syncFrame = sync.SyncFrame(parent=parent, id=wx.ID_ANY, project=project) 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.syncPanel.infoStream) if ok == -1: # cancelled syncFrame.Destroy() return -1 syncFrame.syncPanel.setStatus("Pushing files to Pavlovia") wx.Yield() time.sleep(0.001) # git push -u origin master try: project.firstPush(infoStream=syncFrame.syncPanel.infoStream) project._newRemote = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) else: # existing remote which we should sync (or clone) try: ok = project.getRepo(syncFrame.syncPanel.infoStream) if not ok: closeFrameWhenDone = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) # check for anything to commit before pull/push outcome = showCommitDialog(parent, project, infoStream=syncFrame.syncPanel.infoStream) # 0=nothing to do, 1=OK, -1=cancelled if outcome == -1: # user cancelled syncFrame.Destroy() return -1 try: status = project.sync(syncFrame.syncPanel.infoStream) if status == -1: syncFrame.syncPanel.statusAppend("Couldn't sync") except Exception: # not yet sure what errors might occur # send the error to panel syncFrame.syncPanel.statusAppend(traceback.format_exc()) return 0 wx.Yield() project._lastKnownSync = time.time() if closeFrameWhenDone: syncFrame.Destroy() return 1
def __init__(self, parent, viewer, size=(400, -1), style=wx.NO_BORDER): # Init self wx.Panel.__init__(self, parent, -1, size=size, style=style) self.session = pavlovia.getCurrentSession() # Setup sizer self.sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.sizer) # Add search ctrl self.searchCtrl = wx.SearchCtrl(self) self.searchCtrl.Bind(wx.EVT_SEARCH, self.search) self.sizer.Add(self.searchCtrl, border=4, flag=wx.EXPAND | wx.ALL) # Add button sizer self.btnSizer = wx.BoxSizer(wx.HORIZONTAL) self.sizer.Add(self.btnSizer, border=4, flag=wx.EXPAND | wx.ALL) # Add "me mode" button self.mineBtn = wx.ToggleButton(self, size=(64, -1), label=_translate("Me")) self.mineBtn.SetBitmap( icons.ButtonIcon(stem="person_off", size=16).bitmap) self.mineBtn.SetBitmapFocus( icons.ButtonIcon(stem="person_on", size=16).bitmap) self.mineBtn.SetBitmapPressed( icons.ButtonIcon(stem="person_on", size=16).bitmap) self._mine = False self.mineBtn.Bind(wx.EVT_TOGGLEBUTTON, self.onMineBtn) self.mineBtn.Enable(self.session.userID is not None) self.btnSizer.Add(self.mineBtn, border=6, flag=wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM) self.btnSizer.AddStretchSpacer(1) # Add sort button self.sortBtn = wx.Button(self, label=_translate("Sort...")) self.sortOrder = [] self.sortBtn.Bind(wx.EVT_BUTTON, self.sort) self.btnSizer.Add(self.sortBtn, border=6, flag=wx.LEFT | wx.RIGHT | wx.TOP | wx.BOTTOM) # Add filter button self.filterBtn = wx.Button(self, label=_translate("Filter...")) self.filterTerms = { "Status": [], "Platform": [], "Keywords": [], } self.filterOptions = { "Author": None, "Status": ["running", "piloting", "inactive"], "Platform": ["psychojs", "jspsych", "labjs", "opensesame", "other"], "Visibility": ["public", "private"], "Keywords": None, } self.filterBtn.Bind(wx.EVT_BUTTON, self.filter) self.btnSizer.Add(self.filterBtn, border=6, flag=wx.LEFT | wx.TOP | wx.BOTTOM) # Add filter label self.filterLbl = self.FilterLabel(self, style=wx.ST_ELLIPSIZE_END) self.filterLbl.Bind(wx.EVT_ENTER_WINDOW, self.filterLbl.hoverOn) self.filterLbl.Bind(wx.EVT_LEAVE_WINDOW, self.filterLbl.hoverOff) self.sizer.Add(self.filterLbl, border=6, flag=wx.LEFT | wx.RIGHT) self.filterLbl.update() # Add project list self.projectList = ListCtrl(self, size=(-1, -1), style=wx.LC_REPORT | wx.LC_SINGLE_SEL) self.projectList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.showProject) self.sizer.Add(self.projectList, proportion=1, border=4, flag=wx.EXPAND | wx.ALL) # Setup project list self.projectList.InsertColumn(0, _starred, width=36, format=wx.LIST_FORMAT_CENTER) # Stars #self.projectList.InsertColumn(1, _translate('Status'), width=wx.LIST_AUTOSIZE, format=wx.LIST_FORMAT_LEFT) # Status self.projectList.InsertColumn(2, _translate('Author'), width=wx.LIST_AUTOSIZE, format=wx.LIST_FORMAT_LEFT) # Author self.projectList.InsertColumn(3, _translate('Name'), width=wx.LIST_AUTOSIZE, format=wx.LIST_FORMAT_LEFT) # Name # Setup projects dict self.projects = None # Link ProjectViewer self.viewer = viewer self.projectList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.showProject) # Layout self.Layout() # Initial search self.search()
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: 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) btnSizer.AddMany([updateBtn, cancelBtn]) # 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()
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') 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 # a sync will be necessary so can create syncFrame syncFrame = sync.SyncFrame(parent=parent, id=wx.ID_ANY, project=project) 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.syncPanel.infoStream) if ok == -1: # cancelled syncFrame.Destroy() return -1 syncFrame.syncPanel.setStatus("Pushing files to Pavlovia") wx.Yield() time.sleep(0.001) # git push -u origin master try: project.firstPush(infoStream=syncFrame.syncPanel.infoStream) project._newRemote = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) else: # existing remote which we should sync (or clone) try: ok = project.getRepo(syncFrame.syncPanel.infoStream) if not ok: closeFrameWhenDone = False except Exception as e: closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) # check for anything to commit before pull/push outcome = showCommitDialog(parent, project, infoStream=syncFrame.syncPanel.infoStream) # 0=nothing to do, 1=OK, -1=cancelled if outcome == -1: # user cancelled syncFrame.Destroy() return -1 try: status = project.sync(syncFrame.syncPanel.infoStream) if status == -1: syncFrame.syncPanel.statusAppend("Couldn't sync") except Exception: # not yet sure what errors might occur # send the closeFrameWhenDone = False syncFrame.syncPanel.statusAppend(traceback.format_exc()) wx.Yield() project._lastKnownSync = time.time() if closeFrameWhenDone: syncFrame.Destroy() return 1