Repository: psychopy/psychopy

Issue:
Feature Request - 3rd View Option for Task Execution
A limitation of the current two view options, and something that is present in packages like eprime, is a task execution mode where the code can be run but not edited. 

When running an experiment in coder view it is possible for participants/undergrad assistants to accidentally insert characters into the code. The coder view presently pops up a prompt asking if you want to save the file prior to running when such an instance occurs, and you can use the operating system to restrict editing of a file. 

But a view similar to the coder view except without the ability to change the code would enable those who use either coder or builder to more easily deploy tasks without those issues.



Discussion:

Resolving patch:
diff --git a/psychopy/app/coder/coder.py b/psychopy/app/coder/coder.py
--- a/psychopy/app/coder/coder.py
+++ b/psychopy/app/coder/coder.py
@@ -401,7 +401,7 @@ class CodeEditor(wx.stc.StyledTextCtrl):
     # this comes mostly from the wxPython demo styledTextCtrl 2
     def __init__(self, parent, ID, frame,
                  pos=wx.DefaultPosition, size=wx.Size(100,100),#set the viewer to be small, then it will increase with wx.aui control
-                 style=0):
+                 style=0, readonly=False):
         wx.stc.StyledTextCtrl.__init__(self, parent, ID, pos, size, style)
         #JWP additions
         self.notebook=parent
@@ -465,7 +465,9 @@ def __init__(self, parent, ID, frame,
         self.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
         self.Bind(wx.EVT_KEY_DOWN, self.OnKeyPressed)
 
-        self.setFonts()
+        # black-and-white text signals read-only file open in Coder window
+        if not readonly:
+            self.setFonts()
         self.SetDropTarget(FileDropTarget(coder = self.coder))
 
     def setFonts(self):
@@ -1738,6 +1740,7 @@ def findDocID(self, filename):
     def setCurrentDoc(self, filename, keepHidden=False):
         #check if this file is already open
         docID=self.findDocID(filename)
+        readonly = 'readonly' in self.app.prefs.coder and self.app.prefs.coder['readonly']
         if docID>=0:
             self.currentDoc = self.notebook.GetPage(docID)
             self.notebook.SetSelection(docID)
@@ -1748,7 +1751,8 @@ def setCurrentDoc(self, filename, keepHidden=False):
                 self.fileClose(self.currentDoc.filename)
 
             #create an editor window to put the text in
-            p = self.currentDoc = CodeEditor(self.notebook,-1, frame=self)
+            p = self.currentDoc = CodeEditor(self.notebook,-1, frame=self,
+                                             readonly=readonly)
 
             #load text from document
             if os.path.isfile(filename):
@@ -1790,6 +1794,8 @@ def setCurrentDoc(self, filename, keepHidden=False):
             self.SetStatusText('')
         if not keepHidden:
             self.Show()#if the user had closed the frame it might be hidden
+        if readonly:
+            self.currentDoc.SetReadOnly(True)
     def fileOpen(self, event):
         #get path of current file (empty if current file is '')
         if hasattr(self.currentDoc, 'filename'):
diff --git a/psychopy/app/preferencesDlg.py b/psychopy/app/preferencesDlg.py
--- a/psychopy/app/preferencesDlg.py
+++ b/psychopy/app/preferencesDlg.py
@@ -25,6 +25,7 @@
             'largeIcons': _translate("large icons"), 'defaultView': _translate("default view"),
             'resetPrefs': _translate('reset preferences'), 'autoSavePrefs': _translate('auto-save prefs'),
             'debugMode': _translate('debug mode'), 'locale': _translate('locale'),
+            'readonly': _translate('read-only'),
             'codeFont': _translate('code font'), 'commentFont': _translate('comment font'),
             'outputFont': _translate('output font'), 'outputFontSize': _translate('output font size'),
             'codeFontSize': _translate('code font size'),
diff --git a/psychopy/app/psychopyApp.py b/psychopy/app/psychopyApp.py
--- a/psychopy/app/psychopyApp.py
+++ b/psychopy/app/psychopyApp.py
@@ -11,6 +11,13 @@
 #now used solely as a launcher for the app, not as the app itself.
 
 if __name__=='__main__':
+    if '-x' in sys.argv:
+        # enable execution of .py script from command line using StandAlone python
+        targetScript = sys.argv[sys.argv.index('-x') + 1]
+        from psychopy import core
+        import os
+        core.shellCall([sys.executable, os.path.abspath(targetScript)])
+        sys.exit()
     if '-v' in sys.argv or '--version' in sys.argv:
         print 'PsychoPy2, version %s (c)Jonathan Peirce, 2015, GNU GPL license' %psychopy.__version__
         sys.exit()
@@ -30,6 +37,7 @@
 Options:
     -c, --coder, coder       opens coder view only
     -b, --builder, builder   opens builder view only
+    -x script.py             directly execute script.py using StandAlone python
 
     -v, --version    prints version and exits
     -h, --help       prints this help and exit


Test patch: