boris-behav-obs 8.27.9__py2.py3-none-any.whl → 9.0.1__py2.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.
Files changed (106) hide show
  1. boris/about.py +7 -5
  2. boris/add_modifier.py +35 -35
  3. boris/add_modifier_ui.py +229 -129
  4. boris/advanced_event_filtering.py +3 -3
  5. boris/analysis_plugins/__init__.py +0 -0
  6. boris/analysis_plugins/number_of_occurences.py +60 -0
  7. boris/analysis_plugins/number_of_occurences_by_independent_variable.py +72 -0
  8. boris/analysis_plugins/time_budget.py +95 -0
  9. boris/behav_coding_map_creator.py +103 -108
  10. boris/behavior_binary_table.py +1 -1
  11. boris/behaviors_coding_map.py +8 -8
  12. boris/coding_pad.py +6 -6
  13. boris/config.py +6 -0
  14. boris/config_file.py +1 -1
  15. boris/connections.py +4 -2
  16. boris/converters.py +2 -3
  17. boris/converters_ui.py +187 -110
  18. boris/cooccurence.py +2 -2
  19. boris/core.py +340 -94
  20. boris/core_qrc.py +16088 -13246
  21. boris/core_ui.py +922 -812
  22. boris/db_functions.py +3 -1
  23. boris/dialog.py +14 -13
  24. boris/duration_widget.py +5 -5
  25. boris/edit_event.py +1 -1
  26. boris/edit_event_ui.py +162 -88
  27. boris/event_operations.py +4 -25
  28. boris/events_cursor.py +17 -9
  29. boris/events_snapshots.py +5 -5
  30. boris/exclusion_matrix.py +1 -1
  31. boris/export_events.py +38 -28
  32. boris/export_observation.py +1 -1
  33. boris/external_processes.py +3 -5
  34. boris/geometric_measurement.py +49 -26
  35. boris/gui_utilities.py +31 -30
  36. boris/import_observations.py +2 -4
  37. boris/irr.py +1 -1
  38. boris/latency.py +1 -1
  39. boris/map_creator.py +77 -89
  40. boris/measurement_widget.py +4 -4
  41. boris/media_file.py +2 -4
  42. boris/menu_options.py +1 -3
  43. boris/modifiers_coding_map.py +4 -4
  44. boris/mpv2.py +0 -2
  45. boris/observation.py +124 -29
  46. boris/observation_operations.py +18 -40
  47. boris/observation_ui.py +566 -374
  48. boris/observations_list.py +6 -6
  49. boris/param_panel.py +2 -2
  50. boris/param_panel_ui.py +246 -141
  51. boris/player_dock_widget.py +16 -21
  52. boris/plot_data_module.py +6 -6
  53. boris/plot_events_rt.py +7 -8
  54. boris/plot_spectrogram_rt.py +7 -8
  55. boris/plot_waveform_rt.py +6 -7
  56. boris/plugins.py +79 -0
  57. boris/preferences.py +127 -17
  58. boris/preferences_ui.py +464 -240
  59. boris/project.py +69 -72
  60. boris/project_functions.py +233 -31
  61. boris/project_import_export.py +59 -67
  62. boris/project_ui.py +672 -440
  63. boris/qrc_boris.py +6 -3
  64. boris/qrc_boris5.py +6 -3
  65. boris/select_modifiers.py +2 -2
  66. boris/select_observations.py +2 -2
  67. boris/select_subj_behav.py +3 -3
  68. boris/state_events.py +1 -1
  69. boris/subjects_pad.py +5 -5
  70. boris/synthetic_time_budget.py +2 -2
  71. boris/time_budget_functions.py +15 -0
  72. boris/time_budget_widget.py +4 -4
  73. boris/transitions.py +34 -25
  74. boris/utilities.py +95 -2
  75. boris/version.py +2 -2
  76. boris/video_equalizer.py +4 -4
  77. boris/video_equalizer_ui.py +199 -130
  78. boris/video_operations.py +1 -1
  79. boris/view_df.py +106 -0
  80. boris/view_df_ui.py +75 -0
  81. boris/write_event.py +9 -1
  82. {boris_behav_obs-8.27.9.dist-info → boris_behav_obs-9.0.1.dist-info}/METADATA +5 -5
  83. boris_behav_obs-9.0.1.dist-info/RECORD +103 -0
  84. {boris_behav_obs-8.27.9.dist-info → boris_behav_obs-9.0.1.dist-info}/WHEEL +1 -1
  85. boris/qdarkstyle/__init__.py +0 -479
  86. boris/qdarkstyle/__main__.py +0 -66
  87. boris/qdarkstyle/colorsystem.py +0 -38
  88. boris/qdarkstyle/dark/__init__.py +0 -1
  89. boris/qdarkstyle/dark/darkstyle_rc.py +0 -11379
  90. boris/qdarkstyle/dark/palette.py +0 -38
  91. boris/qdarkstyle/example/__init__.py +0 -4
  92. boris/qdarkstyle/example/__main__.py +0 -386
  93. boris/qdarkstyle/example/ui/__init__.py +0 -4
  94. boris/qdarkstyle/light/__init__.py +0 -1
  95. boris/qdarkstyle/light/lightstyle_rc.py +0 -11305
  96. boris/qdarkstyle/light/palette.py +0 -37
  97. boris/qdarkstyle/palette.py +0 -102
  98. boris/qdarkstyle/utils/__init__.py +0 -73
  99. boris/qdarkstyle/utils/__main__.py +0 -96
  100. boris/qdarkstyle/utils/images.py +0 -449
  101. boris/qdarkstyle/utils/scss.py +0 -318
  102. boris/vlc_local.py +0 -83
  103. boris_behav_obs-8.27.9.dist-info/RECORD +0 -114
  104. {boris_behav_obs-8.27.9.dist-info → boris_behav_obs-9.0.1.dist-info}/LICENSE.TXT +0 -0
  105. {boris_behav_obs-8.27.9.dist-info → boris_behav_obs-9.0.1.dist-info}/entry_points.txt +0 -0
  106. {boris_behav_obs-8.27.9.dist-info → boris_behav_obs-9.0.1.dist-info}/top_level.txt +0 -0
@@ -22,10 +22,10 @@ This file is part of BORIS.
22
22
 
23
23
  import logging
24
24
 
25
- from PyQt5.QtCore import pyqtSignal
25
+ from PySide6.QtCore import Signal
26
26
 
27
- # from PyQt5.QtGui import *
28
- from PyQt5.QtWidgets import (
27
+ # from PySide6.QtGui import *
28
+ from PySide6.QtWidgets import (
29
29
  QApplication,
30
30
  QWidget,
31
31
  QRadioButton,
@@ -46,7 +46,7 @@ from . import config as cfg
46
46
  class wgMeasurement(QWidget):
47
47
  """ """
48
48
 
49
- closeSignal, clearSignal = pyqtSignal(), pyqtSignal()
49
+ closeSignal, clearSignal = Signal(), Signal()
50
50
  flagSaved = True
51
51
  draw_mem = []
52
52
 
boris/media_file.py CHANGED
@@ -20,12 +20,11 @@ This file is part of BORIS.
20
20
 
21
21
  """
22
22
 
23
-
24
23
  from . import config as cfg
25
24
  from . import utilities as util
26
25
  from . import dialog
27
26
  from . import project_functions
28
- from PyQt5.QtWidgets import QFileDialog
27
+ from PySide6.QtWidgets import QFileDialog
29
28
 
30
29
 
31
30
  def get_info(self) -> None:
@@ -100,8 +99,7 @@ def get_info(self) -> None:
100
99
  tot_output += mpv_output + ffmpeg_output + "<br><hr>"
101
100
 
102
101
  else: # no open observation
103
- fn = QFileDialog().getOpenFileNames(self, "Select a media file", "", "Media files (*)")
104
- file_paths = fn[0] if type(fn) is tuple else fn
102
+ file_paths, _ = QFileDialog().getOpenFileNames(self, "Select a media file", "", "Media files (*)")
105
103
  if not file_paths:
106
104
  return
107
105
 
boris/menu_options.py CHANGED
@@ -19,10 +19,9 @@ Copyright 2012-2024 Olivier Friard
19
19
  MA 02110-1301, USA.
20
20
  """
21
21
 
22
-
23
22
  import logging
24
23
  from . import config as cfg
25
- from PyQt5.QtCore import QSize
24
+ from PySide6.QtCore import QSize
26
25
 
27
26
 
28
27
  def update_windows_title(self):
@@ -73,7 +72,6 @@ def update_menu(self):
73
72
  self.actionExport_project,
74
73
  self.actionCheck_project,
75
74
  self.actionClose_project,
76
- self.actionSend_project,
77
75
  self.actionNew_observation,
78
76
  self.actionRemove_path_from_media_files,
79
77
  self.action_create_observations,
@@ -22,9 +22,9 @@ This file is part of BORIS.
22
22
 
23
23
  import binascii
24
24
 
25
- from PyQt5.QtCore import pyqtSignal, QPoint, Qt
26
- from PyQt5.QtGui import QPen, QPixmap, QBrush, QMouseEvent, QPolygonF, QColor
27
- from PyQt5.QtWidgets import (
25
+ from PySide6.QtCore import Signal, QPoint, Qt
26
+ from PySide6.QtGui import QPen, QPixmap, QBrush, QMouseEvent, QPolygonF, QColor
27
+ from PySide6.QtWidgets import (
28
28
  QDialog,
29
29
  QGraphicsView,
30
30
  QGraphicsScene,
@@ -41,7 +41,7 @@ from PyQt5.QtWidgets import (
41
41
 
42
42
  class ModifiersCodingMapWindowClass(QDialog):
43
43
  class View(QGraphicsView):
44
- mousePress = pyqtSignal(QMouseEvent)
44
+ mousePress = Signal(QMouseEvent)
45
45
 
46
46
  def mousePressEvent(self, event):
47
47
  self.mousePress.emit(event)
boris/mpv2.py CHANGED
@@ -868,8 +868,6 @@ class MPV(object):
868
868
  Extra arguments and extra keyword arguments will be passed to mpv as options.
869
869
  """
870
870
 
871
- print(f"{extra_mpv_flags=}")
872
-
873
871
  self.handle = _mpv_create()
874
872
  self._event_thread = None
875
873
  self._core_shutdown = False
boris/observation.py CHANGED
@@ -26,9 +26,9 @@ import pandas as pd
26
26
  import pathlib as pl
27
27
  import datetime as dt
28
28
 
29
- from PyQt5.QtCore import Qt
30
- from PyQt5.QtGui import QColor, QTextCursor
31
- from PyQt5.QtWidgets import (
29
+ from PySide6.QtCore import Qt
30
+ from PySide6.QtGui import QColor, QTextCursor, QAction
31
+ from PySide6.QtWidgets import (
32
32
  QDialog,
33
33
  QVBoxLayout,
34
34
  QHBoxLayout,
@@ -134,7 +134,8 @@ class Observation(QDialog, Ui_Form):
134
134
  self.rb_images.toggled.connect(self.obs_type_changed)
135
135
 
136
136
  # button menu for media
137
- menu_items = [
137
+
138
+ add_media_menu_items = [
138
139
  "media abs path|with absolute path",
139
140
  "media rel path|with relative path",
140
141
  {
@@ -144,10 +145,30 @@ class Observation(QDialog, Ui_Form):
144
145
  ]
145
146
  },
146
147
  ]
147
- menu = QMenu()
148
- menu.triggered.connect(lambda x: self.add_media(mode=x.statusTip()))
149
- self.add_button_menu(menu_items, menu)
150
- self.pbAddVideo.setMenu(menu)
148
+
149
+ self.media_menu = QMenu()
150
+ # Add actions to the menu
151
+ """
152
+ self.action1 = QAction("with absolute path")
153
+ self.action2 = QAction("with relative path")
154
+ self.action3 = QAction("directory with absolute path")
155
+ self.action4 = QAction("directory with relative path")
156
+
157
+ self.menu.addAction(self.action1)
158
+ self.menu.addAction(self.action2)
159
+ self.menu.addAction(self.action3)
160
+ self.menu.addAction(self.action4)
161
+
162
+ # Connect actions to functions
163
+ self.action1.triggered.connect(lambda: self.add_media(mode="media abs path|with absolute path"))
164
+ self.action2.triggered.connect(lambda: self.add_media(mode="media rel path|with relative path"))
165
+ self.action3.triggered.connect(lambda: self.add_media(mode="dir abs path|with absolute path"))
166
+ self.action4.triggered.connect(lambda: self.add_media(mode="dir rel path|wih relative path"))
167
+ """
168
+
169
+ self.media_menu.triggered.connect(lambda x: self.add_media(mode=x.statusTip()))
170
+ self.add_button_menu(add_media_menu_items, self.media_menu)
171
+ self.pbAddVideo.setMenu(self.media_menu)
151
172
 
152
173
  self.pbRemoveVideo.clicked.connect(self.remove_media)
153
174
 
@@ -157,10 +178,23 @@ class Observation(QDialog, Ui_Form):
157
178
  "data rel path|with relative path",
158
179
  ]
159
180
 
160
- menu_data = QMenu()
161
- menu_data.triggered.connect(lambda x: self.add_data_file(mode=x.statusTip()))
162
- self.add_button_menu(data_menu_items, menu_data)
163
- self.pb_add_data_file.setMenu(menu_data)
181
+ self.menu_data = QMenu()
182
+
183
+ # Add actions to the menu
184
+ """
185
+ self.data_action1 = QAction("with absolute path")
186
+ self.data_action2 = QAction("with relative path")
187
+ self.menu_data.addAction(self.data_action1)
188
+ self.menu_data.addAction(self.data_action2)
189
+
190
+ # Connect actions to functions
191
+ self.data_action1.triggered.connect(lambda: self.add_data_file(mode="data abs path|with absolute path"))
192
+ self.data_action2.triggered.connect(lambda: self.add_data_file(mode="data rel path|with relative path"))
193
+ """
194
+
195
+ self.menu_data.triggered.connect(lambda x: self.add_data_file(mode=x.statusTip()))
196
+ self.add_button_menu(data_menu_items, self.menu_data)
197
+ self.pb_add_data_file.setMenu(self.menu_data)
164
198
 
165
199
  # button menu for images
166
200
  images_menu_items = [
@@ -168,10 +202,11 @@ class Observation(QDialog, Ui_Form):
168
202
  "images rel path|with relative path",
169
203
  ]
170
204
 
171
- menu_images = QMenu()
172
- menu_images.triggered.connect(lambda x: self.add_images_directory(mode=x.statusTip()))
173
- self.add_button_menu(images_menu_items, menu_images)
174
- self.pb_add_directory.setMenu(menu_images)
205
+ self.menu_images = QMenu()
206
+
207
+ self.menu_images.triggered.connect(lambda x: self.add_images_directory(mode=x.statusTip()))
208
+ self.add_button_menu(images_menu_items, self.menu_images)
209
+ self.pb_add_directory.setMenu(self.menu_images)
175
210
 
176
211
  self.pb_remove_data_file.clicked.connect(self.remove_data_file)
177
212
  self.pb_view_data_head.clicked.connect(self.view_data_file_head_tail)
@@ -183,8 +218,6 @@ class Observation(QDialog, Ui_Form):
183
218
  self.cbVisualizeSpectrogram.clicked.connect(self.extract_wav)
184
219
  self.cb_visualize_waveform.clicked.connect(self.extract_wav)
185
220
 
186
- # self.cb_media_creation_date_as_offset.clicked.connect(self.check_creation_date)
187
-
188
221
  self.cb_observation_time_interval.clicked.connect(self.limit_time_interval)
189
222
 
190
223
  self.pbSave.clicked.connect(self.pbSave_clicked)
@@ -223,6 +256,48 @@ class Observation(QDialog, Ui_Form):
223
256
  # """
224
257
  # self.de_date_offset.setEnabled(self.cb_date_offset.isChecked())
225
258
 
259
+ def check_media_creation_date(self):
260
+ """
261
+ check if all media files contain creation date time
262
+ search in metadata then in filename
263
+ """
264
+
265
+ creation_date_not_found: list = []
266
+ flag_filename_used = False
267
+
268
+ self.media_creation_time = {}
269
+
270
+ if self.cb_media_creation_date_as_offset.isChecked():
271
+ for row in range(self.twVideo1.rowCount()):
272
+ if self.twVideo1.item(row, 2).text(): # media file path
273
+ date_time_original = util.extract_video_creation_date(
274
+ project_functions.full_path(self.twVideo1.item(row, 2).text(), self.project_path)
275
+ )
276
+ if date_time_original is None:
277
+ date_time_file_name = util.extract_date_time_from_file_name(self.twVideo1.item(row, 2).text())
278
+ if date_time_file_name is None:
279
+ creation_date_not_found.append(self.twVideo1.item(row, 2).text())
280
+ else:
281
+ self.media_creation_time[self.twVideo1.item(row, 2).text()] = date_time_file_name
282
+ flag_filename_used = True
283
+ else:
284
+ self.media_creation_time[self.twVideo1.item(row, 2).text()] = date_time_original
285
+
286
+ if creation_date_not_found:
287
+ QMessageBox.warning(
288
+ self, cfg.programName, "The creation date time was not found for all media file(s).\nThe option was disabled."
289
+ )
290
+ self.cb_media_creation_date_as_offset.setChecked(False)
291
+ self.media_creation_time = {}
292
+ return 1
293
+
294
+ elif flag_filename_used:
295
+ QMessageBox.information(
296
+ self, cfg.programName, "The creation date time was not found in metadata. The media file name(s) was/were used"
297
+ )
298
+
299
+ return 0
300
+
226
301
  def cb_time_offset_changed(self):
227
302
  """
228
303
  activate/desactivate date value
@@ -237,7 +312,7 @@ class Observation(QDialog, Ui_Form):
237
312
  QMessageBox.critical(self, cfg.programName, "A media file must be loaded in player #1")
238
313
  return
239
314
 
240
- first_media_file = ""
315
+ first_media_file: str = ""
241
316
  for row in range(self.twVideo1.rowCount()):
242
317
  if int(self.twVideo1.cellWidget(row, 0).currentText()) == 1:
243
318
  first_media_file = self.twVideo1.item(row, 2).text()
@@ -513,6 +588,13 @@ class Observation(QDialog, Ui_Form):
513
588
  else:
514
589
  QMessageBox.warning(self, cfg.programName, "Select a data file")
515
590
 
591
+ def not_editable_column_color(self):
592
+ """
593
+ return a color for the not editable column
594
+ """
595
+ window_color = QApplication.instance().palette().window().color()
596
+ return QColor(window_color.red() - 5, window_color.green() - 5, window_color.blue() - 5)
597
+
516
598
  def add_data_file(self, mode: str):
517
599
  """
518
600
  user select a data file to be plotted synchronously with media file
@@ -546,16 +628,14 @@ class Observation(QDialog, Ui_Form):
546
628
  QMessageBox.warning(
547
629
  self,
548
630
  cfg.programName,
549
- ("It is not yet possible to plot more than 2 external data sources" "This limitation will be removed in future"),
631
+ ("It is not yet possible to plot more than 2 external data sourcesThis limitation will be removed in future"),
550
632
  )
551
633
  return
552
634
 
553
635
  fd = QFileDialog()
554
636
  fd.setDirectory(os.path.expanduser("~") if (" abs " in mode) else str(pl.Path(self.project_path).parent))
555
637
 
556
- fn = fd.getOpenFileName(self, "Add data file", "", "All files (*)")
557
- file_name = fn[0] if type(fn) is tuple else fn
558
-
638
+ file_name, _ = fd.getOpenFileName(self, "Add data file", "", "All files (*)")
559
639
  if not file_name:
560
640
  return
561
641
 
@@ -662,7 +742,8 @@ class Observation(QDialog, Ui_Form):
662
742
  item = QTableWidgetItem(value)
663
743
  if col_idx == cfg.PLOT_DATA_CONVERTERS_IDX:
664
744
  item.setFlags(Qt.ItemIsEnabled)
665
- item.setBackground(QColor(230, 230, 230))
745
+ # item.setBackground(QColor(230, 230, 230))
746
+ item.setBackground(self.not_editable_column_color())
666
747
  self.tw_data_files.setItem(self.tw_data_files.rowCount() - 1, col_idx, item)
667
748
 
668
749
  # substract first value
@@ -841,6 +922,7 @@ class Observation(QDialog, Ui_Form):
841
922
  ret = dlg.exec_()
842
923
  """
843
924
 
925
+ """
844
926
  not_tagged_media_list: list = []
845
927
  for row in range(self.twVideo1.rowCount()):
846
928
  if self.twVideo1.item(row, 2).text() not in media_not_found_list:
@@ -879,6 +961,8 @@ class Observation(QDialog, Ui_Form):
879
961
  return 1
880
962
  else:
881
963
  return 0 # OK all media have a 'creation time' tag
964
+ """
965
+ return 0
882
966
 
883
967
  def closeEvent(self, event):
884
968
  """
@@ -1062,13 +1146,17 @@ class Observation(QDialog, Ui_Form):
1062
1146
  return False
1063
1147
 
1064
1148
  # check media creation time tag in metadata
1065
- # Disable because the check will be made at the oservation start
1149
+ # Disable because the check will be made at the observation start
1066
1150
  """
1067
1151
  if self.cb_media_creation_date_as_offset.isChecked():
1068
1152
  if self.check_creation_date():
1069
1153
  return False
1070
1154
  """
1071
1155
 
1156
+ # check media creation date time (if option enabled)
1157
+ if self.check_media_creation_date():
1158
+ return False
1159
+
1072
1160
  if self.rb_images.isChecked(): # observation based on images directory
1073
1161
  if not self.lw_images_directory.count():
1074
1162
  QMessageBox.critical(self, cfg.programName, "You have to select at least one images directory")
@@ -1191,8 +1279,7 @@ class Observation(QDialog, Ui_Form):
1191
1279
  # enable stop ongoing state events if n. media > 1
1192
1280
  self.cbCloseCurrentBehaviorsBetweenVideo.setEnabled(self.twVideo1.rowCount() > 0)
1193
1281
 
1194
- # DEVELOPMENT (REMOVE BEFORE RELEASE)
1195
- self.cb_media_creation_date_as_offset.setEnabled(False)
1282
+ # self.creation_date_as_offset()
1196
1283
 
1197
1284
  def add_media(self, mode: str):
1198
1285
  """
@@ -1231,8 +1318,7 @@ class Observation(QDialog, Ui_Form):
1231
1318
  fd.setDirectory(os.path.expanduser("~") if (" abs " in mode) else str(pl.Path(self.project_path).parent))
1232
1319
 
1233
1320
  if "media " in mode:
1234
- fn = fd.getOpenFileNames(self, "Add media file(s)", "", "All files (*)")
1235
- file_paths = fn[0] if type(fn) is tuple else fn
1321
+ file_paths, _ = fd.getOpenFileNames(self, "Add media file(s)", "", "All files (*)")
1236
1322
 
1237
1323
  if file_paths:
1238
1324
  # store directory for next usage
@@ -1274,6 +1360,15 @@ class Observation(QDialog, Ui_Form):
1274
1360
  )
1275
1361
  if response == cfg.CANCEL:
1276
1362
  break
1363
+ # ask to use directory name / path as observation id
1364
+ if response != cfg.CANCEL:
1365
+ selected_obs_id = dialog.MessageDialog(
1366
+ cfg.programName,
1367
+ "Select the observation id",
1368
+ [dir_name, str(pl.Path(dir_name).name), cfg.CANCEL],
1369
+ )
1370
+ if selected_obs_id != cfg.CANCEL:
1371
+ self.leObservationId.setText(selected_obs_id)
1277
1372
 
1278
1373
  self.update_media_options()
1279
1374
 
@@ -32,7 +32,7 @@ import datetime as dt
32
32
  from typing import List, Tuple, Optional
33
33
 
34
34
 
35
- from PyQt5.QtWidgets import (
35
+ from PySide6.QtWidgets import (
36
36
  QMessageBox,
37
37
  QFileDialog,
38
38
  QDateTimeEdit,
@@ -42,10 +42,10 @@ from PyQt5.QtWidgets import (
42
42
  QMainWindow,
43
43
  QDockWidget,
44
44
  )
45
- from PyQt5.QtCore import Qt, QDateTime, QTimer
46
- from PyQt5.QtGui import QFont, QIcon, QTextCursor
45
+ from PySide6.QtCore import Qt, QDateTime, QTimer
46
+ from PySide6.QtGui import QFont, QIcon, QTextCursor
47
47
 
48
- from PyQt5 import QtTest
48
+ from PySide6 import QtTest
49
49
 
50
50
  from . import menu_options
51
51
  from . import config as cfg
@@ -137,7 +137,7 @@ def observations_list(self):
137
137
  QMessageBox.warning(
138
138
  self,
139
139
  cfg.programName,
140
- (f"The observation <b>{self.observationId}</b> is running!<br>" "Close it before editing."),
140
+ (f"The observation <b>{self.observationId}</b> is running!<br>Close it before editing."),
141
141
  )
142
142
 
143
143
  logging.debug("end observations list")
@@ -490,7 +490,7 @@ def observation_length(pj: dict, selected_observations: list) -> tuple:
490
490
  if (
491
491
  dialog.MessageDialog(
492
492
  cfg.programName,
493
- (f"The observation length is not available (<b>{obs_id}</b>).<br>" "Use last event time as observation length?"),
493
+ (f"The observation length is not available (<b>{obs_id}</b>).<br>Use last event time as observation length?"),
494
494
  (cfg.YES, cfg.NO),
495
495
  )
496
496
  == cfg.YES
@@ -655,11 +655,11 @@ def new_observation(self, mode: str = cfg.NEW, obsId: str = "") -> None:
655
655
  observationWindow.teDescription.setPlainText(self.pj[cfg.OBSERVATIONS][obsId][cfg.DESCRIPTION])
656
656
 
657
657
  try:
658
- observationWindow.mediaDurations: dict = self.pj[cfg.OBSERVATIONS][obsId][cfg.MEDIA_INFO][cfg.LENGTH]
659
- observationWindow.mediaFPS: dict = self.pj[cfg.OBSERVATIONS][obsId][cfg.MEDIA_INFO][cfg.FPS]
658
+ observationWindow.mediaDurations = self.pj[cfg.OBSERVATIONS][obsId][cfg.MEDIA_INFO][cfg.LENGTH]
659
+ observationWindow.mediaFPS = self.pj[cfg.OBSERVATIONS][obsId][cfg.MEDIA_INFO][cfg.FPS]
660
660
  except Exception:
661
- observationWindow.mediaDurations: dict = {}
662
- observationWindow.mediaFPS: dict = {}
661
+ observationWindow.mediaDurations = {}
662
+ observationWindow.mediaFPS = {}
663
663
 
664
664
  try:
665
665
  if cfg.HAS_VIDEO in self.pj[cfg.OBSERVATIONS][obsId][cfg.MEDIA_INFO]:
@@ -743,7 +743,7 @@ def new_observation(self, mode: str = cfg.NEW, obsId: str = "") -> None:
743
743
  observationWindow.cb_media_creation_date_as_offset.setEnabled(True)
744
744
 
745
745
  # DEVELOPMENT (REMOVE BEFORE RELEASE)
746
- observationWindow.cb_media_creation_date_as_offset.setEnabled(False)
746
+ # observationWindow.cb_media_creation_date_as_offset.setEnabled(False)
747
747
 
748
748
  observationWindow.cb_media_creation_date_as_offset.setChecked(
749
749
  self.pj[cfg.OBSERVATIONS][obsId].get(cfg.MEDIA_CREATION_DATE_AS_OFFSET, False)
@@ -1083,7 +1083,7 @@ def close_observation(self):
1083
1083
  self.saved_state = self.saveState()
1084
1084
 
1085
1085
  if self.playerType == cfg.MEDIA:
1086
- self.media_scan_sampling_mem: list = []
1086
+ self.media_scan_sampling_mem = []
1087
1087
  logging.info("Stop plot timer")
1088
1088
  self.plot_timer.stop()
1089
1089
 
@@ -1180,31 +1180,6 @@ def check_creation_date(self) -> Tuple[int, dict]:
1180
1180
 
1181
1181
  """
1182
1182
 
1183
- # check if media files exist
1184
-
1185
- """
1186
- media_not_found_list: list = []
1187
- for row in range(self.twVideo1.rowCount()):
1188
- if not pl.Path(self.twVideo1.item(row, 2).text()).is_file():
1189
- media_not_found_list.append(self.twVideo1.item(row, 2).text())
1190
-
1191
- if media_list:
1192
- dlg = dialog.Results_dialog()
1193
- dlg.setWindowTitle("BORIS")
1194
- dlg.pbOK.setText("OK")
1195
- dlg.pbCancel.setVisible(False)
1196
- dlg.ptText.clear()
1197
- dlg.ptText.appendHtml(
1198
- (
1199
- "Some media file(s) were not found:<br>"
1200
- f"{'<br>'.join(media_list)}<br><br>"
1201
- "You cannot select the <b>Use the media creation date/time option</b>."
1202
- )
1203
- )
1204
- dlg.ptText.moveCursor(QTextCursor.Start)
1205
- ret = dlg.exec_()
1206
- """
1207
-
1208
1183
  not_tagged_media_list: list = []
1209
1184
  media_creation_time: dict = {}
1210
1185
 
@@ -1266,7 +1241,7 @@ def initialize_new_media_observation(self) -> bool:
1266
1241
 
1267
1242
  logging.debug("function: initialize new observation for media file(s)")
1268
1243
 
1269
- for dw in [self.dwEthogram, self.dwSubjects, self.dwEvents]:
1244
+ for dw in (self.dwEthogram, self.dwSubjects, self.dwEvents):
1270
1245
  dw.setVisible(True)
1271
1246
 
1272
1247
  ok, msg = project_functions.check_if_media_available(self.pj[cfg.OBSERVATIONS][self.observationId], self.projectFileName)
@@ -1313,12 +1288,15 @@ def initialize_new_media_observation(self) -> bool:
1313
1288
  self.dw_player: list = []
1314
1289
 
1315
1290
  # check if media creation time used as offset
1291
+ # TODO check if cfg.MEDIA_CREATION_TIME dict is present
1292
+ """
1316
1293
  if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.MEDIA_CREATION_DATE_AS_OFFSET, False):
1317
1294
  r, media_creation_time = check_creation_date(self)
1318
1295
 
1319
1296
  if r:
1320
1297
  return False
1321
1298
  self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.MEDIA_CREATION_TIME] = dict(media_creation_time)
1299
+ """
1322
1300
 
1323
1301
  # create dock widgets for players
1324
1302
  for i in range(cfg.N_PLAYER):
@@ -1888,7 +1866,7 @@ def initialize_new_media_observation(self) -> bool:
1888
1866
  self.mpv_eof_reached_signal.connect(self.mpv_eof_reached)
1889
1867
  self.video_click_signal.connect(self.player_clicked)
1890
1868
 
1891
- self.actionPlay.setIcon(QIcon(":/play"))
1869
+ self.actionPlay.setIcon(QIcon(f":/play_{self.theme_mode()}"))
1892
1870
 
1893
1871
  self.display_statusbar_info(self.observationId)
1894
1872
 
@@ -2368,7 +2346,7 @@ def create_observations(self):
2368
2346
  QMessageBox.critical(
2369
2347
  self,
2370
2348
  cfg.programName,
2371
- (f"The observation <b>{media_file}</b> already exists." "<br><br>Aborting the creation of observations"),
2349
+ (f"The observation <b>{media_file}</b> already exists.<br><br>Aborting the creation of observations"),
2372
2350
  )
2373
2351
  return
2374
2352