psychopy 2024.1.4__py3-none-any.whl → 2024.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/.DS_Store +0 -0
- psychopy/CHANGELOG.txt +206 -0
- psychopy/GIT_SHA +1 -0
- psychopy/VERSION +1 -0
- psychopy/__init__.py +77 -15
- psychopy/app/Resources/classic/plugin16.png +0 -0
- psychopy/app/Resources/classic/plugin16@2x.png +0 -0
- psychopy/app/Resources/dark/plugin16.png +0 -0
- psychopy/app/Resources/dark/plugin16@2x.png +0 -0
- psychopy/app/Resources/light/plugin16.png +0 -0
- psychopy/app/Resources/light/plugin16@2x.png +0 -0
- psychopy/app/__init__.py +76 -2
- psychopy/app/_psychopyApp.py +126 -101
- psychopy/app/builder/builder.py +14 -10
- psychopy/app/builder/dialogs/__init__.py +8 -8
- psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
- psychopy/app/builder/dialogs/paramCtrls.py +24 -57
- psychopy/app/builder/validators.py +2 -2
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +4 -4
- psychopy/app/connections/sendusage.py +2 -2
- psychopy/app/connections/updates.py +9 -9
- psychopy/app/dialogs.py +34 -2
- psychopy/app/idle.py +31 -0
- psychopy/app/jobs.py +21 -3
- psychopy/app/linuxconfig/__init__.py +9 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1011 -942
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
- psychopy/app/pavlovia_ui/_base.py +33 -3
- psychopy/app/pavlovia_ui/search.py +0 -1
- psychopy/app/plugin_manager/dialog.py +104 -51
- psychopy/app/plugin_manager/packages.py +5 -0
- psychopy/app/plugin_manager/plugins.py +145 -67
- psychopy/app/preferencesDlg.py +8 -8
- psychopy/app/psychopyApp.py +11 -5
- psychopy/app/ribbon.py +124 -14
- psychopy/app/runner/runner.py +6 -1
- psychopy/app/stdout/stdOutRich.py +27 -11
- psychopy/app/themes/icons.py +52 -2
- psychopy/assets/__init__.py +0 -0
- psychopy/assets/click.png +0 -0
- psychopy/assets/clicknext.png +0 -0
- psychopy/assets/next.png +0 -0
- psychopy/assets/psychopy.ico +0 -0
- psychopy/assets/psychopy.png +0 -0
- psychopy/assets/templates/__init__.py +0 -0
- psychopy/assets/touch.png +0 -0
- psychopy/assets/touchnext.png +0 -0
- psychopy/assets/window.ico +0 -0
- psychopy/changes/2023.1.0.md +9 -0
- psychopy/changes/2024.1.0.md +16 -0
- psychopy/changes/__init__.py +0 -0
- psychopy/clock.py +2 -2
- psychopy/colors.py +2 -1
- psychopy/compatibility.py +53 -1
- psychopy/contrib/.DS_Store +0 -0
- psychopy/contrib/configobj/__init__.py +10 -8
- psychopy/data/__init__.py +3 -2
- psychopy/data/base.py +5 -5
- psychopy/data/experiment.py +130 -4
- psychopy/data/routine.py +56 -0
- psychopy/data/staircase.py +2 -2
- psychopy/data/trial.py +559 -97
- psychopy/data/utils.py +56 -21
- psychopy/demos/.DS_Store +0 -0
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
- psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
- psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
- psychopy/demos/builder/Hardware/.DS_Store +0 -0
- psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
- psychopy/demos/coder/iohub/.DS_Store +0 -0
- psychopy/demos/coder/misc/hdf5_2_csv +33 -0
- psychopy/event.py +30 -29
- psychopy/experiment/.DS_Store +0 -0
- psychopy/experiment/_experiment.py +6 -6
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/__init__.py +6 -3
- psychopy/experiment/components/_base.py +286 -131
- psychopy/experiment/components/aperture/.DS_Store +0 -0
- psychopy/experiment/components/brush/.DS_Store +0 -0
- psychopy/experiment/components/button/.DS_Store +0 -0
- psychopy/experiment/components/button/__init__.py +5 -1
- psychopy/experiment/components/buttonBox/.DS_Store +0 -0
- psychopy/experiment/components/camera/.DS_Store +0 -0
- psychopy/experiment/components/code/.DS_Store +0 -0
- psychopy/experiment/components/dots/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
- psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/form/__init__.py +6 -2
- psychopy/experiment/components/grating/.DS_Store +0 -0
- psychopy/experiment/components/grating/__init__.py +14 -3
- psychopy/experiment/components/image/.DS_Store +0 -0
- psychopy/experiment/components/image/__init__.py +14 -3
- psychopy/experiment/components/joyButtons/.DS_Store +0 -0
- psychopy/experiment/components/joystick/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/.DS_Store +0 -0
- psychopy/experiment/components/keyboard/__init__.py +22 -10
- psychopy/experiment/components/microphone/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +59 -39
- psychopy/experiment/components/mouse/.DS_Store +0 -0
- psychopy/experiment/components/mouse/__init__.py +44 -29
- psychopy/experiment/components/movie/.DS_Store +0 -0
- psychopy/experiment/components/movie/__init__.py +1 -1
- psychopy/experiment/components/panorama/.DS_Store +0 -0
- psychopy/experiment/components/parallelOut/.DS_Store +0 -0
- psychopy/experiment/components/patch/.DS_Store +0 -0
- psychopy/experiment/components/polygon/.DS_Store +0 -0
- psychopy/experiment/components/polygon/__init__.py +26 -6
- psychopy/experiment/components/progress/.DS_Store +0 -0
- psychopy/experiment/components/ratingScale/.DS_Store +0 -0
- psychopy/experiment/components/resourceManager/.DS_Store +0 -0
- psychopy/experiment/components/roi/.DS_Store +0 -0
- psychopy/experiment/components/roi/__init__.py +5 -0
- psychopy/experiment/components/routineSettings/.DS_Store +0 -0
- psychopy/experiment/components/routineSettings/__init__.py +57 -10
- psychopy/experiment/components/serialOut/.DS_Store +0 -0
- psychopy/experiment/components/settings/.DS_Store +0 -0
- psychopy/experiment/components/settings/__init__.py +117 -42
- psychopy/experiment/components/slider/.DS_Store +0 -0
- psychopy/experiment/components/sound/.DS_Store +0 -0
- psychopy/experiment/components/sound/__init__.py +54 -19
- psychopy/experiment/components/static/.DS_Store +0 -0
- psychopy/experiment/components/static/__init__.py +1 -1
- psychopy/experiment/components/text/.DS_Store +0 -0
- psychopy/experiment/components/text/__init__.py +28 -3
- psychopy/experiment/components/textbox/.DS_Store +0 -0
- psychopy/experiment/components/textbox/__init__.py +12 -2
- psychopy/experiment/components/unknown/.DS_Store +0 -0
- psychopy/experiment/components/unknown/__init__.py +1 -2
- psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
- psychopy/experiment/components/variable/.DS_Store +0 -0
- psychopy/experiment/flow.py +11 -4
- psychopy/experiment/loops.py +85 -37
- psychopy/experiment/params.py +74 -32
- psychopy/experiment/py2js_transpiler.py +8 -1
- psychopy/experiment/routines/.DS_Store +0 -0
- psychopy/experiment/routines/_base.py +102 -22
- psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
- psychopy/experiment/routines/counterbalance/__init__.py +5 -1
- psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
- psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
- psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
- psychopy/experiment/routines/photodiodeValidator/__init__.py +6 -5
- psychopy/experiment/routines/unknown/.DS_Store +0 -0
- psychopy/gui/wxgui.py +4 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/__init__.py +1 -1
- psychopy/hardware/base.py +12 -0
- psychopy/hardware/camera/__init__.py +1 -15
- psychopy/hardware/cedrus.py +10 -11
- psychopy/hardware/crs/colorcal.py +13 -22
- psychopy/hardware/crs/optical.py +10 -20
- psychopy/hardware/emulator.py +17 -14
- psychopy/hardware/eyetracker.py +42 -118
- psychopy/hardware/gammasci.py +4 -15
- psychopy/hardware/keyboard.py +102 -10
- psychopy/hardware/listener.py +3 -0
- psychopy/hardware/microphone.py +148 -18
- psychopy/hardware/minolta.py +8 -15
- psychopy/hardware/photodiode.py +191 -16
- psychopy/hardware/photometer/__init__.py +11 -19
- psychopy/hardware/pr.py +8 -15
- psychopy/hardware/speaker.py +39 -4
- psychopy/info.py +0 -71
- psychopy/iohub/.DS_Store +0 -0
- psychopy/iohub/__init__.py +1 -1
- psychopy/iohub/client/__init__.py +30 -20
- psychopy/iohub/client/keyboard.py +24 -24
- psychopy/iohub/datastore/__init__.py +2 -2
- psychopy/iohub/datastore/util.py +2 -2
- psychopy/iohub/default_config.yaml +1 -1
- psychopy/iohub/devices/.DS_Store +0 -0
- psychopy/iohub/devices/__init__.py +112 -25
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
- psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
- psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
- psychopy/iohub/devices/eyetracker/__init__.py +46 -0
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
- psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
- psychopy/iohub/server.py +2 -2
- psychopy/iohub/start_iohub_process.py +3 -0
- psychopy/iohub/util/__init__.py +62 -70
- psychopy/layout.py +5 -5
- psychopy/logging.py +8 -1
- psychopy/microphone.py +10 -37
- psychopy/platform_specific/__init__.py +0 -2
- psychopy/platform_specific/darwin.py +1 -3
- psychopy/platform_specific/linux.py +31 -33
- psychopy/platform_specific/win32.py +38 -13
- psychopy/plugins/__init__.py +148 -116
- psychopy/plugins/util.py +39 -0
- psychopy/preferences/Darwin.spec +4 -2
- psychopy/preferences/FreeBSD.spec +4 -2
- psychopy/preferences/Linux.spec +4 -2
- psychopy/preferences/Windows.spec +4 -2
- psychopy/preferences/baseNoArch.spec +4 -2
- psychopy/preferences/preferences.py +47 -24
- psychopy/projects/pavlovia.py +47 -4
- psychopy/scripts/psyexpCompile.py +0 -4
- psychopy/session.py +153 -21
- psychopy/sound/__init__.py +31 -21
- psychopy/sound/_base.py +20 -3
- psychopy/sound/audioclip.py +320 -33
- psychopy/sound/backend_ptb.py +47 -58
- psychopy/sound/backend_pygame.py +1 -1
- psychopy/sound/backend_pysound.py +6 -15
- psychopy/sound/transcribe.py +53 -0
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
- psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
- psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
- psychopy/tests/data/test_session/.DS_Store +0 -0
- psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
- psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/conftest.py +2 -2
- psychopy/tests/test_app/test_speed.py +4 -1
- psychopy/tests/test_data/test_TrialHandler2.py +146 -1
- psychopy/tests/test_experiment/.DS_Store +0 -0
- psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
- psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
- psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
- psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
- psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
- psychopy/tests/test_experiment/test_py2js.py +1 -1
- psychopy/tests/test_hardware/test_keyboard.py +31 -0
- psychopy/tests/test_hardware/test_ports.py +1 -11
- psychopy/tests/test_liaison/test_Liaison.py +47 -0
- psychopy/tests/test_misc/test_core.py +5 -0
- psychopy/tests/test_session/test_Session.py +5 -1
- psychopy/tests/test_tools/test_versionchooser.py +39 -8
- psychopy/tests/test_visual/test_all_stimuli.py +0 -97
- psychopy/tests/test_visual/test_image.py +6 -5
- psychopy/tests/test_visual/test_textbox.py +36 -0
- psychopy/tests/utils.py +4 -0
- psychopy/tools/filetools.py +1 -1
- psychopy/tools/pkgtools.py +160 -137
- psychopy/tools/versionchooser.py +10 -10
- psychopy/tools/wizard.py +3 -3
- psychopy/visual/.DS_Store +0 -0
- psychopy/visual/backends/pygletbackend.py +24 -13
- psychopy/visual/basevisual.py +5 -11
- psychopy/visual/button.py +2 -14
- psychopy/visual/helpers.py +5 -5
- psychopy/visual/line.py +1 -2
- psychopy/visual/movie2.py +7 -816
- psychopy/visual/movie3.py +7 -589
- psychopy/visual/movies/__init__.py +8 -11
- psychopy/visual/movies/frame.py +5 -2
- psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
- psychopy/visual/noise.py +8 -7
- psychopy/visual/patch.py +7 -16
- psychopy/visual/radial.py +9 -7
- psychopy/visual/ratingscale.py +8 -1415
- psychopy/visual/secondorder.py +10 -9
- psychopy/visual/shape.py +7 -2
- psychopy/visual/text.py +1 -1
- psychopy/visual/textbox2/textbox2.py +28 -5
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/RECORD +307 -213
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
- psychopy/app/Resources/click.png +0 -0
- psychopy/app/Resources/next.png +0 -0
- psychopy/experiment/components/patch/__init__.py +0 -121
- psychopy/experiment/components/patch/classic/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch.png +0 -0
- psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
- psychopy/experiment/components/patch/light/patch.png +0 -0
- psychopy/experiment/components/patch/light/patch@2x.png +0 -0
- psychopy/experiment/components/ratingScale/__init__.py +0 -337
- psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
- psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
- psychopy/platform_specific/posix.py +0 -16
- psychopy/tests/test_sound/test_microphone.py +0 -217
- psychopy/tests/test_visual/test_ratingScale.py +0 -299
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
- /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
- /psychopy/{app/Resources → assets}/USB-C.png +0 -0
- /psychopy/{app/Resources → assets}/USB.png +0 -0
- /psychopy/{app/Resources → assets}/creditCard.png +0 -0
- /psychopy/{app/Resources → assets}/default.mp3 +0 -0
- /psychopy/{app/Resources → assets}/default.mp4 +0 -0
- /psychopy/{app/Resources → assets}/default.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
- /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
- {psychopy-2024.1.4.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -898,9 +898,13 @@ class SurveyCtrl(wx.TextCtrl, _ValidatorMixin, _HideMixin):
|
|
|
898
898
|
|
|
899
899
|
|
|
900
900
|
class TableCtrl(wx.TextCtrl, _ValidatorMixin, _HideMixin, _FileMixin):
|
|
901
|
-
def __init__(self, parent,
|
|
902
|
-
val="", fieldName="",
|
|
901
|
+
def __init__(self, parent, param, fieldName="",
|
|
903
902
|
size=wx.Size(-1, 24)):
|
|
903
|
+
# get val and val type
|
|
904
|
+
val = param.val
|
|
905
|
+
valType = param.valType
|
|
906
|
+
# store param
|
|
907
|
+
self.param = param
|
|
904
908
|
# Create self
|
|
905
909
|
wx.TextCtrl.__init__(self)
|
|
906
910
|
self.Create(parent, -1, val, name=fieldName, size=size)
|
|
@@ -920,19 +924,6 @@ class TableCtrl(wx.TextCtrl, _ValidatorMixin, _HideMixin, _FileMixin):
|
|
|
920
924
|
self.xlBtn.SetToolTip(_translate("Open/create in your default table editor"))
|
|
921
925
|
self.xlBtn.Bind(wx.EVT_BUTTON, self.openExcel)
|
|
922
926
|
self._szr.Add(self.xlBtn)
|
|
923
|
-
# Link to Excel templates for certain contexts
|
|
924
|
-
cmpRoot = Path(experiment.components.__file__).parent
|
|
925
|
-
expRoot = Path(cmpRoot).parent
|
|
926
|
-
self.templates = {
|
|
927
|
-
'Form': Path(cmpRoot) / "form" / "formItems.xltx",
|
|
928
|
-
'CounterBalance': Path(expRoot) / "routines" / "counterbalance" / "counterbalanceItems.xltx",
|
|
929
|
-
'TrialHandler': Path(expRoot) / "loopTemplate.xltx",
|
|
930
|
-
'StairHandler': Path(expRoot) / "loopTemplate.xltx",
|
|
931
|
-
'MultiStairHandler:simple': Path(expRoot) / "staircaseTemplate.xltx",
|
|
932
|
-
'MultiStairHandler:QUEST': Path(expRoot) / "questTemplate.xltx",
|
|
933
|
-
'MultiStairHandler:QUESTPLUS': Path() / "questPlugTemplate.xltx",
|
|
934
|
-
'None': Path(expRoot) / 'blankTemplate.xltx',
|
|
935
|
-
}
|
|
936
927
|
# Specify valid extensions
|
|
937
928
|
self.validExt = [".csv",".tsv",".txt",
|
|
938
929
|
".xl",".xlsx",".xlsm",".xlsb",".xlam",".xltx",".xltm",".xls",".xlt",
|
|
@@ -950,32 +941,15 @@ class TableCtrl(wx.TextCtrl, _ValidatorMixin, _HideMixin, _FileMixin):
|
|
|
950
941
|
def validate(self, evt=None):
|
|
951
942
|
"""Redirect validate calls to global validate method, assigning appropriate valType"""
|
|
952
943
|
validate(self, "file")
|
|
953
|
-
#
|
|
954
|
-
if
|
|
955
|
-
self.xlBtn.
|
|
956
|
-
|
|
957
|
-
# enable Excel button if valid
|
|
958
|
-
self.xlBtn.Enable(self.valid)
|
|
959
|
-
# get frame
|
|
960
|
-
frame = self.GetParent()
|
|
961
|
-
if frame is None:
|
|
962
|
-
frame = self.GetTopLevelParent()
|
|
963
|
-
while hasattr(frame, "GetParent") and not (
|
|
964
|
-
hasattr(frame, "routine") or hasattr(frame, "component") or hasattr(frame, "type")
|
|
965
|
-
):
|
|
966
|
-
frame = frame.GetParent()
|
|
967
|
-
# get comp type from frame
|
|
968
|
-
if hasattr(frame, "component"):
|
|
969
|
-
thisType = frame.component.type
|
|
970
|
-
elif hasattr(frame, "routine"):
|
|
971
|
-
thisType = frame.routine.type
|
|
972
|
-
elif hasattr(frame, "type"):
|
|
973
|
-
thisType = frame.type
|
|
944
|
+
# if field is blank, enable/diable according to whether there's a template
|
|
945
|
+
if not self.GetValue().strip():
|
|
946
|
+
self.xlBtn.Enable("template" in self.param.ctrlParams)
|
|
947
|
+
# otherwise, enable/disable according to validity
|
|
974
948
|
else:
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
949
|
+
self.xlBtn.Enable(self.valid)
|
|
950
|
+
# if value isn't known until runtime, always disable Excel button
|
|
951
|
+
if "$" in self.GetValue():
|
|
952
|
+
self.xlBtn.Disable()
|
|
979
953
|
|
|
980
954
|
def openExcel(self, event):
|
|
981
955
|
"""Either open the specified excel sheet, or make a new one from a template"""
|
|
@@ -986,24 +960,17 @@ class TableCtrl(wx.TextCtrl, _ValidatorMixin, _HideMixin, _FileMixin):
|
|
|
986
960
|
"please remember to add it to {name}").format(name=_translate(self.Name)),
|
|
987
961
|
caption=_translate("Reminder"))
|
|
988
962
|
dlg.ShowModal()
|
|
989
|
-
# get
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
thisType = frame.routine.type
|
|
998
|
-
elif hasattr(frame, "type"):
|
|
999
|
-
thisType = frame.type
|
|
1000
|
-
else:
|
|
1001
|
-
thisType = "None"
|
|
1002
|
-
# open type specific template, or blank
|
|
1003
|
-
if thisType in self.templates:
|
|
1004
|
-
file = self.templates[thisType]
|
|
963
|
+
# get template
|
|
964
|
+
if "template" in self.param.ctrlParams:
|
|
965
|
+
file = self.param.ctrlParams['template']
|
|
966
|
+
# if template is specified as a method, call it now to get the value live
|
|
967
|
+
if callable(file):
|
|
968
|
+
file = file()
|
|
969
|
+
# convert to Path
|
|
970
|
+
file = Path(file)
|
|
1005
971
|
else:
|
|
1006
|
-
|
|
972
|
+
# use blank template if none given
|
|
973
|
+
file = Path(experiment.__file__).parent / 'blankTemplate.xltx',
|
|
1007
974
|
# Open whatever file is used
|
|
1008
975
|
try:
|
|
1009
976
|
os.startfile(file)
|
|
@@ -13,12 +13,12 @@ import psychopy.experiment.utils
|
|
|
13
13
|
from psychopy.tools import stringtools
|
|
14
14
|
from psychopy.localization import _translate
|
|
15
15
|
from . import experiment
|
|
16
|
-
from
|
|
16
|
+
from packaging.version import Version
|
|
17
17
|
from psychopy.tools.fontmanager import FontManager
|
|
18
18
|
|
|
19
19
|
fontMGR = FontManager()
|
|
20
20
|
|
|
21
|
-
if
|
|
21
|
+
if Version(wx.__version__) < Version('4.0.0a1'):
|
|
22
22
|
_ValidatorBase = wx.PyValidator
|
|
23
23
|
else:
|
|
24
24
|
_ValidatorBase = wx.Validator
|
|
@@ -106,14 +106,6 @@ class BaseCodeEditor(wx.stc.StyledTextCtrl, handlers.ThemeMixin):
|
|
|
106
106
|
deleteItem = wx.MenuItem(menu, self.DeleteID, _translate("Delete"))
|
|
107
107
|
selectItem = wx.MenuItem(menu, self.SelectAllID, _translate("Select All"))
|
|
108
108
|
|
|
109
|
-
# Check whether items should be enabled
|
|
110
|
-
undoItem.Enable(self.CanUndo())
|
|
111
|
-
redoItem.Enable(self.CanRedo())
|
|
112
|
-
cutItem.Enable(self.CanCut())
|
|
113
|
-
copyItem.Enable(self.CanCopy())
|
|
114
|
-
pasteItem.Enable(self.CanPaste())
|
|
115
|
-
deleteItem.Enable(self.CanCopy())
|
|
116
|
-
|
|
117
109
|
# Append items to menu
|
|
118
110
|
menu.Append(undoItem)
|
|
119
111
|
menu.Append(redoItem)
|
|
@@ -125,6 +117,14 @@ class BaseCodeEditor(wx.stc.StyledTextCtrl, handlers.ThemeMixin):
|
|
|
125
117
|
menu.Append(deleteItem)
|
|
126
118
|
menu.Append(selectItem)
|
|
127
119
|
|
|
120
|
+
# Check whether items should be enabled
|
|
121
|
+
undoItem.Enable(self.CanUndo())
|
|
122
|
+
redoItem.Enable(self.CanRedo())
|
|
123
|
+
cutItem.Enable(self.CanCut())
|
|
124
|
+
copyItem.Enable(self.CanCopy())
|
|
125
|
+
pasteItem.Enable(self.CanPaste())
|
|
126
|
+
deleteItem.Enable(self.CanCopy())
|
|
127
|
+
|
|
128
128
|
self.PopupMenu(menu)
|
|
129
129
|
menu.Destroy()
|
|
130
130
|
|
psychopy/app/coder/coder.py
CHANGED
|
@@ -2070,6 +2070,7 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
2070
2070
|
# self.OnFindClose(None)
|
|
2071
2071
|
|
|
2072
2072
|
def OnFindClose(self, event):
|
|
2073
|
+
self.findDlg.Destroy()
|
|
2073
2074
|
self.findDlg = None
|
|
2074
2075
|
|
|
2075
2076
|
def OnFileHistory(self, evt=None):
|
|
@@ -2873,10 +2874,6 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
2873
2874
|
# TODO: Allow user to run project from coder
|
|
2874
2875
|
pass
|
|
2875
2876
|
|
|
2876
|
-
def setPavloviaUser(self, user):
|
|
2877
|
-
# TODO: update user icon on button to user avatar
|
|
2878
|
-
pass
|
|
2879
|
-
|
|
2880
2877
|
def resetPrefs(self, event):
|
|
2881
2878
|
"""Reset preferences to default"""
|
|
2882
2879
|
# Present "are you sure" dialog
|
|
@@ -3056,6 +3053,9 @@ class CoderRibbon(ribbon.FrameRibbon):
|
|
|
3056
3053
|
|
|
3057
3054
|
self.addSeparator()
|
|
3058
3055
|
|
|
3056
|
+
# --- Plugin sections ---
|
|
3057
|
+
self.addPluginSections("psychopy.app.builder")
|
|
3058
|
+
|
|
3059
3059
|
# --- Views ---
|
|
3060
3060
|
self.addStretchSpacer()
|
|
3061
3061
|
self.addSeparator()
|
|
@@ -36,10 +36,10 @@ def sendUsageStats(app=None):
|
|
|
36
36
|
OSXver, junk, architecture = platform.mac_ver()
|
|
37
37
|
systemInfo = "OSX_%s" % (OSXver)
|
|
38
38
|
elif sys.platform.startswith('linux'):
|
|
39
|
-
|
|
39
|
+
import distro
|
|
40
40
|
systemInfo = '%s_%s_%s' % (
|
|
41
41
|
'Linux',
|
|
42
|
-
':'.join([x for x in
|
|
42
|
+
':'.join([x for x in [distro.name(), distro.version(), distro.codename()] if x != '']),
|
|
43
43
|
platform.release())
|
|
44
44
|
if len(systemInfo) > 30: # if it's too long PHP/SQL fails to store!?
|
|
45
45
|
systemInfo = systemInfo[0:30]
|
|
@@ -12,7 +12,7 @@ import time
|
|
|
12
12
|
import zipfile
|
|
13
13
|
import platform
|
|
14
14
|
import os
|
|
15
|
-
from
|
|
15
|
+
from packaging.version import Version
|
|
16
16
|
import wx
|
|
17
17
|
import wx.lib.filebrowsebutton
|
|
18
18
|
try:
|
|
@@ -116,8 +116,8 @@ class Updater():
|
|
|
116
116
|
raise(err)
|
|
117
117
|
skip = self.app.prefs.appData['skipVersion'] == self.latest['version']
|
|
118
118
|
if newer and not skip:
|
|
119
|
-
if (
|
|
120
|
-
<=
|
|
119
|
+
if (Version(self.latest['lastUpdatable'])
|
|
120
|
+
<= Version(self.runningVersion)):
|
|
121
121
|
# go to the updating window
|
|
122
122
|
confirmDlg = SuggestUpdateDialog(
|
|
123
123
|
self.latest, self.runningVersion)
|
|
@@ -338,8 +338,8 @@ class InstallUpdateDialog(wx.Dialog):
|
|
|
338
338
|
msg += _translate("Check proxy settings in preferences.")
|
|
339
339
|
self.statusMessage.SetLabel(msg)
|
|
340
340
|
return
|
|
341
|
-
elif (
|
|
342
|
-
<
|
|
341
|
+
elif (Version(self.latest['version'])
|
|
342
|
+
< Version(self.runningVersion)):
|
|
343
343
|
msg = _translate(
|
|
344
344
|
"You are running PsychoPy (%(running)s), which is ahead of "
|
|
345
345
|
"the latest official version (%(latest)s)") % {
|
|
@@ -354,8 +354,8 @@ class InstallUpdateDialog(wx.Dialog):
|
|
|
354
354
|
"PsychoPy v%(latest)s is available\nYou are running v%(running)s")
|
|
355
355
|
msg = txt % {'latest': self.latest['version'],
|
|
356
356
|
'running': self.runningVersion}
|
|
357
|
-
if (
|
|
358
|
-
<=
|
|
357
|
+
if (Version(self.latest['lastUpdatable'])
|
|
358
|
+
<= Version(self.runningVersion)):
|
|
359
359
|
msg += _translate("\nYou can update to the latest version automatically")
|
|
360
360
|
else:
|
|
361
361
|
msg += _translate("\nYou cannot update to the latest version "
|
|
@@ -620,10 +620,10 @@ def sendUsageStats():
|
|
|
620
620
|
OSXver, junk, architecture = platform.mac_ver()
|
|
621
621
|
systemInfo = "OSX_%s_%s" % (OSXver, architecture)
|
|
622
622
|
elif sys.platform.startswith('linux'):
|
|
623
|
-
|
|
623
|
+
import distro
|
|
624
624
|
systemInfo = '%s_%s_%s' % (
|
|
625
625
|
'Linux',
|
|
626
|
-
':'.join([x for x in
|
|
626
|
+
':'.join([x for x in [distro.name(), distro.version(), distro.codename()] if x != '']),
|
|
627
627
|
platform.release())
|
|
628
628
|
if len(systemInfo) > 30: # if it's too long PHP/SQL fails to store!?
|
|
629
629
|
systemInfo = systemInfo[0:30]
|
psychopy/app/dialogs.py
CHANGED
|
@@ -18,7 +18,7 @@ from wx.lib.newevent import NewEvent
|
|
|
18
18
|
|
|
19
19
|
from psychopy import logging
|
|
20
20
|
from psychopy.localization import _translate
|
|
21
|
-
from
|
|
21
|
+
from packaging.version import Version
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
class MessageDialog(wx.Dialog):
|
|
@@ -79,6 +79,38 @@ class MessageDialog(wx.Dialog):
|
|
|
79
79
|
(GBSizerExLayoutEvent, EVT_GBSIZEREX_LAYOUT) = NewEvent()
|
|
80
80
|
|
|
81
81
|
|
|
82
|
+
class RichMessageDialog(wx.Dialog):
|
|
83
|
+
def __init__(
|
|
84
|
+
self,
|
|
85
|
+
parent=None,
|
|
86
|
+
message="",
|
|
87
|
+
title="",
|
|
88
|
+
size=(600, 500),
|
|
89
|
+
style=wx.RESIZE_BORDER
|
|
90
|
+
):
|
|
91
|
+
from psychopy.app.utils import MarkdownCtrl
|
|
92
|
+
# initialise dialog
|
|
93
|
+
wx.Dialog.__init__(
|
|
94
|
+
self, parent,
|
|
95
|
+
title=title,
|
|
96
|
+
size=size,
|
|
97
|
+
style=style
|
|
98
|
+
)
|
|
99
|
+
# setup sizer
|
|
100
|
+
self.border = wx.BoxSizer(wx.VERTICAL)
|
|
101
|
+
self.SetSizer(self.border)
|
|
102
|
+
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
|
103
|
+
self.border.Add(self.sizer, proportion=1, border=6, flag=wx.EXPAND | wx.ALL)
|
|
104
|
+
# add markdown ctrl
|
|
105
|
+
self.ctrl = MarkdownCtrl(
|
|
106
|
+
self, value=message, style=wx.TE_READONLY
|
|
107
|
+
)
|
|
108
|
+
self.sizer.Add(self.ctrl, border=6, proportion=1, flag=wx.EXPAND | wx.ALL)
|
|
109
|
+
# add OK button
|
|
110
|
+
self.btns = self.CreateStdDialogButtonSizer(flags=wx.OK)
|
|
111
|
+
self.border.Add(self.btns, border=12, flag=wx.EXPAND | wx.ALL)
|
|
112
|
+
|
|
113
|
+
|
|
82
114
|
class GlobSizer(wx.GridBagSizer):
|
|
83
115
|
"""This is a GridBagSizer that supports adding/removing/inserting rows and
|
|
84
116
|
columns. It was found online, with not clear use license (public domain?).
|
|
@@ -620,7 +652,7 @@ class ListWidget(GlobSizer):
|
|
|
620
652
|
|
|
621
653
|
|
|
622
654
|
if __name__ == '__main__':
|
|
623
|
-
if
|
|
655
|
+
if Version(wx.__version__) < Version('2.9'):
|
|
624
656
|
app = wx.PySimpleApp()
|
|
625
657
|
else:
|
|
626
658
|
app = wx.App(False)
|
psychopy/app/idle.py
CHANGED
|
@@ -82,6 +82,37 @@ tasks['getPavloviaUser'] = {
|
|
|
82
82
|
currentTask = None
|
|
83
83
|
|
|
84
84
|
|
|
85
|
+
def addTask(taskName, func, tstart=None, tend=None, thread=True):
|
|
86
|
+
"""Add an idle task.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
taskName : str
|
|
91
|
+
Name of the task.
|
|
92
|
+
func : function
|
|
93
|
+
Function to be executed.
|
|
94
|
+
tstart : float, optional
|
|
95
|
+
Start time of the task.
|
|
96
|
+
tend : float, optional
|
|
97
|
+
End time of the task.
|
|
98
|
+
thread : bool, optional
|
|
99
|
+
Whether to run the task in a separate thread.
|
|
100
|
+
|
|
101
|
+
"""
|
|
102
|
+
global tasks
|
|
103
|
+
if taskName in tasks:
|
|
104
|
+
logging.warning('Task {} already exists'.format(taskName))
|
|
105
|
+
return
|
|
106
|
+
|
|
107
|
+
tasks[taskName] = {
|
|
108
|
+
'status': NOT_STARTED,
|
|
109
|
+
'func': func,
|
|
110
|
+
'tstart': tstart,
|
|
111
|
+
'tEnd': tend,
|
|
112
|
+
'thread': thread,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
85
116
|
def doIdleTasks(app=None):
|
|
86
117
|
global currentTask
|
|
87
118
|
|
psychopy/app/jobs.py
CHANGED
|
@@ -37,6 +37,7 @@ import os.path
|
|
|
37
37
|
|
|
38
38
|
import wx
|
|
39
39
|
import os
|
|
40
|
+
import sys
|
|
40
41
|
from subprocess import Popen, PIPE
|
|
41
42
|
from threading import Thread, Event
|
|
42
43
|
from queue import Queue, Empty
|
|
@@ -246,6 +247,22 @@ class Job:
|
|
|
246
247
|
# start the sub-process
|
|
247
248
|
command = self._command
|
|
248
249
|
|
|
250
|
+
# # subprocess inherits the environment of the parent process
|
|
251
|
+
if env is None:
|
|
252
|
+
scriptEnv = os.environ.copy()
|
|
253
|
+
else:
|
|
254
|
+
scriptEnv = env
|
|
255
|
+
|
|
256
|
+
# remove some environment variables that can cause issues
|
|
257
|
+
if 'PYTHONSTARTUP' in scriptEnv:
|
|
258
|
+
del scriptEnv['PYTHONSTARTUP']
|
|
259
|
+
|
|
260
|
+
# Set encoding for text mode pipes, needs to be explicitly set or we
|
|
261
|
+
# crash on windows
|
|
262
|
+
scriptEnv['PYTHONIOENCODING'] = 'utf-8'
|
|
263
|
+
if sys.platform == 'win32':
|
|
264
|
+
scriptEnv['PYTHONLEGACYWINDOWSSTDIO'] = 'utf-8'
|
|
265
|
+
|
|
249
266
|
try:
|
|
250
267
|
self._process = Popen(
|
|
251
268
|
args=command,
|
|
@@ -257,10 +274,11 @@ class Job:
|
|
|
257
274
|
preexec_fn=None,
|
|
258
275
|
shell=False,
|
|
259
276
|
cwd=cwd,
|
|
260
|
-
env=
|
|
261
|
-
universal_newlines=True, # gives us back a string instead of bytes
|
|
277
|
+
env=scriptEnv,
|
|
278
|
+
# universal_newlines=True, # gives us back a string instead of bytes
|
|
262
279
|
creationflags=0,
|
|
263
|
-
text=
|
|
280
|
+
text=False,
|
|
281
|
+
encoding='utf-8'
|
|
264
282
|
)
|
|
265
283
|
except FileNotFoundError:
|
|
266
284
|
return -1 # negative PID means failure
|
|
@@ -19,6 +19,7 @@ import sys
|
|
|
19
19
|
|
|
20
20
|
import wx
|
|
21
21
|
from .ui import BaseLinuxConfigDialog
|
|
22
|
+
from ...core import rush
|
|
22
23
|
|
|
23
24
|
# Text that appears at the top of the dialog with provides instructions to the
|
|
24
25
|
# user.
|
|
@@ -142,3 +143,11 @@ def linuxConfigFileExists():
|
|
|
142
143
|
return True
|
|
143
144
|
|
|
144
145
|
return os.path.isfile(_confPath)
|
|
146
|
+
|
|
147
|
+
def linuxRushAllowed():
|
|
148
|
+
if sys.platform != 'linux':
|
|
149
|
+
return True
|
|
150
|
+
|
|
151
|
+
success = rush(1)
|
|
152
|
+
rush(0)
|
|
153
|
+
return success
|
|
Binary file
|