some picplayer fixes
[vuplus_dvbapp] / lib / python / Plugins / Extensions / PicturePlayer / plugin.py
1 from enigma import *
2
3 from Screens.Screen import Screen
4 from Screens.ServiceInfo import ServiceInfoList, ServiceInfoListEntry
5 from Components.ActionMap import ActionMap, NumberActionMap
6 from Components.Pixmap import Pixmap, MovingPixmap
7 from Components.Label import Label
8
9 from Components.ConfigList import ConfigList
10 from Components.config import *
11
12 from Tools.Directories import resolveFilename, SCOPE_MEDIA
13 from Components.FileList import FileEntryComponent, FileList
14 from Components.AVSwitch import AVSwitch
15
16 from Plugins.Plugin import PluginDescriptor
17
18 import os
19
20 config.pic = ConfigSubsection()
21 config.pic.slidetime = ConfigInteger(default=10, limits=(5, 60))
22 config.pic.resize = ConfigSelection(default="0", choices = [("0", _("simple")), ("1", _("better"))])
23 config.pic.cache = ConfigEnableDisable(default=True)
24 config.pic.lastDir = ConfigText(default=resolveFilename(SCOPE_MEDIA))
25 config.pic.rotate = ConfigSelection(default="0", choices = [("0", _("none")), ("1", _("manual")), ("2", _("by Exif"))])
26
27 def getAspect():
28         val = AVSwitch().getAspectRatioSetting()
29         return val/2
30
31 #------------------------------------------------------------------------------------------
32
33 class ThumbView(Screen):
34         skin = """
35                 <screen position="0,0" size="720,576" flags="wfNoBorder" title="ThumbView" >
36                         <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
37                         <widget name="frame" position="50,63" size="190,200" pixmap="pic_frame.png" zPosition="1" alphatest="on" />
38                         <widget name="label0" position="55,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
39                         <widget name="label1" position="270,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
40                         <widget name="label2" position="485,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
41                         <widget name="label3" position="55,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
42                         <widget name="label4" position="270,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
43                         <widget name="label5" position="485,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
44                         <widget name="thumb0" position="55,68" size="180,160" zPosition="2" transparent="1"  />
45                         <widget name="thumb1" position="270,68" size="180,160" zPosition="2" transparent="1" />
46                         <widget name="thumb2" position="485,68" size="180,160" zPosition="2" transparent="1" />
47                         <widget name="thumb3" position="55,293" size="180,160" zPosition="2" transparent="1" />
48                         <widget name="thumb4" position="270,293" size="180,160" zPosition="2" transparent="1" />
49                         <widget name="thumb5" position="485,293" size="180,160" zPosition="2" transparent="1" />
50                 </screen>"""
51         
52         def __init__(self, session, filelist, name, path):
53                 self.skin = ThumbView.skin
54                 Screen.__init__(self, session)
55
56                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"],
57                 {
58                         "cancel": self.Exit,
59                         "ok": self.KeyOk,
60                         "showEventInfo": self.StartExif,
61                         "right": self.key_right,
62                         "left": self.key_left,
63                         "up": self.key_up,
64                         "down": self.key_down
65                 }, -1)
66                 
67                 for x in range(6):
68                         self["label"+str(x)] = Label()
69                         self["thumb"+str(x)] = Pixmap()
70                 self["frame"] = MovingPixmap()
71                 
72                 self.aspect = getAspect()
73                 self.path = path
74                 self.filelist = filelist
75                 self.currPage = -1
76                 self.index = 0
77                 self.old_index = 0
78                 self.thumblist = []
79                 self.thumbindex = 0
80                 self.list = []
81                 self.poslist = [[50,63],[265,63],[480,63],[50,288],[265,288],[480,288]]
82                 
83                 count=0
84                 pos=0
85                 for x in self.filelist:
86                         if x[0][1] == False:
87                                 self.list.append((x[0][0], self.path + x[0][0], count/6, pos, "(" + str(count+1) + ")  "))
88                                 pos += 1
89                                 if pos == 6:
90                                         pos = 0
91                                 if x[0][0] == name:
92                                         self.index = count
93                                 count += 1
94                 self.maxentry = len(self.list)-1
95                 
96                 if self.maxentry < 0:
97                         self["label0"].setText(_("no Picture found"))
98                 
99                 self.ThumbTimer = eTimer()
100                 self.ThumbTimer.timeout.get().append(self.showThumb)
101
102                 self.fillPage()
103                 
104         def key_left(self):
105                 self.index -= 1
106                 if self.index < 0:
107                         self.index = self.maxentry
108                 self.fillPage()
109                 
110         def key_right(self):
111                 self.index += 1
112                 if self.index > self.maxentry:
113                         self.index = 0
114                 self.fillPage()
115                 
116         def key_up(self):
117                 self.index -= 3
118                 if self.index < 0:
119                         self.index = 0
120                 self.fillPage()
121                 
122         def key_down(self):
123                 self.index += 3
124                 if self.index > self.maxentry:
125                         self.index = self.maxentry
126                 self.fillPage()
127                 
128         def fillPage(self):
129                 if self.maxentry < 0:
130                         return
131
132                 self["frame"].moveTo(self.poslist[self.list[self.index][3]][0], self.poslist[self.list[self.index][3]][1], 1)
133                 self["frame"].startMoving()
134                 
135                 if self.list[self.index][2] != self.currPage:
136                         self.currPage = self.list[self.index][2]
137                         textlist = ["","","","","",""]
138                         self.thumblist = ["","","","","",""]
139                         
140                         for x in self.list:
141                                 if x[2] == self.currPage:
142                                         textlist[x[3]] = x[4] + x[0]
143                                         self.thumblist[x[3]] = x[0]
144                                         
145                         for x in range(6):
146                                 self["label"+str(x)].setText(textlist[x])
147                                 self["thumb"+str(x)].hide()
148                                 
149                         self.ThumbTimer.start(500, True)
150                 
151         def showThumb(self):
152                 if self.thumblist[self.thumbindex] != "":
153                         cachefile = ""
154                         if config.pic.cache.value:
155                                 cachedir = self.path + ".Thumbnails/"
156                                 if not os.path.exists(cachedir):
157                                         os.mkdir(cachedir)
158                                 cachefile = cachedir + self.thumblist[self.thumbindex] + str(180) + str(160) + str(self.aspect)
159
160                         ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1, cachefile)
161                         if ptr != None:
162                                 self["thumb"+str(self.thumbindex)].show()
163                                 self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr.__deref__())
164                         
165                         self.thumbindex += 1
166                         if self.thumbindex < 6:
167                                 self.ThumbTimer.start(500, True)
168                         else:
169                                 self.thumbindex = 0
170                 else:
171                         self.thumbindex = 0
172                 
173         def StartExif(self):
174                 if self.maxentry < 0:
175                         return
176
177                 self.session.open(ExifView, self.list[self.index][1], self.list[self.index][0])
178
179         def KeyOk(self):
180                 if self.maxentry < 0:
181                         return
182
183                 self.old_index = self.index
184                 self.session.openWithCallback(self.returnView ,PicView, self.filelist, self.list[self.index][0], self.path)
185                 
186         def returnView(self, val=0):
187                 self.index = val
188                 if self.old_index != self.index:
189                         self.fillPage()
190                 
191         def Exit(self):
192                 self.close(self.index)
193
194 #------------------------------------------------------------------------------------------
195
196 class PicView(Screen):
197         skin = """
198                 <screen position="0,0" size="720,576" flags="wfNoBorder" title="PicturePlayer" >
199                         <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
200                         <widget name="picture" position="80,50" size="560,450" zPosition="1" transparent="1" />
201                         <widget name="point" position="80,515" size="15,15" zPosition="1" pixmap="BlinkingPoint-fs8.png" alphatest="on" />
202                         <widget name="file" position="150,510" size="350,30" font="Regular;20" halign="center" zPosition="1" transparent="1" />
203                         <ePixmap position="500,515" size="36,20" pixmap="key_info-fs8.png" zPosition="1" alphatest="on" />
204                         <ePixmap position="550,515" size="20,20" pixmap="ico_mp_rewind.png"  zPosition="1" alphatest="on" />
205                         <widget name="play" position="575,515" size="20,20" pixmap="ico_mp_play.png"  zPosition="1" alphatest="on" />
206                         <widget name="pause" position="600,515" size="20,20" pixmap="ico_mp_pause.png"  zPosition="1" alphatest="on" />
207                         <ePixmap position="625,515" size="20,20" pixmap="ico_mp_forward.png"  zPosition="1" alphatest="on" />
208                 </screen>"""
209         
210         def __init__(self, session, filelist, name, path):
211                 self.skin = PicView.skin
212                 Screen.__init__(self, session)
213
214                 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions"],
215                 {
216                         "cancel": self.Exit,
217                         "showEventInfo": self.StartExif,
218                         "green": self.Play,
219                         "yellow": self.Pause,
220                         "blue": self.nextPic,
221                         "red": self.prevPic
222                 }, -1)
223
224                 self.aspect = getAspect()
225                 self.blinking = False
226                 self.autoShow = True
227                 self.slideOn = False
228                 self.pauseOn = False
229                 self.index = 0
230                 self.old = 0
231                 self.list = []
232                 
233                 count=0
234                 for x in filelist:
235                         if x[0][1] == False:
236                                 self.list.append((x[0][0], path + x[0][0], 0))
237                                 if x[0][0] == name:
238                                         self.index = count
239                                 count += 1
240                 self.maxentry = len(self.list)-1
241
242                 self["file"] = Label(_("please wait, loading picture..."))
243                 self["picture"] = Pixmap()
244                 self["point"] = Pixmap()
245                 self["play"] = Pixmap()
246                 self["pause"] = Pixmap()
247                 
248                 self.decodeTimer = eTimer()
249                 self.decodeTimer.timeout.get().append(self.decodePic)
250                 self.decodeTimer.start(300, True)
251
252                 self.slideTimer = eTimer()
253                 self.slideTimer.timeout.get().append(self.slidePic)
254                 
255                 
256         def Pause(self):
257                 if self.slideOn:
258                         if self.pauseOn:
259                                 self.pauseOn=False
260                                 self["pause"].show()
261                         else:
262                                 self.pauseOn=True
263                                 self["play"].show()
264                                 self.slideValue = 0
265                 
266         def Play(self):
267                 if self.pauseOn == False:
268                         if self.slideOn:
269                                 self.slideOn=False
270                                 self["play"].show()
271                         else:
272                                 self.slideOn=True
273                                 self.slideTimer.start(1000, True)
274                         
275                         self.slideValue = int(config.pic.slidetime.value)
276                 
277         def slidePic(self):
278                 if self.slideOn == True and self.pauseOn == False:
279                         self.blinkingWidget("play")
280                         self.slideValue -= 1
281                         if self.slideValue <= 0:
282                                 self.slideValue = int(config.pic.slidetime.value)
283                                 self.nextPic()
284                 
285                         self.slideTimer.start(1000, True)
286
287                 if self.pauseOn:
288                         self.blinkingWidget("pause")
289                         self.slideTimer.start(1000, True)
290
291         def decodePic(self):
292                 self.currPic = loadPic(self.list[self.index][1], 560, 450, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1)
293                 self["point"].hide()
294                 if self.autoShow:
295                         self.showPic()
296                         self.autoShow = False
297                 
298         def showPic(self):
299                 if self.currPic != None:
300                         self.old = self.index
301                         self["file"].setText(self.list[self.old][0] + "  (" + str(self.old+1) + "/" + str(self.maxentry+1) + ")")
302                         self["picture"].instance.setPixmap(self.currPic.__deref__())
303
304                 self.next()
305                 self["point"].show()
306                 self.decodeTimer.start(300, True)
307                 
308         def nextPic(self):
309                 self.showPic()
310                 
311         def prevPic(self):
312                 self.index = self.old
313                 self.prev()
314                 self.autoShow = True
315                 self["point"].show()
316                 self.decodeTimer.start(300, True)
317                 
318         def next(self):
319                 self.index += 1
320                 if self.index > self.maxentry:
321                         self.index = 0
322
323         def prev(self):
324                 self.index -= 1
325                 if self.index < 0:
326                         self.index = self.maxentry
327                         
328         def blinkingWidget(self, name):
329                 if self.blinking:
330                         self.blinking=False
331                         self[name].show()
332                 else:
333                         self.blinking=True
334                         self[name].hide()
335
336         def StartExif(self):
337                 if self.pauseOn == False:
338                         self.Pause()
339                 self.session.openWithCallback(self.StopExif ,ExifView, self.list[self.old][1], self.list[self.old][0])
340                 
341         def StopExif(self):
342                 if self.pauseOn:
343                         self.Pause()
344
345         def Exit(self):
346                 self.close(self.old)
347
348 #------------------------------------------------------------------------------------------
349
350 class ExifView(Screen):
351         skin = """
352                 <screen position="80,130" size="560,320" title="Exif-Data" >
353                         <widget name="exiflist" position="5,5" size="550,310" selectionDisabled="1" />
354                 </screen>"""
355         
356         def __init__(self, session, fullname, name):
357                 self.skin = ExifView.skin
358                 Screen.__init__(self, session)
359
360                 self["actions"] = ActionMap(["OkCancelActions"],
361                 {
362                         "cancel": self.close
363                 }, -1)
364                 
365                 dlist = ["Name:", "EXIF-Version:", "Camera-Make:", "Camera-Model:", "Date/Time:", "User Comments:", "Width / Height:", "Orientation:", "Metering Mode:", "Exposure Program:", "Light Source:", "Flash used:", "CompressedBitsPerPixel:", "ISO Speed Rating:", "X-Resolution:", "Y-Resolution:", "Resolution Unit:", "Brightness:", "Exposure Time:", "Exposure Bias:", "Distance:", "CCD-Width:", "ApertureFNumber:"]
366                 tlist = [ ]
367                 self["exiflist"] = ServiceInfoList(tlist)
368                 tlist.append(ServiceInfoListEntry(dlist[0], name))
369                 count=1
370                 for x in getExif(fullname):
371                         tlist.append(ServiceInfoListEntry(dlist[count], x))
372                         count += 1
373
374 #------------------------------------------------------------------------------------------
375
376 class PicSetup(Screen):
377         skin = """
378                 <screen position="160,220" size="400,120" title="Settings" >
379                         <widget name="liste" position="10,10" size="380,100" />
380                 </screen>"""
381         
382         def __init__(self, session):
383                 self.skin = PicSetup.skin
384                 Screen.__init__(self, session)
385
386                 self["actions"] = NumberActionMap(["SetupActions"],
387                 {
388                         "cancel": self.close,
389                         "left": self.keyLeft,
390                         "right": self.keyRight,
391                         "0": self.keyNumber,
392                         "1": self.keyNumber,
393                         "2": self.keyNumber,
394                         "3": self.keyNumber,
395                         "4": self.keyNumber,
396                         "5": self.keyNumber,
397                         "6": self.keyNumber,
398                         "7": self.keyNumber,
399                         "8": self.keyNumber,
400                         "9": self.keyNumber
401                 }, -1)
402                 
403                 self.list = []
404                 self["liste"] = ConfigList(self.list)
405                 self.list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime))
406                 self.list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize))
407                 self.list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache))
408                 #self.list.append(getConfigListEntry(_("Rotate Picture"), config.pic.rotate))
409                 
410         def keyLeft(self):
411                 self["liste"].handleKey(KEY_LEFT)
412
413         def keyRight(self):
414                 self["liste"].handleKey(KEY_RIGHT)
415                 
416         def keyNumber(self, number):
417                 self["liste"].handleKey(KEY_0 + number)
418
419
420 #------------------------------------------------------------------------------------------
421
422 class picmain(Screen):
423         skin = """
424                 <screen position="160,90" size="400,390" title="PicturePlayer" >
425                         <ePixmap position="10,40" size="36,20" pixmap="key_menu-fs8.png" transparent="1" alphatest="on" />
426                         <ePixmap position="10,70" size="36,20" pixmap="key_info-fs8.png" transparent="1" alphatest="on" />
427                         <ePixmap position="12,100" size="36,20" pixmap="key_red-fs8.png" transparent="1" alphatest="on" />
428                         <eLabel text="Settings" position="60,40" size="120,25" font="Regular;20" transparent="1" />
429                         <eLabel text="Exif-Data" position="60,70" size="120,25" font="Regular;20" transparent="1" />
430                         <eLabel text="Thumbnails" position="60,100" size="120,25" font="Regular;20" transparent="1" />
431                         <widget name="thumbnail" position="200,5" size="180,160" alphatest="on" />
432                         <widget name="filelist" position="5,170" zPosition="2" size="390,210" scrollbarMode="showOnDemand" />
433                 </screen>"""
434         
435         def __init__(self, session):
436                 self.skin = picmain.skin
437                 Screen.__init__(self, session)
438
439                 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions", "MovieSelectionActions"],
440                 {
441                         "ok": self.KeyOk,
442                         "cancel": self.Exit,
443                         "right": self.rightDown,
444                         "left": self.leftUp,
445                         "up": self.up,
446                         "down": self.down,
447                         "showEventInfo": self.StartExif,
448                         "contextMenu": self.Settings,
449                         "red": self.StartThumb
450                 }, -1)
451                 
452                 self.aspect = getAspect()
453                 currDir = config.pic.lastDir.value
454                 if not os.path.exists(currDir):
455                         currDir = "/"
456                 
457                 self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|png|bmp)")
458                 self["filelist"] = self.filelist
459                 self["thumbnail"] = Pixmap()
460                 
461                 self.ThumbTimer = eTimer()
462                 self.ThumbTimer.timeout.get().append(self.showThumb)
463                 self.ThumbTimer.start(500, True)
464                 
465         def up(self):
466                 self["filelist"].up()
467                 self.ThumbTimer.start(1500, True)
468
469         def down(self):
470                 self["filelist"].down()
471                 self.ThumbTimer.start(1500, True)
472                 
473         def leftUp(self):
474                 self["filelist"].pageUp()
475                 self.ThumbTimer.start(1500, True)
476                 
477         def rightDown(self):
478                 self["filelist"].pageDown()
479                 self.ThumbTimer.start(1500, True)
480
481         def showThumb(self):
482                 if not self.filelist.canDescent():
483                         print self.filelist.getCurrentDirectory()
484                         cachefile = ""
485                         if config.pic.cache.value:
486                                 cachedir = self.filelist.getCurrentDirectory() + ".Thumbnails/"
487                                 if not os.path.exists(cachedir):
488                                         os.mkdir(cachedir)
489                                 cachefile = cachedir + self.filelist.getSelection()[0] + str(180) + str(160) + str(self.aspect)
490
491                         ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getSelection()[0], 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile)
492                         if ptr != None:
493                                 self["thumbnail"].show()
494                                 self["thumbnail"].instance.setPixmap(ptr.__deref__())
495                 else:
496                         self["thumbnail"].hide()
497
498         def KeyOk(self):
499                 if self.filelist.canDescent():
500                         self.filelist.descent()
501                 else:
502                         self.session.openWithCallback(self.returnVal, PicView, self.filelist.getFileList(), self.filelist.getSelection()[0], self.filelist.getCurrentDirectory())
503                         
504         def StartThumb(self):
505                 self.session.openWithCallback(self.returnVal, ThumbView, self.filelist.getFileList(), self.filelist.getSelection()[0], self.filelist.getCurrentDirectory())
506
507         def returnVal(self, val=0):
508                 if val > 0:
509                         for x in self.filelist.getFileList():
510                                 if x[0][1] == True:
511                                         val += 1
512                         self.filelist.moveToIndex(val)
513
514         def StartExif(self):
515                 if not self.filelist.canDescent():
516                         self.session.open(ExifView, self.filelist.getCurrentDirectory() + self.filelist.getFilename(), self.filelist.getSelection()[0])
517
518         def Settings(self):
519                 self.session.open(PicSetup)
520         
521         def Exit(self):
522                 if self.filelist.getCurrentDirectory() is None:
523                         config.pic.lastDir.value = "/"
524                 else:
525                         config.pic.lastDir.value = self.filelist.getCurrentDirectory()
526                 config.pic.save()
527                 self.close()
528
529 #------------------------------------------------------------------------------------------
530
531 def main(session, **kwargs):
532         session.open(picmain)
533
534 def Plugins(**kwargs):
535         return PluginDescriptor(name="PicturePlayer", description="Picture Viewer (BMP, PNG, JPG)", icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main)