boris-behav-obs 9.7.12__py3-none-any.whl → 9.8.2__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.
- boris/__init__.py +1 -1
- boris/__main__.py +1 -1
- boris/about.py +4 -3
- boris/add_modifier.py +1 -1
- boris/advanced_event_filtering.py +1 -1
- boris/analysis_plugins/export_to_feral.py +336 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +2 -2
- boris/behav_coding_map_creator.py +1 -1
- boris/behavior_binary_table.py +1 -1
- boris/behaviors_coding_map.py +1 -1
- boris/boris_cli.py +1 -1
- boris/cmd_arguments.py +1 -1
- boris/coding_pad.py +1 -1
- boris/config.py +15 -3
- boris/config_file.py +18 -19
- boris/connections.py +12 -13
- boris/converters.py +1 -1
- boris/converters_ui.py +2 -3
- boris/cooccurence.py +1 -1
- boris/core.py +168 -166
- boris/core_qrc.py +1830 -1967
- boris/core_ui.py +1 -1
- boris/db_functions.py +5 -14
- boris/dialog.py +24 -24
- boris/edit_event.py +1 -1
- boris/event_operations.py +1 -1
- boris/events_cursor.py +1 -1
- boris/events_snapshots.py +133 -78
- boris/exclusion_matrix.py +1 -1
- boris/export_events.py +49 -43
- boris/export_observation.py +1 -1
- boris/external_processes.py +1 -1
- boris/geometric_measurement.py +1 -1
- boris/gui_utilities.py +1 -1
- boris/image_overlay.py +1 -1
- boris/import_observations.py +1 -1
- boris/ipc_mpv.py +1 -1
- boris/irr.py +1 -1
- boris/latency.py +1 -1
- boris/measurement_widget.py +1 -1
- boris/media_file.py +1 -1
- boris/menu_options.py +14 -12
- boris/modifier_coding_map_creator.py +1 -1
- boris/modifiers_coding_map.py +1 -1
- boris/observation.py +13 -14
- boris/observation_operations.py +1 -1
- boris/observations_list.py +1 -1
- boris/otx_parser.py +1 -1
- boris/param_panel.py +1 -1
- boris/player_dock_widget.py +1 -1
- boris/plot_data_module.py +1 -1
- boris/plot_events.py +1 -1
- boris/plot_events_rt.py +1 -1
- boris/plot_spectrogram_rt.py +42 -73
- boris/plot_waveform_rt.py +1 -1
- boris/plugins.py +1 -1
- boris/preferences.py +35 -4
- boris/preferences_ui.py +48 -18
- boris/project.py +1 -1
- boris/project_functions.py +19 -22
- boris/project_import_export.py +1 -1
- boris/select_modifiers.py +1 -1
- boris/select_observations.py +22 -23
- boris/select_subj_behav.py +4 -4
- boris/state_events.py +1 -1
- boris/subjects_pad.py +1 -1
- boris/synthetic_time_budget.py +1 -1
- boris/time_budget_functions.py +1 -1
- boris/time_budget_widget.py +1 -1
- boris/transitions.py +1 -1
- boris/utilities.py +1 -1
- boris/version.py +3 -3
- boris/video_equalizer.py +1 -1
- boris/video_operations.py +1 -1
- boris/view_df.py +28 -4
- boris/write_event.py +1 -1
- {boris_behav_obs-9.7.12.dist-info → boris_behav_obs-9.8.2.dist-info}/METADATA +2 -2
- boris_behav_obs-9.8.2.dist-info/RECORD +110 -0
- {boris_behav_obs-9.7.12.dist-info → boris_behav_obs-9.8.2.dist-info}/WHEEL +1 -1
- boris/analysis_plugins/_export_to_feral.py +0 -225
- boris_behav_obs-9.7.12.dist-info/RECORD +0 -110
- {boris_behav_obs-9.7.12.dist-info → boris_behav_obs-9.8.2.dist-info}/entry_points.txt +0 -0
- {boris_behav_obs-9.7.12.dist-info → boris_behav_obs-9.8.2.dist-info}/licenses/LICENSE.TXT +0 -0
- {boris_behav_obs-9.7.12.dist-info → boris_behav_obs-9.8.2.dist-info}/top_level.txt +0 -0
boris/export_events.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -24,21 +24,15 @@ import datetime as dt
|
|
|
24
24
|
import logging
|
|
25
25
|
import math
|
|
26
26
|
import os
|
|
27
|
-
import tablib
|
|
28
27
|
import pathlib as pl
|
|
29
28
|
from decimal import Decimal as dec
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
from . import
|
|
33
|
-
from . import config as cfg
|
|
34
|
-
from . import select_observations
|
|
35
|
-
from . import export_observation
|
|
36
|
-
from . import select_subj_behav
|
|
37
|
-
from . import project_functions
|
|
38
|
-
from . import dialog
|
|
39
|
-
from . import db_functions
|
|
30
|
+
import tablib
|
|
31
|
+
from PySide6.QtWidgets import QApplication, QFileDialog, QInputDialog, QMessageBox
|
|
40
32
|
|
|
41
|
-
from
|
|
33
|
+
from . import config as cfg
|
|
34
|
+
from . import db_functions, dialog, export_observation, observation_operations, project_functions, select_observations, select_subj_behav
|
|
35
|
+
from . import utilities as util
|
|
42
36
|
|
|
43
37
|
|
|
44
38
|
def export_events_as_behavioral_sequences(self, separated_subjects=False, timed=False):
|
|
@@ -116,8 +110,8 @@ def export_events_as_behavioral_sequences(self, separated_subjects=False, timed=
|
|
|
116
110
|
None,
|
|
117
111
|
cfg.programName,
|
|
118
112
|
f"Error while exporting events as behavioral sequences:<br>{msg}",
|
|
119
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
120
|
-
QMessageBox.NoButton,
|
|
113
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
114
|
+
QMessageBox.StandardButton.NoButton,
|
|
121
115
|
)
|
|
122
116
|
|
|
123
117
|
|
|
@@ -148,8 +142,8 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
148
142
|
None,
|
|
149
143
|
cfg.programName,
|
|
150
144
|
("This function is not available for observations with events that do not have timestamp"),
|
|
151
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
152
|
-
QMessageBox.NoButton,
|
|
145
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
146
|
+
QMessageBox.StandardButton.NoButton,
|
|
153
147
|
)
|
|
154
148
|
return
|
|
155
149
|
|
|
@@ -217,17 +211,14 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
217
211
|
self,
|
|
218
212
|
"Choose a directory to export events",
|
|
219
213
|
os.path.expanduser("~"),
|
|
220
|
-
options=QFileDialog.ShowDirsOnly,
|
|
214
|
+
options=QFileDialog.Option.ShowDirsOnly,
|
|
221
215
|
)
|
|
222
216
|
if not exportDir:
|
|
223
217
|
return
|
|
224
218
|
|
|
225
219
|
if len(selected_observations) == 1:
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
file_name, filter_ = QFileDialog().getSaveFileName(
|
|
230
|
-
self, "Export events", "", ";;".join(available_formats), options=file_dialog_options
|
|
220
|
+
file_name, filter_ = QFileDialog.getSaveFileName(
|
|
221
|
+
self, "Export events", "", ";;".join(available_formats), options=QFileDialog.Option.DontConfirmOverwrite
|
|
231
222
|
)
|
|
232
223
|
if not file_name:
|
|
233
224
|
return
|
|
@@ -238,14 +229,14 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
238
229
|
# check if file with new extension already exists
|
|
239
230
|
if pl.Path(file_name).exists():
|
|
240
231
|
if (
|
|
241
|
-
dialog.MessageDialog(cfg.programName, f"The file {file_name} already exists.",
|
|
232
|
+
dialog.MessageDialog(cfg.programName, f"The file {file_name} already exists.", (cfg.CANCEL, cfg.OVERWRITE))
|
|
242
233
|
== cfg.CANCEL
|
|
243
234
|
):
|
|
244
235
|
return
|
|
245
236
|
|
|
246
237
|
if mode == "jwatcher":
|
|
247
238
|
exportDir = QFileDialog().getExistingDirectory(
|
|
248
|
-
self, "Choose a directory to export events", os.path.expanduser("~"), options=QFileDialog.ShowDirsOnly
|
|
239
|
+
self, "Choose a directory to export events", os.path.expanduser("~"), options=QFileDialog.Option.ShowDirsOnly
|
|
249
240
|
)
|
|
250
241
|
if not exportDir:
|
|
251
242
|
return
|
|
@@ -263,7 +254,7 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
263
254
|
mem_command = dialog.MessageDialog(
|
|
264
255
|
cfg.programName,
|
|
265
256
|
f"The file {file_name} already exists.",
|
|
266
|
-
|
|
257
|
+
(cfg.OVERWRITE, cfg.OVERWRITE_ALL, cfg.SKIP, cfg.SKIP_ALL, cfg.CANCEL),
|
|
267
258
|
)
|
|
268
259
|
if mem_command == cfg.CANCEL:
|
|
269
260
|
return
|
|
@@ -287,7 +278,13 @@ def export_tabular_events(self, mode: str = "tabular") -> None:
|
|
|
287
278
|
)
|
|
288
279
|
|
|
289
280
|
if not r and msg:
|
|
290
|
-
QMessageBox.critical(
|
|
281
|
+
QMessageBox.critical(
|
|
282
|
+
None,
|
|
283
|
+
cfg.programName,
|
|
284
|
+
msg,
|
|
285
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
286
|
+
QMessageBox.StandardButton.NoButton,
|
|
287
|
+
)
|
|
291
288
|
|
|
292
289
|
|
|
293
290
|
def export_aggregated_events(self):
|
|
@@ -397,7 +394,7 @@ def export_aggregated_events(self):
|
|
|
397
394
|
flag_group = True
|
|
398
395
|
if len(selected_observations) > 1:
|
|
399
396
|
flag_group = (
|
|
400
|
-
dialog.MessageDialog(cfg.programName, "Group events from selected observations in one file?",
|
|
397
|
+
dialog.MessageDialog(cfg.programName, "Group events from selected observations in one file?", (cfg.YES, cfg.NO)) == cfg.YES
|
|
401
398
|
)
|
|
402
399
|
|
|
403
400
|
if flag_group:
|
|
@@ -415,11 +412,8 @@ def export_aggregated_events(self):
|
|
|
415
412
|
cfg.RDS,
|
|
416
413
|
)
|
|
417
414
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
fileName, filter_ = QFileDialog().getSaveFileName(
|
|
422
|
-
self, "Export aggregated events", "", ";;".join(file_formats), options=file_dialog_options
|
|
415
|
+
fileName, filter_ = QFileDialog.getSaveFileName(
|
|
416
|
+
self, "Export aggregated events", "", ";;".join(file_formats), options=QFileDialog.Option.DontConfirmOverwrite
|
|
423
417
|
)
|
|
424
418
|
|
|
425
419
|
if not fileName:
|
|
@@ -430,7 +424,7 @@ def export_aggregated_events(self):
|
|
|
430
424
|
# check if file with new extension already exists
|
|
431
425
|
fileName = str(pl.Path(fileName)) + "." + outputFormat
|
|
432
426
|
if pl.Path(fileName).exists():
|
|
433
|
-
if dialog.MessageDialog(cfg.programName, f"The file {fileName} already exists.",
|
|
427
|
+
if dialog.MessageDialog(cfg.programName, f"The file {fileName} already exists.", (cfg.CANCEL, cfg.OVERWRITE)) == cfg.CANCEL:
|
|
434
428
|
return
|
|
435
429
|
|
|
436
430
|
else: # not grouping
|
|
@@ -453,7 +447,7 @@ def export_aggregated_events(self):
|
|
|
453
447
|
outputFormat = cfg.FILE_NAME_SUFFIX[item]
|
|
454
448
|
|
|
455
449
|
exportDir = QFileDialog().getExistingDirectory(
|
|
456
|
-
self, "Choose a directory to export events", os.path.expanduser("~"), options=QFileDialog.ShowDirsOnly
|
|
450
|
+
self, "Choose a directory to export events", os.path.expanduser("~"), options=QFileDialog.Option.ShowDirsOnly
|
|
457
451
|
)
|
|
458
452
|
if not exportDir:
|
|
459
453
|
return
|
|
@@ -471,8 +465,8 @@ def export_aggregated_events(self):
|
|
|
471
465
|
None,
|
|
472
466
|
cfg.programName,
|
|
473
467
|
f"The file {fileName} can not be saved",
|
|
474
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
475
|
-
QMessageBox.NoButton,
|
|
468
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
469
|
+
QMessageBox.StandardButton.NoButton,
|
|
476
470
|
)
|
|
477
471
|
|
|
478
472
|
return
|
|
@@ -530,7 +524,7 @@ def export_aggregated_events(self):
|
|
|
530
524
|
mem_command = dialog.MessageDialog(
|
|
531
525
|
cfg.programName,
|
|
532
526
|
f"The file {fileName} already exists.",
|
|
533
|
-
|
|
527
|
+
(cfg.OVERWRITE, cfg.OVERWRITE_ALL, cfg.SKIP, cfg.SKIP_ALL, cfg.CANCEL),
|
|
534
528
|
)
|
|
535
529
|
if mem_command == cfg.CANCEL:
|
|
536
530
|
return
|
|
@@ -539,7 +533,13 @@ def export_aggregated_events(self):
|
|
|
539
533
|
|
|
540
534
|
r, msg = export_observation.dataset_write(data_single_obs_sorted, fileName, outputFormat, dtype=fields_type(max_modifiers))
|
|
541
535
|
if not r:
|
|
542
|
-
QMessageBox.warning(
|
|
536
|
+
QMessageBox.warning(
|
|
537
|
+
None,
|
|
538
|
+
cfg.programName,
|
|
539
|
+
msg,
|
|
540
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
541
|
+
QMessageBox.StandardButton.NoButton,
|
|
542
|
+
)
|
|
543
543
|
|
|
544
544
|
"""
|
|
545
545
|
# disabled after introduction of the force_number_modifiers parameter in export_aggregated_events function
|
|
@@ -635,7 +635,13 @@ def export_aggregated_events(self):
|
|
|
635
635
|
if flag_group:
|
|
636
636
|
r, msg = export_observation.dataset_write(data_grouped_obs_all, fileName, outputFormat, dtype=fields_type(max_modifiers))
|
|
637
637
|
if not r:
|
|
638
|
-
QMessageBox.warning(
|
|
638
|
+
QMessageBox.warning(
|
|
639
|
+
None,
|
|
640
|
+
cfg.programName,
|
|
641
|
+
msg,
|
|
642
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
643
|
+
QMessageBox.StandardButton.NoButton,
|
|
644
|
+
)
|
|
639
645
|
|
|
640
646
|
|
|
641
647
|
def export_events_as_textgrid(self) -> None:
|
|
@@ -667,8 +673,8 @@ def export_events_as_textgrid(self) -> None:
|
|
|
667
673
|
None,
|
|
668
674
|
cfg.programName,
|
|
669
675
|
("This function is not available for observations with events that do not have timestamp"),
|
|
670
|
-
QMessageBox.Ok | QMessageBox.Default,
|
|
671
|
-
QMessageBox.NoButton,
|
|
676
|
+
QMessageBox.StandardButton.Ok | QMessageBox.StandardButton.Default,
|
|
677
|
+
QMessageBox.StandardButton.NoButton,
|
|
672
678
|
)
|
|
673
679
|
return
|
|
674
680
|
|
|
@@ -697,7 +703,7 @@ def export_events_as_textgrid(self) -> None:
|
|
|
697
703
|
return
|
|
698
704
|
|
|
699
705
|
export_dir = QFileDialog.getExistingDirectory(
|
|
700
|
-
self, "Export events as Praat TextGrid", os.path.expanduser("~"), options=QFileDialog.ShowDirsOnly
|
|
706
|
+
self, "Export events as Praat TextGrid", os.path.expanduser("~"), options=QFileDialog.Option.ShowDirsOnly
|
|
701
707
|
)
|
|
702
708
|
if not export_dir:
|
|
703
709
|
return
|
|
@@ -985,7 +991,7 @@ def export_events_as_textgrid(self) -> None:
|
|
|
985
991
|
mem_command = dialog.MessageDialog(
|
|
986
992
|
cfg.programName,
|
|
987
993
|
f"The file <b>{pl.Path(export_dir) / util.safeFileName(obs_id)}.TextGrid</b> already exists.",
|
|
988
|
-
|
|
994
|
+
(cfg.OVERWRITE, cfg.OVERWRITE_ALL, cfg.SKIP, cfg.SKIP_ALL, cfg.CANCEL),
|
|
989
995
|
)
|
|
990
996
|
if mem_command == cfg.CANCEL:
|
|
991
997
|
return
|
boris/export_observation.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This program is free software; you can redistribute it and/or modify
|
|
7
7
|
it under the terms of the GNU General Public License as published by
|
boris/external_processes.py
CHANGED
boris/geometric_measurement.py
CHANGED
boris/gui_utilities.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This program is free software; you can redistribute it and/or modify
|
|
7
7
|
it under the terms of the GNU General Public License as published by
|
boris/image_overlay.py
CHANGED
boris/import_observations.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This program is free software; you can redistribute it and/or modify
|
|
7
7
|
it under the terms of the GNU General Public License as published by
|
boris/ipc_mpv.py
CHANGED
boris/irr.py
CHANGED
boris/latency.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This program is free software; you can redistribute it and/or modify
|
|
7
7
|
it under the terms of the GNU General Public License as published by
|
boris/measurement_widget.py
CHANGED
boris/media_file.py
CHANGED
boris/menu_options.py
CHANGED
|
@@ -1,28 +1,31 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
This file is part of BORIS.
|
|
7
|
+
|
|
8
|
+
BORIS is free software; you can redistribute it and/or modify
|
|
7
9
|
it under the terms of the GNU General Public License as published by
|
|
8
|
-
the Free Software Foundation; either version
|
|
9
|
-
|
|
10
|
+
the Free Software Foundation; either version 3 of the License, or
|
|
11
|
+
any later version.
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
BORIS is distributed in the hope that it will be useful,
|
|
12
14
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
15
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
16
|
GNU General Public License for more details.
|
|
15
17
|
|
|
16
18
|
You should have received a copy of the GNU General Public License
|
|
17
|
-
along with this program; if not
|
|
18
|
-
|
|
19
|
-
MA 02110-1301, USA.
|
|
19
|
+
along with this program; if not see <http://www.gnu.org/licenses/>.
|
|
20
|
+
|
|
20
21
|
"""
|
|
21
22
|
|
|
22
23
|
import logging
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
from PySide6.QtCore import QSize
|
|
25
26
|
|
|
27
|
+
from . import config as cfg
|
|
28
|
+
|
|
26
29
|
|
|
27
30
|
def update_windows_title(self):
|
|
28
31
|
"""
|
|
@@ -35,10 +38,9 @@ def update_windows_title(self):
|
|
|
35
38
|
if self.pj[cfg.PROJECT_NAME]:
|
|
36
39
|
project_name = self.pj[cfg.PROJECT_NAME]
|
|
37
40
|
else:
|
|
41
|
+
project_name = "Unnamed project"
|
|
38
42
|
if self.projectFileName:
|
|
39
|
-
project_name
|
|
40
|
-
else:
|
|
41
|
-
project_name = "Unnamed project"
|
|
43
|
+
project_name += f" ({self.projectFileName})"
|
|
42
44
|
|
|
43
45
|
self.setWindowTitle(
|
|
44
46
|
f"{self.observationId + ' - ' * (self.observationId != '')}{project_name}{'*' * self.projectChanged}{(' - ' * (project_name != ''))}{cfg.programName}"
|
boris/modifiers_coding_map.py
CHANGED
boris/observation.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This file is part of BORIS.
|
|
7
7
|
|
|
@@ -22,33 +22,32 @@ This file is part of BORIS.
|
|
|
22
22
|
|
|
23
23
|
import logging
|
|
24
24
|
import os
|
|
25
|
-
import pandas as pd
|
|
26
25
|
import pathlib as pl
|
|
27
26
|
|
|
27
|
+
import pandas as pd
|
|
28
28
|
from PySide6.QtCore import Qt
|
|
29
29
|
from PySide6.QtGui import QColor
|
|
30
30
|
from PySide6.QtWidgets import (
|
|
31
|
+
QApplication,
|
|
32
|
+
QComboBox,
|
|
31
33
|
QDialog,
|
|
32
|
-
|
|
34
|
+
QFileDialog,
|
|
33
35
|
QHBoxLayout,
|
|
36
|
+
QHeaderView,
|
|
34
37
|
QLabel,
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
QListWidgetItem,
|
|
39
|
+
QMenu,
|
|
37
40
|
QMessageBox,
|
|
38
|
-
|
|
41
|
+
QPushButton,
|
|
39
42
|
QSizePolicy,
|
|
40
|
-
|
|
43
|
+
QSpacerItem,
|
|
41
44
|
QTableWidgetItem,
|
|
42
|
-
|
|
43
|
-
QMenu,
|
|
44
|
-
QListWidgetItem,
|
|
45
|
-
QHeaderView,
|
|
45
|
+
QVBoxLayout,
|
|
46
46
|
)
|
|
47
47
|
|
|
48
48
|
from . import config as cfg
|
|
49
|
-
from . import dialog, plot_data_module, project_functions
|
|
49
|
+
from . import dialog, gui_utilities, plot_data_module, project_functions
|
|
50
50
|
from . import utilities as util
|
|
51
|
-
from . import gui_utilities
|
|
52
51
|
from .observation_ui import Ui_Form
|
|
53
52
|
|
|
54
53
|
|
|
@@ -1266,7 +1265,7 @@ class Observation(QDialog, Ui_Form):
|
|
|
1266
1265
|
file_path = str(pl.Path(file_path).relative_to(pl.Path(self.project_path).parent))
|
|
1267
1266
|
|
|
1268
1267
|
self.mediaDurations[file_path] = float(media_info["duration"])
|
|
1269
|
-
elif media_info["has_video"] is False and media_info["audio_duration"]:
|
|
1268
|
+
elif media_info["has_video"] is False and media_info["audio_duration"] and media_info["audio_duration"] != "NA":
|
|
1270
1269
|
self.mediaDurations[file_path] = float(media_info["audio_duration"])
|
|
1271
1270
|
else:
|
|
1272
1271
|
return (True, "Media duration not available")
|
boris/observation_operations.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
BORIS
|
|
3
3
|
Behavioral Observation Research Interactive Software
|
|
4
|
-
Copyright 2012-
|
|
4
|
+
Copyright 2012-2026 Olivier Friard
|
|
5
5
|
|
|
6
6
|
This program is free software; you can redistribute it and/or modify
|
|
7
7
|
it under the terms of the GNU General Public License as published by
|
boris/observations_list.py
CHANGED
boris/otx_parser.py
CHANGED
boris/param_panel.py
CHANGED
boris/player_dock_widget.py
CHANGED
boris/plot_data_module.py
CHANGED
boris/plot_events.py
CHANGED