psychopy 2025.1.0__py3-none-any.whl → 2025.2.1__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/VERSION +1 -1
- psychopy/alerts/alertsCatalogue/4810.yaml +19 -0
- psychopy/alerts/alertsCatalogue/alertCategories.yaml +4 -0
- psychopy/alerts/alertsCatalogue/alertmsg.py +15 -1
- psychopy/alerts/alertsCatalogue/generateAlertmsg.py +2 -2
- psychopy/app/Resources/classic/add_many.png +0 -0
- psychopy/app/Resources/classic/add_many@2x.png +0 -0
- psychopy/app/Resources/classic/devices.png +0 -0
- psychopy/app/Resources/classic/devices@2x.png +0 -0
- psychopy/app/Resources/classic/photometer.png +0 -0
- psychopy/app/Resources/classic/photometer@2x.png +0 -0
- psychopy/app/Resources/dark/add_many.png +0 -0
- psychopy/app/Resources/dark/add_many@2x.png +0 -0
- psychopy/app/Resources/dark/devices.png +0 -0
- psychopy/app/Resources/dark/devices@2x.png +0 -0
- psychopy/app/Resources/dark/photometer.png +0 -0
- psychopy/app/Resources/dark/photometer@2x.png +0 -0
- psychopy/app/Resources/light/add_many.png +0 -0
- psychopy/app/Resources/light/add_many@2x.png +0 -0
- psychopy/app/Resources/light/devices.png +0 -0
- psychopy/app/Resources/light/devices@2x.png +0 -0
- psychopy/app/Resources/light/photometer.png +0 -0
- psychopy/app/Resources/light/photometer@2x.png +0 -0
- psychopy/app/_psychopyApp.py +35 -13
- psychopy/app/builder/builder.py +88 -35
- psychopy/app/builder/dialogs/__init__.py +69 -220
- psychopy/app/builder/dialogs/dlgsCode.py +29 -8
- psychopy/app/builder/dialogs/paramCtrls.py +1468 -904
- psychopy/app/builder/validators.py +25 -17
- psychopy/app/coder/coder.py +12 -1
- psychopy/app/coder/repl.py +5 -2
- psychopy/app/colorpicker/__init__.py +1 -1
- psychopy/app/deviceManager/__init__.py +1 -0
- psychopy/app/deviceManager/addDialog.py +218 -0
- psychopy/app/deviceManager/dialog.py +185 -0
- psychopy/app/deviceManager/panel.py +191 -0
- psychopy/app/deviceManager/utils.py +60 -0
- psychopy/app/idle.py +7 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +12695 -10592
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +11221 -9712
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.po +10195 -18
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +11924 -9103
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.po +11917 -9101
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +11084 -9569
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +11590 -5806
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +11091 -9577
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +11072 -9549
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +11071 -9559
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +11072 -9560
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1485 -1137
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +11463 -8757
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +11288 -9434
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.po +10200 -25
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.po +10199 -24
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +11441 -8747
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +11069 -9545
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +12085 -8268
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +11929 -8022
- psychopy/app/plugin_manager/dialog.py +12 -3
- psychopy/app/plugin_manager/packageIndex.py +303 -0
- psychopy/app/plugin_manager/packages.py +203 -63
- psychopy/app/plugin_manager/plugins.py +120 -240
- psychopy/app/preferencesDlg.py +6 -1
- psychopy/app/psychopyApp.py +16 -4
- psychopy/app/runner/runner.py +10 -2
- psychopy/app/runner/scriptProcess.py +8 -3
- psychopy/app/stdout/stdOutRich.py +11 -4
- psychopy/app/themes/icons.py +3 -0
- psychopy/app/utils.py +61 -0
- psychopy/colors.py +10 -5
- psychopy/data/experiment.py +133 -23
- psychopy/data/routine.py +12 -0
- psychopy/data/staircase.py +42 -20
- psychopy/data/trial.py +20 -12
- psychopy/data/utils.py +43 -3
- psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +22 -5
- psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
- psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +2 -12
- psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -8
- psychopy/demos/builder/Feature Demos/movies/movie.psyexp +220 -0
- psychopy/demos/builder/Feature Demos/movies/readme.md +3 -0
- psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +1 -2
- psychopy/demos/builder/Hardware/camera/camera.psyexp +3 -16
- psychopy/demos/builder/Hardware/microphone/microphone.psyexp +3 -16
- psychopy/demos/coder/hardware/hdf5_extract.py +133 -0
- psychopy/event.py +20 -15
- psychopy/experiment/_experiment.py +86 -10
- psychopy/experiment/components/__init__.py +3 -10
- psychopy/experiment/components/_base.py +9 -20
- psychopy/experiment/components/button/__init__.py +1 -1
- psychopy/experiment/components/buttonBox/__init__.py +50 -54
- psychopy/experiment/components/camera/__init__.py +137 -359
- psychopy/experiment/components/keyboard/__init__.py +17 -24
- psychopy/experiment/components/microphone/__init__.py +61 -110
- psychopy/experiment/components/movie/__init__.py +2 -3
- psychopy/experiment/components/serialOut/__init__.py +192 -93
- psychopy/experiment/components/settings/__init__.py +45 -27
- psychopy/experiment/components/sound/__init__.py +82 -73
- psychopy/experiment/components/soundsensor/__init__.py +43 -80
- psychopy/experiment/devices.py +303 -0
- psychopy/experiment/exports.py +20 -18
- psychopy/experiment/flow.py +7 -0
- psychopy/experiment/loops.py +47 -29
- psychopy/experiment/monitor.py +74 -0
- psychopy/experiment/params.py +48 -10
- psychopy/experiment/plugins.py +28 -108
- psychopy/experiment/py2js_transpiler.py +1 -1
- psychopy/experiment/routines/__init__.py +1 -1
- psychopy/experiment/routines/_base.py +59 -24
- psychopy/experiment/routines/audioValidator/__init__.py +19 -155
- psychopy/experiment/routines/visualValidator/__init__.py +25 -25
- psychopy/hardware/__init__.py +20 -57
- psychopy/hardware/button.py +15 -2
- psychopy/hardware/camera/__init__.py +2237 -1394
- psychopy/hardware/joystick/__init__.py +1 -1
- psychopy/hardware/keyboard.py +5 -8
- psychopy/hardware/listener.py +4 -1
- psychopy/hardware/manager.py +75 -35
- psychopy/hardware/microphone.py +53 -7
- psychopy/hardware/monitor.py +144 -0
- psychopy/hardware/photometer/__init__.py +156 -117
- psychopy/hardware/serialdevice.py +16 -2
- psychopy/hardware/soundsensor.py +4 -1
- psychopy/iohub/devices/deviceConfigValidation.py +2 -1
- psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +2 -2
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +1 -0
- psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +10 -0
- psychopy/iohub/devices/keyboard/darwin.py +8 -5
- psychopy/iohub/util/__init__.py +7 -8
- psychopy/localization/generateTranslationTemplate.py +208 -116
- psychopy/localization/messages.pot +4305 -3502
- psychopy/monitors/MonitorCenter.py +174 -74
- psychopy/plugins/__init__.py +6 -4
- psychopy/preferences/devices.py +80 -0
- psychopy/preferences/generateHints.py +2 -1
- psychopy/preferences/preferences.py +35 -11
- psychopy/scripts/psychopy-pkgutil.py +969 -0
- psychopy/scripts/psyexpCompile.py +1 -1
- psychopy/session.py +34 -38
- psychopy/sound/__init__.py +6 -260
- psychopy/sound/audioclip.py +164 -0
- psychopy/sound/backend_ptb.py +8 -0
- psychopy/sound/backend_pygame.py +10 -0
- psychopy/sound/backend_pysound.py +9 -0
- psychopy/sound/backends/__init__.py +0 -0
- psychopy/sound/microphone.py +3 -0
- psychopy/sound/sound.py +58 -0
- psychopy/tests/data/correctScript/python/correctNoiseStimComponent.py +1 -1
- psychopy/tests/data/duplicateHeaders.csv +2 -0
- psychopy/tests/test_app/test_builder/test_BuilderFrame.py +22 -7
- psychopy/tests/test_app/test_builder/test_CompileFromBuilder.py +0 -2
- psychopy/tests/test_data/test_utils.py +5 -1
- psychopy/tests/test_experiment/test_components/test_ButtonBoxComponent.py +22 -2
- psychopy/tests/test_hardware/test_ports.py +0 -12
- psychopy/tests/test_tools/test_stringtools.py +1 -1
- psychopy/tools/attributetools.py +12 -5
- psychopy/tools/fontmanager.py +17 -14
- psychopy/tools/gltools.py +4 -2
- psychopy/tools/movietools.py +43 -2
- psychopy/tools/stringtools.py +33 -8
- psychopy/tools/versionchooser.py +1 -1
- psychopy/validation/audio.py +5 -1
- psychopy/validation/visual.py +5 -1
- psychopy/visual/basevisual.py +8 -7
- psychopy/visual/circle.py +2 -2
- psychopy/visual/helpers.py +3 -1
- psychopy/visual/image.py +29 -109
- psychopy/visual/movies/__init__.py +1800 -313
- psychopy/visual/polygon.py +4 -0
- psychopy/visual/shape.py +2 -2
- psychopy/visual/window.py +35 -12
- psychopy/voicekey/__init__.py +41 -669
- psychopy/voicekey/labjack_vks.py +7 -48
- psychopy/voicekey/parallel_vks.py +7 -42
- psychopy/voicekey/vk_tools.py +114 -263
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/METADATA +20 -13
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/RECORD +222 -190
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/WHEEL +1 -1
- psychopy/visual/movies/players/__init__.py +0 -62
- psychopy/visual/movies/players/ffpyplayer_player.py +0 -1401
- psychopy/voicekey/demo_vks.py +0 -12
- psychopy/voicekey/signal.py +0 -42
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/entry_points.txt +0 -0
- {psychopy-2025.1.0.dist-info → psychopy-2025.2.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
# Part of the PsychoPy library
|
|
4
|
+
# Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
|
|
5
|
+
# Distributed under the terms of the GNU General Public License (GPL).
|
|
6
|
+
|
|
1
7
|
import webbrowser
|
|
2
8
|
|
|
3
9
|
import wx
|
|
10
|
+
import wx.dataview
|
|
4
11
|
import os
|
|
5
12
|
import sys
|
|
6
13
|
import subprocess as sp
|
|
@@ -8,13 +15,22 @@ import subprocess as sp
|
|
|
8
15
|
from psychopy.app import utils
|
|
9
16
|
from psychopy.app.themes import handlers, icons
|
|
10
17
|
from psychopy.localization import _translate
|
|
11
|
-
from psychopy.tools.pkgtools import (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
18
|
+
from psychopy.tools.pkgtools import (getPackageMetadata, getPypiInfo)
|
|
19
|
+
from psychopy.app.plugin_manager.packageIndex import (
|
|
20
|
+
getInstalledPackages,
|
|
21
|
+
getRemotePackages,
|
|
22
|
+
isUserPackageInstalled,
|
|
23
|
+
isSystemPackageInstalled)
|
|
15
24
|
from psychopy.tools.versionchooser import parseVersionSafely
|
|
16
25
|
|
|
17
26
|
|
|
27
|
+
# data flags for package status
|
|
28
|
+
PACKAGE_STATUS_INVALID = -1
|
|
29
|
+
PACKAGE_STATUS_NOT_INSTALLED = 0
|
|
30
|
+
PACKAGE_STATUS_INSTALLED_SYSTEM = 1
|
|
31
|
+
PACKAGE_STATUS_INSTALLED_USER = 2 # installed and user package
|
|
32
|
+
|
|
33
|
+
|
|
18
34
|
class PackageManagerPanel(wx.Panel):
|
|
19
35
|
def __init__(self, parent, dlg):
|
|
20
36
|
wx.Panel.__init__(self, parent)
|
|
@@ -24,21 +40,18 @@ class PackageManagerPanel(wx.Panel):
|
|
|
24
40
|
self.SetSizer(self.border)
|
|
25
41
|
self.sizer = wx.BoxSizer(wx.HORIZONTAL)
|
|
26
42
|
self.border.Add(self.sizer, proportion=1, border=6, flag=wx.ALL | wx.EXPAND)
|
|
27
|
-
#
|
|
43
|
+
# self.packageList.Bind(wx.dataview.EVT_DATAVIEW_ITEM_ACTIVATED, self.onSelectItem)
|
|
44
|
+
self.detailsPanel = PackageDetailsPanel(self, dlg=self.dlg)
|
|
28
45
|
self.packageList = PackageListCtrl(self, dlg=self.dlg)
|
|
29
|
-
self.packageList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onSelectItem)
|
|
30
46
|
self.sizer.Add(self.packageList, flag=wx.EXPAND | wx.ALL)
|
|
31
|
-
# Seperator
|
|
32
47
|
self.sizer.Add(wx.StaticLine(self, style=wx.LI_VERTICAL), border=6, flag=wx.EXPAND | wx.ALL)
|
|
33
|
-
# Add details panel
|
|
34
|
-
self.detailsPanel = PackageDetailsPanel(self, dlg=self.dlg)
|
|
35
48
|
self.sizer.Add(self.detailsPanel, proportion=1, flag=wx.EXPAND | wx.ALL)
|
|
36
49
|
|
|
37
|
-
def
|
|
38
|
-
#
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
self.detailsPanel.package =
|
|
50
|
+
def refresh(self, evt=None):
|
|
51
|
+
# Refresh package list
|
|
52
|
+
self.packageList.searchCtrl.SetValue("")
|
|
53
|
+
self.packageList.refresh()
|
|
54
|
+
self.detailsPanel.package = None
|
|
42
55
|
|
|
43
56
|
|
|
44
57
|
class PIPTerminalPanel(wx.Panel):
|
|
@@ -147,15 +160,47 @@ class PackageListCtrl(wx.Panel):
|
|
|
147
160
|
self.sizer = wx.BoxSizer(wx.VERTICAL)
|
|
148
161
|
self.border.Add(self.sizer, proportion=1, border=12, flag=wx.ALL | wx.EXPAND)
|
|
149
162
|
|
|
163
|
+
# parent package list control
|
|
164
|
+
self.parent = parent
|
|
165
|
+
self.packageDetailsPanel = self.parent.detailsPanel
|
|
166
|
+
|
|
150
167
|
# Search bar
|
|
151
|
-
self.searchCtrl = wx.SearchCtrl(self)
|
|
168
|
+
self.searchCtrl = wx.SearchCtrl(self, style=wx.TE_PROCESS_ENTER)
|
|
152
169
|
self.searchCtrl.Bind(wx.EVT_SEARCH, self.refresh)
|
|
170
|
+
self.searchCtrl.Bind(wx.EVT_SEARCH_CANCEL, self.onSearchCancel)
|
|
171
|
+
self.searchCtrl.Bind(wx.EVT_TEXT, self.onSearchText)
|
|
153
172
|
self.sizer.Add(self.searchCtrl, border=6, flag=wx.ALL | wx.EXPAND)
|
|
173
|
+
|
|
174
|
+
self.searchCtrl.ShowSearchButton(True)
|
|
175
|
+
|
|
154
176
|
# Create list ctrl
|
|
155
|
-
self.ctrl = utils.ListCtrl(self, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
|
|
156
|
-
self.ctrl.setResizeColumn(0)
|
|
157
|
-
self.ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onItemSelected)
|
|
158
|
-
self.ctrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onRightClick)
|
|
177
|
+
# self.ctrl = utils.ListCtrl(self, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
|
|
178
|
+
# self.ctrl.setResizeColumn(0)
|
|
179
|
+
# self.ctrl.Bind(wx.EVT_LIST_ITEM_SELECTED, self.onItemSelected)
|
|
180
|
+
# self.ctrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.onRightClick)
|
|
181
|
+
# self.sizer.Add(self.ctrl, proportion=1, border=6, flag=wx.LEFT | wx.RIGHT | wx.EXPAND)
|
|
182
|
+
|
|
183
|
+
self.ctrl = wx.dataview.TreeListCtrl(self)
|
|
184
|
+
self.ctrl.SetMinSize((120, 400))
|
|
185
|
+
self.ctrl.AppendColumn(_translate("Package"))
|
|
186
|
+
self.ctrl.AppendColumn(_translate("Installed"))
|
|
187
|
+
|
|
188
|
+
self.rootUserPackages = self.ctrl.AppendItem(self.ctrl.GetRootItem(), _translate("User Packages"))
|
|
189
|
+
self.rootSystemPackages = self.ctrl.AppendItem(self.ctrl.GetRootItem(), _translate("System Packages"))
|
|
190
|
+
self.rootRemotePackages = self.ctrl.AppendItem(self.ctrl.GetRootItem(), _translate("Available Packages"))
|
|
191
|
+
|
|
192
|
+
self.ctrl.SetItemText(self.rootUserPackages, _translate("User Packages"))
|
|
193
|
+
self.ctrl.SetItemText(self.rootSystemPackages, _translate("System Packages"))
|
|
194
|
+
self.ctrl.SetItemText(self.rootRemotePackages, _translate("Available Packages"))
|
|
195
|
+
self.ctrl.SetItemData(self.rootUserPackages, PACKAGE_STATUS_INVALID)
|
|
196
|
+
self.ctrl.SetItemData(self.rootSystemPackages, PACKAGE_STATUS_INVALID)
|
|
197
|
+
self.ctrl.SetItemData(self.rootRemotePackages, PACKAGE_STATUS_INVALID)
|
|
198
|
+
self.ctrl.SetColumnWidth(0, 200)
|
|
199
|
+
self.ctrl.SetColumnWidth(1, 100)
|
|
200
|
+
|
|
201
|
+
# self.ctrl.Bind(wx.dataview.EVT_TREELIST_ITEM_ACTIVATED, self.onItemSelected)
|
|
202
|
+
self.ctrl.Bind(wx.dataview.EVT_TREELIST_SELECTION_CHANGED, self.onItemSelected)
|
|
203
|
+
# self.ctrl.Bind(wx.dataview.EVT_DATAVIEW_ITEM_RIGHT_CLICK, self.onRightClick)
|
|
159
204
|
self.sizer.Add(self.ctrl, proportion=1, border=6, flag=wx.LEFT | wx.RIGHT | wx.EXPAND)
|
|
160
205
|
|
|
161
206
|
# "Or..." label
|
|
@@ -180,6 +225,30 @@ class PackageListCtrl(wx.Panel):
|
|
|
180
225
|
|
|
181
226
|
self.Layout()
|
|
182
227
|
|
|
228
|
+
def onSearchText(self, evt=None):
|
|
229
|
+
"""On text change in search box. Used to refresh the package list if
|
|
230
|
+
the search term is empty since the box doesn't trigger a search
|
|
231
|
+
when the text is cleared.
|
|
232
|
+
"""
|
|
233
|
+
# Get search term
|
|
234
|
+
searchTerm = self.searchCtrl.GetValue()
|
|
235
|
+
|
|
236
|
+
if not searchTerm:
|
|
237
|
+
# If empty, refresh
|
|
238
|
+
self.refresh()
|
|
239
|
+
return
|
|
240
|
+
|
|
241
|
+
if evt is not None:
|
|
242
|
+
evt.Skip()
|
|
243
|
+
|
|
244
|
+
def onSearchCancel(self, evt=None):
|
|
245
|
+
"""On search cancel button pressed. Used to refresh the package list
|
|
246
|
+
if the search term is empty since the box doesn't trigger a search
|
|
247
|
+
when the text is cleared.
|
|
248
|
+
"""
|
|
249
|
+
self.searchCtrl.SetValue("")
|
|
250
|
+
self.refresh()
|
|
251
|
+
|
|
183
252
|
def onOpenPipTerminal(self, evt=None):
|
|
184
253
|
# Make dialog
|
|
185
254
|
dlg = wx.Dialog(self, title="PIP Terminal", size=(480, 480), style=wx.RESIZE_BORDER | wx.CAPTION | wx.CLOSE_BOX)
|
|
@@ -196,9 +265,18 @@ class PackageListCtrl(wx.Panel):
|
|
|
196
265
|
|
|
197
266
|
def onItemSelected(self, evt=None):
|
|
198
267
|
# Post event so it can be caught by parent
|
|
199
|
-
evt.SetEventObject(self)
|
|
200
|
-
wx.PostEvent(self, evt)
|
|
201
|
-
|
|
268
|
+
# evt.SetEventObject(self)
|
|
269
|
+
# wx.PostEvent(self, evt)
|
|
270
|
+
|
|
271
|
+
selection = evt.GetItem()
|
|
272
|
+
pipname = None
|
|
273
|
+
if selection.IsOk():
|
|
274
|
+
# check if valid
|
|
275
|
+
if self.ctrl.GetItemData(selection) != PACKAGE_STATUS_INVALID:
|
|
276
|
+
pipname = self.ctrl.GetItemText(selection)
|
|
277
|
+
|
|
278
|
+
self.packageDetailsPanel.package = pipname
|
|
279
|
+
|
|
202
280
|
def onRightClick(self, evt=None):
|
|
203
281
|
# Get package name
|
|
204
282
|
package = evt.GetText()
|
|
@@ -206,11 +284,11 @@ class PackageListCtrl(wx.Panel):
|
|
|
206
284
|
menu = wx.Menu()
|
|
207
285
|
# Map menu functions
|
|
208
286
|
menu.functions = {}
|
|
209
|
-
if
|
|
287
|
+
if isUserPackageInstalled(package):
|
|
210
288
|
# Add uninstall if installed to user
|
|
211
289
|
uninstallOpt = menu.Append(wx.ID_ANY, item=_translate("Uninstall"))
|
|
212
290
|
menu.functions[uninstallOpt.GetId()] = self.onUninstall
|
|
213
|
-
elif
|
|
291
|
+
elif isSystemPackageInstalled(package):
|
|
214
292
|
# Add nothing if installed to protected system folder
|
|
215
293
|
pass
|
|
216
294
|
else:
|
|
@@ -257,35 +335,84 @@ class PackageListCtrl(wx.Panel):
|
|
|
257
335
|
self.refresh()
|
|
258
336
|
|
|
259
337
|
def refresh(self, evt=None):
|
|
338
|
+
# get states of items
|
|
339
|
+
rootRemoteWasExpanded = self.ctrl.IsExpanded(self.rootRemotePackages)
|
|
340
|
+
rootUserWasExpanded = self.ctrl.IsExpanded(self.rootUserPackages)
|
|
341
|
+
rootSystemWasExpanded = self.ctrl.IsExpanded(self.rootSystemPackages)
|
|
342
|
+
|
|
260
343
|
# Get search term
|
|
261
344
|
searchTerm = self.searchCtrl.GetValue()
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
self.ctrl.
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
345
|
+
self.ctrl.DeleteAllItems()
|
|
346
|
+
|
|
347
|
+
self.rootUserPackages = self.ctrl.AppendItem(
|
|
348
|
+
self.ctrl.GetRootItem(), _translate("User Packages"))
|
|
349
|
+
self.ctrl.SetItemData(self.rootUserPackages, PACKAGE_STATUS_INVALID)
|
|
350
|
+
self.rootSystemPackages = self.ctrl.AppendItem(
|
|
351
|
+
self.ctrl.GetRootItem(), _translate("System Packages"))
|
|
352
|
+
self.ctrl.SetItemData(self.rootSystemPackages, PACKAGE_STATUS_INVALID)
|
|
353
|
+
self.rootRemotePackages = self.ctrl.AppendItem(
|
|
354
|
+
self.ctrl.GetRootItem(), _translate("Available Packages"))
|
|
355
|
+
self.ctrl.SetItemData(
|
|
356
|
+
self.rootRemotePackages, PACKAGE_STATUS_INVALID)
|
|
357
|
+
|
|
358
|
+
# get packages
|
|
268
359
|
installedPackages = dict(getInstalledPackages())
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
360
|
+
|
|
361
|
+
systemPackages = installedPackages['system']['packages']
|
|
362
|
+
userPackages = installedPackages['user']['packages']
|
|
363
|
+
availablePackages = getRemotePackages()['packages']
|
|
364
|
+
|
|
365
|
+
# filter on search
|
|
366
|
+
if searchTerm not in (None, ""):
|
|
367
|
+
self.searchCtrl.ShowCancelButton(True)
|
|
368
|
+
systemPackages = {k: v for k, v in systemPackages.items() if searchTerm in k}
|
|
369
|
+
userPackages = {k: v for k, v in userPackages.items() if searchTerm in k}
|
|
370
|
+
availablePackages = [v for v in availablePackages if searchTerm in v]
|
|
371
|
+
else:
|
|
372
|
+
self.searchCtrl.ShowCancelButton(False)
|
|
373
|
+
|
|
374
|
+
for pkg, version in systemPackages.items():
|
|
375
|
+
item = self.ctrl.AppendItem(self.rootSystemPackages, pkg)
|
|
376
|
+
self.ctrl.SetItemText(item, 1, version)
|
|
377
|
+
self.ctrl.SetItemData(item, PACKAGE_STATUS_INSTALLED_SYSTEM)
|
|
378
|
+
# self.ctrl.SetItemFont(item, font=wx.Font().Bold())
|
|
379
|
+
|
|
380
|
+
self.ctrl.SetItemText(
|
|
381
|
+
self.rootSystemPackages,
|
|
382
|
+
_translate("System Packages") + " (%d)" % len(systemPackages))
|
|
383
|
+
|
|
384
|
+
for pkg, version in userPackages.items():
|
|
385
|
+
item = self.ctrl.AppendItem(self.rootUserPackages, pkg)
|
|
386
|
+
self.ctrl.SetItemText(item, 1, version)
|
|
387
|
+
self.ctrl.SetItemData(item, PACKAGE_STATUS_INSTALLED_USER)
|
|
388
|
+
# self.ctrl.SetItemFont(item, font=wx.Font().Bold())
|
|
389
|
+
|
|
390
|
+
self.ctrl.SetItemText(
|
|
391
|
+
self.rootUserPackages,
|
|
392
|
+
_translate("User Packages") + " (%d)" % len(userPackages))
|
|
393
|
+
|
|
394
|
+
if len(availablePackages) > 1000:
|
|
395
|
+
availablePackages = availablePackages[:1000]
|
|
396
|
+
self.ctrl.SetItemText(
|
|
397
|
+
self.rootRemotePackages,
|
|
398
|
+
_translate("Available Packages") + " (1000+)")
|
|
399
|
+
else:
|
|
400
|
+
totalSearchMatches = len(availablePackages)
|
|
401
|
+
self.ctrl.SetItemText(
|
|
402
|
+
self.rootRemotePackages,
|
|
403
|
+
_translate("Available Packages") + " (%d)" % totalSearchMatches)
|
|
404
|
+
|
|
405
|
+
for pkg in availablePackages:
|
|
406
|
+
item = self.ctrl.AppendItem(self.rootRemotePackages, pkg)
|
|
407
|
+
self.ctrl.SetItemData(item, PACKAGE_STATUS_NOT_INSTALLED)
|
|
408
|
+
|
|
409
|
+
# Expand all roots
|
|
410
|
+
if rootRemoteWasExpanded:
|
|
411
|
+
self.ctrl.Expand(self.rootRemotePackages)
|
|
412
|
+
if rootUserWasExpanded:
|
|
413
|
+
self.ctrl.Expand(self.rootUserPackages)
|
|
414
|
+
if rootSystemWasExpanded:
|
|
415
|
+
self.ctrl.Expand(self.rootSystemPackages)
|
|
289
416
|
|
|
290
417
|
def onAddFromFile(self, evt=None):
|
|
291
418
|
# Create dialog to get package file location
|
|
@@ -342,8 +469,8 @@ class PackageDetailsPanel(wx.Panel):
|
|
|
342
469
|
self.installBtn.Bind(wx.EVT_BUTTON, self.onInstall)
|
|
343
470
|
# Version chooser
|
|
344
471
|
self.versionCtrl = wx.Choice(self)
|
|
472
|
+
# self.versionCtrl.Bind(wx.EVT_CHOICE, self.onVersionSelection)
|
|
345
473
|
self.headBtnSzr.Add(self.versionCtrl, border=3, flag=wx.RIGHT | wx.TOP | wx.BOTTOM | wx.ALIGN_CENTER)
|
|
346
|
-
self.versionCtrl.Bind(wx.EVT_CHOICE, self.onVersion)
|
|
347
474
|
# Uninstall button
|
|
348
475
|
self.uninstallBtn = wx.Button(self, label=_translate("Uninstall"))
|
|
349
476
|
self.headBtnSzr.AddStretchSpacer(1)
|
|
@@ -385,6 +512,7 @@ class PackageDetailsPanel(wx.Panel):
|
|
|
385
512
|
metadata = getPackageMetadata(self._package)
|
|
386
513
|
else:
|
|
387
514
|
metadata = {}
|
|
515
|
+
|
|
388
516
|
# Get best data available, prioritising local metadata
|
|
389
517
|
self.params = {
|
|
390
518
|
'name': metadata.get('Name', pypiData.get('Name', pipname)),
|
|
@@ -413,7 +541,7 @@ class PackageDetailsPanel(wx.Panel):
|
|
|
413
541
|
self.versionCtrl.Clear()
|
|
414
542
|
self.versionCtrl.AppendItems(self.params['releases'])
|
|
415
543
|
if self.params['version'] is None:
|
|
416
|
-
self.versionCtrl.SetSelection(
|
|
544
|
+
self.versionCtrl.SetSelection(self.versionCtrl.GetCount() - 1)
|
|
417
545
|
else:
|
|
418
546
|
if self.params['version'] not in self.versionCtrl.GetStrings():
|
|
419
547
|
self.versionCtrl.Append(self.params['version'])
|
|
@@ -423,31 +551,43 @@ class PackageDetailsPanel(wx.Panel):
|
|
|
423
551
|
self.Layout()
|
|
424
552
|
self._applyAppTheme()
|
|
425
553
|
|
|
554
|
+
# def onVersionSelection(self, evt=None):
|
|
555
|
+
# # if the version matches the installed version, disable the install button
|
|
556
|
+
# self.refresh()
|
|
557
|
+
|
|
426
558
|
def refresh(self, evt=None):
|
|
427
|
-
|
|
559
|
+
# check if the package is installed
|
|
560
|
+
installedPackages = dict(getInstalledPackages())
|
|
561
|
+
systemPackages = installedPackages['system']['packages']
|
|
562
|
+
userPackages = installedPackages['user']['packages']
|
|
563
|
+
availablePackages = getRemotePackages()['packages']
|
|
428
564
|
|
|
429
|
-
|
|
565
|
+
pkgName = self.package
|
|
566
|
+
state = False
|
|
567
|
+
if pkgName in userPackages:
|
|
430
568
|
# If installed to the user space, can be uninstalled or changed
|
|
431
569
|
self.uninstallBtn.Enable()
|
|
432
570
|
self.versionCtrl.Enable()
|
|
571
|
+
self.versionCtrl.SetStringSelection(userPackages[pkgName])
|
|
433
572
|
self.installBtn.Enable(
|
|
434
|
-
self.versionCtrl.GetStringSelection() !=
|
|
573
|
+
self.versionCtrl.GetStringSelection() != userPackages[pkgName]
|
|
435
574
|
)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
self.versionCtrl.Disable()
|
|
440
|
-
self.installBtn.Disable()
|
|
441
|
-
elif state == "n":
|
|
442
|
-
# If uninstalled, can only be installed
|
|
575
|
+
state = True
|
|
576
|
+
elif pkgName in availablePackages:
|
|
577
|
+
# If available but not installed, can be installed
|
|
443
578
|
self.uninstallBtn.Disable()
|
|
444
579
|
self.versionCtrl.Enable()
|
|
445
580
|
self.installBtn.Enable()
|
|
581
|
+
self.versionCtrl.SetSelection(self.versionCtrl.GetCount() - 1) # newest
|
|
582
|
+
state = True
|
|
446
583
|
else:
|
|
447
|
-
# If
|
|
584
|
+
# If installed to the system, can't be uninstalled or changed
|
|
585
|
+
if pkgName in systemPackages:
|
|
586
|
+
self.versionCtrl.SetStringSelection(systemPackages[pkgName])
|
|
448
587
|
self.uninstallBtn.Disable()
|
|
449
588
|
self.versionCtrl.Disable()
|
|
450
589
|
self.installBtn.Disable()
|
|
590
|
+
|
|
451
591
|
# Disable all controls if we have None
|
|
452
592
|
self.homeBtn.Enable(state is not None)
|
|
453
593
|
self.nameCtrl.Enable(state is not None)
|