1
2
3
4 """ pyforms.gui.Controls.ControlEventTimeline.ControlEventTimeline
5
6 """
7
8 import csv
9 import os
10 from PyQt4 import QtGui, QtCore
11 from pyforms.gui.Controls.ControlBase import ControlBase
12 from pyforms.gui.Controls.ControlEventTimeline.TimelineWidget import TimelineWidget
13 from pyforms.gui.Controls.ControlEventTimeline.TimelinePopupWindow import TimelinePopupWindow
14
15
16 __author__ = ["Ricardo Ribeiro", "Hugo Cachitas"]
17 __credits__ = ["Ricardo Ribeiro", "Hugo Cachitas"]
18 __license__ = "MIT"
19 __version__ = "0.0"
20 __maintainer__ = "Ricardo Ribeiro"
21 __email__ = "ricardojvr@gmail.com"
22 __status__ = "Development"
26 """
27 Timeline events editor
28 """
29
30 - def __init__(self, label="", defaultValue=0, min=0, max=100, **kwargs):
31 QtGui.QWidget.__init__(self)
32 ControlBase.__init__(self, label, defaultValue, **kwargs)
33 self._max = 100
34
35
36 self._deltaLockAction = self.addPopupMenuOption(
37 "Lock", self.__lockSelected, key='L')
38 self._deltaColorAction = self.addPopupMenuOption(
39 "Pick a color", self.__pickColor)
40 self._deltaRemoveAction = self.addPopupMenuOption(
41 "Remove", self.__removeSelected, key='Delete')
42 self._deltaActions = [self._deltaLockAction,
43 self._deltaColorAction,
44 self._deltaRemoveAction]
45
46 for action in self._deltaActions:
47 action.setVisible(False)
48 self.addPopupMenuOption("-")
49
50
51 self.addPopupMenuOption(
52 "Set track properties...", self.__setLinePropertiesEvent)
53 self.addPopupMenuOption("-")
54 self.addPopupSubMenuOption(
55 "Import/Export", {'Export to CSV': self.__export, 'Import to CSV': self.__import})
56 self.addPopupMenuOption("-")
57 self.addPopupSubMenuOption("Clean", {
58 'Current line': self.__cleanLine, 'Everything': self.__clean, 'Charts': self.__cleanCharts})
59
149
150
151
152
153
155 return "untitled.csv"
156
160
161 - def addPeriod(self, value, track=0, color=None):
163
164
165
166
167
169 for action in self._deltaActions:
170 action.setVisible(
171 True) if self._time._selected is not None else action.setVisible(False)
172
174 """
175 This controls makes possible the edition of a track in the
176 timeline, based on the position of the mouse.
177
178 Updates:
179 - Track label
180 - Track default color
181 """
182 current_track = self.mouseOverLine
183 parent = self._time
184
185
186 d = parent._tracks_info
187 i = current_track
188
189
190 timeline_default_color = parent.color
191 try:
192 parent.color = d[i][1]
193 except KeyError as e:
194 error_message = ("You tried to edit an empty track.",
195 "\n",
196 "Initialize it by creating an event first.")
197 QtGui.QMessageBox.warning(
198 parent, "Attention!", "".join(error_message))
199 return e
200
201
202 dialog = TimelinePopupWindow(parent, i)
203 dialog.setModal(True)
204
205
206 if dialog._ui.exec_() == dialog.Accepted:
207
208 if dialog.behavior is not None:
209 d[i][0] = dialog.behavior
210
211
212 if d[i][1] != dialog.color:
213 for delta in d[i][2]:
214 if delta.color == d[i][1]:
215 delta.color = dialog.color
216 d[i][1] = dialog.color
217 else:
218 pass
219
220
221 parent.color = timeline_default_color
222
223
224 parent._update_tracks_info()
225
227
229
231 """Import annotations from a file."""
232
233 filename = QtGui.QFileDialog.getOpenFileName(parent=self,
234 caption="Import annotations file",
235 directory="",
236 filter="*.csv")
237 if filename == '':
238 return
239 separator = ','
240
241 with open(filename, 'rU') as csvfile:
242 line = csvfile.readline()
243 if ";" in line:
244 separator = ';'
245
246 with open(filename, 'rU') as csvfile:
247 csvfile = csv.reader(csvfile, delimiter=separator)
248 row = next(csvfile)
249
250 if len(row) == 2:
251 with open(filename, 'rU') as csvfile:
252 csvfile = csv.reader(csvfile, delimiter=separator)
253 self._time.importchart_csv(csvfile)
254 else:
255
256
257
258 if self._time._tracks_info:
259 message = ["You are about to import new data. ",
260 "If you proceed, current annotations will be erased. ",
261 "Make sure to export current annotations first to save.",
262 "\n",
263 "Are you sure you want to proceed?"]
264 reply = QtGui.QMessageBox.question(self,
265 "Warning!",
266 "".join(message),
267 QtGui.QMessageBox.Yes | QtGui.QMessageBox.No,
268 QtGui.QMessageBox.No)
269 if reply != QtGui.QMessageBox.Yes:
270 return
271
272 with open(filename, 'rU') as csvfile:
273 csvfile = csv.reader(csvfile, delimiter=separator)
274 self._time.import_csv(csvfile)
275 print("Annotations file imported: {:s}".format(filename))
276
277
278 self._time._update_tracks_info()
279
281 """Export annotations to a file."""
282
283
284 self._time._update_tracks_info()
285
286 filename = QtGui.QFileDialog.getSaveFileName(parent=self,
287 caption="Export annotations file",
288 directory=self.getExportFilename(),
289 filter="CSV Files (*.csv)",
290 options=QtGui.QFileDialog.DontUseNativeDialog)
291 if filename != "":
292 with open(filename, 'wb') as csvfile:
293
294 spamwriter = csv.writer(csvfile, dialect='excel')
295 self._time.export_csv(spamwriter)
296 print("Annotations file exported: {:s}".format(filename))
297
299 reply = QtGui.QMessageBox.question(self, 'Confirm',
300 "Are you sure you want to clean all the events?", QtGui.QMessageBox.Yes |
301 QtGui.QMessageBox.No, QtGui.QMessageBox.No)
302 if reply == QtGui.QMessageBox.Yes:
303 self._time.cleanLine()
304
306 reply = QtGui.QMessageBox.question(self, 'Confirm',
307 "Are you sure you want to clean all the charts?", QtGui.QMessageBox.Yes |
308 QtGui.QMessageBox.No, QtGui.QMessageBox.No)
309 if reply == QtGui.QMessageBox.Yes:
310 self._time.cleanCharts()
311
313 reply = QtGui.QMessageBox.question(self, 'Confirm',
314 "Are you sure you want to clean all the events?", QtGui.QMessageBox.Yes |
315 QtGui.QMessageBox.No, QtGui.QMessageBox.No)
316 if reply == QtGui.QMessageBox.Yes:
317 self._time.clean()
318
320 self._time.color = QtGui.QColorDialog.getColor(self._time.color)
321 if self._time._selected != None:
322 self._time._selected.color = self._time.color
323 self._time.repaint()
324
330
338
345
346
347
348
349
350 @property
353
354 @pointerChanged.setter
357
358 @property
360
361 @value.setter
365
366 @property
367 - def max(self): return self._time.minimumWidth()
368
369 @max.setter
370 - def max(self, value):
374
375 @property
377 globalPos = QtGui.QCursor.pos()
378 widgetPos = self._time.mapFromGlobal(globalPos)
379 return self._time.trackInPosition(widgetPos.x(), widgetPos.y())
380
381
382 @property
385
386 @playVideoEvent.setter
389
390 @property
392
393 @fpsChanged.setter
395
396 @property
398