psychopy 2024.2.4__py3-none-any.whl → 2025.1.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/CHANGELOG.txt +208 -4
- psychopy/LICENSE.txt +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -7
- psychopy/alerts/__init__.py +1 -1
- psychopy/alerts/_alerts.py +53 -17
- psychopy/alerts/_errorHandler.py +3 -4
- psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
- psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
- psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
- psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
- psychopy/alerts/alerttools.py +0 -16
- psychopy/app/Resources/betasplash.png +0 -0
- psychopy/app/Resources/betasplash@2x.png +0 -0
- psychopy/app/Resources/classic/case.png +0 -0
- psychopy/app/Resources/classic/case@2x.png +0 -0
- psychopy/app/Resources/classic/fileaudio.png +0 -0
- psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
- psychopy/app/Resources/classic/filecss.png +0 -0
- psychopy/app/Resources/classic/filecss@2x.png +0 -0
- psychopy/app/Resources/classic/filecsv.png +0 -0
- psychopy/app/Resources/classic/filecsv@2x.png +0 -0
- psychopy/app/Resources/classic/filedesign.png +0 -0
- psychopy/app/Resources/classic/filedesign@2x.png +0 -0
- psychopy/app/Resources/classic/filefont.png +0 -0
- psychopy/app/Resources/classic/filefont@2x.png +0 -0
- psychopy/app/Resources/classic/filegit.png +0 -0
- psychopy/app/Resources/classic/filegit@2x.png +0 -0
- psychopy/app/Resources/classic/filehtml.png +0 -0
- psychopy/app/Resources/classic/filehtml@2x.png +0 -0
- psychopy/app/Resources/classic/fileimage.png +0 -0
- psychopy/app/Resources/classic/fileimage@2x.png +0 -0
- psychopy/app/Resources/classic/fileinfo.png +0 -0
- psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
- psychopy/app/Resources/classic/filejs.png +0 -0
- psychopy/app/Resources/classic/filejs@2x.png +0 -0
- psychopy/app/Resources/classic/filejson.png +0 -0
- psychopy/app/Resources/classic/filejson@2x.png +0 -0
- psychopy/app/Resources/classic/filepkg.png +0 -0
- psychopy/app/Resources/classic/filepkg@2x.png +0 -0
- psychopy/app/Resources/classic/filepsyexp.png +0 -0
- psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/classic/filepy.png +0 -0
- psychopy/app/Resources/classic/filepy@2x.png +0 -0
- psychopy/app/Resources/classic/filetxt.png +0 -0
- psychopy/app/Resources/classic/filetxt@2x.png +0 -0
- psychopy/app/Resources/classic/fileunknown.png +0 -0
- psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
- psychopy/app/Resources/classic/filevideo.png +0 -0
- psychopy/app/Resources/classic/filevideo@2x.png +0 -0
- psychopy/app/Resources/classic/find.png +0 -0
- psychopy/app/Resources/classic/find@2x.png +0 -0
- psychopy/app/Resources/classic/loop.png +0 -0
- psychopy/app/Resources/classic/loop@2x.png +0 -0
- psychopy/app/Resources/classic/regex.png +0 -0
- psychopy/app/Resources/classic/regex@2x.png +0 -0
- psychopy/app/Resources/dark/case.png +0 -0
- psychopy/app/Resources/dark/case@2x.png +0 -0
- psychopy/app/Resources/dark/fileaudio.png +0 -0
- psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
- psychopy/app/Resources/dark/filecss.png +0 -0
- psychopy/app/Resources/dark/filecss@2x.png +0 -0
- psychopy/app/Resources/dark/filecsv.png +0 -0
- psychopy/app/Resources/dark/filecsv@2x.png +0 -0
- psychopy/app/Resources/dark/filedesign.png +0 -0
- psychopy/app/Resources/dark/filedesign@2x.png +0 -0
- psychopy/app/Resources/dark/filefont.png +0 -0
- psychopy/app/Resources/dark/filefont@2x.png +0 -0
- psychopy/app/Resources/dark/filegit.png +0 -0
- psychopy/app/Resources/dark/filegit@2x.png +0 -0
- psychopy/app/Resources/dark/filehtml.png +0 -0
- psychopy/app/Resources/dark/filehtml@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage.png +0 -0
- psychopy/app/Resources/dark/fileimage@2x.png +0 -0
- psychopy/app/Resources/dark/fileinfo.png +0 -0
- psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
- psychopy/app/Resources/dark/filejs.png +0 -0
- psychopy/app/Resources/dark/filejs@2x.png +0 -0
- psychopy/app/Resources/dark/filejson.png +0 -0
- psychopy/app/Resources/dark/filejson@2x.png +0 -0
- psychopy/app/Resources/dark/filepkg.png +0 -0
- psychopy/app/Resources/dark/filepkg@2x.png +0 -0
- psychopy/app/Resources/dark/filepsyexp.png +0 -0
- psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/dark/filepy.png +0 -0
- psychopy/app/Resources/dark/filepy@2x.png +0 -0
- psychopy/app/Resources/dark/filetxt.png +0 -0
- psychopy/app/Resources/dark/filetxt@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown.png +0 -0
- psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
- psychopy/app/Resources/dark/filevideo.png +0 -0
- psychopy/app/Resources/dark/filevideo@2x.png +0 -0
- psychopy/app/Resources/dark/find.png +0 -0
- psychopy/app/Resources/dark/find@2x.png +0 -0
- psychopy/app/Resources/dark/loop.png +0 -0
- psychopy/app/Resources/dark/loop@2x.png +0 -0
- psychopy/app/Resources/dark/regex.png +0 -0
- psychopy/app/Resources/dark/regex@2x.png +0 -0
- psychopy/app/Resources/light/case.png +0 -0
- psychopy/app/Resources/light/case@2x.png +0 -0
- psychopy/app/Resources/light/fileaudio.png +0 -0
- psychopy/app/Resources/light/fileaudio@2x.png +0 -0
- psychopy/app/Resources/light/filecss.png +0 -0
- psychopy/app/Resources/light/filecss@2x.png +0 -0
- psychopy/app/Resources/light/filecsv.png +0 -0
- psychopy/app/Resources/light/filecsv@2x.png +0 -0
- psychopy/app/Resources/light/filedesign.png +0 -0
- psychopy/app/Resources/light/filedesign@2x.png +0 -0
- psychopy/app/Resources/light/filefont.png +0 -0
- psychopy/app/Resources/light/filefont@2x.png +0 -0
- psychopy/app/Resources/light/filegit.png +0 -0
- psychopy/app/Resources/light/filegit@2x.png +0 -0
- psychopy/app/Resources/light/filehtml.png +0 -0
- psychopy/app/Resources/light/filehtml@2x.png +0 -0
- psychopy/app/Resources/light/fileimage.png +0 -0
- psychopy/app/Resources/light/fileimage@2x.png +0 -0
- psychopy/app/Resources/light/fileinfo.png +0 -0
- psychopy/app/Resources/light/fileinfo@2x.png +0 -0
- psychopy/app/Resources/light/filejs.png +0 -0
- psychopy/app/Resources/light/filejs@2x.png +0 -0
- psychopy/app/Resources/light/filejson.png +0 -0
- psychopy/app/Resources/light/filejson@2x.png +0 -0
- psychopy/app/Resources/light/filepkg.png +0 -0
- psychopy/app/Resources/light/filepkg@2x.png +0 -0
- psychopy/app/Resources/light/filepsyexp.png +0 -0
- psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
- psychopy/app/Resources/light/filepy.png +0 -0
- psychopy/app/Resources/light/filepy@2x.png +0 -0
- psychopy/app/Resources/light/filetxt.png +0 -0
- psychopy/app/Resources/light/filetxt@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown.png +0 -0
- psychopy/app/Resources/light/fileunknown@2x.png +0 -0
- psychopy/app/Resources/light/filevideo.png +0 -0
- psychopy/app/Resources/light/filevideo@2x.png +0 -0
- psychopy/app/Resources/light/find.png +0 -0
- psychopy/app/Resources/light/find@2x.png +0 -0
- psychopy/app/Resources/light/loop.png +0 -0
- psychopy/app/Resources/light/loop@2x.png +0 -0
- psychopy/app/Resources/light/regex.png +0 -0
- psychopy/app/Resources/light/regex@2x.png +0 -0
- psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
- psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
- psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
- psychopy/app/Resources/splash.png +0 -0
- psychopy/app/Resources/splash@2x.png +0 -0
- psychopy/app/__init__.py +49 -8
- psychopy/app/__main__.py +3 -0
- psychopy/app/_psychopyApp.py +134 -125
- psychopy/app/builder/builder.py +42 -22
- psychopy/app/builder/dialogs/__init__.py +44 -11
- psychopy/app/builder/dialogs/dlgsCode.py +1 -1
- psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
- psychopy/app/builder/dialogs/findDlg.py +106 -20
- psychopy/app/builder/dialogs/paramCtrls.py +42 -1
- psychopy/app/builder/validators.py +1 -1
- psychopy/app/coder/codeEditorBase.py +8 -8
- psychopy/app/coder/coder.py +32 -29
- psychopy/app/coder/fileBrowser.py +68 -22
- psychopy/app/coder/folding.py +1 -1
- psychopy/app/coder/psychoParser.py +1 -1
- psychopy/app/coder/repl.py +1 -1
- psychopy/app/coder/sourceTree.py +1 -1
- psychopy/app/connections/__init__.py +1 -1
- psychopy/app/connections/news.py +1 -1
- psychopy/app/connections/sendusage.py +1 -1
- psychopy/app/connections/updates.py +1 -1
- psychopy/app/console.py +1 -1
- psychopy/app/errorDlg.py +1 -1
- psychopy/app/frametracker.py +1 -1
- psychopy/app/idle.py +1 -1
- psychopy/app/jobs.py +5 -2
- psychopy/app/linuxconfig/__init__.py +1 -1
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +1514 -3259
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
- psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
- psychopy/app/pavlovia_ui/__init__.py +1 -1
- psychopy/app/pavlovia_ui/_base.py +1 -1
- psychopy/app/pavlovia_ui/functions.py +1 -1
- psychopy/app/pavlovia_ui/menu.py +1 -1
- psychopy/app/pavlovia_ui/project.py +1 -1
- psychopy/app/pavlovia_ui/search.py +1 -1
- psychopy/app/pavlovia_ui/sync.py +1 -1
- psychopy/app/pavlovia_ui/user.py +1 -1
- psychopy/app/plugin_manager/dialog.py +34 -96
- psychopy/app/plugin_manager/packages.py +10 -14
- psychopy/app/plugin_manager/plugins.py +64 -4
- psychopy/app/preferencesDlg.py +12 -37
- psychopy/app/psychopyApp.py +130 -44
- psychopy/app/ribbon.py +1 -0
- psychopy/app/runner/runner.py +37 -15
- psychopy/app/runner/scriptProcess.py +11 -6
- psychopy/app/stdout/stdOutRich.py +9 -2
- psychopy/app/themes/fonts.py +1 -1
- psychopy/app/themes/icons.py +2 -38
- psychopy/app/ui/__init__.py +1 -1
- psychopy/app/utils.py +3 -3
- psychopy/assets/default.mp3 +0 -0
- psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
- psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
- psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
- psychopy/assets/voicekeyThresholdStim.wav +0 -0
- psychopy/clock.py +4 -1
- psychopy/colors.py +2 -0
- psychopy/core.py +1 -1
- psychopy/data/base.py +1 -1
- psychopy/data/experiment.py +151 -46
- psychopy/data/routine.py +27 -1
- psychopy/data/staircase.py +2 -1
- psychopy/data/trial.py +62 -14
- psychopy/data/utils.py +1 -1
- psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
- psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
- psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
- psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
- psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
- psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
- psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
- psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
- psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
- psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
- psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
- psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
- psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
- psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
- psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
- psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
- psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
- psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
- psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
- psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
- psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
- psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
- psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
- psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
- psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
- psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
- psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
- psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
- psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
- psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
- psychopy/demos/builder/{Feature Demos/eyetracking/eyetracking.xml → Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp} +154 -140
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
- psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
- psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
- psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
- psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
- psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
- psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
- psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
- psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
- psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
- psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
- psychopy/devices/__init__.py +1 -1
- psychopy/event.py +1 -1
- psychopy/exceptions.py +1 -1
- psychopy/experiment/__init__.py +1 -1
- psychopy/experiment/_experiment.py +62 -16
- psychopy/experiment/components/__init__.py +1 -6
- psychopy/experiment/components/_base.py +44 -19
- psychopy/experiment/components/aperture/__init__.py +1 -1
- psychopy/experiment/components/brush/__init__.py +2 -2
- psychopy/experiment/components/button/__init__.py +24 -28
- psychopy/experiment/components/camera/__init__.py +38 -39
- psychopy/experiment/components/code/__init__.py +1 -1
- psychopy/experiment/components/dots/__init__.py +1 -1
- psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
- psychopy/experiment/components/form/__init__.py +3 -3
- psychopy/experiment/components/grating/__init__.py +1 -1
- psychopy/experiment/components/image/__init__.py +1 -1
- psychopy/experiment/components/joyButtons/__init__.py +2 -2
- psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
- psychopy/experiment/components/joystick/__init__.py +3 -3
- psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
- psychopy/experiment/components/keyboard/__init__.py +98 -122
- psychopy/experiment/components/microphone/__init__.py +54 -98
- psychopy/experiment/components/mouse/__init__.py +92 -93
- psychopy/experiment/components/movie/__init__.py +28 -50
- psychopy/experiment/components/parallelOut/__init__.py +3 -3
- psychopy/experiment/components/polygon/__init__.py +2 -3
- psychopy/experiment/components/roi/__init__.py +2 -2
- psychopy/experiment/components/routineSettings/__init__.py +2 -0
- psychopy/experiment/components/serialOut/__init__.py +7 -7
- psychopy/experiment/components/settings/__init__.py +317 -313
- psychopy/experiment/components/settings/eyetracking.py +108 -0
- psychopy/experiment/components/slider/__init__.py +5 -5
- psychopy/experiment/components/sound/__init__.py +168 -78
- psychopy/experiment/components/soundsensor/__init__.py +361 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
- psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
- psychopy/experiment/components/static/__init__.py +59 -33
- psychopy/experiment/components/text/__init__.py +2 -6
- psychopy/experiment/components/textbox/__init__.py +3 -7
- psychopy/experiment/components/unknown/__init__.py +2 -0
- psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
- psychopy/experiment/exports.py +1 -1
- psychopy/experiment/flow.py +2 -2
- psychopy/experiment/localization.py +1 -1
- psychopy/experiment/loops.py +43 -10
- psychopy/experiment/params.py +6 -4
- psychopy/experiment/plugins.py +8 -1
- psychopy/experiment/py2js.py +1 -1
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +23 -24
- psychopy/experiment/routines/audioValidator/__init__.py +343 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
- psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
- psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
- psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
- psychopy/experiment/routines/unknown/__init__.py +2 -0
- psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
- psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
- psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
- psychopy/experiment/utils.py +1 -1
- psychopy/gui/__init__.py +1 -1
- psychopy/gui/qtgui.py +15 -6
- psychopy/gui/wxgui.py +1 -1
- psychopy/hardware/__init__.py +0 -1
- psychopy/hardware/base.py +147 -16
- psychopy/hardware/bbtk/__init__.py +10 -16
- psychopy/hardware/brainproducts.py +7 -13
- psychopy/hardware/button.py +21 -2
- psychopy/hardware/buttonbox/__init__.py +1 -1
- psychopy/hardware/camera/__init__.py +16 -3
- psychopy/hardware/cedrus.py +5 -16
- psychopy/hardware/crs/__init__.py +1 -1
- psychopy/hardware/crs/bits.py +36 -33
- psychopy/hardware/crs/colorcal.py +8 -11
- psychopy/hardware/crs/optical.py +7 -10
- psychopy/hardware/crs/shaders.py +18 -5
- psychopy/hardware/emotiv.py +1 -1
- psychopy/hardware/emulator.py +11 -5
- psychopy/hardware/exceptions.py +86 -0
- psychopy/hardware/forp.py +18 -23
- psychopy/hardware/gammasci.py +8 -3
- psychopy/hardware/iolab.py +8 -19
- psychopy/hardware/joystick/__init__.py +865 -266
- psychopy/hardware/joystick/_base.py +251 -0
- psychopy/hardware/joystick/backend_glfw.py +306 -0
- psychopy/hardware/joystick/backend_pyglet.py +309 -0
- psychopy/hardware/joystick/mappings.py +287 -0
- psychopy/hardware/keyboard.py +4 -2
- psychopy/hardware/labhackers.py +1 -1
- psychopy/hardware/labjacks.py +9 -13
- psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
- psychopy/hardware/listener.py +9 -8
- psychopy/hardware/manager.py +24 -35
- psychopy/hardware/microphone.py +534 -154
- psychopy/hardware/minolta.py +14 -4
- psychopy/hardware/mouse/__init__.py +1 -1
- psychopy/hardware/photometer/__init__.py +2 -2
- psychopy/hardware/pr.py +14 -4
- psychopy/hardware/qmix.py +18 -27
- psychopy/hardware/serialdevice.py +43 -12
- psychopy/hardware/soundsensor.py +473 -0
- psychopy/hardware/spatial/__init__.py +231 -0
- psychopy/hardware/speaker.py +298 -36
- psychopy/hardware/triggerbox/__init__.py +1 -1
- psychopy/hardware/triggerbox/base.py +1 -1
- psychopy/hardware/triggerbox/parallel.py +1 -1
- psychopy/info.py +1 -1
- psychopy/iohub/client/__init__.py +17 -0
- psychopy/iohub/client/keyboard.py +5 -0
- psychopy/iohub/devices/eyetracker/__init__.py +10 -18
- psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
- psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
- psychopy/iohub/devices/mouse/linux2.py +6 -1
- psychopy/iohub/devices/mouse/win32.py +5 -0
- psychopy/layout.py +1 -1
- psychopy/liaison.py +91 -39
- psychopy/locale_setup.py +11 -1
- psychopy/localization/__init__.py +1 -1
- psychopy/localization/_localization.py +1 -1
- psychopy/localization/messages.pot +2 -2
- psychopy/logging.py +14 -12
- psychopy/microphone.py +4 -3
- psychopy/misc.py +1 -1
- psychopy/monitors/MonitorCenter.py +3 -3
- psychopy/monitors/__init__.py +1 -1
- psychopy/monitors/calibData.py +1 -1
- psychopy/monitors/calibTools.py +3 -2
- psychopy/platform_specific/__init__.py +1 -1
- psychopy/platform_specific/darwin.py +1 -1
- psychopy/platform_specific/linux.py +1 -1
- psychopy/platform_specific/win32.py +1 -1
- psychopy/plugins/__init__.py +26 -17
- psychopy/plugins/util.py +65 -0
- psychopy/preferences/Darwin.spec +11 -3
- psychopy/preferences/FreeBSD.spec +11 -3
- psychopy/preferences/Linux.spec +11 -3
- psychopy/preferences/Windows.spec +11 -3
- psychopy/preferences/__init__.py +1 -1
- psychopy/preferences/baseNoArch.spec +11 -3
- psychopy/preferences/hints.py +78 -61
- psychopy/preferences/preferences.py +82 -13
- psychopy/projects/__init__.py +1 -1
- psychopy/projects/pavlovia.py +29 -13
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +81 -8
- psychopy/sound/__init__.py +25 -10
- psychopy/sound/_base.py +134 -34
- psychopy/sound/audioclip.py +38 -15
- psychopy/sound/audiodevice.py +1 -1
- psychopy/sound/backend_ptb.py +53 -321
- psychopy/sound/backend_pygame.py +7 -3
- psychopy/sound/backend_pyo.py +53 -22
- psychopy/sound/backend_pysound.py +10 -27
- psychopy/sound/backend_sounddevice.py +33 -21
- psychopy/sound/exceptions.py +1 -1
- psychopy/sound/microphone.py +83 -5
- psychopy/sound/transcribe.py +3 -3
- psychopy/tests/data/test_basic_run.py +1 -0
- psychopy/tests/data/test_loaded_namespace/test_counterbalance.psyexp +142 -0
- psychopy/tests/data/test_loaded_namespace/test_custom_missing.psyexp +129 -0
- psychopy/tests/data/test_loaded_namespace/test_missing_counterbalance.psyexp +116 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_exp.psyexp +181 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_missing.psyexp +140 -0
- psychopy/tests/data/test_loaded_namespace/test_mix_name_calibration.psyexp +164 -0
- psychopy/tests/data/test_sounds/default_16000.wav +0 -0
- psychopy/tests/data/test_sounds/default_192000.wav +0 -0
- psychopy/tests/data/test_sounds/default_22050.wav +0 -0
- psychopy/tests/data/test_sounds/default_32000.wav +0 -0
- psychopy/tests/data/test_sounds/default_44100.wav +0 -0
- psychopy/tests/data/test_sounds/default_48000.wav +0 -0
- psychopy/tests/data/test_sounds/default_8000.wav +0 -0
- psychopy/tests/data/test_sounds/default_96000.wav +0 -0
- psychopy/tests/test_alerts/test_alerttools.py +2 -1
- psychopy/tests/test_app/test_command_line.py +65 -0
- psychopy/tests/test_data/test_TrialHandler2.py +18 -7
- psychopy/tests/test_demos/test_builder_demos.py +1 -1
- psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
- psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
- psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
- psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
- psychopy/tests/test_experiment/test_experiment.py +96 -0
- psychopy/tests/test_experiment/test_loops.py +12 -4
- psychopy/tests/test_experiment/test_params.py +17 -4
- psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
- psychopy/tests/test_hardware/test_photodiode.py +66 -0
- psychopy/tests/test_liaison/test_Liaison.py +4 -4
- psychopy/tests/test_misc/test_clock.py +2 -0
- psychopy/tests/test_misc/test_color.py +2 -0
- psychopy/tests/test_misc/test_event.py +1 -0
- psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
- psychopy/tests/test_sound/test_sound.py +111 -40
- psychopy/tests/test_tools/test_colorspacetools.py +24 -23
- psychopy/tests/test_tools/test_mathtools.py +9 -9
- psychopy/tests/test_tools/test_viewtools.py +101 -0
- psychopy/tests/test_validators/__init__.py +0 -0
- psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
- psychopy/tests/test_visual/test_all_stimuli.py +2 -2
- psychopy/tests/test_visual/test_basevisual.py +37 -7
- psychopy/tests/test_visual/test_button.py +2 -2
- psychopy/tests/test_visual/test_circle.py +10 -2
- psychopy/tests/test_visual/test_dots.py +1 -1
- psychopy/tests/test_visual/test_form.py +13 -13
- psychopy/tests/test_visual/test_gamma.py +3 -3
- psychopy/tests/test_visual/test_image.py +2 -2
- psychopy/tests/test_visual/test_progress.py +2 -2
- psychopy/tests/test_visual/test_roi.py +8 -2
- psychopy/tests/test_visual/test_shape.py +2 -2
- psychopy/tests/test_visual/test_slider.py +2 -2
- psychopy/tests/test_visual/test_target.py +2 -2
- psychopy/tests/test_visual/test_textbox.py +6 -8
- psychopy/tests/test_visual/test_winScalePos.py +6 -5
- psychopy/tests/test_visual/test_window.py +17 -0
- psychopy/tests/utils.py +51 -1
- psychopy/tools/__init__.py +1 -1
- psychopy/tools/arraytools.py +2 -2
- psychopy/tools/attributetools.py +52 -1
- psychopy/tools/audiotools.py +4 -1
- psychopy/tools/colorspacetools.py +6 -4
- psychopy/tools/coordinatetools.py +1 -1
- psychopy/tools/fileerrortools.py +21 -9
- psychopy/tools/filetools.py +2 -2
- psychopy/tools/fontmanager.py +47 -28
- psychopy/tools/gltools.py +2964 -558
- psychopy/tools/imagetools.py +1 -1
- psychopy/tools/mathtools.py +997 -127
- psychopy/tools/monitorunittools.py +7 -1
- psychopy/tools/movietools.py +1 -2
- psychopy/tools/pkgtools.py +157 -127
- psychopy/tools/plottools.py +1 -1
- psychopy/tools/rifttools.py +1 -1
- psychopy/tools/stereotools.py +1 -1
- psychopy/tools/stimulustools.py +172 -2
- psychopy/tools/stringtools.py +22 -2
- psychopy/tools/systemtools.py +1 -1
- psychopy/tools/typetools.py +1 -1
- psychopy/tools/unittools.py +1 -1
- psychopy/tools/versionchooser.py +3 -1
- psychopy/tools/viewtools.py +54 -70
- psychopy/tools/wizard.py +2 -2
- psychopy/validation/__init__.py +6 -0
- psychopy/validation/audio.py +74 -0
- psychopy/validation/visual.py +115 -0
- psychopy/visual/__init__.py +1 -4
- psychopy/visual/aperture.py +9 -6
- psychopy/visual/backends/__init__.py +1 -1
- psychopy/visual/backends/_base.py +1 -1
- psychopy/visual/backends/gamma.py +1 -1
- psychopy/visual/backends/glfwbackend.py +8 -12
- psychopy/visual/backends/pygamebackend.py +1 -1
- psychopy/visual/backends/pygletbackend.py +32 -11
- psychopy/visual/basevisual.py +93 -13
- psychopy/visual/brush.py +1 -1
- psychopy/visual/bufferimage.py +90 -10
- psychopy/visual/button.py +1 -1
- psychopy/visual/circle.py +12 -20
- psychopy/visual/custommouse.py +1 -1
- psychopy/visual/dot.py +80 -14
- psychopy/visual/elementarray.py +84 -10
- psychopy/visual/filters.py +1 -1
- psychopy/visual/form.py +43 -28
- psychopy/visual/grating.py +105 -25
- psychopy/visual/helpers.py +1 -1
- psychopy/visual/image.py +98 -20
- psychopy/visual/line.py +15 -25
- psychopy/visual/movie.py +1 -1
- psychopy/visual/movie2.py +4 -3
- psychopy/visual/movie3.py +4 -3
- psychopy/visual/movies/__init__.py +1 -1
- psychopy/visual/movies/frame.py +1 -1
- psychopy/visual/movies/metadata.py +1 -1
- psychopy/visual/movies/players/__init__.py +1 -1
- psychopy/visual/movies/players/_base.py +1 -1
- psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
- psychopy/visual/nnlvs.py +9 -6
- psychopy/visual/noise.py +4 -16
- psychopy/visual/patch.py +4 -3
- psychopy/visual/pie.py +3 -14
- psychopy/visual/polygon.py +21 -28
- psychopy/visual/radial.py +4 -18
- psychopy/visual/ratingscale.py +4 -3
- psychopy/visual/rect.py +16 -25
- psychopy/visual/rift.py +8 -2
- psychopy/visual/secondorder.py +4 -16
- psychopy/visual/shaders.py +620 -286
- psychopy/visual/shape.py +281 -90
- psychopy/visual/simpleimage.py +1 -1
- psychopy/visual/slider.py +78 -25
- psychopy/visual/stim3d.py +5 -608
- psychopy/visual/text.py +13 -3
- psychopy/visual/textbox2/textbox2.py +188 -56
- psychopy/visual/vlcmoviestim.py +1 -1
- psychopy/visual/window.py +373 -200
- psychopy/web.py +1 -1
- {psychopy-2024.2.4.dist-info → psychopy-2025.1.0.dist-info}/METADATA +9 -9
- {psychopy-2024.2.4.dist-info → psychopy-2025.1.0.dist-info}/RECORD +653 -660
- psychopy/.DS_Store +0 -0
- psychopy/__init__.py.orig +0 -65
- psychopy/app/.DS_Store +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/Resources/classic/filecsv16.png +0 -0
- psychopy/app/Resources/classic/fileimage16.png +0 -0
- psychopy/app/Resources/classic/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/filecsv16.png +0 -0
- psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
- psychopy/app/Resources/dark/fileimage16.png +0 -0
- psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
- psychopy/app/Resources/dark/fileunknown16.png +0 -0
- psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
- psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
- psychopy/app/Resources/light/filecsv16.png +0 -0
- psychopy/app/Resources/light/filecsv16@2x.png +0 -0
- psychopy/app/Resources/light/fileimage16.png +0 -0
- psychopy/app/Resources/light/fileimage16@2x.png +0 -0
- psychopy/app/Resources/light/fileunknown16.png +0 -0
- psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
- psychopy/app/Resources/psychopySplash.png +0 -0
- psychopy/app/Resources/psychopySplash@2x.png +0 -0
- psychopy/app/builder/builder.py.orig +0 -3932
- psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
- psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
- psychopy/app/colorpicker/__init__.py.orig +0 -411
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.po +0 -6127
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.po +0 -7366
- psychopy/core.py.orig +0 -169
- psychopy/demos/builder/.DS_Store +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/index.html +0 -23
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks-legacy-browsers.js +0 -423
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks.js +0 -427
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/chooseBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/facesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/housesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.py +0 -330
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
- psychopy/demos/builder/Experiments/.DS_Store +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
- psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
- psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
- psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xsd +0 -120
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.psyexp +0 -323
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.py +0 -562
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
- psychopy/demos/builder/Tools/gammaCalibration/questStairs.xlsx +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/low_contrast.png +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/make_2nd_order_tex.py +0 -59
- psychopy/demos/builder/Tools/gammaCalibration/resources/second_order_tex.png +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +0 -1
- psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/radialGratingContracting.py +0 -29
- psychopy/experiment/_experiment.py.orig +0 -1032
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py.orig +0 -823
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py.orig +0 -490
- psychopy/experiment/components/settings/__init__.py.orig +0 -1337
- psychopy/experiment/components/textbox/__init__.py.orig +0 -310
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/loops.py.orig +0 -829
- psychopy/experiment/params.py.orig +0 -408
- psychopy/experiment/routine.py.orig +0 -503
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
- psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +0 -680
- psychopy/hardware/iolab.py.orig +0 -238
- psychopy/hardware/serialport.py +0 -51
- psychopy/iohub/datastore/__init__.py.orig +0 -443
- psychopy/iohub/datastore/util.py.orig +0 -692
- psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
- psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py.orig +0 -1295
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/__test.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/corrFullRandom_local.csv +0 -16
- psychopy/tests/data/corrFullRandom_local.tsv +0 -6
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/testLoopsBlocks.psyexp_local.py +0 -328
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/text2_height.png +0 -0
- psychopy/tests/data/text2_normAddBlend.png +0 -0
- psychopy/tests/data/text2_normHexbackground.png +0 -0
- psychopy/tests/data/text2_stencil.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.csv +0 -9
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.csv +0 -9
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
- psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
- psychopy/tests/test_visual/test_image.py.orig +0 -219
- psychopy/visual/basevisual.py.orig +0 -1723
- psychopy/visual/form.py.orig +0 -1181
- psychopy/visual/text.py.orig +0 -752
- psychopy/visual/textbox2/textbox2.py.orig +0 -1315
- psychopy/visual/windowwarp.py.orig +0 -463
- /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
- /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
- /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
- /psychopy/{demos/builder/Tools/gammaCalibration/readme.md → tests/test_plugins/__init__.py} +0 -0
- {psychopy-2024.2.4.dist-info → psychopy-2025.1.0.dist-info}/WHEEL +0 -0
- {psychopy-2024.2.4.dist-info → psychopy-2025.1.0.dist-info}/entry_points.txt +0 -0
- {psychopy-2024.2.4.dist-info → psychopy-2025.1.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""Dialog classes for the Builder, including ParamCtrls
|
|
@@ -28,9 +28,10 @@ from .dlgsConditions import DlgConditions
|
|
|
28
28
|
from .dlgsCode import DlgCodeComponentProperties, CodeBox
|
|
29
29
|
from .findDlg import BuilderFindDlg
|
|
30
30
|
from . import paramCtrls
|
|
31
|
-
from psychopy import
|
|
31
|
+
from psychopy.app.utils import HyperLinkCtrl
|
|
32
|
+
from psychopy import data, logging, exceptions, plugins
|
|
32
33
|
from psychopy.localization import _translate
|
|
33
|
-
from psychopy.tools import versionchooser as vc
|
|
34
|
+
from psychopy.tools import versionchooser as vc, pkgtools
|
|
34
35
|
from psychopy.alerts import alert
|
|
35
36
|
from ...colorpicker import PsychoColorPicker
|
|
36
37
|
from pathlib import Path
|
|
@@ -194,6 +195,13 @@ class ParamCtrls():
|
|
|
194
195
|
fieldName=fieldName,
|
|
195
196
|
size=wx.Size(int(self.valueWidth), 24))
|
|
196
197
|
self.valueCtrl.allowedVals = param.allowedVals
|
|
198
|
+
elif param.inputType == 'font':
|
|
199
|
+
self.valueCtrl = paramCtrls.FontCtrl(
|
|
200
|
+
parent,
|
|
201
|
+
val=str(param.val),
|
|
202
|
+
valType=param.valType,
|
|
203
|
+
fieldName=fieldName,
|
|
204
|
+
size=wx.Size(int(self.valueWidth), 24))
|
|
197
205
|
elif param.inputType == 'survey':
|
|
198
206
|
self.valueCtrl = paramCtrls.SurveyCtrl(
|
|
199
207
|
parent,
|
|
@@ -649,6 +657,9 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
|
|
|
649
657
|
"false": "Disable", # permitted: hide, show, enable, disable
|
|
650
658
|
}"""
|
|
651
659
|
isChanged = False
|
|
660
|
+
# This list will be used to delay the populate actions on the
|
|
661
|
+
# dependent params
|
|
662
|
+
populateCtrls = []
|
|
652
663
|
for thisDep in self.parent.element.depends:
|
|
653
664
|
if not (
|
|
654
665
|
thisDep['param'] in list(self.ctrls) + ['start', 'stop']
|
|
@@ -683,9 +694,10 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
|
|
|
683
694
|
# only repopulate if dependency ctrl has changed
|
|
684
695
|
dependencyParam = self.parent.element.params[thisDep['dependsOn']]
|
|
685
696
|
if dependencyParam.val != dependencyCtrls.getValue():
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
dependentCtrls
|
|
697
|
+
# Delay the populate action
|
|
698
|
+
populateCtrls.append(
|
|
699
|
+
[dependencyParam, dependencyCtrls, dependentCtrls]
|
|
700
|
+
)
|
|
689
701
|
else:
|
|
690
702
|
# if action is "enable" then do ctrl.Enable() etc
|
|
691
703
|
for ctrlName in ['valueCtrl', 'nameCtrl', 'updatesCtrl']:
|
|
@@ -694,6 +706,11 @@ class ParamNotebook(wx.Notebook, handlers.ThemeMixin):
|
|
|
694
706
|
evalStr = ("dependentCtrls.{}.{}()"
|
|
695
707
|
.format(ctrlName, action.title()))
|
|
696
708
|
eval(evalStr)
|
|
709
|
+
# Execute the populate actions
|
|
710
|
+
for elem in populateCtrls:
|
|
711
|
+
elem[0].val = elem[1].getValue()
|
|
712
|
+
if hasattr(elem[2].valueCtrl, "populate"):
|
|
713
|
+
elem[2].valueCtrl.populate()
|
|
697
714
|
# Update sizer
|
|
698
715
|
if isChanged:
|
|
699
716
|
self.sizer.SetEmptyCellSize((0, 0))
|
|
@@ -879,6 +896,7 @@ class _BaseParamsDlg(wx.Dialog):
|
|
|
879
896
|
self.showAdvanced = showAdvanced
|
|
880
897
|
self.order = element.order
|
|
881
898
|
self.depends = element.depends
|
|
899
|
+
self.plugin = element.plugin
|
|
882
900
|
self.data = []
|
|
883
901
|
# max( len(str(self.params[x])) for x in keys )
|
|
884
902
|
self.maxFieldLength = 10
|
|
@@ -907,12 +925,26 @@ class _BaseParamsDlg(wx.Dialog):
|
|
|
907
925
|
|
|
908
926
|
self.mainSizer.Add(self.ctrls, # ctrls is the notebook of params
|
|
909
927
|
proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
|
|
928
|
+
# if element came from a plugin that's not installed, add button to open plugins dlg
|
|
929
|
+
self.pluginBtn = HyperLinkCtrl(
|
|
930
|
+
self, label=_translate("Requires plugin {}, click here to install.").format(self.plugin)
|
|
931
|
+
)
|
|
932
|
+
self.pluginBtn.Bind(wx.EVT_BUTTON, self.jumpToPlugin)
|
|
933
|
+
self.mainSizer.Add(self.pluginBtn, border=6, flag=wx.CENTER | wx.ALL)
|
|
934
|
+
# show/hide button according to whether the plugin is installed or not
|
|
935
|
+
self.pluginBtn.Show(
|
|
936
|
+
self.plugin not in (None, "None", "") and self.plugin not in plugins.listPlugins()
|
|
937
|
+
)
|
|
910
938
|
|
|
911
939
|
self.SetSizerAndFit(self.mainSizer)
|
|
912
940
|
|
|
913
941
|
def getParams(self):
|
|
914
942
|
return self.ctrls.getParams()
|
|
915
943
|
|
|
944
|
+
def jumpToPlugin(self, evt):
|
|
945
|
+
dlg = self.frame.openPluginManager()
|
|
946
|
+
dlg.jumpToPlugin(self.plugin)
|
|
947
|
+
|
|
916
948
|
def openMonitorCenter(self, event):
|
|
917
949
|
self.app.openMonitorCenter(event)
|
|
918
950
|
self.paramCtrls['Monitor'].valueCtrl.SetFocus()
|
|
@@ -962,8 +994,7 @@ class _BaseParamsDlg(wx.Dialog):
|
|
|
962
994
|
border=3)
|
|
963
995
|
self.OKbtn = wx.Button(self, wx.ID_OK, _translate(" OK "))
|
|
964
996
|
# intercept OK button if a loop dialog, in case file name was edited:
|
|
965
|
-
|
|
966
|
-
self.OKbtn.Bind(wx.EVT_BUTTON, self.onOK)
|
|
997
|
+
self.OKbtn.Bind(wx.EVT_BUTTON, self.onOK)
|
|
967
998
|
self.OKbtn.SetDefault()
|
|
968
999
|
CANCEL = wx.Button(self, wx.ID_CANCEL, _translate(" Cancel "))
|
|
969
1000
|
|
|
@@ -1025,9 +1056,11 @@ class _BaseParamsDlg(wx.Dialog):
|
|
|
1025
1056
|
def onOK(self, event=None):
|
|
1026
1057
|
"""Handler for OK button which should validate dialog contents.
|
|
1027
1058
|
"""
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1059
|
+
# run "on ok" validation for each ctrl
|
|
1060
|
+
for ctrl in self.paramCtrls.values():
|
|
1061
|
+
if hasattr(ctrl, "valueCtrl") and hasattr(ctrl.valueCtrl, "onOK"):
|
|
1062
|
+
ctrl.valueCtrl.onOK()
|
|
1063
|
+
|
|
1031
1064
|
event.Skip()
|
|
1032
1065
|
|
|
1033
1066
|
def onTextEventCode(self, event=None):
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""Dialog classes for the Builder Code component
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""Conditions-file preview and mini-editor for the Builder
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import wx
|
|
2
2
|
from psychopy import experiment
|
|
3
|
+
from psychopy.experiment.components.routineSettings import RoutineSettingsComponent
|
|
3
4
|
from psychopy.app import utils
|
|
4
5
|
from psychopy.app.themes import icons
|
|
5
6
|
from psychopy.localization import _translate
|
|
7
|
+
from psychopy.tools import stringtools
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
class BuilderFindDlg(wx.Dialog):
|
|
@@ -25,10 +27,34 @@ class BuilderFindDlg(wx.Dialog):
|
|
|
25
27
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
|
26
28
|
self.border.Add(self.sizer, border=12, proportion=1, flag=wx.EXPAND | wx.ALL)
|
|
27
29
|
|
|
30
|
+
# create search box and controls
|
|
31
|
+
self.searchPnl = wx.Panel(self)
|
|
32
|
+
self.searchPnl.sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
33
|
+
self.searchPnl.SetSizer(self.searchPnl.sizer)
|
|
34
|
+
self.sizer.Add(self.searchPnl, flag=wx.EXPAND | wx.ALL, border=6)
|
|
35
|
+
|
|
28
36
|
# create search box
|
|
29
|
-
self.termCtrl = wx.SearchCtrl(self)
|
|
30
|
-
self.termCtrl.Bind(wx.
|
|
31
|
-
self.sizer.Add(self.termCtrl,
|
|
37
|
+
self.termCtrl = wx.SearchCtrl(self.searchPnl)
|
|
38
|
+
self.termCtrl.Bind(wx.EVT_TEXT, self.onSearchTyping)
|
|
39
|
+
self.searchPnl.sizer.Add(self.termCtrl, proportion=1, flag=wx.EXPAND, border=6)
|
|
40
|
+
|
|
41
|
+
# add toggle for case sensitivity
|
|
42
|
+
self.caseSensitiveToggle = wx.ToggleButton(self.searchPnl, style=wx.BU_EXACTFIT)
|
|
43
|
+
self.caseSensitiveToggle.SetBitmap(
|
|
44
|
+
icons.ButtonIcon("case", size=16, theme="light").bitmap
|
|
45
|
+
)
|
|
46
|
+
self.caseSensitiveToggle.SetToolTip(_translate("Match case?"))
|
|
47
|
+
self.caseSensitiveToggle.Bind(wx.EVT_TOGGLEBUTTON, self.onSearchTyping)
|
|
48
|
+
self.searchPnl.sizer.Add(self.caseSensitiveToggle, flag=wx.EXPAND | wx.LEFT, border=6)
|
|
49
|
+
|
|
50
|
+
# add toggle for regex
|
|
51
|
+
self.regexToggle = wx.ToggleButton(self.searchPnl, style=wx.BU_EXACTFIT)
|
|
52
|
+
self.regexToggle.SetBitmap(
|
|
53
|
+
icons.ButtonIcon("regex", size=16, theme="light").bitmap
|
|
54
|
+
)
|
|
55
|
+
self.regexToggle.SetToolTip(_translate("Match regex?"))
|
|
56
|
+
self.regexToggle.Bind(wx.EVT_TOGGLEBUTTON, self.onSearchTyping)
|
|
57
|
+
self.searchPnl.sizer.Add(self.regexToggle, flag=wx.EXPAND | wx.LEFT, border=6)
|
|
32
58
|
|
|
33
59
|
# create results box
|
|
34
60
|
self.resultsCtrl = utils.ListCtrl(self, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
|
|
@@ -41,11 +67,18 @@ class BuilderFindDlg(wx.Dialog):
|
|
|
41
67
|
# setup component icons
|
|
42
68
|
self.imageList = wx.ImageList(16, 16)
|
|
43
69
|
self.imageMap = {}
|
|
70
|
+
# icon for each Component/Routine
|
|
44
71
|
for cls in experiment.getAllElements().values():
|
|
45
72
|
i = self.imageList.Add(
|
|
46
73
|
icons.ComponentIcon(cls, theme="light", size=16).bitmap
|
|
47
74
|
)
|
|
48
75
|
self.imageMap[cls] = i
|
|
76
|
+
# icon for loop
|
|
77
|
+
i = self.imageList.Add(
|
|
78
|
+
icons.ButtonIcon("loop", theme="light", size=16).bitmap
|
|
79
|
+
)
|
|
80
|
+
self.imageMap[experiment.loops.LoopInitiator] = i
|
|
81
|
+
# set icons
|
|
49
82
|
self.resultsCtrl.SetImageList(self.imageList, wx.IMAGE_LIST_SMALL)
|
|
50
83
|
|
|
51
84
|
# add buttons
|
|
@@ -65,49 +98,62 @@ class BuilderFindDlg(wx.Dialog):
|
|
|
65
98
|
|
|
66
99
|
def resetListCtrl(self):
|
|
67
100
|
self.resultsCtrl.ClearAll()
|
|
68
|
-
self.resultsCtrl.AppendColumn(_translate("
|
|
101
|
+
self.resultsCtrl.AppendColumn(_translate("Location"), width=120)
|
|
69
102
|
self.resultsCtrl.AppendColumn(_translate("Parameter"), width=120)
|
|
70
103
|
self.resultsCtrl.AppendColumn(_translate("Value"), width=-1)
|
|
71
104
|
self.resultsCtrl.resizeLastColumn(minWidth=120)
|
|
72
105
|
self.selectedResult = None
|
|
73
106
|
|
|
74
|
-
def
|
|
75
|
-
|
|
76
|
-
|
|
107
|
+
def onSearchTyping(self, evt):
|
|
108
|
+
term = self.termCtrl.GetValue()
|
|
109
|
+
caseSensitive = self.caseSensitiveToggle.GetValue()
|
|
110
|
+
regex = self.regexToggle.GetValue()
|
|
111
|
+
|
|
77
112
|
if term:
|
|
78
113
|
# get locations of term in experiment
|
|
79
|
-
self.results = getParamLocations(self.exp, term=term)
|
|
114
|
+
self.results = getParamLocations(self.exp, term=term, caseSensitive=caseSensitive, regex=regex)
|
|
80
115
|
else:
|
|
81
116
|
# return nothing for blank string
|
|
82
117
|
self.results = []
|
|
118
|
+
|
|
83
119
|
# clear old output
|
|
84
120
|
self.resetListCtrl()
|
|
121
|
+
|
|
85
122
|
# show new output
|
|
86
123
|
for result in self.results:
|
|
87
124
|
# unpack result
|
|
88
|
-
|
|
125
|
+
parent, comp, paramName, param = result
|
|
89
126
|
# sanitize val for display
|
|
90
127
|
val = str(param.val)
|
|
91
128
|
if "\n" in val:
|
|
92
129
|
# if multiline, show first line with match
|
|
93
130
|
for line in val.split("\n"):
|
|
94
|
-
if
|
|
131
|
+
if compareStrings(line, term, caseSensitive, regex):
|
|
95
132
|
val = line
|
|
96
133
|
break
|
|
134
|
+
# construct location string
|
|
135
|
+
if parent is None:
|
|
136
|
+
location = comp.name
|
|
137
|
+
else:
|
|
138
|
+
location = f"{comp.name} ({parent.name})"
|
|
97
139
|
# construct entry
|
|
98
|
-
entry = [
|
|
140
|
+
entry = [location, param.label, val]
|
|
99
141
|
# add entry
|
|
100
142
|
self.resultsCtrl.Append(entry)
|
|
101
143
|
# set image for comp
|
|
144
|
+
fallbackImg = icons.ButtonIcon("experiment", theme="light", size=16).bitmap
|
|
102
145
|
self.resultsCtrl.SetItemImage(
|
|
103
146
|
item=self.resultsCtrl.GetItemCount()-1,
|
|
104
|
-
image=self.imageMap
|
|
147
|
+
image=self.imageMap.get(type(comp), fallbackImg)
|
|
105
148
|
)
|
|
149
|
+
|
|
106
150
|
# size
|
|
107
151
|
self.resultsCtrl.Layout()
|
|
108
152
|
# disable Go button until item selected
|
|
109
153
|
self.okBtn.Disable()
|
|
110
154
|
|
|
155
|
+
evt.Skip()
|
|
156
|
+
|
|
111
157
|
def onSelectResult(self, evt):
|
|
112
158
|
if evt.GetEventType() == wx.EVT_LIST_ITEM_SELECTED.typeId:
|
|
113
159
|
# if item is selected, store its info
|
|
@@ -127,7 +173,7 @@ class BuilderFindDlg(wx.Dialog):
|
|
|
127
173
|
if self.selectedResult is None:
|
|
128
174
|
return
|
|
129
175
|
# do usual OK button stuff
|
|
130
|
-
self.Close()
|
|
176
|
+
# self.Close()
|
|
131
177
|
# unpack
|
|
132
178
|
rt, comp, paramName, param = self.selectedResult
|
|
133
179
|
# navigate to routine
|
|
@@ -137,17 +183,39 @@ class BuilderFindDlg(wx.Dialog):
|
|
|
137
183
|
if isinstance(comp, experiment.components.BaseComponent):
|
|
138
184
|
# if we have a component, open its dialog and navigate to categ page
|
|
139
185
|
if hasattr(comp, 'type') and comp.type.lower() == 'code':
|
|
140
|
-
|
|
186
|
+
# For code components, we need to find the index of the page
|
|
187
|
+
openToPage = list(comp.params.keys()).index(paramName)
|
|
141
188
|
else:
|
|
142
189
|
openToPage = param.categ
|
|
143
190
|
page.editComponentProperties(component=comp, openToPage=openToPage)
|
|
144
|
-
|
|
191
|
+
elif isinstance(comp, experiment.routines.BaseStandaloneRoutine):
|
|
145
192
|
# if we're in a standalone routine, just navigate to categ page
|
|
146
193
|
i = page.ctrls.getCategoryIndex(param.categ)
|
|
147
194
|
page.ctrls.ChangeSelection(i)
|
|
195
|
+
elif isinstance(comp, experiment.loops.LoopInitiator):
|
|
196
|
+
# if we're in a loop, open the loop dialog
|
|
197
|
+
self.frame.flowPanel.canvas.editLoopProperties(loop=comp.loop)
|
|
198
|
+
|
|
148
199
|
|
|
200
|
+
def compareStrings(text, term, caseSensitive, regex):
|
|
201
|
+
# lowercase everything if doing a non-case-sensitive check
|
|
202
|
+
if not caseSensitive:
|
|
203
|
+
term = term.lower()
|
|
204
|
+
text = text.lower()
|
|
205
|
+
# convert to regex object if using regex
|
|
206
|
+
if regex:
|
|
207
|
+
# if term isn't valid regex, assume no match
|
|
208
|
+
try:
|
|
209
|
+
stringtools.re.compile(term)
|
|
210
|
+
except stringtools.re.error:
|
|
211
|
+
return False
|
|
212
|
+
# convert to a regex searchable
|
|
213
|
+
text = stringtools.RegexSearchable(text)
|
|
214
|
+
|
|
215
|
+
return term in text
|
|
149
216
|
|
|
150
|
-
|
|
217
|
+
|
|
218
|
+
def getParamLocations(exp, term, caseSensitive=False, regex=False):
|
|
151
219
|
"""
|
|
152
220
|
Get locations of params containing the given term.
|
|
153
221
|
|
|
@@ -162,6 +230,7 @@ def getParamLocations(exp, term):
|
|
|
162
230
|
List of tuples, with each tuple functioning as a path to the found
|
|
163
231
|
param
|
|
164
232
|
"""
|
|
233
|
+
|
|
165
234
|
# array to store results in
|
|
166
235
|
found = []
|
|
167
236
|
|
|
@@ -170,20 +239,37 @@ def getParamLocations(exp, term):
|
|
|
170
239
|
if isinstance(rt, experiment.routines.BaseStandaloneRoutine):
|
|
171
240
|
# find in standalone routine
|
|
172
241
|
for paramName, param in rt.params.items():
|
|
173
|
-
if
|
|
242
|
+
if compareStrings(str(param.val), term, caseSensitive, regex):
|
|
174
243
|
# append path (routine -> param)
|
|
175
244
|
found.append(
|
|
176
|
-
(
|
|
245
|
+
(None, rt, paramName, param)
|
|
177
246
|
)
|
|
178
247
|
if isinstance(rt, experiment.routines.Routine):
|
|
179
248
|
# find in regular routine
|
|
180
249
|
for comp in rt:
|
|
181
250
|
for paramName, param in comp.params.items():
|
|
182
|
-
if
|
|
251
|
+
if compareStrings(str(param.val), term, caseSensitive, regex):
|
|
252
|
+
# treat RoutineSettings as synonymous with the Routine
|
|
253
|
+
if isinstance(comp, RoutineSettingsComponent):
|
|
254
|
+
parent = None
|
|
255
|
+
else:
|
|
256
|
+
parent = rt
|
|
183
257
|
# append path (routine -> component -> param)
|
|
184
258
|
found.append(
|
|
185
|
-
(
|
|
259
|
+
(parent, comp, paramName, param)
|
|
186
260
|
)
|
|
261
|
+
for obj in exp.flow:
|
|
262
|
+
# find in loop
|
|
263
|
+
if isinstance(obj, experiment.loops.LoopInitiator):
|
|
264
|
+
loop = obj.loop
|
|
265
|
+
for paramName, param in loop.params.items():
|
|
266
|
+
if compareStrings(str(param.val), term, caseSensitive, regex):
|
|
267
|
+
# append path (loop -> param)
|
|
268
|
+
found.append(
|
|
269
|
+
(None, obj, paramName, param)
|
|
270
|
+
)
|
|
187
271
|
|
|
188
272
|
return found
|
|
189
273
|
|
|
274
|
+
|
|
275
|
+
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
import ast
|
|
8
8
|
import os
|
|
@@ -1180,3 +1180,44 @@ class DictCtrl(ListWidget, _ValidatorMixin, _HideMixin):
|
|
|
1180
1180
|
Hide all items in the dict ctrl
|
|
1181
1181
|
"""
|
|
1182
1182
|
self.Show(False)
|
|
1183
|
+
|
|
1184
|
+
|
|
1185
|
+
class FontCtrl(SingleLineCtrl):
|
|
1186
|
+
def onOK(self):
|
|
1187
|
+
# get a font manager
|
|
1188
|
+
from psychopy.tools.fontmanager import FontManager, MissingFontError
|
|
1189
|
+
fm = FontManager()
|
|
1190
|
+
# check whether the font is installed
|
|
1191
|
+
installed = fm.getFontsMatching(self.GetValue(), fallback=False)
|
|
1192
|
+
# if not installed, ask the user whether to download from Google Fonts
|
|
1193
|
+
if not installed:
|
|
1194
|
+
# create dialog
|
|
1195
|
+
dlg = wx.MessageDialog(
|
|
1196
|
+
self.GetTopLevelParent(),
|
|
1197
|
+
_translate(
|
|
1198
|
+
"Font {} is not installed, would you like to download it from Google Fonts?"
|
|
1199
|
+
).format(self.GetValue()),
|
|
1200
|
+
style=wx.YES|wx.NO|wx.ICON_QUESTION
|
|
1201
|
+
)
|
|
1202
|
+
# download if yes
|
|
1203
|
+
if dlg.ShowModal() == wx.ID_YES:
|
|
1204
|
+
try:
|
|
1205
|
+
fm.addGoogleFont(self.GetValue().strip())
|
|
1206
|
+
except MissingFontError as err:
|
|
1207
|
+
dlg = wx.MessageDialog(
|
|
1208
|
+
self.GetTopLevelParent(),
|
|
1209
|
+
_translate(
|
|
1210
|
+
"Could not download font {} from Google Fonts, reason: {}"
|
|
1211
|
+
).format(self.GetValue(), err),
|
|
1212
|
+
style=wx.OK|wx.ICON_ERROR
|
|
1213
|
+
)
|
|
1214
|
+
dlg.ShowModal()
|
|
1215
|
+
else:
|
|
1216
|
+
dlg = wx.MessageDialog(
|
|
1217
|
+
self.GetTopLevelParent(),
|
|
1218
|
+
_translate(
|
|
1219
|
+
"Font download successfully"
|
|
1220
|
+
),
|
|
1221
|
+
style=wx.OK|wx.ICON_INFORMATION
|
|
1222
|
+
)
|
|
1223
|
+
dlg.ShowModal()
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Part of the PsychoPy library
|
|
5
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
5
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
6
6
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
7
7
|
|
|
8
8
|
"""Module containing validators for various parameters.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
# Part of the PsychoPy library
|
|
10
|
-
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-
|
|
10
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
11
11
|
# Distributed under the terms of the GNU General Public License (GPL).
|
|
12
12
|
|
|
13
13
|
import wx
|
|
@@ -79,13 +79,13 @@ class BaseCodeEditor(wx.stc.StyledTextCtrl, handlers.ThemeMixin):
|
|
|
79
79
|
|
|
80
80
|
if not hasattr(self, "UndoID"):
|
|
81
81
|
# Create a new ID for all items
|
|
82
|
-
self.UndoID = wx.
|
|
83
|
-
self.RedoID = wx.
|
|
84
|
-
self.CutID = wx.
|
|
85
|
-
self.CopyID = wx.
|
|
86
|
-
self.PasteID = wx.
|
|
87
|
-
self.DeleteID = wx.
|
|
88
|
-
self.SelectAllID = wx.
|
|
82
|
+
self.UndoID = wx.NewIdRef(count=1)
|
|
83
|
+
self.RedoID = wx.NewIdRef(count=1)
|
|
84
|
+
self.CutID = wx.NewIdRef(count=1)
|
|
85
|
+
self.CopyID = wx.NewIdRef(count=1)
|
|
86
|
+
self.PasteID = wx.NewIdRef(count=1)
|
|
87
|
+
self.DeleteID = wx.NewIdRef(count=1)
|
|
88
|
+
self.SelectAllID = wx.NewIdRef(count=1)
|
|
89
89
|
|
|
90
90
|
# Bind items to relevant method
|
|
91
91
|
self.Bind(wx.EVT_MENU, self.onUndo, id=self.UndoID)
|
psychopy/app/coder/coder.py
CHANGED
|
@@ -1340,9 +1340,9 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
1340
1340
|
|
|
1341
1341
|
Provides menu items to clear all, select all and copy selected text."""
|
|
1342
1342
|
if not hasattr(self, "outputMenuID1"):
|
|
1343
|
-
self.outputMenuID1 = wx.
|
|
1344
|
-
self.outputMenuID2 = wx.
|
|
1345
|
-
self.outputMenuID3 = wx.
|
|
1343
|
+
self.outputMenuID1 = wx.NewIdRef(count=1)
|
|
1344
|
+
self.outputMenuID2 = wx.NewIdRef(count=1)
|
|
1345
|
+
self.outputMenuID3 = wx.NewIdRef(count=1)
|
|
1346
1346
|
|
|
1347
1347
|
self.Bind(wx.EVT_MENU, self.outputClear, id=self.outputMenuID1)
|
|
1348
1348
|
self.Bind(wx.EVT_MENU, self.outputSelectAll, id=self.outputMenuID2)
|
|
@@ -1429,7 +1429,7 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
1429
1429
|
wx.ID_ANY, _translate("Reset preferences...")
|
|
1430
1430
|
)
|
|
1431
1431
|
self.Bind(wx.EVT_MENU, self.resetPrefs, item)
|
|
1432
|
-
# item = menu.Append(wx.
|
|
1432
|
+
# item = menu.Append(wx.NewIdRef(count=1), "Plug&ins")
|
|
1433
1433
|
# self.Bind(wx.EVT_MENU, self.pluginManager, id=item.GetId())
|
|
1434
1434
|
# -------------Close coder frame
|
|
1435
1435
|
menu.AppendSeparator()
|
|
@@ -1963,27 +1963,12 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
1963
1963
|
if self._lastCaretPos != pos:
|
|
1964
1964
|
self.currentDoc.OnUpdateUI(evt=None)
|
|
1965
1965
|
self._lastCaretPos = pos
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
msg = _translate("'%s' was modified outside of PsychoPy:\n\n"
|
|
1973
|
-
"Reload (without saving)?") % filename
|
|
1974
|
-
dlg = dialogs.MessageDialog(self, message=msg, type='Warning')
|
|
1975
|
-
if dlg.ShowModal() == wx.ID_YES:
|
|
1976
|
-
self.statusBar.SetStatusText(_translate('Reloading file'))
|
|
1977
|
-
self.fileReload(event,
|
|
1978
|
-
filename=self.currentDoc.filename,
|
|
1979
|
-
checkSave=False)
|
|
1980
|
-
self.showingReloadDialog = False
|
|
1981
|
-
self.statusBar.SetStatusText('')
|
|
1982
|
-
dlg.Destroy()
|
|
1983
|
-
self.fileStatusLastChecked = time.time()
|
|
1984
|
-
# Enable / disable save button
|
|
1985
|
-
self.ribbon.buttons['save'].Enable(self.currentDoc.UNSAVED)
|
|
1986
|
-
self.fileMenu.Enable(wx.ID_SAVE, self.currentDoc.UNSAVED)
|
|
1966
|
+
# if file has been modified externally, show message
|
|
1967
|
+
if (
|
|
1968
|
+
time.time() - self.fileStatusLastChecked > self.fileStatusCheckInterval
|
|
1969
|
+
and not self.showingReloadDialog
|
|
1970
|
+
):
|
|
1971
|
+
self.checkExternallyModified(event)
|
|
1987
1972
|
|
|
1988
1973
|
def pageChanged(self, event):
|
|
1989
1974
|
"""Event called when the user switches between editor tabs."""
|
|
@@ -2022,21 +2007,33 @@ class CoderFrame(BaseAuiFrame, handlers.ThemeMixin):
|
|
|
2022
2007
|
self.ribbon.buttons['pilotRunner'].Enable(isExp)
|
|
2023
2008
|
|
|
2024
2009
|
self.statusBar.SetStatusText(fileType, 2)
|
|
2025
|
-
|
|
2026
|
-
|
|
2010
|
+
# check for external modified
|
|
2011
|
+
self.checkExternallyModified(event)
|
|
2012
|
+
|
|
2013
|
+
def checkExternallyModified(self, event=None):
|
|
2014
|
+
"""
|
|
2015
|
+
Check whether the current file has been modified externally, and show a message dialog if
|
|
2016
|
+
so.
|
|
2017
|
+
"""
|
|
2027
2018
|
if not self.expectedModTime(self.currentDoc):
|
|
2019
|
+
self.showingReloadDialog = True
|
|
2028
2020
|
filename = os.path.basename(self.currentDoc.filename)
|
|
2029
2021
|
msg = _translate("'%s' was modified outside of PsychoPy:\n\n"
|
|
2030
|
-
|
|
2022
|
+
"Reload (without saving)?") % filename
|
|
2031
2023
|
dlg = dialogs.MessageDialog(self, message=msg, type='Warning')
|
|
2024
|
+
dlg.Raise()
|
|
2032
2025
|
if dlg.ShowModal() == wx.ID_YES:
|
|
2033
2026
|
self.statusBar.SetStatusText(_translate('Reloading file'))
|
|
2034
2027
|
self.fileReload(event,
|
|
2035
2028
|
filename=self.currentDoc.filename,
|
|
2036
2029
|
checkSave=False)
|
|
2037
|
-
|
|
2030
|
+
self.showingReloadDialog = False
|
|
2038
2031
|
self.statusBar.SetStatusText('')
|
|
2039
2032
|
dlg.Destroy()
|
|
2033
|
+
self.fileStatusLastChecked = time.time()
|
|
2034
|
+
# Enable / disable save button
|
|
2035
|
+
self.ribbon.buttons['save'].Enable(self.currentDoc.UNSAVED)
|
|
2036
|
+
self.fileMenu.Enable(wx.ID_SAVE, self.currentDoc.UNSAVED)
|
|
2040
2037
|
|
|
2041
2038
|
# def pluginManager(self, evt=None, value=True):
|
|
2042
2039
|
# """Show the plugin manager frame."""
|
|
@@ -2959,6 +2956,12 @@ class CoderRibbon(ribbon.FrameRibbon):
|
|
|
2959
2956
|
tooltip=_translate("Redo last action"),
|
|
2960
2957
|
callback=parent.redo
|
|
2961
2958
|
)
|
|
2959
|
+
# find
|
|
2960
|
+
self.addButton(
|
|
2961
|
+
section="edit", name="find", label=_translate("Find"), icon="find",
|
|
2962
|
+
tooltip=_translate("Search the current file for a specific term"),
|
|
2963
|
+
callback=parent.OnFindNext
|
|
2964
|
+
)
|
|
2962
2965
|
|
|
2963
2966
|
self.addSeparator()
|
|
2964
2967
|
|