boris-behav-obs 9.7.7__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 +26 -0
- boris/__main__.py +25 -0
- boris/about.py +143 -0
- boris/add_modifier.py +635 -0
- boris/add_modifier_ui.py +303 -0
- boris/advanced_event_filtering.py +455 -0
- boris/analysis_plugins/__init__.py +0 -0
- boris/analysis_plugins/_latency.py +59 -0
- boris/analysis_plugins/irr_cohen_kappa.py +109 -0
- boris/analysis_plugins/irr_cohen_kappa_with_modifiers.py +112 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa.py +157 -0
- boris/analysis_plugins/irr_weighted_cohen_kappa_with_modifiers.py +162 -0
- boris/analysis_plugins/list_of_dataframe_columns.py +22 -0
- boris/analysis_plugins/number_of_occurences.py +22 -0
- boris/analysis_plugins/number_of_occurences_by_independent_variable.py +54 -0
- boris/analysis_plugins/time_budget.py +61 -0
- boris/behav_coding_map_creator.py +1110 -0
- boris/behavior_binary_table.py +305 -0
- boris/behaviors_coding_map.py +239 -0
- boris/boris_cli.py +340 -0
- boris/cmd_arguments.py +49 -0
- boris/coding_pad.py +280 -0
- boris/config.py +785 -0
- boris/config_file.py +356 -0
- boris/connections.py +409 -0
- boris/converters.py +333 -0
- boris/converters_ui.py +225 -0
- boris/cooccurence.py +250 -0
- boris/core.py +5901 -0
- boris/core_qrc.py +15958 -0
- boris/core_ui.py +1107 -0
- boris/db_functions.py +324 -0
- boris/dev.py +134 -0
- boris/dialog.py +1108 -0
- boris/duration_widget.py +238 -0
- boris/edit_event.py +245 -0
- boris/edit_event_ui.py +233 -0
- boris/event_operations.py +1040 -0
- boris/events_cursor.py +61 -0
- boris/events_snapshots.py +596 -0
- boris/exclusion_matrix.py +141 -0
- boris/export_events.py +1006 -0
- boris/export_observation.py +1203 -0
- boris/external_processes.py +332 -0
- boris/geometric_measurement.py +941 -0
- boris/gui_utilities.py +135 -0
- boris/image_overlay.py +72 -0
- boris/import_observations.py +242 -0
- boris/ipc_mpv.py +325 -0
- boris/irr.py +634 -0
- boris/latency.py +244 -0
- boris/measurement_widget.py +161 -0
- boris/media_file.py +115 -0
- boris/menu_options.py +213 -0
- boris/modifier_coding_map_creator.py +1013 -0
- boris/modifiers_coding_map.py +157 -0
- boris/mpv.py +2016 -0
- boris/mpv2.py +2193 -0
- boris/observation.py +1453 -0
- boris/observation_operations.py +2538 -0
- boris/observation_ui.py +679 -0
- boris/observations_list.py +337 -0
- boris/otx_parser.py +442 -0
- boris/param_panel.py +201 -0
- boris/param_panel_ui.py +305 -0
- boris/player_dock_widget.py +198 -0
- boris/plot_data_module.py +536 -0
- boris/plot_events.py +634 -0
- boris/plot_events_rt.py +237 -0
- boris/plot_spectrogram_rt.py +316 -0
- boris/plot_waveform_rt.py +230 -0
- boris/plugins.py +431 -0
- boris/portion/__init__.py +31 -0
- boris/portion/const.py +95 -0
- boris/portion/dict.py +365 -0
- boris/portion/func.py +52 -0
- boris/portion/interval.py +581 -0
- boris/portion/io.py +181 -0
- boris/preferences.py +510 -0
- boris/preferences_ui.py +770 -0
- boris/project.py +2007 -0
- boris/project_functions.py +2041 -0
- boris/project_import_export.py +1096 -0
- boris/project_ui.py +794 -0
- boris/qrc_boris.py +10389 -0
- boris/qrc_boris5.py +2579 -0
- boris/select_modifiers.py +312 -0
- boris/select_observations.py +210 -0
- boris/select_subj_behav.py +286 -0
- boris/state_events.py +197 -0
- boris/subjects_pad.py +106 -0
- boris/synthetic_time_budget.py +290 -0
- boris/time_budget_functions.py +1136 -0
- boris/time_budget_widget.py +1039 -0
- boris/transitions.py +365 -0
- boris/utilities.py +1810 -0
- boris/version.py +24 -0
- boris/video_equalizer.py +159 -0
- boris/video_equalizer_ui.py +248 -0
- boris/video_operations.py +310 -0
- boris/view_df.py +104 -0
- boris/view_df_ui.py +75 -0
- boris/write_event.py +538 -0
- boris_behav_obs-9.7.7.dist-info/METADATA +139 -0
- boris_behav_obs-9.7.7.dist-info/RECORD +109 -0
- boris_behav_obs-9.7.7.dist-info/WHEEL +5 -0
- boris_behav_obs-9.7.7.dist-info/entry_points.txt +2 -0
- boris_behav_obs-9.7.7.dist-info/licenses/LICENSE.TXT +674 -0
- boris_behav_obs-9.7.7.dist-info/top_level.txt +1 -0
boris/converters.py
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
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
|
+
|
|
23
|
+
import sys
|
|
24
|
+
import json
|
|
25
|
+
import urllib.request
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
from PySide6.QtWidgets import QMessageBox, QTableWidgetItem, QFileDialog, QInputDialog, QLineEdit
|
|
29
|
+
|
|
30
|
+
from . import dialog
|
|
31
|
+
from . import config as cfg
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def pb_code_help_clicked(self):
|
|
35
|
+
"""
|
|
36
|
+
help for writing converters
|
|
37
|
+
"""
|
|
38
|
+
msg = QMessageBox()
|
|
39
|
+
msg.setIcon(QMessageBox.Information)
|
|
40
|
+
msg.setWindowTitle("Help for writing converters")
|
|
41
|
+
|
|
42
|
+
msg.setText(
|
|
43
|
+
(
|
|
44
|
+
"A converter is a function that will convert a time value from external data into seconds.<br>"
|
|
45
|
+
"A time value like 00:23:59 must be converted into seconds before to be plotted synchronously with your media.<br>"
|
|
46
|
+
"For this you can use BORIS native converters or write your own converter.<br>"
|
|
47
|
+
'A converter must be written using the <a href="www.python.org">Python3</a> language.<br>'
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# msg.setInformativeText("This is additional information")
|
|
52
|
+
|
|
53
|
+
msg.setStandardButtons(QMessageBox.Ok)
|
|
54
|
+
msg.exec_()
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def add_converter(self):
|
|
58
|
+
"""
|
|
59
|
+
Add a new converter
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
for w in [
|
|
63
|
+
self.le_converter_name,
|
|
64
|
+
self.le_converter_description,
|
|
65
|
+
self.pteCode,
|
|
66
|
+
self.pb_save_converter,
|
|
67
|
+
self.pb_cancel_converter,
|
|
68
|
+
]:
|
|
69
|
+
w.setEnabled(True)
|
|
70
|
+
# disable buttons
|
|
71
|
+
for w in [
|
|
72
|
+
self.pb_add_converter,
|
|
73
|
+
self.pb_modify_converter,
|
|
74
|
+
self.pb_delete_converter,
|
|
75
|
+
self.pb_load_from_file,
|
|
76
|
+
self.pb_load_from_repo,
|
|
77
|
+
self.tw_converters,
|
|
78
|
+
]:
|
|
79
|
+
w.setEnabled(False)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def modify_converter(self):
|
|
83
|
+
"""
|
|
84
|
+
Modifiy the selected converter
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
if not self.tw_converters.selectedIndexes():
|
|
88
|
+
QMessageBox.warning(self, cfg.programName, "Select a converter in the table")
|
|
89
|
+
return
|
|
90
|
+
|
|
91
|
+
for w in [
|
|
92
|
+
self.le_converter_name,
|
|
93
|
+
self.le_converter_description,
|
|
94
|
+
self.pteCode,
|
|
95
|
+
self.pb_save_converter,
|
|
96
|
+
self.pb_cancel_converter,
|
|
97
|
+
]:
|
|
98
|
+
w.setEnabled(True)
|
|
99
|
+
|
|
100
|
+
# disable buttons
|
|
101
|
+
for w in [
|
|
102
|
+
self.pb_add_converter,
|
|
103
|
+
self.pb_modify_converter,
|
|
104
|
+
self.pb_delete_converter,
|
|
105
|
+
self.pb_load_from_file,
|
|
106
|
+
self.pb_load_from_repo,
|
|
107
|
+
self.tw_converters,
|
|
108
|
+
]:
|
|
109
|
+
w.setEnabled(False)
|
|
110
|
+
|
|
111
|
+
self.le_converter_name.setText(self.tw_converters.item(self.tw_converters.selectedIndexes()[0].row(), 0).text())
|
|
112
|
+
self.le_converter_description.setText(self.tw_converters.item(self.tw_converters.selectedIndexes()[0].row(), 1).text())
|
|
113
|
+
self.pteCode.setPlainText(self.tw_converters.item(self.tw_converters.selectedIndexes()[0].row(), 2).text().replace("@", "\n"))
|
|
114
|
+
|
|
115
|
+
self.row_in_modification = self.tw_converters.selectedIndexes()[0].row()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def code_2_func(self, name: str, code: str):
|
|
119
|
+
"""
|
|
120
|
+
convert code to function
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
name (str): function name
|
|
124
|
+
code (str): Python code
|
|
125
|
+
|
|
126
|
+
Returns:
|
|
127
|
+
str: string containing Python function
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
function = f"def {name}(INPUT):\n"
|
|
131
|
+
function += """ INPUT = INPUT.decode("utf-8") if isinstance(INPUT, bytes) else INPUT\n"""
|
|
132
|
+
function += "\n".join([" " + row for row in code.split("\n")])
|
|
133
|
+
function += "\n return OUTPUT"
|
|
134
|
+
|
|
135
|
+
return function
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def save_converter(self):
|
|
139
|
+
"""Save converter"""
|
|
140
|
+
|
|
141
|
+
# check if name
|
|
142
|
+
self.le_converter_name.setText(self.le_converter_name.text().strip())
|
|
143
|
+
if not self.le_converter_name.text():
|
|
144
|
+
QMessageBox.critical(self, "BORIS", "The converter must have a name")
|
|
145
|
+
return
|
|
146
|
+
|
|
147
|
+
if not self.le_converter_name.text().replace("_", "a").isalnum():
|
|
148
|
+
QMessageBox.critical(self, "BORIS", "Forbidden characters are used in converter name.<br>Use a..z, A..Z, 0..9 _")
|
|
149
|
+
return
|
|
150
|
+
|
|
151
|
+
# test code with exec
|
|
152
|
+
code: str = self.pteCode.toPlainText()
|
|
153
|
+
if not code:
|
|
154
|
+
QMessageBox.critical(self, "BORIS", "The converter must have Python code")
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
function = code_2_func(self, name=self.le_converter_name.text(), code=code)
|
|
158
|
+
|
|
159
|
+
try:
|
|
160
|
+
exec(function)
|
|
161
|
+
except Exception:
|
|
162
|
+
QMessageBox.critical(self, "BORIS", f"The code produces an error:<br><b>{sys.exc_info()[1]}</b>")
|
|
163
|
+
return
|
|
164
|
+
|
|
165
|
+
if self.row_in_modification == -1:
|
|
166
|
+
self.tw_converters.setRowCount(self.tw_converters.rowCount() + 1)
|
|
167
|
+
row = self.tw_converters.rowCount() - 1
|
|
168
|
+
else:
|
|
169
|
+
row = self.row_in_modification
|
|
170
|
+
|
|
171
|
+
self.tw_converters.setItem(row, 0, QTableWidgetItem(self.le_converter_name.text()))
|
|
172
|
+
self.tw_converters.setItem(row, 1, QTableWidgetItem(self.le_converter_description.text()))
|
|
173
|
+
self.tw_converters.setItem(row, 2, QTableWidgetItem(self.pteCode.toPlainText().replace("\n", "@")))
|
|
174
|
+
|
|
175
|
+
self.row_in_modification = -1
|
|
176
|
+
|
|
177
|
+
for w in [self.le_converter_name, self.le_converter_description, self.pteCode]:
|
|
178
|
+
w.setEnabled(False)
|
|
179
|
+
w.clear()
|
|
180
|
+
self.pb_save_converter.setEnabled(False)
|
|
181
|
+
self.pb_cancel_converter.setEnabled(False)
|
|
182
|
+
self.tw_converters.setEnabled(True)
|
|
183
|
+
|
|
184
|
+
self.flag_modified = True
|
|
185
|
+
|
|
186
|
+
# enable buttons
|
|
187
|
+
for w in [
|
|
188
|
+
self.pb_add_converter,
|
|
189
|
+
self.pb_modify_converter,
|
|
190
|
+
self.pb_delete_converter,
|
|
191
|
+
self.pb_load_from_file,
|
|
192
|
+
self.pb_load_from_repo,
|
|
193
|
+
self.tw_converters,
|
|
194
|
+
]:
|
|
195
|
+
w.setEnabled(True)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def cancel_converter(self):
|
|
199
|
+
"""Cancel converter"""
|
|
200
|
+
|
|
201
|
+
for w in [self.le_converter_name, self.le_converter_description, self.pteCode]:
|
|
202
|
+
w.setEnabled(False)
|
|
203
|
+
w.clear()
|
|
204
|
+
self.pb_save_converter.setEnabled(False)
|
|
205
|
+
self.pb_cancel_converter.setEnabled(False)
|
|
206
|
+
|
|
207
|
+
# enable buttons
|
|
208
|
+
for w in [
|
|
209
|
+
self.pb_add_converter,
|
|
210
|
+
self.pb_modify_converter,
|
|
211
|
+
self.pb_delete_converter,
|
|
212
|
+
self.pb_load_from_file,
|
|
213
|
+
self.pb_load_from_repo,
|
|
214
|
+
self.tw_converters,
|
|
215
|
+
]:
|
|
216
|
+
w.setEnabled(True)
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def delete_converter(self):
|
|
220
|
+
"""
|
|
221
|
+
Delete selected converter
|
|
222
|
+
"""
|
|
223
|
+
|
|
224
|
+
if self.tw_converters.selectedIndexes():
|
|
225
|
+
if dialog.MessageDialog("BORIS", "Confirm converter deletion", [cfg.CANCEL, cfg.OK]) == cfg.OK:
|
|
226
|
+
self.tw_converters.removeRow(self.tw_converters.selectedIndexes()[0].row())
|
|
227
|
+
else:
|
|
228
|
+
QMessageBox.warning(self, cfg.programName, "Select a converter in the table")
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
def load_converters_from_file_repo(self, mode: str):
|
|
232
|
+
"""
|
|
233
|
+
Load converters from file (JSON) or BORIS remote repository
|
|
234
|
+
Args:
|
|
235
|
+
mode (str): string "repo" or "file"
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
converters_from_file = {}
|
|
239
|
+
if mode == "file":
|
|
240
|
+
file_name, _ = QFileDialog.getOpenFileName(self, "Load converters from file", "", "All files (*)")
|
|
241
|
+
|
|
242
|
+
if file_name:
|
|
243
|
+
with open(file_name, "r") as f_in:
|
|
244
|
+
try:
|
|
245
|
+
converters_from_file = json.loads(f_in.read())["BORIS converters"]
|
|
246
|
+
except Exception:
|
|
247
|
+
QMessageBox.critical(self, cfg.programName, "This file does not contain converters...")
|
|
248
|
+
return
|
|
249
|
+
|
|
250
|
+
if mode == "repo":
|
|
251
|
+
converters_repo_URL = "https://www.boris.unito.it/static/converters.json"
|
|
252
|
+
try:
|
|
253
|
+
converters_from_repo = urllib.request.urlopen(converters_repo_URL).read().strip().decode("utf-8")
|
|
254
|
+
except Exception:
|
|
255
|
+
QMessageBox.critical(self, cfg.programName, "An error occured during retrieving converters from BORIS remote repository")
|
|
256
|
+
return
|
|
257
|
+
|
|
258
|
+
try:
|
|
259
|
+
converters_from_file = eval(converters_from_repo)["BORIS converters"]
|
|
260
|
+
except Exception:
|
|
261
|
+
QMessageBox.critical(self, cfg.programName, "An error occured during retrieving converters from BORIS remote repository")
|
|
262
|
+
return
|
|
263
|
+
|
|
264
|
+
if converters_from_file:
|
|
265
|
+
diag_choose_conv = dialog.ChooseObservationsToImport("Choose the converters to load:", sorted(list(converters_from_file.keys())))
|
|
266
|
+
|
|
267
|
+
if diag_choose_conv.exec_():
|
|
268
|
+
selected_converters = diag_choose_conv.get_selected_observations()
|
|
269
|
+
if selected_converters:
|
|
270
|
+
# extract converter names from table
|
|
271
|
+
converter_names = []
|
|
272
|
+
for row in range(self.tw_converters.rowCount()):
|
|
273
|
+
converter_names.append(self.tw_converters.item(row, 0).text())
|
|
274
|
+
|
|
275
|
+
for converter in selected_converters:
|
|
276
|
+
converter_name = converter
|
|
277
|
+
|
|
278
|
+
if converter in converter_names:
|
|
279
|
+
while True:
|
|
280
|
+
text, ok = QInputDialog.getText(
|
|
281
|
+
self,
|
|
282
|
+
"Converter conflict",
|
|
283
|
+
"The converter already exists<br>Rename it:",
|
|
284
|
+
QLineEdit.Normal,
|
|
285
|
+
converter,
|
|
286
|
+
)
|
|
287
|
+
if not ok:
|
|
288
|
+
break
|
|
289
|
+
if text in converter_names:
|
|
290
|
+
QMessageBox.critical(self, cfg.programName, "This name already exists in converters")
|
|
291
|
+
|
|
292
|
+
if not text.replace("_", "a").isalnum():
|
|
293
|
+
QMessageBox.critical(
|
|
294
|
+
self,
|
|
295
|
+
cfg.programName,
|
|
296
|
+
"This name contains forbidden character(s).<br>Use a..z, A..Z, 0..9 _",
|
|
297
|
+
)
|
|
298
|
+
|
|
299
|
+
if text != converter and text not in converter_names and text.replace("_", "a").isalnum():
|
|
300
|
+
break
|
|
301
|
+
|
|
302
|
+
if ok:
|
|
303
|
+
converter_name = text
|
|
304
|
+
else:
|
|
305
|
+
continue
|
|
306
|
+
# test if code does not produce error
|
|
307
|
+
function = code_2_func(self, name=converter_name, code=converters_from_file[converter]["code"])
|
|
308
|
+
|
|
309
|
+
try:
|
|
310
|
+
exec(function)
|
|
311
|
+
except Exception:
|
|
312
|
+
QMessageBox.critical(
|
|
313
|
+
self,
|
|
314
|
+
"BORIS",
|
|
315
|
+
(f"The code of {converter_name} converter produces an error: <br><b>{sys.exc_info()[1]}</b>"),
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
self.tw_converters.setRowCount(self.tw_converters.rowCount() + 1)
|
|
319
|
+
self.tw_converters.setItem(self.tw_converters.rowCount() - 1, 0, QTableWidgetItem(converter_name))
|
|
320
|
+
self.tw_converters.setItem(
|
|
321
|
+
self.tw_converters.rowCount() - 1,
|
|
322
|
+
1,
|
|
323
|
+
QTableWidgetItem(converters_from_file[converter]["description"]),
|
|
324
|
+
)
|
|
325
|
+
self.tw_converters.setItem(
|
|
326
|
+
self.tw_converters.rowCount() - 1,
|
|
327
|
+
2,
|
|
328
|
+
QTableWidgetItem(converters_from_file[converter]["code"].replace("\n", "@")),
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
self.flag_modified = True
|
|
332
|
+
|
|
333
|
+
[self.tw_converters.resizeColumnToContents(idx) for idx in [0, 1]]
|
boris/converters_ui.py
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
|
|
3
|
+
################################################################################
|
|
4
|
+
## Form generated from reading UI file 'converters.ui'
|
|
5
|
+
##
|
|
6
|
+
## Created by: Qt User Interface Compiler version 6.8.0
|
|
7
|
+
##
|
|
8
|
+
## WARNING! All changes made in this file will be lost when recompiling UI file!
|
|
9
|
+
################################################################################
|
|
10
|
+
|
|
11
|
+
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
|
|
12
|
+
QMetaObject, QObject, QPoint, QRect,
|
|
13
|
+
QSize, QTime, QUrl, Qt)
|
|
14
|
+
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
|
|
15
|
+
QFont, QFontDatabase, QGradient, QIcon,
|
|
16
|
+
QImage, QKeySequence, QLinearGradient, QPainter,
|
|
17
|
+
QPalette, QPixmap, QRadialGradient, QTransform)
|
|
18
|
+
from PySide6.QtWidgets import (QAbstractItemView, QApplication, QHBoxLayout, QHeaderView,
|
|
19
|
+
QLabel, QLineEdit, QPlainTextEdit, QPushButton,
|
|
20
|
+
QSizePolicy, QSpacerItem, QTableWidget, QTableWidgetItem,
|
|
21
|
+
QVBoxLayout, QWidget)
|
|
22
|
+
|
|
23
|
+
class Ui_converters(object):
|
|
24
|
+
def setupUi(self, converters):
|
|
25
|
+
if not converters.objectName():
|
|
26
|
+
converters.setObjectName(u"converters")
|
|
27
|
+
converters.resize(1029, 530)
|
|
28
|
+
self.verticalLayout = QVBoxLayout(converters)
|
|
29
|
+
self.verticalLayout.setObjectName(u"verticalLayout")
|
|
30
|
+
self.label_4 = QLabel(converters)
|
|
31
|
+
self.label_4.setObjectName(u"label_4")
|
|
32
|
+
|
|
33
|
+
self.verticalLayout.addWidget(self.label_4)
|
|
34
|
+
|
|
35
|
+
self.tw_converters = QTableWidget(converters)
|
|
36
|
+
if (self.tw_converters.columnCount() < 3):
|
|
37
|
+
self.tw_converters.setColumnCount(3)
|
|
38
|
+
__qtablewidgetitem = QTableWidgetItem()
|
|
39
|
+
self.tw_converters.setHorizontalHeaderItem(0, __qtablewidgetitem)
|
|
40
|
+
__qtablewidgetitem1 = QTableWidgetItem()
|
|
41
|
+
self.tw_converters.setHorizontalHeaderItem(1, __qtablewidgetitem1)
|
|
42
|
+
__qtablewidgetitem2 = QTableWidgetItem()
|
|
43
|
+
self.tw_converters.setHorizontalHeaderItem(2, __qtablewidgetitem2)
|
|
44
|
+
self.tw_converters.setObjectName(u"tw_converters")
|
|
45
|
+
self.tw_converters.setEditTriggers(QAbstractItemView.NoEditTriggers)
|
|
46
|
+
self.tw_converters.setSelectionMode(QAbstractItemView.SingleSelection)
|
|
47
|
+
self.tw_converters.setSelectionBehavior(QAbstractItemView.SelectRows)
|
|
48
|
+
self.tw_converters.setSortingEnabled(True)
|
|
49
|
+
|
|
50
|
+
self.verticalLayout.addWidget(self.tw_converters)
|
|
51
|
+
|
|
52
|
+
self.horizontalLayout = QHBoxLayout()
|
|
53
|
+
self.horizontalLayout.setObjectName(u"horizontalLayout")
|
|
54
|
+
self.pb_add_converter = QPushButton(converters)
|
|
55
|
+
self.pb_add_converter.setObjectName(u"pb_add_converter")
|
|
56
|
+
|
|
57
|
+
self.horizontalLayout.addWidget(self.pb_add_converter)
|
|
58
|
+
|
|
59
|
+
self.pb_modify_converter = QPushButton(converters)
|
|
60
|
+
self.pb_modify_converter.setObjectName(u"pb_modify_converter")
|
|
61
|
+
|
|
62
|
+
self.horizontalLayout.addWidget(self.pb_modify_converter)
|
|
63
|
+
|
|
64
|
+
self.pb_delete_converter = QPushButton(converters)
|
|
65
|
+
self.pb_delete_converter.setObjectName(u"pb_delete_converter")
|
|
66
|
+
|
|
67
|
+
self.horizontalLayout.addWidget(self.pb_delete_converter)
|
|
68
|
+
|
|
69
|
+
self.pb_load_from_file = QPushButton(converters)
|
|
70
|
+
self.pb_load_from_file.setObjectName(u"pb_load_from_file")
|
|
71
|
+
|
|
72
|
+
self.horizontalLayout.addWidget(self.pb_load_from_file)
|
|
73
|
+
|
|
74
|
+
self.pb_load_from_repo = QPushButton(converters)
|
|
75
|
+
self.pb_load_from_repo.setObjectName(u"pb_load_from_repo")
|
|
76
|
+
|
|
77
|
+
self.horizontalLayout.addWidget(self.pb_load_from_repo)
|
|
78
|
+
|
|
79
|
+
self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
80
|
+
|
|
81
|
+
self.horizontalLayout.addItem(self.horizontalSpacer)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
self.verticalLayout.addLayout(self.horizontalLayout)
|
|
85
|
+
|
|
86
|
+
self.horizontalLayout_3 = QHBoxLayout()
|
|
87
|
+
self.horizontalLayout_3.setObjectName(u"horizontalLayout_3")
|
|
88
|
+
self.label_2 = QLabel(converters)
|
|
89
|
+
self.label_2.setObjectName(u"label_2")
|
|
90
|
+
self.label_2.setMinimumSize(QSize(120, 0))
|
|
91
|
+
|
|
92
|
+
self.horizontalLayout_3.addWidget(self.label_2)
|
|
93
|
+
|
|
94
|
+
self.le_converter_name = QLineEdit(converters)
|
|
95
|
+
self.le_converter_name.setObjectName(u"le_converter_name")
|
|
96
|
+
|
|
97
|
+
self.horizontalLayout_3.addWidget(self.le_converter_name)
|
|
98
|
+
|
|
99
|
+
self.horizontalSpacer_3 = QSpacerItem(10, 20, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
|
100
|
+
|
|
101
|
+
self.horizontalLayout_3.addItem(self.horizontalSpacer_3)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
self.verticalLayout.addLayout(self.horizontalLayout_3)
|
|
105
|
+
|
|
106
|
+
self.horizontalLayout_5 = QHBoxLayout()
|
|
107
|
+
self.horizontalLayout_5.setObjectName(u"horizontalLayout_5")
|
|
108
|
+
self.label_3 = QLabel(converters)
|
|
109
|
+
self.label_3.setObjectName(u"label_3")
|
|
110
|
+
self.label_3.setMinimumSize(QSize(120, 0))
|
|
111
|
+
|
|
112
|
+
self.horizontalLayout_5.addWidget(self.label_3)
|
|
113
|
+
|
|
114
|
+
self.le_converter_description = QLineEdit(converters)
|
|
115
|
+
self.le_converter_description.setObjectName(u"le_converter_description")
|
|
116
|
+
|
|
117
|
+
self.horizontalLayout_5.addWidget(self.le_converter_description)
|
|
118
|
+
|
|
119
|
+
self.horizontalSpacer_4 = QSpacerItem(10, 20, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
|
120
|
+
|
|
121
|
+
self.horizontalLayout_5.addItem(self.horizontalSpacer_4)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
self.verticalLayout.addLayout(self.horizontalLayout_5)
|
|
125
|
+
|
|
126
|
+
self.horizontalLayout_2 = QHBoxLayout()
|
|
127
|
+
self.horizontalLayout_2.setObjectName(u"horizontalLayout_2")
|
|
128
|
+
self.verticalLayout_3 = QVBoxLayout()
|
|
129
|
+
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
|
|
130
|
+
self.label = QLabel(converters)
|
|
131
|
+
self.label.setObjectName(u"label")
|
|
132
|
+
|
|
133
|
+
self.verticalLayout_3.addWidget(self.label)
|
|
134
|
+
|
|
135
|
+
self.pb_code_help = QPushButton(converters)
|
|
136
|
+
self.pb_code_help.setObjectName(u"pb_code_help")
|
|
137
|
+
|
|
138
|
+
self.verticalLayout_3.addWidget(self.pb_code_help)
|
|
139
|
+
|
|
140
|
+
self.verticalSpacer_2 = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
|
141
|
+
|
|
142
|
+
self.verticalLayout_3.addItem(self.verticalSpacer_2)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
self.horizontalLayout_2.addLayout(self.verticalLayout_3)
|
|
146
|
+
|
|
147
|
+
self.pteCode = QPlainTextEdit(converters)
|
|
148
|
+
self.pteCode.setObjectName(u"pteCode")
|
|
149
|
+
font = QFont()
|
|
150
|
+
font.setFamilies([u"Monospace"])
|
|
151
|
+
self.pteCode.setFont(font)
|
|
152
|
+
|
|
153
|
+
self.horizontalLayout_2.addWidget(self.pteCode)
|
|
154
|
+
|
|
155
|
+
self.verticalLayout_2 = QVBoxLayout()
|
|
156
|
+
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
|
|
157
|
+
self.pb_save_converter = QPushButton(converters)
|
|
158
|
+
self.pb_save_converter.setObjectName(u"pb_save_converter")
|
|
159
|
+
|
|
160
|
+
self.verticalLayout_2.addWidget(self.pb_save_converter)
|
|
161
|
+
|
|
162
|
+
self.pb_cancel_converter = QPushButton(converters)
|
|
163
|
+
self.pb_cancel_converter.setObjectName(u"pb_cancel_converter")
|
|
164
|
+
|
|
165
|
+
self.verticalLayout_2.addWidget(self.pb_cancel_converter)
|
|
166
|
+
|
|
167
|
+
self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Expanding)
|
|
168
|
+
|
|
169
|
+
self.verticalLayout_2.addItem(self.verticalSpacer)
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
|
176
|
+
|
|
177
|
+
self.horizontalLayout_4 = QHBoxLayout()
|
|
178
|
+
self.horizontalLayout_4.setObjectName(u"horizontalLayout_4")
|
|
179
|
+
self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum)
|
|
180
|
+
|
|
181
|
+
self.horizontalLayout_4.addItem(self.horizontalSpacer_2)
|
|
182
|
+
|
|
183
|
+
self.pb_cancel_widget = QPushButton(converters)
|
|
184
|
+
self.pb_cancel_widget.setObjectName(u"pb_cancel_widget")
|
|
185
|
+
|
|
186
|
+
self.horizontalLayout_4.addWidget(self.pb_cancel_widget)
|
|
187
|
+
|
|
188
|
+
self.pbOK = QPushButton(converters)
|
|
189
|
+
self.pbOK.setObjectName(u"pbOK")
|
|
190
|
+
|
|
191
|
+
self.horizontalLayout_4.addWidget(self.pbOK)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
self.verticalLayout.addLayout(self.horizontalLayout_4)
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
self.retranslateUi(converters)
|
|
198
|
+
|
|
199
|
+
QMetaObject.connectSlotsByName(converters)
|
|
200
|
+
# setupUi
|
|
201
|
+
|
|
202
|
+
def retranslateUi(self, converters):
|
|
203
|
+
converters.setWindowTitle(QCoreApplication.translate("converters", u"Time converters", None))
|
|
204
|
+
self.label_4.setText(QCoreApplication.translate("converters", u"Converters", None))
|
|
205
|
+
___qtablewidgetitem = self.tw_converters.horizontalHeaderItem(0)
|
|
206
|
+
___qtablewidgetitem.setText(QCoreApplication.translate("converters", u"Name", None));
|
|
207
|
+
___qtablewidgetitem1 = self.tw_converters.horizontalHeaderItem(1)
|
|
208
|
+
___qtablewidgetitem1.setText(QCoreApplication.translate("converters", u"Description", None));
|
|
209
|
+
___qtablewidgetitem2 = self.tw_converters.horizontalHeaderItem(2)
|
|
210
|
+
___qtablewidgetitem2.setText(QCoreApplication.translate("converters", u"Code", None));
|
|
211
|
+
self.pb_add_converter.setText(QCoreApplication.translate("converters", u"Add new converter", None))
|
|
212
|
+
self.pb_modify_converter.setText(QCoreApplication.translate("converters", u"Modify converter", None))
|
|
213
|
+
self.pb_delete_converter.setText(QCoreApplication.translate("converters", u"Delete converter", None))
|
|
214
|
+
self.pb_load_from_file.setText(QCoreApplication.translate("converters", u"Load converters from file", None))
|
|
215
|
+
self.pb_load_from_repo.setText(QCoreApplication.translate("converters", u"Load converters from BORIS repository", None))
|
|
216
|
+
self.label_2.setText(QCoreApplication.translate("converters", u"Name", None))
|
|
217
|
+
self.label_3.setText(QCoreApplication.translate("converters", u"Description", None))
|
|
218
|
+
self.label.setText(QCoreApplication.translate("converters", u"Python code", None))
|
|
219
|
+
self.pb_code_help.setText(QCoreApplication.translate("converters", u"Help", None))
|
|
220
|
+
self.pb_save_converter.setText(QCoreApplication.translate("converters", u"Save converter", None))
|
|
221
|
+
self.pb_cancel_converter.setText(QCoreApplication.translate("converters", u"Cancel", None))
|
|
222
|
+
self.pb_cancel_widget.setText(QCoreApplication.translate("converters", u"Cancel", None))
|
|
223
|
+
self.pbOK.setText(QCoreApplication.translate("converters", u"OK", None))
|
|
224
|
+
# retranslateUi
|
|
225
|
+
|