1"""
2 File:
3 JetDialogs.py
4
5 Contents and purpose:
6 Dialog boxes used in JetCreator
7
8 Copyright (c) 2008 Android Open Source Project
9
10 Licensed under the Apache License, Version 2.0 (the "License");
11 you may not use this file except in compliance with the License.
12 You may obtain a copy of the License at
13
14      http://www.apache.org/licenses/LICENSE-2.0
15
16 Unless required by applicable law or agreed to in writing, software
17 distributed under the License is distributed on an "AS IS" BASIS,
18 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 See the License for the specific language governing permissions and
20 limitations under the License.
21"""
22
23import wx
24import thread
25import wx.lib.newevent
26
27from JetDefs import *
28from JetCtrls import *
29from JetFile import *
30from JetUtils import *
31from JetPreview import *
32from JetSegGraph import *
33from eas import *
34from JetStatusEvent import *
35
36PLAY_SEGMENT = 1
37PLAY_MIDI = 2
38
39class JetEdit():
40    """ Class used to build dialog box controls from the definitions in JetDefs """
41    def __init__(self, panel, ctrlList, callbackClass):
42        LBL_OFFSET = 15
43
44        ctrls = getattr(JetDefs, ctrlList)
45        self.ctrls = {}
46        for Lbl, Text, Row, Col, Len, Min, Max, Id, Lst, Fct, Enabled, HelpText in ctrls:
47            try:
48                iDisplayLbl = True
49                if Text[0:3] == "btn":
50                    self.ctrls[Text] = wx.Button(panel, Id, Lbl, wx.Point(Col, Row), size=Len)
51                    if Fct > "":
52                        self.ctrls[Text].Bind(wx.EVT_BUTTON, getattr(callbackClass, Fct), self.ctrls[Text], id=Id)
53                    if Id == wx.ID_OK:
54                        self.ctrls[Text].SetDefault()
55                    iDisplayLbl = False
56                else:
57                    if Text[0:3] == "txt":
58                        self.ctrls[Text] = wx.TextCtrl(panel, Id, "", wx.Point(Col, Row + LBL_OFFSET +3), wx.Size(Len,-1))
59                    elif Text[0:4] == "spn1":
60                        self.ctrls[Text] = JetSpinOneBased(panel, Id, "", wx.Point(Col, Row + LBL_OFFSET), wx.Size(Len,-1), min=Min, max=Max)
61                    elif Text[0:3] == "spn":
62                        self.ctrls[Text] = JetSpin(panel, Id, "", wx.Point(Col, Row + LBL_OFFSET), wx.Size(Len,-1), min=Min, max=Max)
63                    elif Text[0:3] == "cmb":
64                        self.ctrls[Text] = wx.ComboBox(panel, Id, "", wx.Point(Col, Row + LBL_OFFSET), wx.Size(Len,-1), Lst, wx.CB_DROPDOWN | wx.CB_READONLY )
65                        self.ctrls[Text].SetValue(Lst[0])
66                        if Fct > "":
67                            self.ctrls[Text].Bind(wx.EVT_COMBOBOX, getattr(callbackClass, Fct), self.ctrls[Text])
68                    elif Text[0:2] == "tm":
69                        self.ctrls[Text] = TimeCtrl(panel, pos=(Col, Row + LBL_OFFSET), ctlName=Text)
70                    elif Text[0:7] == "filecmb":
71                        self.ctrls[Text] = JetFileCombo(panel, pos=(Col, Row + LBL_OFFSET), size=wx.Size(Len,-1), title=Lbl, spec=Lst, id=Id)
72                    elif Text[0:7] == "filetxt":
73                        self.ctrls[Text] = JetFileText(panel, pos=(Col, Row + LBL_OFFSET), size=wx.Size(Len,-1), title=Lbl, spec=Lst, id=Id)
74                    elif Text[0:2] == "fr":
75                        self.ctrls[Text] = wx.StaticBox(parent=panel, id=wx.ID_ANY, label=Lbl, pos=(Row, Col), size=Len)
76                        iDisplayLbl = False
77                    elif Text[0:3] == "chk":
78                        self.ctrls[Text] = JetCheckBox(panel, Id, label=Lbl, pos=(Col, Row), size=wx.Size(Len,-1))
79                        iDisplayLbl = False
80                        if Fct > "":
81                            self.ctrls[Text].Bind(wx.EVT_CHECKBOX , getattr(callbackClass, Fct), self.ctrls[Text])
82                    elif Text[0:6] == "rdobox":
83                        self.ctrls[Text] = wx.RadioBox(panel, Id, label=Lbl, pos=(Col, Row), size=Len, choices=Lst, majorDimension=1, style=wx.RA_SPECIFY_COLS)
84                        iDisplayLbl = False
85                        if Fct > "":
86                            self.ctrls[Text].Bind(wx.EVT_RADIOBOX , getattr(callbackClass, Fct), self.ctrls[Text])
87                    elif Text[0:3] == "opt":
88                        self.ctrls[Text] = JetRadioButton(panel, Id, label=Lbl, pos=(Col, Row), size=wx.Size(Len,-1))
89                        iDisplayLbl = False
90                        self.ctrls[Text].SetValue(Lst)
91                        if Fct > "":
92                            self.ctrls[Text].Bind(wx.EVT_RADIOBUTTON , getattr(callbackClass, Fct), self.ctrls[Text])
93                    elif Text[0:3] == "lst":
94                        self.ctrls[Text] = wx.ListBox(panel, Id, pos=(Col, Row), size=Len)
95                        iDisplayLbl = False
96                    elif Text[0:4] == "grd2":
97                        self.ctrls[Text] = JetTrackCtrl(panel, Id, pos=(Col, Row + LBL_OFFSET), size=Len, style=wx.LC_REPORT | wx.SUNKEN_BORDER)
98                        iDisplayLbl = True
99                    elif Text[0:3] == "grd":
100                        self.ctrls[Text] = JetListCtrl(panel, Id, pos=(Col, Row), size=Len)
101                        iDisplayLbl = False
102                    elif Text[0:5] == "graph":
103                        self.ctrls[Text] = SegmentGraph(panel, pos=(Col, Row), size=Len)
104                        iDisplayLbl = False
105                    elif Text[0:3] == "hlp":
106                        self.ctrls[Text] = wx.ContextHelpButton(panel, Id, pos=(Col, Row))
107                        iDisplayLbl = False
108                    elif Text[0:3] == "lbl":
109                        self.ctrls[Text] = wx.StaticText(panel, Id, Lbl, wx.Point(Col, Row), size=wx.Size(Len[0],Len[1]))
110                        iDisplayLbl = False
111                    elif Text[0:3] == "box":
112                        self.ctrls[Text] = wx.StaticBox(panel, wx.ID_ANY, Lbl, pos=(Col, Row), size=Len)
113                        iDisplayLbl = False
114
115                if iDisplayLbl:
116                    self.ctrls[Lbl] = wx.StaticText(panel, Id, Lbl, wx.Point(Col, Row))
117                if not Enabled:
118                    self.ctrls[Text].Enable(False)
119
120                helpText = IniGetValue(JetDefs.JETCREATOR_HLP, ctrlList, Lbl)
121                if helpText > "":
122                    self.ctrls[Text].SetHelpText(helpText)
123
124            #except AttributeError:
125                #No stub function for testing
126                #print("def " + Fct + "(self, event): pass")
127            except:
128                raise
129
130    def GetValue(self, fld):
131        """ Gets the value of a control """
132        return self.ctrls[fld].GetValue()
133
134    def SetValue(self, fld, val):
135        """ Sets the value of a control """
136        self.ctrls[fld].SetValue(val)
137
138class JetOpen(wx.Dialog):
139    """ Opens a jet definition file """
140    def __init__(self):
141        wx.Dialog.__init__(self, None, -1, JetDefs.DLG_JETOPEN)
142        self.fileName = ""
143        self.je = JetEdit(self, "JETOPEN_CTRLS", self)
144        fileList = GetRecentJetFiles()
145        self.je.ctrls[JetDefs.F_JLIST].AppendItems(fileList)
146        if len(fileList) > 0:
147            self.je.ctrls[JetDefs.F_JFILE].SetValue(fileList[0])
148        self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnOpen)
149        self.Bind(wx.EVT_LISTBOX, self.OnClick)
150        self.SetSize(JetDefs.JETOPEN_SIZE)
151        self.CenterOnParent()
152
153    def OnJetImport(self, event):
154        """ Exit the dialog with flag to import """
155        self.EndModal(JetDefs.ID_JET_IMPORT)
156
157    def OnClick(self, event):
158        """ Clicking on item in listbox """
159        sValue = self.je.ctrls[JetDefs.F_JLIST].GetString(self.je.ctrls[JetDefs.F_JLIST].GetSelection())
160        self.je.ctrls[JetDefs.F_JFILE].SetValue(sValue)
161
162    def OnOpen(self, event):
163        """ Double clicking on item in listbox """
164        sValue = self.je.ctrls[JetDefs.F_JLIST].GetString(self.je.ctrls[JetDefs.F_JLIST].GetSelection())
165        self.je.ctrls[JetDefs.F_JFILE].SetValue(sValue)
166        if self.Validate():
167            self.fileName = self.je.ctrls[JetDefs.F_JFILE].GetValue()
168            AppendRecentJetFile(self.fileName)
169            self.EndModal(JetDefs.ID_JET_OPEN)
170
171    def OnOk(self, event):
172        """ Clicking the ok button """
173        if self.Validate():
174            self.fileName = self.je.ctrls[JetDefs.F_JFILE].GetValue()
175            AppendRecentJetFile(self.fileName)
176            self.EndModal(JetDefs.ID_JET_OPEN)
177
178    def OnNew(self, event):
179        """ Exit the dialog with flag to create new blank jet file """
180        self.EndModal(JetDefs.ID_JET_NEW)
181
182    def Validate(self):
183        """ Validates the filename """
184        if len(self.je.ctrls[JetDefs.F_JFILE].GetValue()) == 0:
185            InfoMsg("Jet Filename", "The Jet filename is blank.")
186            self.je.ctrls[JetDefs.F_JFILE].SetFocus()
187            return False
188        if not FileExists(self.je.ctrls[JetDefs.F_JFILE].GetValue()):
189            InfoMsg("MIDI File", "The file does not exist.")
190            self.je.ctrls[JetDefs.F_JFILE].SetFocus()
191            return False
192        return True
193
194class JetPreferences(wx.Dialog):
195    """ Preferences dialog box """
196    def __init__(self):
197        wx.Dialog.__init__(self, None, -1, JetDefs.DLG_PREFERENCES)
198        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
199        self.je = JetEdit(self, "PREFERENCES_CTRLS", self)
200        self.SetSize(JetDefs.PREFERENCES_SIZE)
201        self.CenterOnParent()
202
203    def OnOk(self, event):
204        self.EndModal(wx.ID_OK)
205
206    def GetValue(self, fld):
207        return self.je.ctrls[fld].GetValue()
208
209    def SetValue(self, fld, val):
210        self.je.ctrls[fld].SetValue(val)
211
212
213class JetAbout(wx.Dialog):
214    """ About dialog box """
215    def __init__(self):
216        wx.Dialog.__init__(self, None, -1, JetDefs.DLG_ABOUT)
217        img = __import__('img_splash')
218        bmp = img.getBitmap()
219        b = wx.StaticBitmap(self, -1, bmp)
220        self.SetSize((bmp.GetWidth(), bmp.GetHeight()))
221        self.CenterOnParent()
222        s = __import__('sys')
223        print(s.platform)
224
225    def OnOk(self, event):
226        self.EndModal(wx.ID_OK)
227
228    def GetValue(self, fld):
229        return self.je.ctrls[fld].GetValue()
230
231    def SetValue(self, fld, val):
232        self.je.ctrls[fld].SetValue(val)
233
234
235class JetPropertiesDialog(wx.Dialog):
236    """ Properties dialog box """
237    def __init__(self):
238        wx.Dialog.__init__(self, None, -1, JetDefs.DLG_PROPERTIES)
239        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
240        self.je = JetEdit(self, "JET_PROPERTIES_CTRLS", self)
241        self.SetSize(JetDefs.JET_PROPERTIES_SIZE)
242        self.CenterOnParent()
243
244    def OnOk(self, event):
245        self.EndModal(wx.ID_OK)
246
247    def GetValue(self, fld):
248        return self.je.ctrls[fld].GetValue()
249
250    def SetValue(self, fld, val):
251        self.je.ctrls[fld].SetValue(val)
252
253
254class JetErrors(wx.Dialog):
255    """ Errors dialog box """
256    def __init__(self, title):
257        wx.Dialog.__init__(self, None, -1, title)
258        self.je = JetEdit(self, "ERRORDLG", self)
259        self.SetSize(JetDefs.ERRORDLG_SIZE)
260        self.CenterOnParent()
261
262    def OnOk(self, event):
263        self.EndModal(wx.ID_OK)
264
265    def SetErrors(self, errors):
266        self.je.ctrls[JetDefs.F_ERRGRID].AddCol("Error", JetDefs.ERRORCOLW)
267        self.je.ctrls[JetDefs.F_ERRGRID].AddCol("Description", JetDefs.ERRORCOLW)
268        self.je.ctrls[JetDefs.F_ERRGRID].AddRows(errors)
269
270
271class SegEdit(wx.Dialog):
272    """ Dialog box to edit segments """
273    def __init__(self, title, currentJetConfigFile):
274        wx.Dialog.__init__(self, None, -1, title)
275        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
276        self.currentJetConfigFile = currentJetConfigFile
277        self.je = JetEdit(self, "SEGDLG_CTRLS", self)
278        self.je.ctrls[JetDefs.F_MIDIFILE].cmb.Bind(wx.EVT_KILL_FOCUS, self.OnMidiChanged)
279        self.je.ctrls[JetDefs.F_MIDIFILE].cmb.Bind(wx.EVT_COMBOBOX, self.OnMidiChanged)
280        self.je.ctrls[JetDefs.F_MIDIFILE].SetEventFire(True)
281        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_TRACK, JetDefs.MUTEGRD_TRACK)
282        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_CHANNEL, JetDefs.MUTEGRD_CHANNEL)
283        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_NAME, JetDefs.MUTEGRD_NAME)
284        self.je.ctrls[JetDefs.F_MUTEFLAGS].BindCheckBox(self.OnEventChecked)
285        self.je.ctrls[JetDefs.F_START].SetChangeCallbackFct(self.UpdateGraph)
286        self.je.ctrls[JetDefs.F_END].SetChangeCallbackFct(self.UpdateGraph)
287        self.je.ctrls[JetDefs.F_DISPEMPTYTRACKS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_DISPEMPTYTRACKS, JetDefs.F_DISPEMPTYTRACKS, 'bool', 'False'))
288        self.je.ctrls[JetDefs.F_GRAPHLABELS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'))
289        self.je.ctrls[JetDefs.F_GRAPHCLIPS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'))
290        self.je.ctrls[JetDefs.F_GRAPHAPPEVTS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
291        self.replicatePrefix = ""
292        self.lstReplicate = []
293        self.chkReplaceMatching = False
294
295        EVT_JET_STATUS(self, self.OnJetStatusUpdate)
296        wx.EVT_CLOSE(self, self.OnClose)
297
298        self.Player = None
299        self.segment = None
300        self.graphSegment = None
301        self.jetevents = []
302        self.lastMidiFile = ""
303        self.lastMidiInfo = None
304        self.playMode = PLAY_SEGMENT
305        self.graphMode = PLAY_MIDI
306        self.SetSize(JetDefs.SEGDLG_SIZE)
307        self.CenterOnParent()
308
309    def OnClose(self, event):
310        """ Closing the dialog box """
311        self.ShutdownPlayer()
312        self.je.ctrls[JetDefs.F_START].UnBindKillFocus()
313        self.je.ctrls[JetDefs.F_END].UnBindKillFocus()
314        self.EndModal(wx.ID_CANCEL)
315
316    def ShutdownPlayer(self):
317        """ Shutdown player flag """
318        if self.Player is not None:
319            self.Player.SetKeepPlayingFlag(False)
320
321    def OnMidiChanged(self, event):
322        """ When new midi file selected, get its info """
323        self.UpdateMaxMbt()
324        event.Skip()
325
326    def UpdateMaxMbt(self):
327        """ Get midi info in thread so UI smoother """
328        thread.start_new_thread(self.UpdateMaxMbtThread, ())
329
330    def UpdateMaxMbtThread(self):
331        """ Thread to get midi file info """
332        if self.je.ctrls[JetDefs.F_MIDIFILE].GetValue() == self.lastMidiFile:
333            return
334        self.lastMidiFile = self.je.ctrls[JetDefs.F_MIDIFILE].GetValue()
335        self.lastMidiInfo = GetMidiInfo(self.je.ctrls[JetDefs.F_MIDIFILE].GetValue())
336        wx.PostEvent(self, JetStatusEvent(JetDefs.PST_MIDI_INFO, self.lastMidiInfo))
337
338    def GetValue(self, fld):
339        """ Gets a control value """
340        return self.je.ctrls[fld].GetValue()
341
342    def SetValue(self, fld, val):
343        """ Sets a control value """
344        self.je.ctrls[fld].SetValue(val)
345        if self.je.ctrls[fld] == self.je.ctrls[JetDefs.F_MIDIFILE]:
346            self.UpdateMaxMbt()
347
348    def OnOk(self, event):
349        """ Exits dialog box """
350        self.ShutdownPlayer()
351        if self.Validate():
352            self.je.ctrls[JetDefs.F_START].UnBindKillFocus()
353            self.je.ctrls[JetDefs.F_END].UnBindKillFocus()
354            self.EndModal(wx.ID_OK)
355
356    def Validate(self):
357        """ Validates the control values before exiting """
358        if not CompareMbt(self.je.ctrls[JetDefs.F_START].GetValue(), self.je.ctrls[JetDefs.F_END].GetValue()):
359            InfoMsg("Start/End", "The segment starting and ending times are illogical.")
360            self.je.ctrls[JetDefs.F_START].SetFocus()
361            return False
362        if len(self.je.ctrls[JetDefs.F_SEGNAME].GetValue()) == 0:
363            InfoMsg("Segment Name", "The segment must have a name.")
364            self.je.ctrls[JetDefs.F_SEGNAME].SetFocus()
365            return False
366        if len(self.je.ctrls[JetDefs.F_MIDIFILE].GetValue()) == 0:
367            InfoMsg("MIDI File", "The segment must have a midi file selected.")
368            self.je.ctrls[JetDefs.F_MIDIFILE].SetFocus()
369            return False
370        if not FileExists(self.je.ctrls[JetDefs.F_MIDIFILE].GetValue()):
371            InfoMsg("MIDI File", "The MIDI file does not exist.")
372            self.je.ctrls[JetDefs.F_MIDIFILE].SetFocus()
373            return False
374        if len(self.je.ctrls[JetDefs.F_DLSFILE].GetValue()) > 0:
375            if not FileExists(self.je.ctrls[JetDefs.F_DLSFILE].GetValue()):
376                InfoMsg("DLS File", "The DLS file does not exist.")
377                self.je.ctrls[JetDefs.F_DLSFILE].SetFocus()
378                return False
379        self.je.ctrls[JetDefs.F_MUTEFLAGS].SetValue(ComputeMuteFlagsFromList(self.je.ctrls[JetDefs.F_MUTEFLAGS]))
380        return True
381
382    def SetSegment(self, mode):
383        """ Builds the segment info for graphing """
384        if mode == PLAY_SEGMENT:
385            jetevents = self.jetevents
386            segment = JetSegment(self.GetValue(JetDefs.F_SEGNAME),
387                                 self.GetValue(JetDefs.F_MIDIFILE),
388                                 self.GetValue(JetDefs.F_START),
389                                 self.GetValue(JetDefs.F_END),
390                                 JetDefs.MBT_ZEROSTR,
391                                 self.GetValue(JetDefs.F_SEGNAME),
392                                 self.GetValue(JetDefs.F_QUANTIZE),
393                                 jetevents,
394                                 self.GetValue(JetDefs.F_DLSFILE),
395                                 None,
396                                 self.GetValue(JetDefs.F_TRANSPOSE),
397                                 self.GetValue(JetDefs.F_REPEAT),
398                                 self.GetValue(JetDefs.F_MUTEFLAGS))
399        else:
400            jetevents = []
401            segment = JetSegment(self.GetValue(JetDefs.F_SEGNAME),
402                                 self.GetValue(JetDefs.F_MIDIFILE),
403                                 JetDefs.MBT_ZEROSTR,
404                                 self.lastMidiInfo.endMbtStr,
405                                 JetDefs.MBT_ZEROSTR,
406                                 self.GetValue(JetDefs.F_SEGNAME),
407                                 self.GetValue(JetDefs.F_QUANTIZE),
408                                 jetevents,
409                                 self.GetValue(JetDefs.F_DLSFILE),
410                                 None,
411                                 0,
412                                 0,
413                                 0)
414        return segment
415
416    def OnEventChecked(self, index, checked):
417        """ Track is checked so mute or unmute it """
418        if self.Player is not None:
419            trackNum = self.je.ctrls[JetDefs.F_MUTEFLAGS].GetTrackNumber(index)
420            self.Player.SetMuteFlag(trackNum, checked)
421
422    def OnPlay(self, event):
423        """ Play the segment button pressed """
424        if self.je.ctrls[JetDefs.F_PLAY].GetLabel() == JetDefs.BUT_STOP:
425            self.Player.SetKeepPlayingFlag(False)
426            return
427
428        if not self.Validate():
429            return
430
431        self.playMode = PLAY_SEGMENT
432        self.graphSegment = self.SetSegment(self.graphMode)
433        self.UpdateGraph()
434        self.Player = PreviewPlayer(self.je.ctrls[JetDefs.F_PLAY], self.SetSegment(self.playMode))
435        self.Player.SetGraphCtrl(self.je.ctrls[JetDefs.F_GRAPH], self)
436        self.PlayerThread = thread.start_new_thread(self.Player .Start, ())
437
438    def OnPlayMidi(self, event):
439        """ Play the whole midi file pressed """
440        if self.je.ctrls[JetDefs.F_PLAYMIDI].GetLabel() == JetDefs.BUT_STOP:
441            self.Player.SetKeepPlayingFlag(False)
442            return
443
444        if not self.Validate():
445            return
446
447        self.playMode = PLAY_MIDI
448        self.graphSegment = self.SetSegment(self.graphMode)
449        self.UpdateGraph()
450        self.Player = PreviewPlayer(self.je.ctrls[JetDefs.F_PLAYMIDI], self.SetSegment(self.playMode))
451        self.Player.SetGraphCtrl(self.je.ctrls[JetDefs.F_GRAPH], self)
452        self.PlayerThread = thread.start_new_thread(self.Player .Start, ())
453
454    def OnSetGraphType(self, event):
455        """ Sets the type of graph """
456        self.SetGraphType(event.GetInt())
457
458    def SetGraphType(self, iMode):
459        """ Sets the type of graph """
460        if iMode == 1:
461            self.graphMode = PLAY_SEGMENT
462        else:
463            self.graphMode = PLAY_MIDI
464        self.graphSegment = self.SetSegment(self.graphMode)
465        self.UpdateGraph()
466
467    def OnGraphUpdate(self, evt):
468        """ Calls graph control to draw """
469        self.je.ctrls[JetDefs.F_GRAPH].DoDrawing()
470
471    def UpdateGraph(self):
472        """ Updates values for graph control """
473        if self.graphMode == PLAY_SEGMENT:
474            self.je.ctrls[JetDefs.F_GRAPH].LoadSegment(self.graphSegment, showLabels=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'), showClips=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'), showAppEvts=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
475        else:
476            if self.playMode == PLAY_SEGMENT:
477                iMidiMode = True
478            else:
479                iMidiMode = False
480            self.je.ctrls[JetDefs.F_GRAPH].LoadSegment(self.graphSegment,(self.GetValue(JetDefs.F_SEGNAME), self.GetValue(JetDefs.F_START), self.GetValue(JetDefs.F_END)), iMidiMode, showLabels=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'), showClips=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'), showAppEvts=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
481
482    def OnJetStatusUpdate(self, evt):
483        """ All UI needed by thread must be called via Postevent or OS X crashes """
484        if evt.mode == JetDefs.PST_UPD_LOCATION:
485            self.je.ctrls[JetDefs.F_GRAPH].UpdateLocation(evt.data)
486        elif evt.mode == JetDefs.PST_PLAY:
487            if self.playMode == PLAY_SEGMENT:
488                self.je.ctrls[JetDefs.F_PLAY].SetLabel(JetDefs.BUT_STOP)
489                self.je.ctrls[JetDefs.F_PLAYMIDI].Enabled = False
490            else:
491                self.je.ctrls[JetDefs.F_RDOGRAPH].Enabled = False
492                self.je.ctrls[JetDefs.F_PLAYMIDI].SetLabel(JetDefs.BUT_STOP)
493                self.je.ctrls[JetDefs.F_PLAY].Enabled = False
494
495            self.je.ctrls[JetDefs.F_PAUSE].Enabled = True
496            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
497        elif evt.mode == JetDefs.PST_DONE:
498            self.je.ctrls[JetDefs.F_RDOGRAPH].Enabled = True
499            if self.playMode == PLAY_SEGMENT:
500                self.je.ctrls[JetDefs.F_PLAY].SetLabel(JetDefs.BUT_PLAYSEG)
501                self.je.ctrls[JetDefs.F_PLAYMIDI].Enabled = True
502            else:
503                self.je.ctrls[JetDefs.F_PLAYMIDI].SetLabel(JetDefs.BUT_PLAYMIDI)
504                self.je.ctrls[JetDefs.F_PLAY].Enabled = True
505
506            self.je.ctrls[JetDefs.F_PAUSE].Enabled = False
507            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
508        elif evt.mode == JetDefs.PST_PAUSE:
509            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_RESUME)
510        elif evt.mode == JetDefs.PST_RESUME:
511            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
512        elif evt.mode == JetDefs.PST_MIDI_INFO:
513            ClearRowSelections(self.je.ctrls[JetDefs.F_MUTEFLAGS])
514            self.md = evt.data
515            if self.md.err == 0:
516                self.je.ctrls[JetDefs.F_END].SetMaxMbt(self.md.maxMeasures+1,self.md.maxBeats,self.md.maxTicks)
517                if self.je.ctrls[JetDefs.F_END].GetValue() == JetDefs.MBT_ZEROSTR:
518                    self.je.ctrls[JetDefs.F_END].SetValue((self.md.maxMeasures,0,0))
519                self.je.ctrls[JetDefs.F_START].SetMaxMbt(self.md.maxMeasures+1,self.md.maxBeats,self.md.maxTicks)
520                self.je.ctrls[JetDefs.F_MUTEFLAGS].DeleteAllItems()
521                loadEmpty = IniGetValue(self.currentJetConfigFile, JetDefs.INI_DISPEMPTYTRACKS, JetDefs.INI_DISPEMPTYTRACKS, 'bool', 'False')
522                for track in self.md.trackList:
523                    self.je.ctrls[JetDefs.F_MUTEFLAGS].AddTrackRow(track, loadEmpty)
524                self.je.ctrls[JetDefs.F_MUTEFLAGS].CheckTracks(self.je.ctrls[JetDefs.F_MUTEFLAGS].GetValue())
525                self.graphSegment = self.SetSegment(self.graphMode)
526                self.UpdateGraph()
527
528    def OnSetTrackDisplayOption(self, evt):
529        IniSetValue(self.currentJetConfigFile, JetDefs.INI_DISPEMPTYTRACKS, JetDefs.INI_DISPEMPTYTRACKS, self.je.ctrls[JetDefs.F_DISPEMPTYTRACKS].GetValue())
530        loadEmpty = IniGetValue(self.currentJetConfigFile, JetDefs.INI_DISPEMPTYTRACKS, JetDefs.INI_DISPEMPTYTRACKS, 'bool', 'False')
531        if self.md is not None:
532            self.je.ctrls[JetDefs.F_MUTEFLAGS].DeleteAllItems()
533            if self.md.err == 0:
534                for track in self.md.trackList:
535                    self.je.ctrls[JetDefs.F_MUTEFLAGS].AddTrackRow(track, loadEmpty)
536
537    def OnPause(self, evt):
538        """ Pauses the playback """
539        self.Player.Pause()
540
541    def OnSetGraphOptions(self, evt):
542        """ Sets graph options """
543        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, self.je.ctrls[JetDefs.F_GRAPHLABELS].GetValue())
544        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, self.je.ctrls[JetDefs.F_GRAPHAPPEVTS].GetValue())
545        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, self.je.ctrls[JetDefs.F_GRAPHCLIPS].GetValue())
546        self.UpdateGraph()
547
548    def OnReplicate(self, evt):
549        dlg = JetReplicate("Replicate Segment")
550        dlg.SetValue(JetDefs.F_RPREPLACE, True)
551        dlg.SetName(self.GetValue(JetDefs.F_SEGNAME))
552        dlg.event_type = "SEGMENT"
553        dlg.event_max = self.je.ctrls[JetDefs.F_START].GetMaxMbt()
554        dlg.length = MbtDifference(ConvertStrTimeToTuple(self.GetValue(JetDefs.F_START)), ConvertStrTimeToTuple(self.GetValue(JetDefs.F_END)))
555        result = dlg.ShowModal()
556        if result == wx.ID_OK:
557            self.replicatePrefix = dlg.GetValue(JetDefs.F_RPPREFIX)
558            self.lstReplicate = dlg.lstReplicate
559            self.chkReplaceMatching = dlg.GetValue(JetDefs.F_RPREPLACE)
560            self.EndModal(wx.ID_OK)
561        else:
562            dlg.Destroy()
563
564class EventEdit(wx.Dialog):
565    """ Event edit dialog box """
566    def __init__(self, title, currentJetConfigFile):
567        wx.Dialog.__init__(self, None, -1, title)
568        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
569        self.title = title
570        self.currentJetConfigFile = currentJetConfigFile
571        self.je = JetEdit(self, "EVTDLG_CTRLS", self)
572        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_TRACK, JetDefs.MUTEGRD_TRACK)
573        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_CHANNEL, JetDefs.MUTEGRD_CHANNEL)
574        self.je.ctrls[JetDefs.F_MUTEFLAGS].AddCol(JetDefs.GRD_NAME, JetDefs.MUTEGRD_NAME)
575        self.je.ctrls[JetDefs.F_ESTART].SetChangeCallbackFct(self.UpdateGraph)
576        self.je.ctrls[JetDefs.F_EEND].SetChangeCallbackFct(self.UpdateGraph)
577        self.je.ctrls[JetDefs.F_GRAPHLABELS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'))
578        self.je.ctrls[JetDefs.F_GRAPHCLIPS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'))
579        self.je.ctrls[JetDefs.F_GRAPHAPPEVTS].SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
580        EVT_JET_STATUS(self, self.OnJetStatusUpdate)
581        self.segment = None
582        self.Player = None
583        self.event_id = 1
584        self.replicatePrefix = ""
585        self.lstReplicate = []
586        self.chkReplaceMatching = False
587
588        wx.EVT_CLOSE(self, self.OnClose)
589        self.SetSize(JetDefs.EVTDLG_SIZE)
590        self.CenterOnParent()
591
592    def OnGraphUpdate(self, evt):
593        """ Calls the graph module to update the graph """
594        self.je.ctrls[JetDefs.F_GRAPH].DoDrawing()
595
596    def OnJetStatusUpdate(self, evt):
597        """ Updates to UI needed by play thread come through here otherwise OS X crashes """
598        if evt.mode == JetDefs.PST_UPD_LOCATION:
599            self.je.ctrls[JetDefs.F_GRAPH].UpdateLocation(evt.data)
600        elif evt.mode == JetDefs.PST_PLAY:
601            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
602            self.je.ctrls[JetDefs.F_PLAY].SetLabel(JetDefs.BUT_STOP)
603            self.je.ctrls[JetDefs.F_PAUSE].Enabled = True
604            self.je.ctrls[JetDefs.F_ETRIGGERBUT].Enabled = True
605            self.je.ctrls[JetDefs.F_EMUTEBUT].Enabled = True
606        elif evt.mode == JetDefs.PST_DONE:
607            self.je.ctrls[JetDefs.F_EMUTEBUT].SetLabel(JetDefs.BUT_UNMUTE)
608            self.je.ctrls[JetDefs.F_PLAY].SetLabel(JetDefs.BUT_PLAY)
609            self.je.ctrls[JetDefs.F_PAUSE].Enabled = False
610            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
611            self.je.ctrls[JetDefs.F_ETRIGGERBUT].Enabled = False
612            self.je.ctrls[JetDefs.F_EMUTEBUT].Enabled = False
613        elif evt.mode == JetDefs.PST_PAUSE:
614            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_RESUME)
615        elif evt.mode == JetDefs.PST_RESUME:
616            self.je.ctrls[JetDefs.F_PAUSE].SetLabel(JetDefs.BUT_PAUSE)
617
618    def OnPause(self, evt):
619        """ Pause the player """
620        self.Player.Pause()
621
622    def UpdateGraph(self):
623        """ Called back from player thread to update the graph """
624        if len(self.segment.jetevents) == 0:
625            self.segment.jetevents.append(JetEvent(self.je.ctrls[JetDefs.F_ENAME].GetValue(),
626                                                   self.je.ctrls[JetDefs.F_ETYPE].GetValue(),
627                                                   1,
628                                                   self.je.ctrls[JetDefs.F_ETRACK].GetValue(),
629                                                   self.je.ctrls[JetDefs.F_ECHANNEL].GetValue(),
630                                                   self.je.ctrls[JetDefs.F_ESTART].GetValue(),
631                                                   self.je.ctrls[JetDefs.F_EEND].GetValue()))
632
633        self.segment.jetevents[0].event_name = self.je.ctrls[JetDefs.F_ENAME].GetValue()
634        self.segment.jetevents[0].event_type = self.je.ctrls[JetDefs.F_ETYPE].GetValue()
635        self.segment.jetevents[0].event_start = self.je.ctrls[JetDefs.F_ESTART].GetValue()
636        self.segment.jetevents[0].event_end = self.je.ctrls[JetDefs.F_EEND].GetValue()
637        self.je.ctrls[JetDefs.F_GRAPH].LoadSegment(self.segment, showLabels=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'), showClips=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'), showAppEvts=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
638
639    def OnClose(self, event):
640        """ Called when dialog is closed """
641        self.ShutdownPlayer()
642        self.je.ctrls[JetDefs.F_ESTART].UnBindKillFocus()
643        self.je.ctrls[JetDefs.F_EEND].UnBindKillFocus()
644        self.EndModal(wx.ID_CANCEL)
645
646    def ShutdownPlayer(self):
647        """ Sets flag to kill play loop """
648        if self.Player is not None:
649            self.Player.SetKeepPlayingFlag(False)
650
651    def GetValue(self, fld):
652        """ Gets the value of a control """
653        return self.je.ctrls[fld].GetValue()
654
655    def SetValue(self, fld, val):
656        """ Sets the value of a control """
657        self.je.ctrls[fld].SetValue(val)
658
659    def SetEventId(self):
660        """ Sets the eventid value """
661        if self.title == JetDefs.MAIN_ADDEVENTTITLE:
662            iNextEventId = -1
663            for evt in self.segment.jetevents:
664                if evt.event_type == JetDefs.E_CLIP:
665                    if iNextEventId < evt.event_id:
666                        iNextEventId = evt.event_id
667            self.je.ctrls[JetDefs.F_EEVENTID].SetValue(iNextEventId + 1)
668
669    def OnEventSelect(self, event=None):
670        """ Adjusts the dialog box controls for various types of events """
671        eType = self.je.ctrls[JetDefs.F_ETYPE].GetValue()
672        if eType == JetDefs.E_EOS:
673            self.je.ctrls[JetDefs.F_ENAME].SetValue(JetDefs.E_EOS)
674            self.je.ctrls[JetDefs.F_ENAME].Enable(False)
675            self.je.ctrls[JetDefs.F_ESTART].Enable(False)
676            self.je.ctrls[JetDefs.F_EEND].Enable(True)
677            self.je.ctrls[JetDefs.F_ETRIGGERBUT].Enable(False)
678            self.je.ctrls[JetDefs.F_EEVENTID].Enable(False)
679        elif eType == JetDefs.E_CLIP:
680            if len(self.je.ctrls[JetDefs.F_ENAME].GetValue()) == 0 or self.je.ctrls[JetDefs.F_ENAME].GetValue() == JetDefs.E_EOS or self.je.ctrls[JetDefs.F_ENAME].GetValue() == JetDefs.E_APP:
681                self.je.ctrls[JetDefs.F_ENAME].SetValue(JetDefs.E_CLIP)
682            self.je.ctrls[JetDefs.F_ENAME].Enable(True)
683            self.je.ctrls[JetDefs.F_ESTART].Enable(True)
684            self.je.ctrls[JetDefs.F_EEND].Enable(True)
685            self.je.ctrls[JetDefs.F_ETRIGGERBUT].Enable(True)
686            self.je.ctrls[JetDefs.F_EEVENTID].Enable(True)
687            self.je.ctrls[JetDefs.F_EEVENTID].SetRange(JetDefs.EVENTID_MIN, JetDefs.EVENTID_MAX)
688            if self.je.ctrls[JetDefs.F_EEVENTID].GetValue() < JetDefs.EVENTID_MIN:
689                self.je.ctrls[JetDefs.F_EEVENTID].SetValue(JetDefs.EVENTID_MIN)
690            if self.je.ctrls[JetDefs.F_EEVENTID].GetValue() > JetDefs.EVENTID_MAX:
691                self.je.ctrls[JetDefs.F_EEVENTID].SetValue(JetDefs.EVENTID_MAX)
692            self.SetEventId()
693        elif eType == JetDefs.E_APP:
694            if len(self.je.ctrls[JetDefs.F_ENAME].GetValue()) == 0 or self.je.ctrls[JetDefs.F_ENAME].GetValue() == JetDefs.E_EOS:
695                self.je.ctrls[JetDefs.F_ENAME].SetValue(JetDefs.E_APP)
696            self.je.ctrls[JetDefs.F_ENAME].Enable(True)
697            self.je.ctrls[JetDefs.F_ESTART].Enable(True)
698            self.je.ctrls[JetDefs.F_EEND].Enable(False)
699            self.je.ctrls[JetDefs.F_ETRIGGERBUT].Enable(False)
700            self.je.ctrls[JetDefs.F_EEVENTID].Enable(True)
701            self.je.ctrls[JetDefs.F_EEVENTID].SetRange(JetDefs.APPCONTROLLERID_MIN, JetDefs.APPCONTROLLERID_MAX)
702            if self.je.ctrls[JetDefs.F_EEVENTID].GetValue() < JetDefs.APPCONTROLLERID_MIN:
703                self.je.ctrls[JetDefs.F_EEVENTID].SetValue(JetDefs.APPCONTROLLERID_MIN)
704            if self.je.ctrls[JetDefs.F_EEVENTID].GetValue() > JetDefs.APPCONTROLLERID_MAX:
705                self.je.ctrls[JetDefs.F_EEVENTID].SetValue(JetDefs.APPCONTROLLERID_MAX)
706
707    def OnOk(self, event):
708        """ Exits the dialog box """
709        self.ShutdownPlayer()
710        if self.Validate():
711            self.je.ctrls[JetDefs.F_ESTART].UnBindKillFocus()
712            self.je.ctrls[JetDefs.F_EEND].UnBindKillFocus()
713            self.EndModal(wx.ID_OK)
714
715    def Validate(self):
716        """ Validates the control values prior to exiting """
717        if len(self.je.ctrls[JetDefs.F_ENAME].GetValue()) == 0:
718            InfoMsg("Event Name", "The event must have a name.")
719            self.je.ctrls[JetDefs.F_ENAME].SetFocus()
720            return False
721        if len(self.je.ctrls[JetDefs.F_ETYPE].GetValue()) == 0:
722            InfoMsg("Event Name", "The event type must be selected.")
723            self.je.ctrls[JetDefs.F_ETYPE].SetFocus()
724            return False
725        if self.je.ctrls[JetDefs.F_ETYPE].GetValue() == JetDefs.E_CLIP:
726            if not CompareMbt(self.je.ctrls[JetDefs.F_ESTART].GetValue(), self.je.ctrls[JetDefs.F_EEND].GetValue()):
727                InfoMsg("Start/End", "The event starting and ending times are illogical.")
728                self.je.ctrls[JetDefs.F_ESTART].SetFocus()
729                return False
730            if MbtVal(self.je.ctrls[JetDefs.F_ESTART].GetValue()) < MbtVal(self.je.ctrls[JetDefs.F_START].GetValue()):
731                InfoMsg("Event Starting Time", "The event starting time is illogical.")
732                self.je.ctrls[JetDefs.F_ESTART].SetFocus()
733                return False
734            if MbtVal(self.je.ctrls[JetDefs.F_EEND].GetValue()) > MbtVal(self.je.ctrls[JetDefs.F_END].GetValue()):
735                InfoMsg("Event Ending Time", "The event ending time is illogical.")
736                self.je.ctrls[JetDefs.F_ESTART].SetFocus()
737                return False
738        if self.je.ctrls[JetDefs.F_ETYPE].GetValue() == JetDefs.E_APP:
739            self.je.ctrls[JetDefs.F_EEND].SetValue(self.je.ctrls[JetDefs.F_ESTART].GetValue())
740        if self.je.ctrls[JetDefs.F_ETYPE].GetValue() == JetDefs.E_EOS:
741            self.je.ctrls[JetDefs.F_ESTART].SetValue(self.je.ctrls[JetDefs.F_EEND].GetValue())
742        return True
743
744    def SetSegment(self, segment):
745        """ Sets the segment values, then calls the graph update """
746        self.segment = segment
747        md = GetMidiInfo(segment.filename)
748        if md.err == 0:
749            self.SetValue(JetDefs.F_SEGNAME, segment.segname)
750            self.SetValue(JetDefs.F_MUTEFLAGS, segment.mute_flags)
751            self.SetValue(JetDefs.F_MIDIFILE, segment.filename)
752            self.SetValue(JetDefs.F_DLSFILE, segment.dlsfile)
753            self.SetValue(JetDefs.F_START, segment.start)
754            self.SetValue(JetDefs.F_END, segment.end)
755            self.SetValue(JetDefs.F_QUANTIZE, segment.quantize)
756            self.SetValue(JetDefs.F_TRANSPOSE, segment.transpose)
757            self.SetValue(JetDefs.F_REPEAT, segment.repeat)
758            maxMeasures = abs(int(self.je.ctrls[JetDefs.F_END].GetValue('int')[0]))
759            self.je.ctrls[JetDefs.F_EEND].SetMaxMbt(maxMeasures+1,md.maxBeats,md.maxTicks)
760            self.je.ctrls[JetDefs.F_ESTART].SetMaxMbt(maxMeasures+1,md.maxBeats,md.maxTicks)
761            minMeasures = abs(int(self.je.ctrls[JetDefs.F_START].GetValue('int')[0]))
762            self.je.ctrls[JetDefs.F_EEND].SetMinMbt(minMeasures+1,0,0)
763            self.je.ctrls[JetDefs.F_ESTART].SetMinMbt(minMeasures+1,0,0)
764            self.je.ctrls[JetDefs.F_END].GetValue('int')
765            self.je.ctrls[JetDefs.F_ETRACK].SetRange(1, md.maxTracks)
766            self.je.ctrls[JetDefs.F_MUTEFLAGS].DeleteAllItems()
767            for track in md.trackList:
768                self.je.ctrls[JetDefs.F_MUTEFLAGS].AddTrackRow(track)
769            self.je.ctrls[JetDefs.F_MUTEFLAGS].CheckTracks(self.je.ctrls[JetDefs.F_MUTEFLAGS].GetValue())
770            self.je.ctrls[JetDefs.F_MUTEFLAGS].SetTextColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
771        self.je.ctrls[JetDefs.F_GRAPH].LoadSegment(segment, showLabels=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'), showClips=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'), showAppEvts=IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
772
773    def OnPlay(self, event):
774        """ Plays the segment allowing interaction with events """
775        if self.je.ctrls[JetDefs.F_PLAY].GetLabel() == JetDefs.BUT_STOP:
776            self.Player.SetKeepPlayingFlag(False)
777            return
778
779        if not self.Validate():
780            return
781
782        jetevents = []
783        jetevents.append(JetEvent(self.GetValue(JetDefs.F_ENAME), self.GetValue(JetDefs.F_ETYPE),
784                                  self.event_id, int(self.GetValue(JetDefs.F_ETRACK)),
785                                  int(self.GetValue(JetDefs.F_ECHANNEL)),
786                                  self.GetValue(JetDefs.F_ESTART), self.GetValue(JetDefs.F_EEND)))
787
788        segment = JetSegment(self.GetValue(JetDefs.F_SEGNAME),
789                             self.GetValue(JetDefs.F_MIDIFILE),
790                             self.GetValue(JetDefs.F_START),
791                             self.GetValue(JetDefs.F_END),
792                             JetDefs.MBT_ZEROSTR,
793                             self.GetValue(JetDefs.F_SEGNAME),
794                             self.GetValue(JetDefs.F_QUANTIZE),
795                             jetevents,
796                             self.GetValue(JetDefs.F_DLSFILE),
797                             None,
798                             self.GetValue(JetDefs.F_TRANSPOSE),
799                             self.GetValue(JetDefs.F_REPEAT),
800                             self.GetValue(JetDefs.F_MUTEFLAGS))
801
802        self.Player = PreviewPlayer(self.je.ctrls[JetDefs.F_PLAY], segment)
803        self.Player.SetGraphCtrl(self.je.ctrls[JetDefs.F_GRAPH], self)
804        self.je.ctrls[JetDefs.F_GRAPH].ClickCallbackFct = self.GraphTriggerClip
805        self.Player.trigger_button = self.je.ctrls[JetDefs.F_ETRIGGERBUT]
806        self.Player.mute_button = self.je.ctrls[JetDefs.F_EMUTEBUT]
807        thread.start_new_thread(self.Player .Start, ())
808
809    def GraphTriggerClip(self, sClipName, iEventId):
810        """ Triggers a clip via graph """
811        if self.Player is not None:
812            self.Player.GraphTriggerClip(sClipName, iEventId)
813
814    def OnMute(self, event):
815        """ Mutes a track """
816        if self.Player is not None:
817            self.Player.MuteTrackViaButton(self.je.ctrls[JetDefs.F_EMUTEBUT],
818                                           int(self.je.ctrls[JetDefs.F_ETRACK].GetValue()))
819
820    def OnTriggerClip(self, event):
821        """ Triggers a clip """
822        if self.Player is not None:
823            self.Player.TriggerClip(self.event_id)
824
825    def OnSetGraphOptions(self, evt):
826        """ Sets graph options """
827        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, self.je.ctrls[JetDefs.F_GRAPHLABELS].GetValue())
828        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, self.je.ctrls[JetDefs.F_GRAPHAPPEVTS].GetValue())
829        IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, self.je.ctrls[JetDefs.F_GRAPHCLIPS].GetValue())
830        self.UpdateGraph()
831
832    def OnReplicate(self, evt):
833        dlg = JetReplicate("Replicate Event")
834        dlg.SetValue(JetDefs.F_RPREPLACE, True)
835        dlg.SetName(self.GetValue(JetDefs.F_ENAME))
836        dlg.event_type = self.GetValue(JetDefs.F_ETYPE)
837        dlg.event_max = self.segment.end
838        dlg.length = MbtDifference(ConvertStrTimeToTuple(self.GetValue(JetDefs.F_ESTART)), ConvertStrTimeToTuple(self.GetValue(JetDefs.F_EEND)))
839        result = dlg.ShowModal()
840        if result == wx.ID_OK:
841            self.replicatePrefix = dlg.GetValue(JetDefs.F_RPPREFIX)
842            self.lstReplicate = dlg.lstReplicate
843            self.chkReplaceMatching = dlg.GetValue(JetDefs.F_RPREPLACE)
844            self.EndModal(wx.ID_OK)
845        else:
846            dlg.Destroy()
847
848class JetReplicate(wx.Dialog):
849    """ Replicate dialog box """
850    def __init__(self, title):
851        wx.Dialog.__init__(self, None, -1, title)
852        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
853        self.je = JetEdit(self, "REPLICATE_CTRLS", self)
854
855        self.je.ctrls[JetDefs.F_RPINCREMENT].SetMinMbt(0,0,0)
856        self.je.ctrls[JetDefs.F_RPINCREMENT].SetValue((-1,-1,-1))
857        self.je.ctrls[JetDefs.F_RPNUMBER].SetValue(1)
858        for title, width, fld in JetDefs.REPLICATE_GRID:
859            self.je.ctrls[JetDefs.F_RPGRDPREVIEW].AddCol(title, width)
860        self.lstReplicate = []
861
862        self.SetSize(JetDefs.REPLICATE_SIZE)
863        self.CenterOnParent()
864
865    def OnOk(self, event):
866        self.EndModal(wx.ID_OK)
867
868    def GetValue(self, fld):
869        return self.je.ctrls[fld].GetValue()
870
871    def SetValue(self, fld, val):
872        self.je.ctrls[fld].SetValue(val)
873
874    def SetName(self, name):
875        for i in range(len(name), 1, -1):
876            if not name[i-1].isdigit() and name[i-1] <> ' ':
877                break
878            else:
879                name = name[0:i-1]
880        self.SetValue(JetDefs.F_RPPREFIX, name)
881
882    def Validate(self):
883        if self.GetValue(JetDefs.F_RPPREFIX) == '':
884            InfoMsg("Message", "Prefix is required.")
885            return False
886        return True
887
888    def OnPreview(self, event):
889        if not self.Validate():
890            return
891        start = MbtVal(self.GetValue(JetDefs.F_ESTART))
892        max = MbtVal(self.event_max)
893        increment = MbtVal((self.je.ctrls[JetDefs.F_RPINCREMENT].GetMeasure(), self.je.ctrls[JetDefs.F_RPINCREMENT].GetBeat(), self.je.ctrls[JetDefs.F_RPINCREMENT].GetTick()))
894
895        self.lstReplicate = []
896        iTo = int(self.GetValue(JetDefs.F_RPNUMBER))
897        for i in range(iTo):
898            evt_name = "%s %.2d" % (self.GetValue(JetDefs.F_RPPREFIX), i)
899            s_ticks = start + (i * increment)
900            s_mbt = TicksToMbt(s_ticks)
901            evt_start =  "%d:%d:%d" % (s_mbt[0]+1, s_mbt[1]+1, s_mbt[2])
902            if self.event_type == JetDefs.E_CLIP or self.event_type == "SEGMENT":
903                e_ticks = s_ticks + self.length
904                e_mbt = TicksToMbt(e_ticks)
905                evt_end = "%d:%d:%d" % (e_mbt[0]+1, e_mbt[1]+1, e_mbt[2])
906            else:
907                e_ticks = s_ticks
908                evt_end = evt_start
909            if s_ticks <= max and e_ticks <= max:
910                self.lstReplicate.append((evt_name, evt_start, evt_end))
911
912        self.je.ctrls[JetDefs.F_RPGRDPREVIEW].DeleteAllItems()
913        self.je.ctrls[JetDefs.F_RPGRDPREVIEW].AddRows(self.lstReplicate)
914
915class JetMove(wx.Dialog):
916    """ Move events dialog box """
917    def __init__(self, title):
918        wx.Dialog.__init__(self, None, -1, title)
919        self.SetExtraStyle(wx.DIALOG_EX_CONTEXTHELP)
920        self.je = JetEdit(self, "MOVE_CTRLS", self)
921
922        self.je.ctrls[JetDefs.F_RPINCREMENT].SetMinMbt(-999,-4,-480)
923        self.je.ctrls[JetDefs.F_RPINCREMENT].SetValue((-1,-1,-1))
924        for title, width, fld in JetDefs.REPLICATE_GRID:
925            self.je.ctrls[JetDefs.F_RPGRDPREVIEW].AddCol(title, width)
926        self.lstMove = []
927        self.lstMoveMbt = []
928        self.lstMoveItems = []
929
930        self.SetSize(JetDefs.REPLICATE_SIZE)
931        self.CenterOnParent()
932
933    def OnOk(self, event):
934        self.EndModal(wx.ID_OK)
935
936    def GetValue(self, fld):
937        return self.je.ctrls[fld].GetValue()
938
939    def SetValue(self, fld, val):
940        self.je.ctrls[fld].SetValue(val)
941
942    def OnPreview(self, event):
943        increment = MbtVal((abs(self.je.ctrls[JetDefs.F_RPINCREMENT].GetMeasure()), abs(self.je.ctrls[JetDefs.F_RPINCREMENT].GetBeat()), abs(self.je.ctrls[JetDefs.F_RPINCREMENT].GetTick())))
944        if self.je.ctrls[JetDefs.F_RPINCREMENT].GetMeasure() < 0 or self.je.ctrls[JetDefs.F_RPINCREMENT].GetBeat() < 0 or self.je.ctrls[JetDefs.F_RPINCREMENT].GetTick() < 0:
945            increment = 0 - increment
946        self.lstMove = []
947        self.lstMoveMbt = []
948        for itm in self.lstMoveItems:
949            max = MbtVal(itm[3])
950            evt_name = itm[0]
951            start = MbtVal(itm[1])
952            s_ticks = start + increment
953
954            s_mbt = TicksToMbt(s_ticks)
955            evt_start =  "%d:%d:%d" % (s_mbt[0]+1, s_mbt[1]+1, s_mbt[2])
956            evt_start_save = "%d:%d:%d" % s_mbt
957
958            end = MbtVal(itm[2])
959            e_ticks = end + increment
960            e_mbt = TicksToMbt(e_ticks)
961            evt_end = "%d:%d:%d" % (e_mbt[0]+1, e_mbt[1]+1, e_mbt[2])
962            evt_end_save = "%d:%d:%d" % e_mbt
963
964            if s_ticks <= max and e_ticks <= max and s_ticks >= 0 and e_ticks >= 0:
965                self.lstMove.append((evt_name, evt_start, evt_end))
966                self.lstMoveMbt.append((evt_name, evt_start_save, evt_end_save))
967
968        self.je.ctrls[JetDefs.F_RPGRDPREVIEW].DeleteAllItems()
969        self.je.ctrls[JetDefs.F_RPGRDPREVIEW].AddRows(self.lstMove)
970
971if __name__ == '__main1__':
972    """ Test dialogs """
973    app = wx.PySimpleApp()
974
975    #dlg = JetOpen()
976    #dlg = JetPropertiesDialog()
977    #dlg = ExportDialog("Export Jet File")
978    #dlg = JetAbout()
979
980    dlg = JetReplicate("Replicate Event")
981    dlg.SetValue(JetDefs.F_RPREPLACE, True)
982    dlg.event_max = "5:0:0"
983    dlg.event_type = JetDefs.E_APP
984    dlg.length = 480
985    dlg.SetName("abc 02")
986    result = dlg.ShowModal()
987    if result == wx.ID_OK:
988        print("OK")
989
990    dlg.Destroy()
991
992if __name__ == '__main1__':
993    """ Test Segment dialog """
994    app = wx.PySimpleApp()
995
996    helpProvider = wx.SimpleHelpProvider()
997    wx.HelpProvider_Set(helpProvider)
998
999    dlg = SegEdit("Segments", JetDefs.UNTITLED_FILE)
1000    dlg.SetValue(JetDefs.F_SEGNAME, "Test Segment Name")
1001    dlg.SetValue(JetDefs.F_MIDIFILE, '/Users/BHruska/JetContent/jenn_Burning Line.mid')
1002    dlg.SetValue(JetDefs.F_MIDIFILE, 'C:/_Data/JetCreator/JetDemo1/jenn_Burning Line.mid')
1003    dlg.SetValue(JetDefs.F_DLSFILE, '')
1004    dlg.SetValue(JetDefs.F_START, '4:0:0')
1005    dlg.SetValue(JetDefs.F_END, '8:0:0')
1006    dlg.SetValue(JetDefs.F_QUANTIZE, 6)
1007
1008    result = dlg.ShowModal()
1009    dlg.Destroy()
1010
1011if __name__ == '__main__':
1012    """ Test Event dialog """
1013    app = wx.PySimpleApp()
1014
1015    jetevents = []
1016
1017    segment = JetSegment("Test Segment Name", 'C:/_Data/JetCreator/JetDemo1/jenn_Burning Line.mid',
1018                            '0:0:0', '4:0:0', None,
1019                            "Test Segment Name", 6, jetevents,
1020                            '', None, 0,0,3)
1021
1022    dlg = EventEdit("Event Edit", JetDefs.UNTITLED_FILE)
1023    dlg.SetValue(JetDefs.F_ENAME, "Test Event Name")
1024    dlg.SetValue(JetDefs.F_ETYPE, "TriggerClip")
1025    dlg.SetSegment(segment)
1026
1027    result = dlg.ShowModal()
1028    dlg.Destroy()
1029
1030
1031
1032