Home | History | Annotate | Download | only in JetCreator
      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 
     23 import wx
     24 import thread
     25 import wx.lib.newevent
     26 
     27 from JetDefs import *
     28 from JetCtrls import *
     29 from JetFile import *
     30 from JetUtils import *
     31 from JetPreview import *
     32 from JetSegGraph import *
     33 from eas import *
     34 from JetStatusEvent import *
     35 
     36 PLAY_SEGMENT = 1
     37 PLAY_MIDI = 2
     38 
     39 class 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 
    138 class 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     
    194 class 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 
    213 class 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 
    235 class 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 
    254 class 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         
    271 class 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 
    564 class 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 
    848 class 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 
    915 class 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 
    971 if __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         
    992 if __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 
   1011 if __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