boris-behav-obs 9.7.4__tar.gz → 9.7.6__tar.gz

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.
Files changed (126) hide show
  1. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/PKG-INFO +1 -1
  2. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/config.py +1 -1
  3. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/core.py +14 -3
  4. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/ipc_mpv.py +49 -1
  5. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/observation.py +5 -3
  6. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/observation_operations.py +21 -5
  7. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/preferences.py +5 -2
  8. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/project.py +1 -1
  9. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/project_functions.py +9 -4
  10. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/utilities.py +7 -7
  11. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/version.py +2 -2
  12. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/PKG-INFO +1 -1
  13. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/pyproject.toml +1 -1
  14. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/LICENSE.TXT +0 -0
  15. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/MANIFEST.in +0 -0
  16. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/README.TXT +0 -0
  17. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/README.md +0 -0
  18. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/__init__.py +0 -0
  19. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/__main__.py +0 -0
  20. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/about.py +0 -0
  21. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/add_modifier.py +0 -0
  22. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/add_modifier_ui.py +0 -0
  23. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/advanced_event_filtering.py +0 -0
  24. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/__init__.py +0 -0
  25. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/_latency.py +0 -0
  26. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/irr_cohen_kappa.py +0 -0
  27. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +0 -0
  28. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/irr_weighted_cohen_kappa.py +0 -0
  29. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +0 -0
  30. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/list_of_dataframe_columns.py +0 -0
  31. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/number_of_occurences.py +0 -0
  32. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
  33. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/analysis_plugins/time_budget.py +0 -0
  34. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/behav_coding_map_creator.py +0 -0
  35. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/behavior_binary_table.py +0 -0
  36. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/behaviors_coding_map.py +0 -0
  37. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/boris_cli.py +0 -0
  38. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/cmd_arguments.py +0 -0
  39. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/coding_pad.py +0 -0
  40. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/config_file.py +0 -0
  41. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/connections.py +0 -0
  42. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/converters.py +0 -0
  43. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/converters_ui.py +0 -0
  44. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/cooccurence.py +0 -0
  45. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/core_qrc.py +0 -0
  46. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/core_ui.py +0 -0
  47. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/db_functions.py +0 -0
  48. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/dev.py +0 -0
  49. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/dialog.py +0 -0
  50. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/duration_widget.py +0 -0
  51. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/edit_event.py +0 -0
  52. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/edit_event_ui.py +0 -0
  53. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/event_operations.py +0 -0
  54. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/events_cursor.py +0 -0
  55. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/events_snapshots.py +0 -0
  56. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/exclusion_matrix.py +0 -0
  57. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/export_events.py +0 -0
  58. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/export_observation.py +0 -0
  59. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/external_processes.py +0 -0
  60. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/geometric_measurement.py +0 -0
  61. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/gui_utilities.py +0 -0
  62. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/image_overlay.py +0 -0
  63. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/import_observations.py +0 -0
  64. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/irr.py +0 -0
  65. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/latency.py +0 -0
  66. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/measurement_widget.py +0 -0
  67. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/media_file.py +0 -0
  68. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/menu_options.py +0 -0
  69. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/modifier_coding_map_creator.py +0 -0
  70. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/modifiers_coding_map.py +0 -0
  71. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/mpv.py +0 -0
  72. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/mpv2.py +0 -0
  73. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/observation_ui.py +0 -0
  74. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/observations_list.py +0 -0
  75. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/otx_parser.py +0 -0
  76. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/param_panel.py +0 -0
  77. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/param_panel_ui.py +0 -0
  78. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/player_dock_widget.py +0 -0
  79. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plot_data_module.py +0 -0
  80. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plot_events.py +0 -0
  81. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plot_events_rt.py +0 -0
  82. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plot_spectrogram_rt.py +0 -0
  83. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plot_waveform_rt.py +0 -0
  84. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/plugins.py +0 -0
  85. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/__init__.py +0 -0
  86. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/const.py +0 -0
  87. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/dict.py +0 -0
  88. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/func.py +0 -0
  89. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/interval.py +0 -0
  90. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/portion/io.py +0 -0
  91. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/preferences_ui.py +0 -0
  92. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/project_import_export.py +0 -0
  93. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/project_ui.py +0 -0
  94. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/qrc_boris.py +0 -0
  95. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/qrc_boris5.py +0 -0
  96. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/select_modifiers.py +0 -0
  97. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/select_observations.py +0 -0
  98. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/select_subj_behav.py +0 -0
  99. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/state_events.py +0 -0
  100. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/subjects_pad.py +0 -0
  101. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/synthetic_time_budget.py +0 -0
  102. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/time_budget_functions.py +0 -0
  103. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/time_budget_widget.py +0 -0
  104. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/transitions.py +0 -0
  105. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/video_equalizer.py +0 -0
  106. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/video_equalizer_ui.py +0 -0
  107. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/video_operations.py +0 -0
  108. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/view_df.py +0 -0
  109. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/view_df_ui.py +0 -0
  110. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris/write_event.py +0 -0
  111. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/SOURCES.txt +0 -0
  112. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
  113. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/entry_points.txt +0 -0
  114. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/requires.txt +0 -0
  115. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/boris_behav_obs.egg-info/top_level.txt +0 -0
  116. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/setup.cfg +0 -0
  117. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_db_functions.py +0 -0
  118. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_export_observation.py +0 -0
  119. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_irr.py +0 -0
  120. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_observation_gui.py +0 -0
  121. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_otx_parser.py +0 -0
  122. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_preferences_gui.py +0 -0
  123. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_project_functions.py +0 -0
  124. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_time_budget.py +0 -0
  125. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_utilities.py +0 -0
  126. {boris_behav_obs-9.7.4 → boris_behav_obs-9.7.6}/tests/test_utilities2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.7.4
3
+ Version: 9.7.6
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -132,7 +132,7 @@ POINT_EVENT_PLOT_COLOR = "black"
132
132
 
133
133
  CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
134
134
 
135
- FAST_FORWARD_DEFAULT_VALUE:float = 10.0
135
+ FAST_FORWARD_DEFAULT_VALUE: float = 10.0
136
136
 
137
137
  ADAPT_FAST_JUMP = "adapt_fast_jump"
138
138
  ADAPT_FAST_JUMP_DEFAULT = False
@@ -63,6 +63,7 @@ from PySide6.QtCore import (
63
63
  QAbstractTableModel,
64
64
  QElapsedTimer,
65
65
  QSettings,
66
+ QTimer
66
67
  )
67
68
  from PySide6.QtGui import QIcon, QPixmap, QFont, QKeyEvent, QDesktopServices, QColor, QPainter, QPolygon, QAction
68
69
  from PySide6.QtMultimedia import QSoundEffect
@@ -318,6 +319,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
318
319
  data: list = []
319
320
  not_paired: list = []
320
321
 
322
+
321
323
  '''
322
324
  def add_button_menu(self, data, menu_obj):
323
325
  """
@@ -3951,13 +3953,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
3951
3953
  if self.dw_player[0].player.duration is None:
3952
3954
  return
3953
3955
  print(f"{slider_position=}")
3954
-
3956
+
3955
3957
  d = self.dw_player[0].player.duration
3956
3958
  print(f"{d=}")
3957
3959
  if d is None:
3958
3960
  return
3959
3961
  video_position = slider_position * d
3960
- #video_position = slider_position * self.dw_player[0].player.duration
3962
+ # video_position = slider_position * self.dw_player[0].player.duration
3961
3963
  # self.dw_player[0].player.command("seek", str(video_position), "absolute")
3962
3964
  self.dw_player[0].player.seek(video_position, "absolute")
3963
3965
 
@@ -5458,7 +5460,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
5458
5460
  check if first player ended
5459
5461
  """
5460
5462
 
5461
- print("play_video")
5463
+ logging.debug("play_video")
5462
5464
 
5463
5465
  if self.geometric_measurements_mode:
5464
5466
  return
@@ -5840,6 +5842,15 @@ def main():
5840
5842
  )
5841
5843
  sys.exit()
5842
5844
 
5845
+ if sys.platform.startswith("darwin"):
5846
+ QMessageBox.warning(
5847
+ None,
5848
+ cfg.programName,
5849
+ (f"This version of BORIS for macOS is still EXPERIMENTAL and should be used at your own risk."),
5850
+ QMessageBox.Ok | QMessageBox.Default,
5851
+ QMessageBox.NoButton,
5852
+ )
5853
+
5843
5854
  window.show()
5844
5855
  window.raise_() # for overlapping widget (?)
5845
5856
 
@@ -1,8 +1,29 @@
1
+ """
2
+ BORIS
3
+ Behavioral Observation Research Interactive Software
4
+ Copyright 2012-2025 Olivier Friard
5
+
6
+ This file is part of BORIS.
7
+
8
+ BORIS is free software; you can redistribute it and/or modify
9
+ it under the terms of the GNU General Public License as published by
10
+ the Free Software Foundation; either version 3 of the License, or
11
+ any later version.
12
+
13
+ BORIS is distributed in the hope that it will be useful,
14
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ GNU General Public License for more details.
17
+
18
+ You should have received a copy of the GNU General Public License
19
+ along with this program; if not see <http://www.gnu.org/licenses/>.
20
+
21
+ """
22
+
1
23
  import socket
2
24
  import json
3
25
  import subprocess
4
26
 
5
- # from PySide6.QtCore import QTimer
6
27
  import logging
7
28
  import config as cfg
8
29
 
@@ -117,6 +138,14 @@ class IPC_MPV:
117
138
  def playlist(self):
118
139
  return self.send_command({"command": ["get_property", "playlist"]})
119
140
 
141
+ def playlist_next(self):
142
+ self.send_command({"command": ["playlist-next"]})
143
+ return
144
+
145
+ def playlist_prev(self):
146
+ self.send_command({"command": ["playlist-prev"]})
147
+ return
148
+
120
149
  @property
121
150
  def playlist_pos(self):
122
151
  return self.send_command({"command": ["get_property", "playlist-pos"]})
@@ -265,6 +294,25 @@ class IPC_MPV:
265
294
  def core_idle(self):
266
295
  return self.send_command({"command": ["get_property", "core-idle"]})
267
296
 
297
+ @property
298
+ def video_pan_x(self):
299
+ return self.send_command({"command": ["get_property", "video-pan-x"]})
300
+
301
+ @video_pan_x.setter
302
+ def video_pan_x(self, value):
303
+ self.send_command({"command": ["set_property", "video-pan-x", value]})
304
+ return
305
+
306
+ @property
307
+ def video_pan_y(self):
308
+ return self.send_command({"command": ["get_property", "video-pan-y"]})
309
+
310
+ @video_pan_y.setter
311
+ def video_pan_y(self, value):
312
+ self.send_command({"command": ["set_property", "video-pan-y", value]})
313
+ return
314
+
315
+
268
316
  """
269
317
  @property
270
318
  def xxx(self):
@@ -42,7 +42,7 @@ from PySide6.QtWidgets import (
42
42
  QApplication,
43
43
  QMenu,
44
44
  QListWidgetItem,
45
- QHeaderView
45
+ QHeaderView,
46
46
  )
47
47
 
48
48
  from . import config as cfg
@@ -76,7 +76,10 @@ class AssignConverter(QDialog):
76
76
  self.cbb[-1].addItems(["None"] + sorted(converters.keys()))
77
77
 
78
78
  if column_idx in col_conv:
79
- self.cbb[-1].setCurrentIndex((["None"] + sorted(converters.keys())).index(col_conv[column_idx]))
79
+ if col_conv[column_idx] in (["None"] + sorted(converters.keys())):
80
+ self.cbb[-1].setCurrentIndex((["None"] + sorted(converters.keys())).index(col_conv[column_idx]))
81
+ else:
82
+ self.cbb[-1].setCurrentIndex(0)
80
83
  else:
81
84
  self.cbb[-1].setCurrentIndex(0)
82
85
  hbox.addWidget(self.cbb[-1])
@@ -229,7 +232,6 @@ class Observation(QDialog, Ui_Form):
229
232
 
230
233
  self.twVideo1.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
231
234
 
232
-
233
235
  self.mediaDurations, self.mediaFPS, self.mediaHasVideo, self.mediaHasAudio, self.media_creation_time = {}, {}, {}, {}, {}
234
236
 
235
237
  for w in (
@@ -113,6 +113,8 @@ def observations_list(self):
113
113
  result, selected_obs = select_observations.select_observations2(self, cfg.SINGLE)
114
114
 
115
115
  if not selected_obs:
116
+ # activate main window
117
+ self.activateWindow()
116
118
  return
117
119
 
118
120
  if self.observationId:
@@ -122,10 +124,14 @@ def observations_list(self):
122
124
  )
123
125
  if response == cfg.NO:
124
126
  self.show_data_files()
127
+ # activate main window
128
+ self.activateWindow()
129
+
125
130
  return ""
126
131
  else:
127
132
  close_observation(self)
128
133
 
134
+
129
135
  QtTest.QTest.qWait(1000)
130
136
 
131
137
  if result == cfg.OPEN:
@@ -145,6 +151,8 @@ def observations_list(self):
145
151
  )
146
152
 
147
153
  logging.debug("end observations list")
154
+ # activate main window
155
+ self.activateWindow()
148
156
 
149
157
 
150
158
  def open_observation(self, mode: str) -> str:
@@ -1151,6 +1159,9 @@ def close_observation(self):
1151
1159
  logging.info("Stop plot timer")
1152
1160
  self.plot_timer.stop()
1153
1161
 
1162
+ if self.MPV_IPC_MODE:
1163
+ self.main_window_activation_timer.stop()
1164
+
1154
1165
  for i, player in enumerate(self.dw_player):
1155
1166
  if (
1156
1167
  str(i + 1) in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE]
@@ -1340,8 +1351,6 @@ def initialize_new_media_observation(self) -> bool:
1340
1351
  self.playerType = cfg.VIEWER_MEDIA
1341
1352
  return True
1342
1353
 
1343
- # print(f"{self.process=}")
1344
-
1345
1354
  self.playerType = cfg.MEDIA
1346
1355
  self.fps = 0
1347
1356
 
@@ -1365,7 +1374,7 @@ def initialize_new_media_observation(self) -> bool:
1365
1374
 
1366
1375
  # add all media files to media lists
1367
1376
  self.setDockOptions(QMainWindow.AnimatedDocks | QMainWindow.AllowNestedDocks)
1368
- self.dw_player: list = []
1377
+ self.dw_player = []
1369
1378
 
1370
1379
  # check if media creation time used as offset
1371
1380
  # TODO check if cfg.MEDIA_CREATION_TIME dict is present
@@ -1831,8 +1840,8 @@ def initialize_new_media_observation(self) -> bool:
1831
1840
  self.dw_player[i].resize_signal.connect(self.resize_dw)
1832
1841
 
1833
1842
  # add durations list
1834
- self.dw_player[i].media_durations: list = []
1835
- self.dw_player[i].cumul_media_durations: List[int] = [0] # [idx for idx,x in enumerate(l) if l[idx-1]<pos<=x]
1843
+ self.dw_player[i].media_durations = []
1844
+ self.dw_player[i].cumul_media_durations = [0] # [idx for idx,x in enumerate(l) if l[idx-1]<pos<=x]
1836
1845
 
1837
1846
  # add fps list
1838
1847
  self.dw_player[i].fps = {}
@@ -1844,6 +1853,13 @@ def initialize_new_media_observation(self) -> bool:
1844
1853
  if r:
1845
1854
  break
1846
1855
 
1856
+ # start timer for activating the main window
1857
+ self.main_window_activation_timer = QTimer()
1858
+ self.main_window_activation_timer.setInterval(500)
1859
+ self.main_window_activation_timer.timeout.connect(self.activateWindow)
1860
+ self.main_window_activation_timer.start()
1861
+
1862
+
1847
1863
  for mediaFile in self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][n_player]:
1848
1864
  logging.debug(f"media file: {mediaFile}")
1849
1865
 
@@ -222,7 +222,7 @@ def preferences(self):
222
222
  # beep every
223
223
  preferencesWindow.sbBeepEvery.setValue(self.beep_every)
224
224
  # frame step size
225
- #preferencesWindow.sb_frame_step_size.setValue(self.config_param.get(cfg.FRAME_STEP_SIZE, cfg.FRAME_STEP_SIZE_DEFAULT_VALUE))
225
+ # preferencesWindow.sb_frame_step_size.setValue(self.config_param.get(cfg.FRAME_STEP_SIZE, cfg.FRAME_STEP_SIZE_DEFAULT_VALUE))
226
226
 
227
227
  # alert no focal subject
228
228
  preferencesWindow.cbAlertNoFocalSubject.setChecked(self.alertNoFocalSubject)
@@ -422,7 +422,7 @@ def preferences(self):
422
422
  self.beep_every = preferencesWindow.sbBeepEvery.value()
423
423
 
424
424
  # frame step size
425
- #self.config_param[cfg.FRAME_STEP_SIZE] = preferencesWindow.sb_frame_step_size.value()
425
+ # self.config_param[cfg.FRAME_STEP_SIZE] = preferencesWindow.sb_frame_step_size.value()
426
426
 
427
427
  self.alertNoFocalSubject = preferencesWindow.cbAlertNoFocalSubject.isChecked()
428
428
 
@@ -505,3 +505,6 @@ def preferences(self):
505
505
 
506
506
  else:
507
507
  break
508
+
509
+ # activate main window
510
+ self.activateWindow()
@@ -1977,7 +1977,7 @@ class projectDialog(QDialog, Ui_dlgProject):
1977
1977
  self.pj[cfg.INDEPENDENT_VARIABLES] = dict(self.indVar)
1978
1978
 
1979
1979
  # converters
1980
- converters = {}
1980
+ converters: dict = {}
1981
1981
  for row in range(self.tw_converters.rowCount()):
1982
1982
  converters[self.tw_converters.item(row, 0).text()] = {
1983
1983
  "name": self.tw_converters.item(row, 0).text(),
@@ -1472,12 +1472,17 @@ def open_project_json(project_file_name: str) -> tuple:
1472
1472
  projectChanged = True
1473
1473
 
1474
1474
  # check if behavioral categories are stored as a list
1475
- if isinstance(pj[cfg.BEHAVIORAL_CATEGORIES_CONF], list):
1476
- # convert to dict
1477
- pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = {str(idx): {"name": bc} for idx, bc in enumerate(pj[cfg.BEHAVIORAL_CATEGORIES_CONF])}
1478
- logging.info("Behavioral categories was converted from a list to a dictionary")
1475
+ if cfg.BEHAVIORAL_CATEGORIES_CONF in pj:
1476
+ if isinstance(pj[cfg.BEHAVIORAL_CATEGORIES_CONF], list):
1477
+ # convert to dict
1478
+ pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = {str(idx): {"name": bc} for idx, bc in enumerate(pj[cfg.BEHAVIORAL_CATEGORIES_CONF])}
1479
+ logging.info("Behavioral categories was converted from a list to a dictionary")
1480
+ projectChanged = True
1481
+ else:
1482
+ pj[cfg.BEHAVIORAL_CATEGORIES_CONF] = dict()
1479
1483
  projectChanged = True
1480
1484
 
1485
+
1481
1486
  # add category key if not found
1482
1487
  for idx in pj[cfg.ETHOGRAM]:
1483
1488
  if cfg.BEHAVIOR_CATEGORY not in pj[cfg.ETHOGRAM][idx]:
@@ -476,16 +476,16 @@ def txt2np_array(
476
476
  function += f" {line}\n"
477
477
  function += """ return OUTPUT"""
478
478
 
479
-
480
- print('=============')
479
+ print("=============")
481
480
  print(function)
482
- print('=============')
481
+ print("=============")
483
482
 
484
483
  import types
484
+
485
485
  mod = types.ModuleType("converter_module")
486
486
  exec(function, mod.__dict__)
487
487
 
488
- '''
488
+ """
489
489
  try:
490
490
  exec(function)
491
491
  except Exception:
@@ -495,13 +495,13 @@ def txt2np_array(
495
495
  print(f"{column_converter=}")
496
496
  print(locals())
497
497
  print(f"{conv_name=}")
498
- '''
498
+ """
499
499
 
500
- #np_converters[column_idx - 1] = locals()['conv_name']
500
+ # np_converters[column_idx - 1] = locals()['conv_name']
501
501
  np_converters[column_idx - 1] = getattr(mod, conv_name)
502
502
 
503
503
  else:
504
- return False, f"converter {cfg.converters_param[column_idx]} not found", np.array([])
504
+ return False, f"converter {column_converter[column_idx]} not found", np.array([])
505
505
 
506
506
  # snif txt file
507
507
  try:
@@ -20,5 +20,5 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
- __version__ = "9.7.4"
24
- __version_date__ = "2025-11-06"
23
+ __version__ = "9.7.6"
24
+ __version_date__ = "2025-11-13"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: boris-behav-obs
3
- Version: 9.7.4
3
+ Version: 9.7.6
4
4
  Summary: BORIS - Behavioral Observation Research Interactive Software
5
5
  Author-email: Olivier Friard <olivier.friard@unito.it>
6
6
  License-Expression: GPL-3.0-only
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "boris-behav-obs"
3
- version = "9.7.4"
3
+ version = "9.7.6"
4
4
  description = "BORIS - Behavioral Observation Research Interactive Software"
5
5
  authors = [{ name="Olivier Friard", email="olivier.friard@unito.it" }]
6
6
  readme = "README.md"