1 from enigma import eTimer, loadPic, getExif
2 from Screens.Screen import Screen
3 from Screens.ServiceInfo import ServiceInfoList, ServiceInfoListEntry
4 from Components.ActionMap import ActionMap, NumberActionMap
5 from Components.Pixmap import Pixmap, MovingPixmap
6 from Components.Label import Label
8 from Components.ConfigList import ConfigList
9 from Components.config import *
11 from Tools.Directories import resolveFilename, pathExists, createDir, SCOPE_MEDIA
12 from Components.FileList import FileEntryComponent, FileList
13 from Components.AVSwitch import AVSwitch
15 from Plugins.Plugin import PluginDescriptor
17 config.pic = ConfigSubsection()
18 config.pic.slidetime = ConfigInteger(default=10, limits=(5, 60))
19 config.pic.resize = ConfigSelection(default="0", choices = [("0", _("simple")), ("1", _("better"))])
20 config.pic.cache = ConfigEnableDisable(default=True)
21 config.pic.lastDir = ConfigText(default=resolveFilename(SCOPE_MEDIA))
22 config.pic.rotate = ConfigSelection(default="0", choices = [("0", _("none")), ("1", _("manual")), ("2", _("by Exif"))])
25 val = AVSwitch().getAspectRatioSetting()
28 #------------------------------------------------------------------------------------------
30 class ThumbView(Screen):
32 <screen position="0,0" size="720,576" flags="wfNoBorder" title="ThumbView" >
33 <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
34 <widget name="frame" position="50,63" size="190,200" pixmap="pic_frame.png" zPosition="1" alphatest="on" />
35 <widget name="label0" position="55,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
36 <widget name="label1" position="270,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
37 <widget name="label2" position="485,240" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
38 <widget name="label3" position="55,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
39 <widget name="label4" position="270,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
40 <widget name="label5" position="485,465" size="180,20" font="Regular;13" halign="center" zPosition="2" transparent="1" />
41 <widget name="thumb0" position="55,68" size="180,160" zPosition="2" transparent="1" />
42 <widget name="thumb1" position="270,68" size="180,160" zPosition="2" transparent="1" />
43 <widget name="thumb2" position="485,68" size="180,160" zPosition="2" transparent="1" />
44 <widget name="thumb3" position="55,293" size="180,160" zPosition="2" transparent="1" />
45 <widget name="thumb4" position="270,293" size="180,160" zPosition="2" transparent="1" />
46 <widget name="thumb5" position="485,293" size="180,160" zPosition="2" transparent="1" />
49 def __init__(self, session, filelist, name, path):
50 self.skin = ThumbView.skin
51 Screen.__init__(self, session)
53 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "MovieSelectionActions"],
57 "showEventInfo": self.StartExif,
58 "right": self.key_right,
59 "left": self.key_left,
65 self["label"+str(x)] = Label()
66 self["thumb"+str(x)] = Pixmap()
67 self["frame"] = MovingPixmap()
69 self.aspect = getAspect()
71 self.filelist = filelist
78 self.poslist = [[50,63],[265,63],[480,63],[50,288],[265,288],[480,288]]
82 for x in self.filelist:
84 self.list.append((x[0][0], self.path + x[0][0], count/6, pos, "(" + str(count+1) + ") "))
91 self.maxentry = len(self.list)-1
94 self["label0"].setText(_("no Picture found"))
96 self.ThumbTimer = eTimer()
97 self.ThumbTimer.timeout.get().append(self.showThumb)
104 self.index = self.maxentry
109 if self.index > self.maxentry:
121 if self.index > self.maxentry:
122 self.index = self.maxentry
126 if self.maxentry < 0:
129 self["frame"].moveTo(self.poslist[self.list[self.index][3]][0], self.poslist[self.list[self.index][3]][1], 1)
130 self["frame"].startMoving()
132 if self.list[self.index][2] != self.currPage:
133 self.currPage = self.list[self.index][2]
134 textlist = ["","","","","",""]
135 self.thumblist = ["","","","","",""]
138 if x[2] == self.currPage:
139 textlist[x[3]] = x[4] + x[0]
140 self.thumblist[x[3]] = x[0]
143 self["label"+str(x)].setText(textlist[x])
144 self["thumb"+str(x)].hide()
146 self.ThumbTimer.start(500, True)
149 if self.thumblist[self.thumbindex] != "":
151 if config.pic.cache.value:
152 cachedir = self.path + ".Thumbnails/"
153 cachefile = cachedir + self.thumblist[self.thumbindex] + str(180) + str(160) + str(self.aspect)
154 if not pathExists(cachedir):
155 if not createDir(cachedir):
158 ptr = loadPic(self.path + self.thumblist[self.thumbindex], 180, 160, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1, cachefile)
160 self["thumb"+str(self.thumbindex)].show()
161 self["thumb"+str(self.thumbindex)].instance.setPixmap(ptr)
164 if self.thumbindex < 6:
165 self.ThumbTimer.start(500, True)
172 if self.maxentry < 0:
175 self.session.open(ExifView, self.list[self.index][1], self.list[self.index][0])
178 if self.maxentry < 0:
181 self.old_index = self.index
182 self.session.openWithCallback(self.returnView ,PicView, self.filelist, self.list[self.index][0], self.path)
184 def returnView(self, val=0):
186 if self.old_index != self.index:
190 self.close(self.index)
192 #------------------------------------------------------------------------------------------
194 class PicView(Screen):
196 <screen position="0,0" size="720,576" flags="wfNoBorder" title="PicturePlayer" >
197 <eLabel position="0,0" zPosition="0" size="720,576" backgroundColor="black" />
198 <widget name="picture" position="80,50" size="560,450" zPosition="1" transparent="1" />
199 <widget name="point" position="80,515" size="15,15" zPosition="1" pixmap="BlinkingPoint-fs8.png" alphatest="on" />
200 <widget name="file" position="150,510" size="350,30" font="Regular;20" halign="center" zPosition="1" transparent="1" />
201 <ePixmap position="500,515" size="36,20" pixmap="key_info-fs8.png" zPosition="1" alphatest="on" />
202 <ePixmap position="550,515" size="20,20" pixmap="ico_mp_rewind.png" zPosition="1" alphatest="on" />
203 <widget name="play" position="575,515" size="20,20" pixmap="ico_mp_play.png" zPosition="1" alphatest="on" />
204 <widget name="pause" position="600,515" size="20,20" pixmap="ico_mp_pause.png" zPosition="1" alphatest="on" />
205 <ePixmap position="625,515" size="20,20" pixmap="ico_mp_forward.png" zPosition="1" alphatest="on" />
208 def __init__(self, session, filelist, name, path):
209 self.skin = PicView.skin
210 Screen.__init__(self, session)
212 self["actions"] = ActionMap(["OkCancelActions", "ColorActions", "MovieSelectionActions"],
215 "showEventInfo": self.StartExif,
217 "yellow": self.Pause,
218 "blue": self.nextPic,
222 self.aspect = getAspect()
223 self.blinking = False
234 self.list.append((x[0][0], path + x[0][0], 0))
238 self.maxentry = len(self.list)-1
240 self["file"] = Label(_("please wait, loading picture..."))
241 self["picture"] = Pixmap()
242 self["point"] = Pixmap()
243 self["play"] = Pixmap()
244 self["pause"] = Pixmap()
246 self.decodeTimer = eTimer()
247 self.decodeTimer.timeout.get().append(self.decodePic)
248 self.decodeTimer.start(300, True)
250 self.slideTimer = eTimer()
251 self.slideTimer.timeout.get().append(self.slidePic)
265 if self.pauseOn == False:
271 self.slideTimer.start(1000, True)
273 self.slideValue = int(config.pic.slidetime.value)
276 if self.slideOn == True and self.pauseOn == False:
277 self.blinkingWidget("play")
279 if self.slideValue <= 0:
280 self.slideValue = int(config.pic.slidetime.value)
283 self.slideTimer.start(1000, True)
286 self.blinkingWidget("pause")
287 self.slideTimer.start(1000, True)
290 self.currPic = loadPic(self.list[self.index][1], 560, 450, self.aspect, int(config.pic.resize.value), int(config.pic.rotate.value),1)
294 self.autoShow = False
297 if self.currPic != None:
298 self.old = self.index
299 self["file"].setText(self.list[self.old][0] + " (" + str(self.old+1) + "/" + str(self.maxentry+1) + ")")
300 self["picture"].instance.setPixmap(self.currPic)
304 self.decodeTimer.start(300, True)
310 self.index = self.old
314 self.decodeTimer.start(300, True)
318 if self.index > self.maxentry:
324 self.index = self.maxentry
326 def blinkingWidget(self, name):
335 if self.pauseOn == False:
337 self.session.openWithCallback(self.StopExif ,ExifView, self.list[self.old][1], self.list[self.old][0])
346 #------------------------------------------------------------------------------------------
348 class ExifView(Screen):
350 <screen position="80,130" size="560,320" title="Exif-Data" >
351 <widget name="exiflist" position="5,5" size="550,310" selectionDisabled="1" />
354 def __init__(self, session, fullname, name):
355 self.skin = ExifView.skin
356 Screen.__init__(self, session)
358 self["actions"] = ActionMap(["OkCancelActions"],
363 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:"]
365 self["exiflist"] = ServiceInfoList(tlist)
366 tlist.append(ServiceInfoListEntry(dlist[0], name))
368 for x in getExif(fullname):
369 tlist.append(ServiceInfoListEntry(dlist[count], x))
372 #------------------------------------------------------------------------------------------
374 class PicSetup(Screen):
376 <screen position="160,220" size="400,120" title="Settings" >
377 <widget name="liste" position="10,10" size="380,100" />
380 def __init__(self, session):
381 self.skin = PicSetup.skin
382 Screen.__init__(self, session)
384 self["actions"] = NumberActionMap(["SetupActions"],
386 "cancel": self.close,
387 "left": self.keyLeft,
388 "right": self.keyRight,
402 self["liste"] = ConfigList(self.list)
403 self.list.append(getConfigListEntry(_("Slideshow Interval (sec.)"), config.pic.slidetime))
404 self.list.append(getConfigListEntry(_("Scaling Mode"), config.pic.resize))
405 self.list.append(getConfigListEntry(_("Cache Thumbnails"), config.pic.cache))
406 #self.list.append(getConfigListEntry(_("Rotate Picture"), config.pic.rotate))
409 self["liste"].handleKey(KEY_LEFT)
412 self["liste"].handleKey(KEY_RIGHT)
414 def keyNumber(self, number):
415 self["liste"].handleKey(KEY_0 + number)
418 #------------------------------------------------------------------------------------------
420 class picmain(Screen):
422 <screen position="160,90" size="400,390" title="PicturePlayer" >
423 <ePixmap position="10,40" size="36,20" pixmap="key_menu-fs8.png" transparent="1" alphatest="on" />
424 <ePixmap position="10,70" size="36,20" pixmap="key_info-fs8.png" transparent="1" alphatest="on" />
425 <ePixmap position="12,100" size="36,20" pixmap="key_red-fs8.png" transparent="1" alphatest="on" />
426 <eLabel text="Settings" position="60,40" size="120,25" font="Regular;20" transparent="1" />
427 <eLabel text="Exif-Data" position="60,70" size="120,25" font="Regular;20" transparent="1" />
428 <eLabel text="Thumbnails" position="60,100" size="120,25" font="Regular;20" transparent="1" />
429 <widget name="thumbnail" position="200,5" size="180,160" alphatest="on" />
430 <widget name="filelist" position="5,170" zPosition="2" size="390,210" scrollbarMode="showOnDemand" />
433 def __init__(self, session):
434 self.skin = picmain.skin
435 Screen.__init__(self, session)
437 self["actions"] = ActionMap(["OkCancelActions", "DirectionActions", "ColorActions", "MovieSelectionActions"],
441 "right": self.rightDown,
445 "showEventInfo": self.StartExif,
446 "contextMenu": self.Settings,
447 "red": self.StartThumb
450 self.aspect = getAspect()
451 currDir = config.pic.lastDir.value
452 if not pathExists(currDir):
455 self.filelist = FileList(currDir, matchingPattern = "(?i)^.*\.(jpeg|jpg|png|bmp)")
456 self["filelist"] = self.filelist
457 self["thumbnail"] = Pixmap()
459 self.ThumbTimer = eTimer()
460 self.ThumbTimer.timeout.get().append(self.showThumb)
461 self.ThumbTimer.start(500, True)
464 self["filelist"].up()
465 self.ThumbTimer.start(1500, True)
468 self["filelist"].down()
469 self.ThumbTimer.start(1500, True)
472 self["filelist"].pageUp()
473 self.ThumbTimer.start(1500, True)
476 self["filelist"].pageDown()
477 self.ThumbTimer.start(1500, True)
480 if not self.filelist.canDescent():
482 if config.pic.cache.value:
483 cachedir = self.filelist.getCurrentDirectory() + ".Thumbnails/"
484 cachefile = cachedir + self.filelist.getFilename() + str(180) + str(160) + str(self.aspect)
485 if not pathExists(cachedir):
486 if not createDir(cachedir):
489 ptr = loadPic(self.filelist.getCurrentDirectory() + self.filelist.getFilename(), 180, 160, self.aspect, int(config.pic.resize.value), 0, 0, cachefile)
491 self["thumbnail"].show()
492 self["thumbnail"].instance.setPixmap(ptr)
494 self["thumbnail"].hide()
497 if self.filelist.canDescent():
498 self.filelist.descent()
500 self.session.openWithCallback(self.returnVal, PicView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory())
502 def StartThumb(self):
503 self.session.openWithCallback(self.returnVal, ThumbView, self.filelist.getFileList(), self.filelist.getFilename(), self.filelist.getCurrentDirectory())
505 def returnVal(self, val=0):
507 for x in self.filelist.getFileList():
510 self.filelist.moveToIndex(val)
513 if not self.filelist.canDescent():
514 self.session.open(ExifView, self.filelist.getCurrentDirectory() + self.filelist.getFilename(), self.filelist.getFilename())
517 self.session.open(PicSetup)
520 if self.filelist.getCurrentDirectory() is None:
521 config.pic.lastDir.value = "/"
523 config.pic.lastDir.value = self.filelist.getCurrentDirectory()
528 #------------------------------------------------------------------------------------------
530 def main(session, **kwargs):
531 session.open(picmain)
533 def filescan_open(list, session, **kwargs):
534 session.open(picmain) # list
537 # we expect not to be called if the MediaScanner plugin is not available,
538 # thus we don't catch an ImportError exception here
539 from Plugins.Extensions.MediaScanner.plugin import Scanner, ScanPath
541 Scanner(extensions = ["jpg", "jpe", "jpeg"],
544 ScanPath(path = "DCIM", with_subdirs = True),
545 ScanPath(path = "", with_subdirs = False),
548 description = "View Photos...",
549 openfnc = filescan_open,
552 def Plugins(**kwargs):
554 [PluginDescriptor(name="PicturePlayer", description="Picture Viewer (BMP, PNG, JPG)", icon="pictureplayer.png", where = PluginDescriptor.WHERE_PLUGINMENU, fnc=main),
555 PluginDescriptor(name="PicturePlayer", where = PluginDescriptor.WHERE_FILESCAN, fnc = filescan)]