don't crash when exitting dvd image selection without selection
[vuplus_dvbapp] / lib / python / Plugins / Extensions / DVDBurn / TitleList.py
1 import DVDProject, TitleList, TitleCutter, ProjectSettings, DVDToolbox, Process
2 from Screens.Screen import Screen
3 from Screens.ChoiceBox import ChoiceBox
4 from Screens.InputBox import InputBox
5 from Screens.MessageBox import MessageBox
6 from Screens.HelpMenu import HelpableScreen
7 from Screens.TaskView import JobView
8 from Components.Task import job_manager
9 from Components.ActionMap import HelpableActionMap, ActionMap
10 from Components.Sources.List import List
11 from Components.Sources.StaticText import StaticText
12 from Components.Sources.Progress import Progress
13 from Components.Label import Label
14 from enigma import eListboxPythonMultiContent, gFont, RT_HALIGN_LEFT
15 from Tools.Directories import resolveFilename, SCOPE_PLUGINS
16
17 class TitleList(Screen, HelpableScreen):
18         skin = """
19                 <screen position="90,83" size="560,445" title="DVD Tool" >
20                     <ePixmap pixmap="skin_default/buttons/red.png" position="0,0" size="140,40" alphatest="on" />
21                     <ePixmap pixmap="skin_default/buttons/green.png" position="140,0" size="140,40" alphatest="on" />
22                     <ePixmap pixmap="skin_default/buttons/yellow.png" position="280,0" size="140,40" alphatest="on" />
23                     <ePixmap pixmap="skin_default/buttons/blue.png" position="420,0" size="140,40" alphatest="on" />
24                     <widget source="key_red" render="Label" position="0,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#9f1313" transparent="1" />
25                     <widget source="key_green" render="Label" position="140,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#1f771f" transparent="1" />
26                     <widget source="key_yellow" render="Label" position="280,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#a08500" transparent="1" />
27                     <widget source="key_blue" render="Label" position="420,0" zPosition="1" size="140,40" font="Regular;20" halign="center" valign="center" backgroundColor="#18188b" transparent="1" />
28                     <widget source="title_label" render="Label" position="10,48" size="540,38" font="Regular;18" />
29                     <widget name="error_label" position="10,48" size="540,395" zPosition="3" font="Regular;20" />
30                     <widget source="titles" render="Listbox" scrollbarMode="showOnDemand" position="10,86" size="540,312">
31                         <convert type="StaticMultiList" />
32                     </widget>
33                     <widget source="space_bar" render="Progress" position="10,410" size="540,26" borderWidth="1" backgroundColor="#254f7497" />
34                     <widget source="space_label" render="Label" position="40,414" size="480,22" zPosition="2" font="Regular;18" halign="center" transparent="1" foregroundColor="#000000" />
35                 </screen>"""
36
37         def __init__(self, session, project = None):
38                 Screen.__init__(self, session)
39                 HelpableScreen.__init__(self)
40                 
41                 self["titleactions"] = HelpableActionMap(self, "DVDTitleList",
42                         {
43                                 "addTitle": (self.addTitle, _("Add a new title"), _("Add title")),
44                                 "editTitle": (self.editTitle, _("Edit chapters of current title"), _("Edit title")),
45                                 "removeCurrentTitle": (self.removeCurrentTitle, _("Remove currently selected title"), _("Remove title")),
46                                 "settings": (self.settings, _("Collection settings"), _("Settings")),
47                                 "burnProject": (self.burnProject, _("Burn DVD"), _("Burn DVD")),
48                         })
49
50                 self["MovieSelectionActions"] = HelpableActionMap(self, "MovieSelectionActions",
51                         {
52                                 "contextMenu": (self.showMenu, _("menu")),
53                         })
54
55                 self["actions"] = ActionMap(["OkCancelActions"],
56                         {
57                                 "cancel": self.leave
58                         })
59
60                 self["key_red"] = StaticText(_("Remove title"))
61                 self["key_green"] = StaticText(_("Add title"))
62                 self["key_yellow"] = StaticText(_("Edit title"))
63                 self["key_blue"] = StaticText(_("Settings"))
64
65                 self["title_label"] = StaticText()
66                 self["error_label"] = Label("")
67                 self["space_label"] = StaticText()
68                 self["space_bar"] = Progress()
69
70                 if project is not None:
71                         self.project = project
72                 else:
73                         self.newProject()
74
75                 self["titles"] = List(list = [ ], enableWrapAround = True, item_height=30, fonts = [gFont("Regular", 20)])
76                 self.updateTitleList()
77                 
78         def showMenu(self):
79                 menu = []
80                 if self.project.settings.output.getValue() == "dvd":
81                         menu.append((_("Burn DVD"), "burn"));
82                 elif self.project.settings.output.getValue() == "iso":
83                         menu.append((_("Create DVD-ISO"), "burn"));
84                 menu.append((_("Preview menu"), "previewMenu"));
85                 menu.append((_("DVD media toolbox"), "toolbox"));
86                 menu.append((_("Collection settings"), "settings"));
87                 menu.append((_("Add a new title"), "addtitle"));
88                 menu.append((_("Remove title"), "removetitle"));
89                 menu.append((_("Edit chapters of current title"), "edittitle"));
90                 menu.append((_("Burn existing image to DVD"), "burniso"));
91                 menu.append((_("Exit"), "exit"));
92                 self.session.openWithCallback(self.menuCallback, ChoiceBox, title="", list=menu)
93
94         def menuCallback(self, choice):
95                 if choice is None:
96                         return
97                 if choice[1] == "removetitle":
98                         self.removeCurrentTitle()
99                 elif choice[1] == "addtitle":
100                         self.addTitle()
101                 elif choice[1] == "edittitle":
102                         self.editTitle()
103                 elif choice[1] == "toolbox":
104                         self.toolbox()
105                 elif choice[1] == "settings":
106                         self.settings()
107                 elif choice[1] == "previewMenu":
108                         self.previewMenu()
109                 elif choice[1] == "burn":
110                         self.burnProject()
111                 elif choice[1] == "burniso":
112                         self.session.openWithCallback(self.burnISO, ProjectSettings.FileBrowser, "image", self.project.settings)
113                 elif choice[1] == "exit":
114                         self.leave()
115
116         def newProject(self):
117                 self.project = DVDProject.DVDProject()
118                 if self.loadTemplate():
119                         self.project.session = self.session
120                         self.settingsCB()
121
122         def addTitle(self):
123                 from Screens.MovieSelection import MovieSelection
124                 from Components.Button import Button
125                 from Components.ActionMap import HelpableActionMap
126                 class MovieSelectionNoMenu(MovieSelection):
127                         def __init__(self, session):
128                                 MovieSelection.__init__(self, session)
129                                 self.skinName = "MovieSelection"
130                                 self["key_red"] = Button(_("Edit title"))
131                                 self["key_green"] = Button(_("Add"))
132                                 self["ColorActions"] = HelpableActionMap(self, "ColorActions",
133                                 {
134                                         "red": (self.movieSelected, _("Add a new title")),
135                                         "green": (self.insertWithoutEdit, ("insert without cutlist editor"))
136                                 })
137                         def updateTags(self):
138                                 pass
139                         def doContext(self):
140                                 print "context menu forbidden inside DVDBurn to prevent calling multiple instances"
141                         def insertWithoutEdit(self):
142                                 current = self.getCurrent()
143                                 if current is not None:
144                                         current.edit = False
145                                         self.close(current)
146                         def movieSelected(self):
147                                 current = self.getCurrent()
148                                 if current is not None:
149                                         current.edit = True
150                                         self.close(current)
151                 self.session.openWithCallback(self.selectedSource, MovieSelectionNoMenu)
152
153         def selectedSource(self, source):
154                 if source is None:
155                         return None
156                 t = self.project.addService(source)
157                 try:
158                         editor = source.edit
159                 except AttributeError:
160                         editor = True
161                 self.editTitle(t, editor)
162
163         def removeCurrentTitle(self):
164                 title = self.getCurrentTitle()
165                 self.removeTitle(title)
166         
167         def removeTitle(self, title):
168                 if title is not None:
169                         self.project.titles.remove(title)
170                         self.updateTitleList()
171
172         def toolbox(self):
173                 self.session.open(DVDToolbox.DVDToolbox)
174
175         def settings(self):
176                 self.session.openWithCallback(self.settingsCB, ProjectSettings.ProjectSettings, self.project)
177
178         def settingsCB(self, update=True):
179                 if not update:
180                         return
181                 self["title_label"].text = _("Table of content for collection") + " \"" + self.project.settings.name.getValue() + "\":"
182
183         def loadTemplate(self):
184                 filename = resolveFilename(SCOPE_PLUGINS)+"Extensions/DVDBurn/DreamboxDVDtemplate.ddvdp.xml"
185                 if self.project.loadProject(filename):
186                         self["error_label"].hide()
187                         return True
188                 else:
189                         self["error_label"].text = self.project.error
190                         self["error_label"].show()
191                         return False
192
193         def burnProject(self):
194                 if self.project.settings.authormode.getValue() == "data_ts":
195                         job = Process.DVDdataJob(self.project)
196                         job_manager.AddJob(job)
197                         job_manager.in_background = False
198                         self.session.openWithCallback(self.JobViewCB, JobView, job)
199                 else:
200                         autochapter = self.project.settings.autochapter.getValue()
201                         if autochapter > 0:
202                                 for title in self.project.titles:
203                                         title.produceAutoChapter(autochapter)
204                         job = Process.DVDJob(self.project)
205                         job_manager.AddJob(job)
206                         job_manager.in_background = False
207                         self.session.openWithCallback(self.JobViewCB, JobView, job)
208
209         def burnISO(self, path, scope):
210                 if path:
211                         job = Process.DVDisoJob(self.project, path)
212                         job_manager.AddJob(job)
213                         job_manager.in_background = False
214                         self.session.openWithCallback(self.JobViewCB, JobView, job)
215
216         def JobViewCB(self, in_background):
217                 job_manager.in_background = in_background
218
219         def previewMenu(self):
220                 job = Process.DVDJob(self.project, menupreview=True)
221                 job_manager.in_background = False
222                 job_manager.AddJob(job)
223                 
224         def updateTitleList(self):
225                 res = [ ]
226                 totalsize = 0
227                 for title in self.project.titles:
228                         a = [ title, (eListboxPythonMultiContent.TYPE_TEXT, 0, 10, 500, 50, 0, RT_HALIGN_LEFT, title.name)  ]
229                         res.append(a)
230                         totalsize += title.estimatedDiskspace
231                 self["titles"].list = res
232                 self.updateSize(totalsize)
233                 
234         def updateSize(self, totalsize):
235                 size = int((totalsize/1024)/1024)
236                 max_SL = 4370
237                 max_DL = 7950
238                 if size > max_DL:
239                         percent = 100 * size / float(max_DL)
240                         self["space_label"].text = "%d MB - " % size + _("exceeds dual layer medium!") + " (%.2f%% " % (100-percent) + _("free") + ")"
241                         self["space_bar"].value = int(percent)
242                 elif size > max_SL:
243                         percent = 100 * size / float(max_DL)
244                         self["space_label"].text = "%d MB  " % size + _("of a DUAL layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
245                         self["space_bar"].value = int(percent)
246                 elif size < max_SL:
247                         percent = 100 * size / float(max_SL)
248                         self["space_label"].text = "%d MB " % size + _("of a SINGLE layer medium used.") + " (%.2f%% " % (100-percent) + _("free") + ")"
249                         self["space_bar"].value = int(percent)
250
251         def getCurrentTitle(self):
252                 t = self["titles"].getCurrent()
253                 return t and t[0]
254
255         def editTitle(self, title = None, editor = True):
256                 t = title or self.getCurrentTitle()
257                 if t is not None:
258                         self.current_edit_title = t
259                         if editor:
260                                 self.session.openWithCallback(self.titleEditDone, TitleCutter.TitleCutter, t)
261                         else:
262                                 self.session.openWithCallback(self.titleEditDone, TitleCutter.CutlistReader, t)
263
264         def titleEditDone(self, cutlist):
265                 t = self.current_edit_title
266                 t.cuesheet = cutlist
267                 t.produceFinalCuesheet()
268                 if t.sVideoType != 0:
269                         self.session.openWithCallback(self.DVDformatCB,MessageBox,text = _("The DVD standard doesn't support H.264 (HDTV) video streams. Do you want to create a Dreambox format data DVD (which will not play in stand-alone DVD players) instead?"), type = MessageBox.TYPE_YESNO)
270                 else:
271                         self.updateTitleList()
272
273         def DVDformatCB(self, answer):
274                 t = self.current_edit_title
275                 if answer == True:
276                         self.project.settings.authormode.setValue("data_ts")
277                         self.updateTitleList()
278                 else:
279                         self.removeTitle(t)
280
281         def leave(self):
282                 self.close()