Merge commit 'origin/master' into tmbinc/FixTimingBugs
[enigma2.git] / lib / python / Components / Converter / ServicePosition.py
1 from Converter import Converter
2 from Poll import Poll
3 from enigma import iPlayableService
4 from Components.Element import cached, ElementError
5
6 class ServicePosition(Converter, Poll, object):
7         TYPE_LENGTH = 0
8         TYPE_POSITION = 1
9         TYPE_REMAINING = 2
10         TYPE_GAUGE = 3
11
12         def __init__(self, type):
13                 Poll.__init__(self)
14                 Converter.__init__(self, type)
15
16                 args = type.split(',')
17                 type = args.pop(0)
18
19                 self.negate = 'Negate' in args
20                 self.detailed = 'Detailed' in args
21                 self.showHours = 'ShowHours' in args
22                 self.showNoSeconds = 'ShowNoSeconds' in args
23
24                 if self.detailed:
25                         self.poll_interval = 100
26                 else:
27                         self.poll_interval = 500
28
29                 if type == "Length":
30                         self.type = self.TYPE_LENGTH
31                 elif type == "Position":
32                         self.type = self.TYPE_POSITION
33                 elif type == "Remaining":
34                         self.type = self.TYPE_REMAINING
35                 elif type == "Gauge":
36                         self.type = self.TYPE_GAUGE
37                 else:
38                         raise ElementError("type must be {Length|Position|Remaining|Gauge} with optional arguments {Negate|Detailed|ShowHours|ShowNoSeconds} for ServicePosition converter")
39
40                 self.poll_enabled = self.type != self.TYPE_LENGTH
41
42         def getSeek(self):
43                 s = self.source.service
44                 return s and s.seek()
45
46         @cached
47         def getPosition(self):
48                 seek = self.getSeek()
49                 if seek is None:
50                         return None
51                 pos = seek.getPlayPosition()
52                 if pos[0]:
53                         return 0
54                 return pos[1]
55
56         @cached
57         def getLength(self):
58                 seek = self.getSeek()
59                 if seek is None:
60                         return None
61                 length = seek.getLength()
62                 if length[0]:
63                         return 0
64                 return length[1]
65
66         @cached
67         def getCutlist(self):
68                 service = self.source.service
69                 cue = service and service.cueSheet()
70                 return cue and cue.getCutList()
71
72         @cached
73         def getText(self):
74                 seek = self.getSeek()
75                 if seek is None:
76                         return ""
77                 else:
78                         if self.type == self.TYPE_LENGTH:
79                                 l = self.length
80                         elif self.type == self.TYPE_POSITION:
81                                 l = self.position
82                         elif self.type == self.TYPE_REMAINING:
83                                 l = self.length - self.position
84
85                         if not self.detailed:
86                                 l /= 90000
87
88                         if self.negate: l = -l
89
90                         if l > 0:
91                                 sign = ""
92                         else:
93                                 l = -l
94                                 sign = "-"
95
96                         if not self.detailed:
97                                 if self.showHours:
98                                         if self.showNoSeconds:
99                                                 return sign + "%d:%02d" % (l/3600, l%3600/60)
100                                         else:
101                                                 return sign + "%d:%02d:%02d" % (l/3600, l%3600/60, l%60)
102                                 else:
103                                         if self.showNoSeconds:
104                                                 return sign + "%d" % (l/60)
105                                         else:
106                                                 return sign + "%d:%02d" % (l/60, l%60)
107                         else:
108                                 if self.showHours:
109                                         return sign + "%d:%02d:%02d:%03d" % ((l/3600/90000), (l/90000)%3600/60, (l/90000)%60, (l%90000)/90)
110                                 else:
111                                         return sign + "%d:%02d:%03d" % ((l/60/90000), (l/90000)%60, (l%90000)/90)
112
113         # range/value are for the Progress renderer
114         range = 10000
115
116         @cached
117         def getValue(self):
118                 pos = self.position
119                 len = self.length
120                 if pos is None or len is None or len <= 0:
121                         return None
122                 return pos * 10000 / len
123
124         position = property(getPosition)
125         length = property(getLength)
126         cutlist = property(getCutlist)
127         text = property(getText)
128         value = property(getValue)
129
130         def changed(self, what):
131                 cutlist_refresh = what[0] != self.CHANGED_SPECIFIC or what[1] in (iPlayableService.evCuesheetChanged,)
132                 time_refresh = what[0] == self.CHANGED_POLL or what[0] == self.CHANGED_SPECIFIC and what[1] in (iPlayableService.evCuesheetChanged,)
133
134                 if cutlist_refresh:
135                         if self.type == self.TYPE_GAUGE:
136                                 self.downstream_elements.cutlist_changed()
137
138                 if time_refresh:
139                         self.downstream_elements.changed(what)