boris-behav-obs 9.7.1__tar.gz → 9.7.7__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.
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/PKG-INFO +3 -4
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/README.md +2 -3
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/about.py +5 -5
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/add_modifier_ui.py +47 -29
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/config.py +7 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/config_file.py +3 -3
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/core.py +89 -55
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/ipc_mpv.py +52 -31
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/observation.py +8 -1
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/observation_operations.py +23 -6
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plot_data_module.py +2 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/preferences.py +9 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/preferences_ui.py +46 -28
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/project.py +1 -1
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/project_functions.py +27 -12
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/utilities.py +23 -4
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/version.py +2 -2
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/video_operations.py +8 -1
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/PKG-INFO +3 -4
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/pyproject.toml +1 -1
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/LICENSE.TXT +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/MANIFEST.in +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/README.TXT +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/__init__.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/__main__.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/add_modifier.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/advanced_event_filtering.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/__init__.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/_latency.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/irr_cohen_kappa.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/irr_weighted_cohen_kappa.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/list_of_dataframe_columns.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/number_of_occurences.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/number_of_occurences_by_independent_variable.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/analysis_plugins/time_budget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/behav_coding_map_creator.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/behavior_binary_table.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/behaviors_coding_map.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/boris_cli.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/cmd_arguments.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/coding_pad.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/connections.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/converters.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/converters_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/cooccurence.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/core_qrc.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/core_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/db_functions.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/dev.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/dialog.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/duration_widget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/edit_event.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/edit_event_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/event_operations.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/events_cursor.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/events_snapshots.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/exclusion_matrix.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/export_events.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/export_observation.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/external_processes.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/geometric_measurement.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/gui_utilities.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/image_overlay.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/import_observations.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/irr.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/latency.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/measurement_widget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/media_file.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/menu_options.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/modifier_coding_map_creator.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/modifiers_coding_map.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/mpv.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/mpv2.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/observation_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/observations_list.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/otx_parser.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/param_panel.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/param_panel_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/player_dock_widget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plot_events.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plot_events_rt.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plot_spectrogram_rt.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plot_waveform_rt.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/plugins.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/__init__.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/const.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/dict.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/func.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/interval.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/portion/io.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/project_import_export.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/project_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/qrc_boris.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/qrc_boris5.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/select_modifiers.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/select_observations.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/select_subj_behav.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/state_events.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/subjects_pad.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/synthetic_time_budget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/time_budget_functions.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/time_budget_widget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/transitions.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/video_equalizer.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/video_equalizer_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/view_df.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/view_df_ui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris/write_event.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/SOURCES.txt +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/dependency_links.txt +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/entry_points.txt +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/requires.txt +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/boris_behav_obs.egg-info/top_level.txt +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/setup.cfg +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_db_functions.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_export_observation.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_irr.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_observation_gui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_otx_parser.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_preferences_gui.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_project_functions.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_time_budget.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/tests/test_utilities.py +0 -0
- {boris_behav_obs-9.7.1 → boris_behav_obs-9.7.7}/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.
|
|
3
|
+
Version: 9.7.7
|
|
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
|
|
@@ -44,15 +44,14 @@ BORIS (Behavioral Observation Research Interactive Software)
|
|
|
44
44
|
|
|
45
45
|
BORIS is an easy-to-use event logging software for video/audio coding or live observations.
|
|
46
46
|
|
|
47
|
-
BORIS is a free and open-source software available for GNU/Linux and
|
|
48
|
-
You can not longer run BORIS natively on MacOS (since v.8). Some alternatives to run the last version of BORIS are available, see [BORIS on MacOS](https://www.boris.unito.it/download_mac).
|
|
47
|
+
BORIS is a free and open-source software available for GNU/Linux, Windows and macOS.
|
|
49
48
|
|
|
50
49
|
It provides also some analysis tools like time budget and some plotting functions.
|
|
51
50
|
|
|
52
51
|
<!-- The BO-RIS paper has more than [ citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
|
|
53
52
|
|
|
54
53
|
|
|
55
|
-
The BORIS paper has more than
|
|
54
|
+
The BORIS paper has more than 2423 citations in peer-reviewed scientific publications.
|
|
56
55
|
|
|
57
56
|
|
|
58
57
|
|
|
@@ -6,15 +6,14 @@ BORIS (Behavioral Observation Research Interactive Software)
|
|
|
6
6
|
|
|
7
7
|
BORIS is an easy-to-use event logging software for video/audio coding or live observations.
|
|
8
8
|
|
|
9
|
-
BORIS is a free and open-source software available for GNU/Linux and
|
|
10
|
-
You can not longer run BORIS natively on MacOS (since v.8). Some alternatives to run the last version of BORIS are available, see [BORIS on MacOS](https://www.boris.unito.it/download_mac).
|
|
9
|
+
BORIS is a free and open-source software available for GNU/Linux, Windows and macOS.
|
|
11
10
|
|
|
12
11
|
It provides also some analysis tools like time budget and some plotting functions.
|
|
13
12
|
|
|
14
13
|
<!-- The BO-RIS paper has more than [ citations](https://www.boris.unito.it/citations) in peer-reviewed scientific publications. -->
|
|
15
14
|
|
|
16
15
|
|
|
17
|
-
The BORIS paper has more than
|
|
16
|
+
The BORIS paper has more than 2423 citations in peer-reviewed scientific publications.
|
|
18
17
|
|
|
19
18
|
|
|
20
19
|
|
|
@@ -40,7 +40,7 @@ def actionAbout_activated(self):
|
|
|
40
40
|
About dialog
|
|
41
41
|
"""
|
|
42
42
|
|
|
43
|
-
programs_versions: list = ["MPV media player"]
|
|
43
|
+
programs_versions: list[str] = ["MPV media player"]
|
|
44
44
|
|
|
45
45
|
mpv_lib_version, mpv_lib_file_path, mpv_api_version = util.mpv_lib_version()
|
|
46
46
|
programs_versions.append(
|
|
@@ -53,13 +53,13 @@ def actionAbout_activated(self):
|
|
|
53
53
|
|
|
54
54
|
# ffmpeg
|
|
55
55
|
if self.ffmpeg_bin == "ffmpeg" and sys.platform.startswith("linux"):
|
|
56
|
-
ffmpeg_true_path = subprocess.getoutput("which ffmpeg")
|
|
56
|
+
ffmpeg_true_path: str = subprocess.getoutput("which ffmpeg")
|
|
57
57
|
else:
|
|
58
58
|
ffmpeg_true_path = self.ffmpeg_bin
|
|
59
59
|
programs_versions.extend(
|
|
60
60
|
[
|
|
61
61
|
"\nFFmpeg",
|
|
62
|
-
subprocess.getoutput(f'"{self.ffmpeg_bin}" -version').split("\n")[0],
|
|
62
|
+
subprocess.getoutput(cmd=f'"{self.ffmpeg_bin}" -version').split(sep="\n")[0],
|
|
63
63
|
f"Path: {ffmpeg_true_path}",
|
|
64
64
|
"https://www.ffmpeg.org",
|
|
65
65
|
]
|
|
@@ -75,11 +75,11 @@ def actionAbout_activated(self):
|
|
|
75
75
|
programs_versions.extend(["\nPandas", f"version {pd.__version__}", "https://pandas.pydata.org"])
|
|
76
76
|
|
|
77
77
|
# graphviz
|
|
78
|
-
gv_result = subprocess.getoutput("dot -V")
|
|
78
|
+
gv_result = subprocess.getoutput(cmd="dot -V")
|
|
79
79
|
|
|
80
80
|
programs_versions.extend(["\nGraphViz", gv_result if "graphviz" in gv_result else "not installed", "https://www.graphviz.org/"])
|
|
81
81
|
|
|
82
|
-
about_dialog = QMessageBox()
|
|
82
|
+
about_dialog: QMessageBox = QMessageBox()
|
|
83
83
|
about_dialog.setIconPixmap(QPixmap(":/boris_unito"))
|
|
84
84
|
|
|
85
85
|
about_dialog.setWindowTitle(f"About {cfg.programName}")
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
################################################################################
|
|
4
4
|
## Form generated from reading UI file 'add_modifier.ui'
|
|
5
5
|
##
|
|
6
|
-
## Created by: Qt User Interface Compiler version 6.
|
|
6
|
+
## Created by: Qt User Interface Compiler version 6.10.0
|
|
7
7
|
##
|
|
8
8
|
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
9
9
|
################################################################################
|
|
@@ -24,18 +24,16 @@ class Ui_Dialog(object):
|
|
|
24
24
|
def setupUi(self, Dialog):
|
|
25
25
|
if not Dialog.objectName():
|
|
26
26
|
Dialog.setObjectName(u"Dialog")
|
|
27
|
-
Dialog.resize(
|
|
28
|
-
self.
|
|
29
|
-
self.
|
|
27
|
+
Dialog.resize(1339, 789)
|
|
28
|
+
self.verticalLayout_4 = QVBoxLayout(Dialog)
|
|
29
|
+
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
|
|
30
30
|
self.cb_ask_at_stop = QCheckBox(Dialog)
|
|
31
31
|
self.cb_ask_at_stop.setObjectName(u"cb_ask_at_stop")
|
|
32
32
|
|
|
33
|
-
self.
|
|
33
|
+
self.verticalLayout_4.addWidget(self.cb_ask_at_stop)
|
|
34
34
|
|
|
35
|
-
self.
|
|
36
|
-
self.
|
|
37
|
-
self.horizontalLayout_5 = QHBoxLayout()
|
|
38
|
-
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
|
35
|
+
self.horizontalLayout_8 = QHBoxLayout()
|
|
36
|
+
self.horizontalLayout_8.setObjectName(u"horizontalLayout_8")
|
|
39
37
|
self.verticalLayout_2 = QVBoxLayout()
|
|
40
38
|
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
|
41
39
|
self.lbModifier = QLabel(Dialog)
|
|
@@ -69,7 +67,7 @@ class Ui_Dialog(object):
|
|
|
69
67
|
self.verticalLayout_2.addItem(self.verticalSpacer)
|
|
70
68
|
|
|
71
69
|
|
|
72
|
-
self.
|
|
70
|
+
self.horizontalLayout_8.addLayout(self.verticalLayout_2)
|
|
73
71
|
|
|
74
72
|
self.verticalLayout_3 = QVBoxLayout()
|
|
75
73
|
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
|
@@ -88,7 +86,7 @@ class Ui_Dialog(object):
|
|
|
88
86
|
self.verticalLayout_3.addItem(self.verticalSpacer_2)
|
|
89
87
|
|
|
90
88
|
|
|
91
|
-
self.
|
|
89
|
+
self.horizontalLayout_8.addLayout(self.verticalLayout_3)
|
|
92
90
|
|
|
93
91
|
self.verticalLayout = QVBoxLayout()
|
|
94
92
|
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
@@ -102,30 +100,42 @@ class Ui_Dialog(object):
|
|
|
102
100
|
|
|
103
101
|
self.verticalLayout.addWidget(self.tabWidgetModifiersSets)
|
|
104
102
|
|
|
103
|
+
self.horizontalLayout_5 = QHBoxLayout()
|
|
104
|
+
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
|
105
105
|
self.lb_name = QLabel(Dialog)
|
|
106
106
|
self.lb_name.setObjectName(u"lb_name")
|
|
107
107
|
|
|
108
|
-
self.
|
|
108
|
+
self.horizontalLayout_5.addWidget(self.lb_name)
|
|
109
109
|
|
|
110
110
|
self.le_name = QLineEdit(Dialog)
|
|
111
111
|
self.le_name.setObjectName(u"le_name")
|
|
112
112
|
|
|
113
|
-
self.
|
|
113
|
+
self.horizontalLayout_5.addWidget(self.le_name)
|
|
114
114
|
|
|
115
|
+
|
|
116
|
+
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
|
117
|
+
|
|
118
|
+
self.horizontalLayout_6 = QHBoxLayout()
|
|
119
|
+
self.horizontalLayout_6.setObjectName(u"horizontalLayout_6")
|
|
115
120
|
self.lb_description = QLabel(Dialog)
|
|
116
121
|
self.lb_description.setObjectName(u"lb_description")
|
|
117
122
|
|
|
118
|
-
self.
|
|
123
|
+
self.horizontalLayout_6.addWidget(self.lb_description)
|
|
119
124
|
|
|
120
125
|
self.le_description = QLineEdit(Dialog)
|
|
121
126
|
self.le_description.setObjectName(u"le_description")
|
|
122
127
|
|
|
123
|
-
self.
|
|
128
|
+
self.horizontalLayout_6.addWidget(self.le_description)
|
|
129
|
+
|
|
124
130
|
|
|
131
|
+
self.verticalLayout.addLayout(self.horizontalLayout_6)
|
|
132
|
+
|
|
133
|
+
self.horizontalLayout_7 = QHBoxLayout()
|
|
134
|
+
self.horizontalLayout_7.setObjectName(u"horizontalLayout_7")
|
|
125
135
|
self.lbType = QLabel(Dialog)
|
|
126
136
|
self.lbType.setObjectName(u"lbType")
|
|
127
137
|
|
|
128
|
-
self.
|
|
138
|
+
self.horizontalLayout_7.addWidget(self.lbType)
|
|
129
139
|
|
|
130
140
|
self.cbType = QComboBox(Dialog)
|
|
131
141
|
self.cbType.addItem("")
|
|
@@ -134,7 +144,14 @@ class Ui_Dialog(object):
|
|
|
134
144
|
self.cbType.addItem("")
|
|
135
145
|
self.cbType.setObjectName(u"cbType")
|
|
136
146
|
|
|
137
|
-
self.
|
|
147
|
+
self.horizontalLayout_7.addWidget(self.cbType)
|
|
148
|
+
|
|
149
|
+
self.horizontalSpacer_3 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
150
|
+
|
|
151
|
+
self.horizontalLayout_7.addItem(self.horizontalSpacer_3)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
self.verticalLayout.addLayout(self.horizontalLayout_7)
|
|
138
155
|
|
|
139
156
|
self.lbValues = QLabel(Dialog)
|
|
140
157
|
self.lbValues.setObjectName(u"lbValues")
|
|
@@ -198,28 +215,32 @@ class Ui_Dialog(object):
|
|
|
198
215
|
|
|
199
216
|
self.horizontalLayout_4 = QHBoxLayout()
|
|
200
217
|
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
|
201
|
-
|
|
202
|
-
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
203
|
-
|
|
204
218
|
self.pb_add_subjects = QPushButton(Dialog)
|
|
205
219
|
self.pb_add_subjects.setObjectName(u"pb_add_subjects")
|
|
206
220
|
|
|
207
|
-
self.
|
|
221
|
+
self.horizontalLayout_4.addWidget(self.pb_add_subjects)
|
|
208
222
|
|
|
209
223
|
self.pb_load_file = QPushButton(Dialog)
|
|
210
224
|
self.pb_load_file.setObjectName(u"pb_load_file")
|
|
211
225
|
|
|
212
|
-
self.
|
|
226
|
+
self.horizontalLayout_4.addWidget(self.pb_load_file)
|
|
227
|
+
|
|
228
|
+
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
229
|
+
|
|
230
|
+
self.horizontalLayout_4.addItem(self.horizontalSpacer_2)
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
213
234
|
|
|
214
235
|
self.verticalSpacer_3 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
|
215
236
|
|
|
216
237
|
self.verticalLayout.addItem(self.verticalSpacer_3)
|
|
217
238
|
|
|
218
239
|
|
|
219
|
-
self.
|
|
240
|
+
self.horizontalLayout_8.addLayout(self.verticalLayout)
|
|
220
241
|
|
|
221
242
|
|
|
222
|
-
self.verticalLayout_4.addLayout(self.
|
|
243
|
+
self.verticalLayout_4.addLayout(self.horizontalLayout_8)
|
|
223
244
|
|
|
224
245
|
self.horizontalLayout_2 = QHBoxLayout()
|
|
225
246
|
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
@@ -241,9 +262,6 @@ class Ui_Dialog(object):
|
|
|
241
262
|
self.verticalLayout_4.addLayout(self.horizontalLayout_2)
|
|
242
263
|
|
|
243
264
|
|
|
244
|
-
self.verticalLayout_5.addLayout(self.verticalLayout_4)
|
|
245
|
-
|
|
246
|
-
|
|
247
265
|
self.retranslateUi(Dialog)
|
|
248
266
|
|
|
249
267
|
self.tabWidgetModifiersSets.setCurrentIndex(-1)
|
|
@@ -256,8 +274,8 @@ class Ui_Dialog(object):
|
|
|
256
274
|
Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Set modifiers", None))
|
|
257
275
|
self.cb_ask_at_stop.setText(QCoreApplication.translate("Dialog", u"Ask for modifier(s) when behavior stops", None))
|
|
258
276
|
self.lbModifier.setText(QCoreApplication.translate("Dialog", u"Modifier", None))
|
|
259
|
-
self.lbCode.setText(QCoreApplication.translate("Dialog", u"
|
|
260
|
-
self.lbCodeHelp.setText(QCoreApplication.translate("Dialog", u"
|
|
277
|
+
self.lbCode.setText(QCoreApplication.translate("Dialog", u"Shortcut", None))
|
|
278
|
+
self.lbCodeHelp.setText(QCoreApplication.translate("Dialog", u"The shortcut is case sensitive. Type one character or a function key (F1, F2... F12)", None))
|
|
261
279
|
self.pbAddModifier.setText(QCoreApplication.translate("Dialog", u"->", None))
|
|
262
280
|
self.pbModifyModifier.setText(QCoreApplication.translate("Dialog", u"<-", None))
|
|
263
281
|
self.lb_name.setText(QCoreApplication.translate("Dialog", u"Set name", None))
|
|
@@ -132,6 +132,8 @@ POINT_EVENT_PLOT_COLOR = "black"
|
|
|
132
132
|
|
|
133
133
|
CHAR_FORBIDDEN_IN_MODIFIERS = "(|),`~"
|
|
134
134
|
|
|
135
|
+
FAST_FORWARD_DEFAULT_VALUE: float = 10.0
|
|
136
|
+
|
|
135
137
|
ADAPT_FAST_JUMP = "adapt_fast_jump"
|
|
136
138
|
ADAPT_FAST_JUMP_DEFAULT = False
|
|
137
139
|
|
|
@@ -419,6 +421,10 @@ MPV_HWDEC_AUTOSAFE = "auto-safe"
|
|
|
419
421
|
MPV_HWDEC_OPTIONS = (MPV_HWDEC_AUTO, MPV_HWDEC_AUTOSAFE, MPV_HWDEC_NO)
|
|
420
422
|
MPV_HWDEC_DEFAULT_VALUE = MPV_HWDEC_AUTO
|
|
421
423
|
|
|
424
|
+
# frame step size (disabled)
|
|
425
|
+
# FRAME_STEP_SIZE: str = "frame_step_size"
|
|
426
|
+
# FRAME_STEP_SIZE_DEFAULT_VALUE: int = 1
|
|
427
|
+
|
|
422
428
|
ANALYSIS_PLUGINS = "analysis_plugins"
|
|
423
429
|
EXCLUDED_PLUGINS = "excluded_plugins"
|
|
424
430
|
PERSONAL_PLUGINS_DIR = "personal_plugins_dir"
|
|
@@ -730,6 +736,7 @@ INIT_PARAM = {
|
|
|
730
736
|
MPV_HWDEC: MPV_HWDEC_DEFAULT_VALUE,
|
|
731
737
|
PROJECT_FILE_INDENTATION: PROJECT_FILE_INDENTATION_DEFAULT_VALUE,
|
|
732
738
|
f"{MEDIA} tw fields": MEDIA_TW_EVENTS_FIELDS_DEFAULT,
|
|
739
|
+
# FRAME_STEP_SIZE: FRAME_STEP_SIZE_DEFAULT_VALUE,
|
|
733
740
|
}
|
|
734
741
|
|
|
735
742
|
SDIS_EXT = "sds"
|
|
@@ -82,11 +82,11 @@ def read(self):
|
|
|
82
82
|
|
|
83
83
|
logging.debug(f"time format: {self.timeFormat}")
|
|
84
84
|
|
|
85
|
-
self.fast =
|
|
85
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
86
86
|
try:
|
|
87
|
-
self.fast =
|
|
87
|
+
self.fast = float(settings.value("Time/fast_forward_speed"))
|
|
88
88
|
except Exception:
|
|
89
|
-
self.fast =
|
|
89
|
+
self.fast = cfg.FAST_FORWARD_DEFAULT_VALUE
|
|
90
90
|
|
|
91
91
|
logging.debug(f"Time/fast_forward_speed: {self.fast}")
|
|
92
92
|
|
|
@@ -41,9 +41,9 @@ from PIL.ImageQt import Image
|
|
|
41
41
|
import subprocess
|
|
42
42
|
import locale
|
|
43
43
|
import tempfile
|
|
44
|
+
import math
|
|
44
45
|
import time
|
|
45
46
|
import urllib.request
|
|
46
|
-
from typing import Union, Tuple
|
|
47
47
|
from decimal import Decimal as dec
|
|
48
48
|
from decimal import ROUND_DOWN
|
|
49
49
|
import gzip
|
|
@@ -54,17 +54,7 @@ import shutil
|
|
|
54
54
|
|
|
55
55
|
matplotlib.use("QtAgg")
|
|
56
56
|
|
|
57
|
-
from PySide6.QtCore import
|
|
58
|
-
Qt,
|
|
59
|
-
QPoint,
|
|
60
|
-
Signal,
|
|
61
|
-
QEvent,
|
|
62
|
-
QDateTime,
|
|
63
|
-
QUrl,
|
|
64
|
-
QAbstractTableModel,
|
|
65
|
-
QElapsedTimer,
|
|
66
|
-
QSettings,
|
|
67
|
-
)
|
|
57
|
+
from PySide6.QtCore import Qt, QPoint, Signal, QEvent, QDateTime, QUrl, QAbstractTableModel, QElapsedTimer, QSettings, QTimer
|
|
68
58
|
from PySide6.QtGui import QIcon, QPixmap, QFont, QKeyEvent, QDesktopServices, QColor, QPainter, QPolygon, QAction
|
|
69
59
|
from PySide6.QtMultimedia import QSoundEffect
|
|
70
60
|
from PySide6.QtWidgets import (
|
|
@@ -242,7 +232,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
242
232
|
current_player: int = 0 # id of the selected (left click) video player
|
|
243
233
|
|
|
244
234
|
mem_media_name: str = "" # record current media name. Use to check if media changed
|
|
245
|
-
mem_playlist_index:
|
|
235
|
+
mem_playlist_index: int | None = None
|
|
246
236
|
saved_state = None
|
|
247
237
|
user_move_slider: bool = False
|
|
248
238
|
observationId: str = "" # current observation id
|
|
@@ -739,7 +729,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
739
729
|
text: str = "Behaviors to show in ethogram list",
|
|
740
730
|
table: str = cfg.ETHOGRAM,
|
|
741
731
|
behavior_type: list = cfg.STATE_EVENT_TYPES,
|
|
742
|
-
) ->
|
|
732
|
+
) -> tuple[bool, list]:
|
|
743
733
|
"""
|
|
744
734
|
allow user to:
|
|
745
735
|
filter behaviors in ethogram widget
|
|
@@ -1510,15 +1500,17 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
1510
1500
|
logging.debug("previous media file")
|
|
1511
1501
|
|
|
1512
1502
|
if self.playerType == cfg.MEDIA:
|
|
1513
|
-
if len(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][cfg.PLAYER1]) == 1:
|
|
1514
|
-
|
|
1503
|
+
#if len(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.FILE][cfg.PLAYER1]) == 1:
|
|
1504
|
+
# self.seek_mediaplayer(dec(0))
|
|
1505
|
+
# return
|
|
1515
1506
|
|
|
1516
1507
|
# check if media not first media
|
|
1517
1508
|
if self.dw_player[0].player.playlist_pos > 0:
|
|
1518
1509
|
self.dw_player[0].player.playlist_prev()
|
|
1519
1510
|
|
|
1520
1511
|
elif self.dw_player[0].player.playlist_count == 1:
|
|
1521
|
-
self.
|
|
1512
|
+
self.seek_mediaplayer(dec(0))
|
|
1513
|
+
#self.statusbar.showMessage("There is only one media file", 5000)
|
|
1522
1514
|
|
|
1523
1515
|
if hasattr(self, "spectro"):
|
|
1524
1516
|
self.spectro.memChunk = -1
|
|
@@ -3682,14 +3674,18 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3682
3674
|
"""
|
|
3683
3675
|
show next frame
|
|
3684
3676
|
"""
|
|
3677
|
+
# frame_step_size = self.config_param.get(cfg.FRAME_STEP_SIZE, cfg.FRAME_STEP_SIZE_DEFAULT_VALUE)
|
|
3678
|
+
|
|
3685
3679
|
if self.playerType == cfg.IMAGES:
|
|
3686
3680
|
if self.image_idx < len(self.images_list) - 1:
|
|
3687
|
-
self.image_idx += 1
|
|
3681
|
+
self.image_idx += 1 # frame_step_size
|
|
3688
3682
|
self.extract_frame(self.dw_player[0])
|
|
3689
3683
|
|
|
3690
3684
|
if self.playerType == cfg.MEDIA:
|
|
3691
3685
|
for dw in self.dw_player:
|
|
3686
|
+
# for _ in range(frame_step_size):
|
|
3692
3687
|
dw.player.frame_step()
|
|
3688
|
+
# time.sleep(0.5)
|
|
3693
3689
|
|
|
3694
3690
|
if self.geometric_measurements_mode:
|
|
3695
3691
|
self.extract_frame(dw)
|
|
@@ -3866,7 +3862,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3866
3862
|
write_event.write_event(self, event, cumulative_time)
|
|
3867
3863
|
# write_event.write_event(self, event, self.getLaps())
|
|
3868
3864
|
|
|
3869
|
-
def get_frame_index(self, player_idx: int = 0) ->
|
|
3865
|
+
def get_frame_index(self, player_idx: int = 0) -> int | str:
|
|
3870
3866
|
"""
|
|
3871
3867
|
returns frame index for player player_idx
|
|
3872
3868
|
"""
|
|
@@ -3947,7 +3943,14 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
3947
3943
|
slider_position = self.video_slider.value() / (cfg.SLIDER_MAXIMUM - 1)
|
|
3948
3944
|
if self.dw_player[0].player.duration is None:
|
|
3949
3945
|
return
|
|
3950
|
-
|
|
3946
|
+
print(f"{slider_position=}")
|
|
3947
|
+
|
|
3948
|
+
d = self.dw_player[0].player.duration
|
|
3949
|
+
print(f"{d=}")
|
|
3950
|
+
if d is None:
|
|
3951
|
+
return
|
|
3952
|
+
video_position = slider_position * d
|
|
3953
|
+
# video_position = slider_position * self.dw_player[0].player.duration
|
|
3951
3954
|
# self.dw_player[0].player.command("seek", str(video_position), "absolute")
|
|
3952
3955
|
self.dw_player[0].player.seek(video_position, "absolute")
|
|
3953
3956
|
|
|
@@ -4142,7 +4145,22 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4142
4145
|
self.dw_player[n_player].player.playlist_pos = self.dw_player[n_player].player.playlist_count - 1
|
|
4143
4146
|
self.seek_mediaplayer(self.dw_player[n_player].media_durations[-1], player=n_player)
|
|
4144
4147
|
|
|
4145
|
-
def
|
|
4148
|
+
def activate_main_window(self):
|
|
4149
|
+
"""
|
|
4150
|
+
activate main window in order to capture keyboard events
|
|
4151
|
+
called only in IPC mode
|
|
4152
|
+
"""
|
|
4153
|
+
# check if eof reached
|
|
4154
|
+
#print(f"{self.dw_player[0].player.playlist_pos=}")
|
|
4155
|
+
#print(f"{self.dw_player[0].player.playlist_count=}")
|
|
4156
|
+
if self.dw_player[0].player.eof_reached and self.dw_player[0].player.core_idle:
|
|
4157
|
+
logging.debug("end of playlist reached")
|
|
4158
|
+
if self.dw_player[0].player.playlist_pos is not None and self.dw_player[0].player.playlist_count is not None:
|
|
4159
|
+
if self.dw_player[0].player.playlist_pos == self.dw_player[0].player.playlist_count - 1:
|
|
4160
|
+
self.pause_video()
|
|
4161
|
+
self.activateWindow()
|
|
4162
|
+
|
|
4163
|
+
def mpv_timer_out(self, value: float | None = None, scroll_slider=True):
|
|
4146
4164
|
"""
|
|
4147
4165
|
print the media current position and total length for MPV player
|
|
4148
4166
|
scroll video slider to video position
|
|
@@ -4152,13 +4170,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4152
4170
|
if not self.observationId:
|
|
4153
4171
|
return
|
|
4154
4172
|
|
|
4155
|
-
print("mpv timer out")
|
|
4156
|
-
|
|
4157
4173
|
cumulative_time_pos = self.getLaps()
|
|
4158
|
-
print(f"{cumulative_time_pos=}")
|
|
4159
4174
|
# get frame index
|
|
4160
4175
|
frame_idx = self.get_frame_index()
|
|
4161
|
-
print(f"{frame_idx=}")
|
|
4162
4176
|
# frame_idx = 0
|
|
4163
4177
|
|
|
4164
4178
|
if value is None: # ipc mpv
|
|
@@ -4205,8 +4219,9 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4205
4219
|
ct = self.getLaps(n_player=n_player)
|
|
4206
4220
|
|
|
4207
4221
|
# sync players 2..8 if time diff >= 1 s
|
|
4208
|
-
if
|
|
4209
|
-
self.
|
|
4222
|
+
if not math.isnan(ct) and not math.isnan(ct0):
|
|
4223
|
+
if abs(ct0 - (ct + dec(self.pj[cfg.OBSERVATIONS][self.observationId][cfg.MEDIA_INFO][cfg.OFFSET][str(n_player + 1)]))) >= 1:
|
|
4224
|
+
self.sync_time(n_player, ct0) # self.seek_mediaplayer(ct0, n_player)
|
|
4210
4225
|
|
|
4211
4226
|
currentTimeOffset = dec(cumulative_time_pos + self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TIME_OFFSET])
|
|
4212
4227
|
|
|
@@ -4237,12 +4252,11 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4237
4252
|
self.show_current_states_in_subjects_table()
|
|
4238
4253
|
|
|
4239
4254
|
# current media name
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
current_playlist_index = self.dw_player[0].player.playlist_pos
|
|
4255
|
+
playlist = self.dw_player[0].player.playlist
|
|
4256
|
+
playlist_pos = self.dw_player[0].player.playlist_pos
|
|
4257
|
+
if playlist is not None and playlist_pos is not None:
|
|
4258
|
+
current_media_name = Path(playlist[playlist_pos]["filename"]).name
|
|
4259
|
+
current_playlist_index = playlist_pos
|
|
4246
4260
|
else:
|
|
4247
4261
|
current_media_name = ""
|
|
4248
4262
|
current_playlist_index = None
|
|
@@ -4315,8 +4329,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4315
4329
|
|
|
4316
4330
|
self.actionPlay.setIcon(QIcon(f":/play_{gui_utilities.theme_mode()}"))
|
|
4317
4331
|
|
|
4318
|
-
print(f"{msg=}")
|
|
4319
|
-
|
|
4320
4332
|
if msg:
|
|
4321
4333
|
self.lb_current_media_time.setText(msg)
|
|
4322
4334
|
|
|
@@ -4488,7 +4500,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4488
4500
|
for x in self.pj[cfg.OBSERVATIONS][obs_id][cfg.EVENTS]
|
|
4489
4501
|
)
|
|
4490
4502
|
|
|
4491
|
-
def choose_behavior(self, obs_key) ->
|
|
4503
|
+
def choose_behavior(self, obs_key) -> None | str:
|
|
4492
4504
|
"""
|
|
4493
4505
|
fill listwidget with all behaviors coded by key
|
|
4494
4506
|
|
|
@@ -4520,7 +4532,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4520
4532
|
else:
|
|
4521
4533
|
return None
|
|
4522
4534
|
|
|
4523
|
-
def choose_subject(self, subject_key) ->
|
|
4535
|
+
def choose_subject(self, subject_key) -> None | str:
|
|
4524
4536
|
"""
|
|
4525
4537
|
fill listwidget with all subjects coded by key
|
|
4526
4538
|
|
|
@@ -4602,13 +4614,15 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4602
4614
|
|
|
4603
4615
|
if self.playerType == cfg.MEDIA:
|
|
4604
4616
|
# cumulative time
|
|
4617
|
+
if self.dw_player[n_player].player.time_pos is None:
|
|
4618
|
+
return dec("NaN")
|
|
4605
4619
|
mem_laps = sum(self.dw_player[n_player].media_durations[0 : self.dw_player[n_player].player.playlist_pos]) + (
|
|
4606
4620
|
0 if self.dw_player[n_player].player.time_pos is None else self.dw_player[n_player].player.time_pos * 1000
|
|
4607
4621
|
)
|
|
4608
4622
|
|
|
4609
4623
|
return dec(str(round(mem_laps / 1000, 3)))
|
|
4610
4624
|
|
|
4611
|
-
def get_obs_time(self, n_player: int = 0) ->
|
|
4625
|
+
def get_obs_time(self, n_player: int = 0) -> tuple[dec, dec | None]:
|
|
4612
4626
|
"""
|
|
4613
4627
|
returns time in current media and cumulative time from begining of observation
|
|
4614
4628
|
do not add time offset
|
|
@@ -4621,7 +4635,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
4621
4635
|
"""
|
|
4622
4636
|
|
|
4623
4637
|
if not self.observationId:
|
|
4624
|
-
return dec("0")
|
|
4638
|
+
return dec("0"), dec("0")
|
|
4625
4639
|
|
|
4626
4640
|
if self.pj[cfg.OBSERVATIONS][self.observationId][cfg.TYPE] == cfg.LIVE:
|
|
4627
4641
|
if "finished" in self.pb_live_obs.text():
|
|
@@ -5457,7 +5471,7 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5457
5471
|
check if first player ended
|
|
5458
5472
|
"""
|
|
5459
5473
|
|
|
5460
|
-
|
|
5474
|
+
logging.debug("play_video")
|
|
5461
5475
|
|
|
5462
5476
|
if self.geometric_measurements_mode:
|
|
5463
5477
|
return
|
|
@@ -5465,6 +5479,13 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5465
5479
|
if self.playerType != cfg.MEDIA:
|
|
5466
5480
|
return
|
|
5467
5481
|
|
|
5482
|
+
# check if playlist is ended. If it is ended restart playlist from beginning
|
|
5483
|
+
if self.dw_player[0].player.eof_reached and self.dw_player[0].player.core_idle:
|
|
5484
|
+
if self.dw_player[0].player.playlist_pos is not None and self.dw_player[0].player.playlist_count is not None:
|
|
5485
|
+
if self.dw_player[0].player.playlist_pos == self.dw_player[0].player.playlist_count - 1:
|
|
5486
|
+
self.seek_mediaplayer(dec(0))
|
|
5487
|
+
|
|
5488
|
+
|
|
5468
5489
|
# check if player 1 is ended
|
|
5469
5490
|
for i, dw in enumerate(self.dw_player):
|
|
5470
5491
|
if (
|
|
@@ -5475,9 +5496,6 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5475
5496
|
|
|
5476
5497
|
self.lb_player_status.clear()
|
|
5477
5498
|
|
|
5478
|
-
# if self.pj[cfg.OBSERVATIONS][self.observationId].get(cfg.VISUALIZE_WAVEFORM, False) \
|
|
5479
|
-
# or self.pj[cfg.OBSERVATIONS][self.observationId].get(VISUALIZE_SPECTROGRAM, False):
|
|
5480
|
-
|
|
5481
5499
|
self.statusbar.showMessage("", 0)
|
|
5482
5500
|
|
|
5483
5501
|
if self.ipc_mpv_timer is not None:
|
|
@@ -5554,16 +5572,19 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5554
5572
|
|
|
5555
5573
|
decrement = self.fast * self.play_rate if self.config_param.get(cfg.ADAPT_FAST_JUMP, cfg.ADAPT_FAST_JUMP_DEFAULT) else self.fast
|
|
5556
5574
|
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5575
|
+
try:
|
|
5576
|
+
new_time = (
|
|
5577
|
+
sum(self.dw_player[0].media_durations[0 : self.dw_player[0].player.playlist_pos]) / 1000
|
|
5578
|
+
+ self.dw_player[0].player.playback_time
|
|
5579
|
+
- decrement
|
|
5580
|
+
)
|
|
5581
|
+
except Exception:
|
|
5582
|
+
return
|
|
5562
5583
|
|
|
5563
5584
|
if new_time < decrement:
|
|
5564
5585
|
new_time = 0
|
|
5565
5586
|
|
|
5566
|
-
self.seek_mediaplayer(new_time)
|
|
5587
|
+
self.seek_mediaplayer(dec(new_time))
|
|
5567
5588
|
|
|
5568
5589
|
self.update_visualizations()
|
|
5569
5590
|
|
|
@@ -5577,13 +5598,16 @@ class MainWindow(QMainWindow, Ui_MainWindow):
|
|
|
5577
5598
|
|
|
5578
5599
|
logging.info(f"Jump forward for {increment} seconds")
|
|
5579
5600
|
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5601
|
+
try:
|
|
5602
|
+
new_time = (
|
|
5603
|
+
sum(self.dw_player[0].media_durations[0 : self.dw_player[0].player.playlist_pos]) / 1000
|
|
5604
|
+
+ self.dw_player[0].player.playback_time
|
|
5605
|
+
+ increment
|
|
5606
|
+
)
|
|
5607
|
+
except Exception:
|
|
5608
|
+
return
|
|
5585
5609
|
|
|
5586
|
-
self.seek_mediaplayer(new_time)
|
|
5610
|
+
self.seek_mediaplayer(dec(new_time))
|
|
5587
5611
|
|
|
5588
5612
|
self.update_visualizations()
|
|
5589
5613
|
|
|
@@ -5839,6 +5863,15 @@ def main():
|
|
|
5839
5863
|
)
|
|
5840
5864
|
sys.exit()
|
|
5841
5865
|
|
|
5866
|
+
if sys.platform.startswith("darwin"):
|
|
5867
|
+
QMessageBox.warning(
|
|
5868
|
+
None,
|
|
5869
|
+
cfg.programName,
|
|
5870
|
+
(f"This version of BORIS for macOS is still EXPERIMENTAL and should be used at your own risk."),
|
|
5871
|
+
QMessageBox.Ok | QMessageBox.Default,
|
|
5872
|
+
QMessageBox.NoButton,
|
|
5873
|
+
)
|
|
5874
|
+
|
|
5842
5875
|
window.show()
|
|
5843
5876
|
window.raise_() # for overlapping widget (?)
|
|
5844
5877
|
|
|
@@ -5865,3 +5898,4 @@ def main():
|
|
|
5865
5898
|
del window
|
|
5866
5899
|
|
|
5867
5900
|
sys.exit(return_code)
|
|
5901
|
+
|