1 from Screen import Screen
2 from Components.Button import Button
3 from Components.ActionMap import HelpableActionMap, ActionMap
4 from Components.MenuList import MenuList
5 from Components.MovieList import MovieList
6 from Components.DiskInfo import DiskInfo
7 from Components.Pixmap import Pixmap
8 from Components.Label import Label
9 from Components.PluginComponent import plugins
10 from Components.config import config, ConfigSubsection, ConfigText, ConfigInteger, ConfigLocations
11 from Components.Sources.ServiceEvent import ServiceEvent
13 from Plugins.Plugin import PluginDescriptor
15 from Screens.MessageBox import MessageBox
16 from Screens.ChoiceBox import ChoiceBox
17 from Screens.LocationBox import MovieLocationBox
18 from Screens.HelpMenu import HelpableScreen
20 from Tools.Directories import *
21 from Tools.BoundFunction import boundFunction
23 from enigma import eServiceReference, eServiceCenter, eTimer, eSize
25 config.movielist = ConfigSubsection()
26 config.movielist.moviesort = ConfigInteger(default=MovieList.SORT_RECORDED)
27 config.movielist.listtype = ConfigInteger(default=MovieList.LISTTYPE_ORIGINAL)
28 config.movielist.description = ConfigInteger(default=MovieList.HIDE_DESCRIPTION)
29 config.movielist.last_videodir = ConfigText(default=resolveFilename(SCOPE_HDD))
30 config.movielist.last_timer_videodir = ConfigText(default=resolveFilename(SCOPE_HDD))
31 config.movielist.videodirs = ConfigLocations(default=[resolveFilename(SCOPE_HDD)])
33 class MovieContextMenu(Screen):
34 def __init__(self, session, csel, service):
35 Screen.__init__(self, session)
37 self.service = service
39 self["actions"] = ActionMap(["OkCancelActions"],
41 "ok": self.okbuttonClick,
42 "cancel": self.cancelClick
45 menu = [(_("delete..."), self.delete)]
47 for p in plugins.getPlugins(PluginDescriptor.WHERE_MOVIELIST):
48 menu.append((p.description, boundFunction(self.execPlugin, p)))
50 if config.movielist.moviesort.value == MovieList.SORT_ALPHANUMERIC:
51 menu.append((_("sort by date"), boundFunction(self.sortBy, MovieList.SORT_RECORDED)))
53 menu.append((_("alphabetic sort"), boundFunction(self.sortBy, MovieList.SORT_ALPHANUMERIC)))
55 menu.append((_("list style default"), boundFunction(self.listType, MovieList.LISTTYPE_ORIGINAL)))
56 menu.append((_("list style compact with description"), boundFunction(self.listType, MovieList.LISTTYPE_COMPACT_DESCRIPTION)))
57 menu.append((_("list style compact"), boundFunction(self.listType, MovieList.LISTTYPE_COMPACT)))
58 menu.append((_("list style single line"), boundFunction(self.listType, MovieList.LISTTYPE_MINIMAL)))
60 if config.movielist.description.value == MovieList.SHOW_DESCRIPTION:
61 menu.append((_("hide extended description"), boundFunction(self.showDescription, MovieList.HIDE_DESCRIPTION)))
63 menu.append((_("show extended description"), boundFunction(self.showDescription, MovieList.SHOW_DESCRIPTION)))
64 self["menu"] = MenuList(menu)
66 def okbuttonClick(self):
67 self["menu"].getCurrent()[1]()
69 def cancelClick(self):
72 def sortBy(self, newType):
73 config.movielist.moviesort.value = newType
74 self.csel.selectedmovie = self.csel.getCurrent()
75 self.csel.setSortType(newType)
76 self.csel.reloadList()
80 def listType(self, newType):
81 config.movielist.listtype.value = newType
82 self.csel.setListType(newType)
83 self.csel.list.redrawList()
86 def showDescription(self, newType):
87 config.movielist.description.value = newType
88 self.csel.setDescriptionState(newType)
89 self.csel.updateDescription()
92 def execPlugin(self, plugin):
93 plugin(session=self.session, service=self.service)
96 serviceHandler = eServiceCenter.getInstance()
97 offline = serviceHandler.offlineOperations(self.service)
98 info = serviceHandler.info(self.service)
99 name = info and info.getName(self.service) or _("this recording")
101 if offline is not None:
103 if not offline.deleteFromDisk(1):
106 self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (name))
108 self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
110 def deleteConfirmed(self, confirmed):
114 serviceHandler = eServiceCenter.getInstance()
115 offline = serviceHandler.offlineOperations(self.service)
117 if offline is not None:
119 if not offline.deleteFromDisk(0):
123 self.session.openWithCallback(self.close, MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
125 self.csel["list"].removeService(self.service)
126 self.csel["freeDiskSpace"].update()
129 class SelectionEventInfo:
131 self["Service"] = ServiceEvent()
132 self.list.connectSelChanged(self.__selectionChanged)
133 self.timer = eTimer()
134 self.timer.callback.append(self.updateEventInfo)
135 self.onShown.append(self.__selectionChanged)
137 def __selectionChanged(self):
138 if self.execing and config.movielist.description.value == MovieList.SHOW_DESCRIPTION:
139 self.timer.start(100, True)
141 def updateEventInfo(self):
142 serviceref = self.getCurrent()
143 self["Service"].newService(serviceref)
145 class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
146 def __init__(self, session, selectedmovie = None):
147 Screen.__init__(self, session)
148 HelpableScreen.__init__(self)
151 self.selected_tags = None
153 self.movemode = False
154 self.bouquet_mark_edit = False
156 self.delayTimer = eTimer()
157 self.delayTimer.callback.append(self.updateHDDData)
159 self["waitingtext"] = Label(_("Please wait... Loading list..."))
161 # create optional description border and hide immediately
162 self["DescriptionBorder"] = Pixmap()
163 self["DescriptionBorder"].hide()
165 if not pathExists(config.movielist.last_videodir.value):
166 config.movielist.last_videodir.value = resolveFilename(SCOPE_HDD)
167 config.movielist.last_videodir.save()
168 self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
170 self["list"] = MovieList(None,
171 config.movielist.listtype.value,
172 config.movielist.moviesort.value,
173 config.movielist.description.value)
175 self.list = self["list"]
176 self.selectedmovie = selectedmovie
179 SelectionEventInfo.__init__(self)
181 self["key_red"] = Button(_("All..."))
182 self["key_green"] = Button("")
183 self["key_yellow"] = Button("")
184 self["key_blue"] = Button("")
186 self["freeDiskSpace"] = self.diskinfo = DiskInfo(config.movielist.last_videodir.value, DiskInfo.FREE, update=False)
188 if config.usage.setup_level.index >= 2: # expert+
189 self["InfobarActions"] = HelpableActionMap(self, "InfobarActions",
191 "showMovies": (self.doPathSelect, _("select the movie path")),
195 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
197 "contextMenu": (self.doContext, _("menu")),
198 "showEventInfo": (self.showEventInformation, _("show event details")),
201 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
203 "red": (self.showAll, _("show all")),
204 "green": (self.showTagsFirst, _("show first tag")),
205 "yellow": (self.showTagsSecond, _("show second tag")),
206 "blue": (self.showTagsMenu, _("show tag menu")),
209 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
211 "cancel": (self.abort, _("exit movielist")),
212 "ok": (self.movieSelected, _("select movie")),
215 self.onShown.append(self.go)
216 self.onLayoutFinish.append(self.saveListsize)
219 def updateDescription(self):
220 if config.movielist.description.value == MovieList.SHOW_DESCRIPTION:
221 self["DescriptionBorder"].show()
222 self["list"].instance.resize(eSize(self.listWidth, self.listHeight-self["DescriptionBorder"].instance.size().height()))
224 self["Service"].newService(None)
225 self["DescriptionBorder"].hide()
226 self["list"].instance.resize(eSize(self.listWidth, self.listHeight))
228 def showEventInformation(self):
229 from Screens.EventView import EventViewSimple
230 from ServiceReference import ServiceReference
231 evt = self["list"].getCurrentEvent()
233 self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
237 # ouch. this should redraw our "Please wait..."-text.
238 # this is of course not the right way to do this.
239 self.delayTimer.start(10, 1)
242 def saveListsize(self):
243 listsize = self["list"].instance.size()
244 self.listWidth = listsize.width()
245 self.listHeight = listsize.height()
246 self.updateDescription()
248 def updateHDDData(self):
250 if self.selectedmovie is not None:
252 self["waitingtext"].visible = False
256 self["list"].moveTo(self.selectedmovie)
258 def getCurrent(self):
259 return self["list"].getCurrent()
261 def movieSelected(self):
262 current = self.getCurrent()
263 if current is not None:
268 current = self.getCurrent()
269 if current is not None:
270 self.session.open(MovieContextMenu, self, current)
276 def saveconfig(self):
277 config.movielist.moviesort.save()
278 config.movielist.listtype.save()
279 config.movielist.description.save()
281 def getTagDescription(self, tag):
282 # TODO: access the tag database
285 def updateTags(self):
286 # get a list of tags available in this list
287 self.tags = list(self["list"].tags)
289 # by default, we do not display any filtering options
293 # when tags are present, however, the first two are
294 # directly mapped to the second, third ("green", "yellow") buttons
295 if len(self.tags) > 0:
296 self.tag_first = self.getTagDescription(self.tags[0])
298 if len(self.tags) > 1:
299 self.tag_second = self.getTagDescription(self.tags[1])
301 self["key_green"].text = self.tag_first
302 self["key_yellow"].text = self.tag_second
304 # the rest is presented in a list, available on the
305 # fourth ("blue") button
306 if len(self.tags) > 2:
307 self["key_blue"].text = _("Other...")
309 self["key_blue"].text = ""
311 def setListType(self, type):
312 self["list"].setListType(type)
314 def setDescriptionState(self, val):
315 self["list"].setDescriptionState(val)
317 def setSortType(self, type):
318 self["list"].setSortType(type)
320 def reloadList(self):
321 if not pathExists(config.movielist.last_videodir.value):
322 path = resolveFilename(SCOPE_HDD)
323 config.movielist.last_videodir.value = path
324 config.movielist.last_videodir.save()
325 self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + path)
326 self["freeDiskSpace"].path = path
327 self["list"].reload(self.current_ref, self.selected_tags)
328 title = _("Recorded files...")
329 if self.selected_tags is not None:
330 title += " - " + ','.join(self.selected_tags)
331 if config.usage.setup_level.index >= 2: # expert+
332 title += " " + config.movielist.last_videodir.value
334 self["freeDiskSpace"].update()
336 def doPathSelect(self):
337 self.session.openWithCallback(
340 _("Please select the movie path..."),
341 config.movielist.last_videodir.value
344 def gotFilename(self, res):
345 if res is not None and res is not config.movielist.last_videodir.value:
347 config.movielist.last_videodir.value = res
348 config.movielist.last_videodir.save()
349 self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
350 self["freeDiskSpace"].path = res
355 _("Directory %s nonexistent.") % (res),
356 type = MessageBox.TYPE_ERROR,
361 self.selected_tags = None
364 def showTagsN(self, n):
365 if len(self.tags) < n:
366 self.showTagWarning()
368 print "select tag #%d, %s, %s" % (n, self.tags[n - 1], ','.join(self.tags))
369 self.selected_tags = set([self.tags[n - 1]])
372 def showTagsFirst(self):
375 def showTagsSecond(self):
378 def tagChosen(self, tag):
380 self.selected_tags = set([tag[0]])
383 def showTagsMenu(self):
384 if len(self.tags) < 3:
385 self.showTagWarning()
387 list = [(tag, self.getTagDescription(tag)) for tag in self.tags ]
388 self.session.openWithCallback(self.tagChosen, ChoiceBox, title=_("Please select keyword to filter..."), list = list)
390 def showTagWarning(self):
392 self.session.open(MessageBox, _("You need to define some keywords first!\nPress the menu-key to define keywords.\nDo you want to define keywords now?"), MessageBox.TYPE_ERROR)