add new network config
[enigma2.git] / lib / python / Screens / MovieSelection.py
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, configfile
11 from Components.Sources.ServiceEvent import ServiceEvent
12
13 from Plugins.Plugin import PluginDescriptor
14
15 from Screens.MessageBox import MessageBox
16 from Screens.ChoiceBox import ChoiceBox
17 from Screens.LocationBox import LocationBox
18 from Screens.HelpMenu import HelpableScreen
19
20 from Tools.Directories import *
21 from Tools.BoundFunction import boundFunction
22
23 from enigma import eServiceReference, eServiceCenter, eTimer, eSize
24
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 # FIXME: see if this is always accessible by InfoBarGenerics
30 config.movielist.last_videodir = ConfigText(default=resolveFilename(SCOPE_HDD))
31
32 class MovieContextMenu(Screen):
33         def __init__(self, session, csel, service):
34                 Screen.__init__(self, session)
35                 self.csel = csel
36                 self.service = service
37
38                 self["actions"] = ActionMap(["OkCancelActions"],
39                         {
40                                 "ok": self.okbuttonClick,
41                                 "cancel": self.cancelClick
42                         })
43
44                 menu = [(_("delete..."), self.delete)]
45                 
46                 for p in plugins.getPlugins(PluginDescriptor.WHERE_MOVIELIST):
47                         menu.append((p.description, boundFunction(self.execPlugin, p)))
48                 
49                 if config.movielist.moviesort.value == MovieList.SORT_ALPHANUMERIC:
50                         menu.append((_("sort by date"), boundFunction(self.sortBy, MovieList.SORT_RECORDED)))
51                 else:
52                         menu.append((_("alphabetic sort"), boundFunction(self.sortBy, MovieList.SORT_ALPHANUMERIC)))
53                 
54                 menu.append((_("list style default"), boundFunction(self.listType, MovieList.LISTTYPE_ORIGINAL)))
55                 menu.append((_("list style compact with description"), boundFunction(self.listType, MovieList.LISTTYPE_COMPACT_DESCRIPTION)))
56                 menu.append((_("list style compact"), boundFunction(self.listType, MovieList.LISTTYPE_COMPACT)))
57                 menu.append((_("list style single line"), boundFunction(self.listType, MovieList.LISTTYPE_MINIMAL)))
58                 
59                 if config.movielist.description.value == MovieList.SHOW_DESCRIPTION:
60                         menu.append((_("hide extended description"), boundFunction(self.showDescription, MovieList.HIDE_DESCRIPTION)))
61                 else:
62                         menu.append((_("show extended description"), boundFunction(self.showDescription, MovieList.SHOW_DESCRIPTION)))
63                 self["menu"] = MenuList(menu)
64
65         def okbuttonClick(self):
66                 self["menu"].getCurrent()[1]()
67
68         def cancelClick(self):
69                 self.close(False)
70
71         def sortBy(self, newType):
72                 self.csel.saveflag = True
73                 config.movielist.moviesort.value = newType
74                 self.csel.selectedmovie = self.csel.getCurrent()
75                 self.csel.setSortType(newType)
76                 self.csel.reloadList()
77                 self.csel.moveTo()
78                 self.close()
79
80         def listType(self, newType):
81                 self.csel.saveflag = True
82                 config.movielist.listtype.value = newType
83                 self.csel.setListType(newType)
84                 self.csel.list.redrawList()
85                 self.close()
86
87         def showDescription(self, newType):
88                 self.csel.saveflag = True
89                 config.movielist.description.value = newType
90                 self.csel.setDescriptionState(newType)
91                 self.csel.updateDescription()
92                 self.close()
93
94         def execPlugin(self, plugin):
95                 plugin(session=self.session, service=self.service)
96
97         def delete(self):
98                 serviceHandler = eServiceCenter.getInstance()
99                 offline = serviceHandler.offlineOperations(self.service)
100                 info = serviceHandler.info(self.service)
101                 name = info and info.getName(self.service) or _("this recording")
102                 result = False
103                 if offline is not None:
104                         # simulate first
105                         if not offline.deleteFromDisk(1):
106                                 result = True
107                 if result == True:
108                         self.session.openWithCallback(self.deleteConfirmed, MessageBox, _("Do you really want to delete %s?") % (name))
109                 else:
110                         self.session.openWithCallback(self.close, MessageBox, _("You cannot delete this!"), MessageBox.TYPE_ERROR)
111
112         def deleteConfirmed(self, confirmed):
113                 if not confirmed:
114                         return self.close()
115                 
116                 serviceHandler = eServiceCenter.getInstance()
117                 offline = serviceHandler.offlineOperations(self.service)
118                 result = False
119                 if offline is not None:
120                         # really delete!
121                         if not offline.deleteFromDisk(0):
122                                 result = True
123                 
124                 if result == False:
125                         self.session.openWithCallback(self.close, MessageBox, _("Delete failed!"), MessageBox.TYPE_ERROR)
126                 else:
127                         list = self.csel["list"].removeService(self.service)
128                         self.close()
129
130 class SelectionEventInfo:
131         def __init__(self):
132                 self["Service"] = ServiceEvent()
133                 self.list.connectSelChanged(self.__selectionChanged)
134                 self.timer = eTimer()
135                 self.timer.callback.append(self.updateEventInfo)
136                 self.onShown.append(self.__selectionChanged)
137
138         def __selectionChanged(self):
139                 if self.execing and config.movielist.description.value == MovieList.SHOW_DESCRIPTION:
140                         self.timer.start(100, True)
141
142         def updateEventInfo(self):
143                 serviceref = self.getCurrent()
144                 self["Service"].newService(serviceref)
145
146 class MovieSelection(Screen, HelpableScreen, SelectionEventInfo):
147         def __init__(self, session, selectedmovie = None):
148                 Screen.__init__(self, session)
149                 HelpableScreen.__init__(self)
150
151                 self.saveflag = False
152
153                 self.tags = [ ]
154                 self.selected_tags = None
155
156                 self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + config.movielist.last_videodir.value)
157
158                 self.movemode = False
159                 self.bouquet_mark_edit = False
160
161                 self.delayTimer = eTimer()
162                 self.delayTimer.callback.append(self.updateHDDData)
163
164                 self["waitingtext"] = Label(_("Please wait... Loading list..."))
165
166                 # create optional description border and hide immediately
167                 self["DescriptionBorder"] = Pixmap()
168                 self["DescriptionBorder"].hide()
169
170                 self["list"] = MovieList(None,
171                         config.movielist.listtype.value,
172                         config.movielist.moviesort.value,
173                         config.movielist.description.value)
174
175                 self.list = self["list"]
176                 self.selectedmovie = selectedmovie
177
178                 # Need list for init
179                 SelectionEventInfo.__init__(self)
180
181                 self["key_red"] = Button(_("All..."))
182                 self["key_green"] = Button("")
183                 self["key_yellow"] = Button("")
184                 self["key_blue"] = Button("")
185
186                 #self["freeDiskSpace"] = DiskInfo(resolveFilename(SCOPE_HDD), DiskInfo.FREE, update=False)
187                 self["freeDiskSpace"] = self.diskinfo = DiskInfo(resolveFilename(SCOPE_HDD), DiskInfo.FREE, update=False)
188
189                 if config.usage.setup_level.index >= 2: # expert+
190                         self["InfobarActions"] = HelpableActionMap(self, "InfobarActions", 
191                                 {
192                                         "showMovies": (self.doPathSelect, _("select the movie path")),
193                                 })
194
195
196                 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
197                         {
198                                 "contextMenu": (self.doContext, _("menu")),
199                                 "showEventInfo": (self.showEventInformation, _("show event details")),
200                         })
201
202                 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
203                         {
204                                 "red": (self.showAll, _("show all")),
205                                 "green": (self.showTagsFirst, _("show first tag")),
206                                 "yellow": (self.showTagsSecond, _("show second tag")),
207                                 "blue": (self.showTagsMenu, _("show tag menu")),
208                         })
209
210                 self["OkCancelActions"] = HelpableActionMap(self, "OkCancelActions",
211                         {
212                                 "cancel": (self.abort, _("exit movielist")),
213                                 "ok": (self.movieSelected, _("select movie")),
214                         })
215
216                 self.onShown.append(self.go)
217                 self.inited = False
218
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()))
223                 else:
224                         self["Service"].newService(None)
225                         self["DescriptionBorder"].hide()
226                         self["list"].instance.resize(eSize(self.listWidth, self.listHeight))
227
228         def showEventInformation(self):
229                 from Screens.EventView import EventViewSimple
230                 from ServiceReference import ServiceReference
231                 evt = self["list"].getCurrentEvent()
232                 if evt:
233                         self.session.open(EventViewSimple, evt, ServiceReference(self.getCurrent()))
234
235         def go(self):
236                 if not self.inited:
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)
240                         self.inited=True
241                 # as this workaround is here anyways we can wait until the skin is initialized
242                 # and afterwards read out the information we need to draw the dynamic style
243                         listsize = self["list"].instance.size()
244                         self.listWidth = listsize.width()
245                         self.listHeight = listsize.height()
246                         self.updateDescription()
247
248         def updateHDDData(self):
249                 self.reloadList()
250                 if self.selectedmovie is not None:
251                         self.moveTo()
252                 self["waitingtext"].visible = False
253                 self["freeDiskSpace"].update()
254                 self.updateTags()
255
256         def moveTo(self):
257                 self["list"].moveTo(self.selectedmovie)
258
259         def getCurrent(self):
260                 return self["list"].getCurrent()
261
262         def movieSelected(self):
263                 current = self.getCurrent()
264                 if current is not None:
265                         self.saveconfig()
266                         self.close(current)
267
268         def doContext(self):
269                 current = self.getCurrent()
270                 if current is not None:
271                         self.session.open(MovieContextMenu, self, current)
272
273         def abort(self):
274                 self.saveconfig()
275                 self.close(None)
276
277         def saveconfig(self):
278                 if self.saveflag == True:
279                         config.movielist.moviesort.save()
280                         config.movielist.listtype.save()
281                         config.movielist.description.save()
282                         configfile.save()
283                         self.saveflag = False
284
285         def getTagDescription(self, tag):
286                 # TODO: access the tag database
287                 return tag
288
289         def updateTags(self):
290                 # get a list of tags available in this list
291                 self.tags = list(self["list"].tags)
292                 
293                 # by default, we do not display any filtering options
294                 self.tag_first = ""
295                 self.tag_second = ""
296                 
297                 # when tags are present, however, the first two are 
298                 # directly mapped to the second, third ("green", "yellow") buttons
299                 if len(self.tags) > 0:
300                         self.tag_first = self.getTagDescription(self.tags[0])
301                 
302                 if len(self.tags) > 1:
303                         self.tag_second = self.getTagDescription(self.tags[1])
304                 
305                 self["key_green"].text = self.tag_first
306                 self["key_yellow"].text = self.tag_second
307                 
308                 # the rest is presented in a list, available on the
309                 # fourth ("blue") button
310                 if len(self.tags) > 2:
311                         self["key_blue"].text = _("Other...")
312                 else:
313                         self["key_blue"].text = ""
314
315         def setListType(self, type):
316                 self["list"].setListType(type)
317
318         def setDescriptionState(self, val):
319                 self["list"].setDescriptionState(val)
320
321         def setSortType(self, type):
322                 self["list"].setSortType(type)
323
324         def reloadList(self):
325                 self["list"].reload(self.current_ref, self.selected_tags)
326                 title = _("Recorded files...")
327                 if self.selected_tags is not None:
328                         title += " - " + ','.join(self.selected_tags)
329                 if config.usage.setup_level.index >= 2: # expert+
330                         title += "  " + config.movielist.last_videodir.value
331                 self.setTitle(title)
332
333         def doPathSelect(self):
334                 self.session.openWithCallback(
335                         self.gotFilename,
336                         LocationBox,
337                         _("Please select the movie path..."),
338                         currDir = config.movielist.last_videodir.value
339                 )
340
341         def gotFilename(self, res):
342                 if res is not None and res is not config.movielist.last_videodir.value:
343                         config.movielist.last_videodir.value = res
344                         self.current_ref = eServiceReference("2:0:1:0:0:0:0:0:0:0:" + res)
345                         self.reloadList()
346                         self.updateTags()
347
348         def showAll(self):
349                 self.selected_tags = None
350                 self.reloadList()
351
352         def showTagsN(self, n):
353                 if len(self.tags) < n:
354                         self.showTagWarning()
355                 else:
356                         print "select tag #%d, %s, %s" % (n, self.tags[n - 1], ','.join(self.tags))
357                         self.selected_tags = set([self.tags[n - 1]])
358                         self.reloadList()
359
360         def showTagsFirst(self):
361                 self.showTagsN(1)
362
363         def showTagsSecond(self):
364                 self.showTagsN(2)
365
366         def tagChosen(self, tag):
367                 if tag is not None:
368                         self.selected_tags = set([tag[0]])
369                         self.reloadList()
370
371         def showTagsMenu(self):
372                 if len(self.tags) < 3:
373                         self.showTagWarning()
374                 else:
375                         list = [(tag, self.getTagDescription(tag)) for tag in self.tags ]
376                         self.session.openWithCallback(self.tagChosen, ChoiceBox, title=_("Please select keyword to filter..."), list = list)
377
378         def showTagWarning(self):
379                 # TODO
380                 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)