Home | History | Annotate | Download | only in JetCreator
      1 """
      2  File:  
      3  JetCreator.py
      4  
      5  Contents and purpose:
      6  Jet file creation utility for JET sound engine
      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 from __future__ import with_statement
     24 
     25 import wx
     26 import sys
     27 import thread
     28 import copy
     29 import wx.html
     30 import operator
     31 
     32 from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
     33 from eas import *
     34 from JetFile import *
     35 from JetUtils import *
     36 from JetCtrls import *
     37 from JetDialogs import *
     38 from JetSegGraph import SegmentGraph, Marker
     39 from JetAudition import *
     40 from JetStatusEvent import *
     41 
     42 import img_favicon
     43 import img_New
     44 
     45 provider = wx.SimpleHelpProvider()
     46 wx.HelpProvider_Set(provider)
     47 
     48 
     49 class JetCreator(wx.Frame):
     50     """ Main window of JetCreator utility """
     51     def __init__(self, parent, id, jetConfigFile, importFlag=False):
     52         wx.Frame.__init__(self, parent, id, size=(1050, 720), style=wx.DEFAULT_FRAME_STYLE | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX)
     53 
     54         self.myicon = img_favicon.getIcon() 
     55         self.SetIcon(self.myicon) 
     56         self.UndoStack = []
     57         self.RedoStack = []
     58         self.queueSegs = []
     59         self.clipBoard = None
     60         self.jet = None
     61         self.playerLock = threading.RLock()
     62         self.SetKeepPlayingFlag(True)
     63         self.currentSegmentName = None
     64         self.currentSegmentIndex = None
     65         self.currentEventName = None
     66         self.currentEventIndex = None
     67         self.currentCtrl = ""
     68         self.currentJetConfigFile = jetConfigFile
     69         self.paused = False
     70         self.eventlistSort = (0, 1)
     71         self.seglistSort = (0, 1)
     72         if self.currentJetConfigFile == "":
     73             FileKillClean(JetDefs.UNTITLED_FILE)
     74             self.currentJetConfigFile = JetDefs.UNTITLED_FILE
     75         
     76         self.jet_file = JetFile(self.currentJetConfigFile, "")
     77         
     78         if not ValidateConfig(self.jet_file):
     79             FileKillClean(JetDefs.UNTITLED_FILE)
     80             self.currentJetConfigFile = JetDefs.UNTITLED_FILE
     81             self.jet_file = JetFile(self.currentJetConfigFile, "")
     82 
     83         if self.currentJetConfigFile == JetDefs.UNTITLED_FILE:
     84             self.LoadDefaultProperties()
     85             
     86         self.initLayout()
     87         self.initStatusBar()
     88         self.createMenuBar()
     89         self.createToolbar()
     90         self.SetCurrentFile(self.currentJetConfigFile)
     91         self.initHelp()
     92         
     93         self.graph.ClickCallbackFct = self.GraphTriggerClip
     94         
     95         EVT_JET_STATUS(self, self.OnJetStatusUpdate)
     96         
     97         wx.EVT_CLOSE(self, self.OnClose)
     98 
     99         self.Centre()
    100         self.Show(True)
    101         
    102         if importFlag:
    103             self.OnJetImportArchive(None)
    104      
    105         self.eventList.OnSortOrderChangedAlert = self.OnEventSortOrderChanged
    106         self.segList.OnSortOrderChangedAlert = self.OnSegSortOrderChanged
    107         
    108     def initLayout(self):
    109         """ Initializes the screen layout """
    110         panel = wx.Panel(self, -1)
    111 
    112         hboxMain = wx.BoxSizer(wx.HORIZONTAL)
    113 
    114         leftPanel = wx.Panel(panel, -1)
    115         leftTopPanel = wx.Panel(leftPanel, -1)
    116         leftBotPanel = wx.Panel(leftPanel, -1)
    117         rightPanel = wx.Panel(panel, -1)
    118         
    119         self.segList = JetCheckListCtrl(rightPanel)
    120         for title, width, fld in JetDefs.SEGMENT_GRID:
    121             self.segList.AddCol(title, width)
    122 
    123         self.eventList = JetListCtrl(rightPanel)
    124         for title, width, fld in JetDefs.CLIPS_GRID:
    125             self.eventList.AddCol(title, width)
    126 
    127         self.eventList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEventListClick)
    128         self.segList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSegListClick)
    129         self.segList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnSegmentUpdate)
    130         self.eventList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnEventUpdate)
    131         
    132         self.segList.BindCheckBox(self.OnSegmentChecked)
    133         
    134         BUT_SIZE = (95, 25)
    135         self.btnAddSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_ADD, size=BUT_SIZE)
    136         self.btnRevSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_REVISE, size=BUT_SIZE)
    137         self.btnDelSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_DELETE, size=BUT_SIZE)
    138         self.btnMoveSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_MOVE, size=BUT_SIZE)
    139 
    140         self.btnQueueAll = wx.Button(leftTopPanel, -1, JetDefs.BUT_QUEUEALL, size=BUT_SIZE)
    141         self.btnDequeueAll = wx.Button(leftTopPanel, -1, JetDefs.BUT_DEQUEUEALL, size=BUT_SIZE)
    142         self.btnPlay = wx.Button(leftTopPanel, -1, JetDefs.BUT_PLAY, size=BUT_SIZE)
    143         self.btnPause = wx.Button(leftTopPanel, -1, JetDefs.BUT_PAUSE, size=BUT_SIZE)
    144         self.btnAudition = wx.Button(leftTopPanel, -1, JetDefs.BUT_AUDITION, size=BUT_SIZE)
    145         
    146         self.btnAddEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_ADD, size=BUT_SIZE)
    147         self.btnRevEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_REVISE, size=BUT_SIZE)
    148         self.btnDelEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_DELETE, size=BUT_SIZE)
    149         self.btnMoveEvents = wx.Button(leftBotPanel, -1, JetDefs.BUT_MOVE, size=BUT_SIZE)
    150         
    151         self.Bind(wx.EVT_BUTTON, self.OnSegmentAdd, id=self.btnAddSeg.GetId())
    152         self.Bind(wx.EVT_BUTTON, self.OnSegmentUpdate, id=self.btnRevSeg.GetId())
    153         self.Bind(wx.EVT_BUTTON, self.OnSegmentDelete, id=self.btnDelSeg.GetId())
    154         self.Bind(wx.EVT_BUTTON, self.OnSegmentsMove, id=self.btnMoveSeg.GetId())
    155 
    156         self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=self.btnQueueAll.GetId())
    157         self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=self.btnDequeueAll.GetId())
    158         self.Bind(wx.EVT_BUTTON, self.OnPlay, id=self.btnPlay.GetId())
    159         self.Bind(wx.EVT_BUTTON, self.OnPause, id=self.btnPause.GetId())
    160         self.Bind(wx.EVT_BUTTON, self.OnAudition, id=self.btnAudition.GetId())
    161         
    162         self.Bind(wx.EVT_BUTTON, self.OnEventAdd, id=self.btnAddEvt.GetId())
    163         self.Bind(wx.EVT_BUTTON, self.OnEventUpdate, id=self.btnRevEvt.GetId())
    164         self.Bind(wx.EVT_BUTTON, self.OnEventDelete, id=self.btnDelEvt.GetId())
    165         self.Bind(wx.EVT_BUTTON, self.OnEventsMove, id=self.btnMoveEvents.GetId())
    166         
    167         BORDER = 5
    168         BUT_SPACE = 3
    169         vBoxLeftTop = wx.BoxSizer(wx.VERTICAL)
    170         vBoxLeftBot = wx.BoxSizer(wx.VERTICAL)
    171 
    172         vBoxLeftTop.Add(self.btnAddSeg, 0, wx.TOP, BORDER)
    173         vBoxLeftTop.Add(self.btnRevSeg, 0, wx.TOP, BUT_SPACE)
    174         vBoxLeftTop.Add(self.btnDelSeg, 0, wx.TOP, BUT_SPACE)
    175         vBoxLeftTop.Add(self.btnMoveSeg, 0, wx.TOP, BUT_SPACE)
    176         vBoxLeftTop.Add((-1, 12))
    177         vBoxLeftTop.Add(self.btnQueueAll, 0, wx.TOP, BUT_SPACE)
    178         vBoxLeftTop.Add(self.btnDequeueAll, 0, wx.TOP, BUT_SPACE)
    179         vBoxLeftTop.Add(self.btnPlay, 0, wx.TOP, BUT_SPACE)
    180         vBoxLeftTop.Add(self.btnPause, 0, wx.TOP, BUT_SPACE)
    181         vBoxLeftTop.Add(self.btnAudition, 0, wx.TOP, BUT_SPACE)
    182 
    183         vBoxLeftBot.Add(self.btnAddEvt, 0)
    184         vBoxLeftBot.Add(self.btnRevEvt, 0, wx.TOP, BUT_SPACE)
    185         vBoxLeftBot.Add(self.btnDelEvt, 0, wx.TOP, BUT_SPACE)
    186         vBoxLeftBot.Add(self.btnMoveEvents, 0, wx.TOP, BUT_SPACE)
    187         
    188         leftTopPanel.SetSizer(vBoxLeftTop)
    189         leftBotPanel.SetSizer(vBoxLeftBot)
    190 
    191         vboxLeft = wx.BoxSizer(wx.VERTICAL)
    192         vboxLeft.Add(leftTopPanel, 1, wx.EXPAND)
    193         vboxLeft.Add(leftBotPanel, 1, wx.EXPAND)
    194         vboxLeft.Add((-1, 25))
    195         
    196         leftPanel.SetSizer(vboxLeft)
    197 
    198         self.log = wx.TextCtrl(rightPanel, -1)
    199         self.graph = SegmentGraph(rightPanel, size=(-1, 50))
    200         
    201         vboxRight = wx.BoxSizer(wx.VERTICAL)
    202         vboxRight.Add(self.segList, 4, wx.EXPAND | wx.TOP, BORDER)
    203         vboxRight.Add((-1, 10))
    204         vboxRight.Add(self.eventList, 3, wx.EXPAND | wx.TOP, BORDER)
    205         vboxRight.Add((-1, 10))
    206         vboxRight.Add(self.log, 0, wx.EXPAND)
    207         vboxRight.Add((-1, 5))
    208         vboxRight.Add(self.graph, 1, wx.EXPAND)
    209         vboxRight.Add((-1, 10))
    210 
    211         rightPanel.SetSizer(vboxRight)
    212 
    213         hboxMain.Add(leftPanel, 0, wx.EXPAND | wx.RIGHT | wx.LEFT, BORDER)
    214         hboxMain.Add(rightPanel, 1, wx.EXPAND)
    215         hboxMain.Add((BORDER, -1))
    216 
    217         panel.SetSizer(hboxMain)
    218 
    219         pnlGraph = wx.Panel(leftBotPanel, -1)
    220         graphSizer1 = wx.BoxSizer(wx.VERTICAL)
    221         pnlGraph.SetSizer(graphSizer1)
    222         
    223         graphBox = wx.StaticBox(pnlGraph, wx.ID_ANY, label='Graph')
    224         graphSizer2 = wx.StaticBoxSizer(graphBox, wx.VERTICAL)
    225 
    226         self.chkGraphLabels = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_LBLS)
    227         self.chkGraphClips = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_TRIGGER)
    228         self.chkGraphAppEvts = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_APP)
    229         
    230         graphSizer2.Add(self.chkGraphLabels, 0, wx.TOP, BUT_SPACE)
    231         graphSizer2.Add(self.chkGraphClips, 0, wx.TOP, BUT_SPACE)
    232         graphSizer2.Add(self.chkGraphAppEvts, 0, wx.TOP | wx.BOTTOM, BUT_SPACE)
    233         graphSizer1.Add((-1, 10))
    234         graphSizer1.Add(graphSizer2)
    235 
    236         vBoxLeftBot.Add(pnlGraph, 0, wx.TOP, BUT_SPACE)
    237 
    238         self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphLabels.GetId())
    239         self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphClips.GetId())
    240         self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphAppEvts.GetId())
    241         
    242 
    243     def initHelp(self):
    244         """ Initializes the help text for screen elements """
    245         self.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, ''))
    246         self.segList.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, JetDefs.MAIN_SEGLIST))
    247         self.eventList.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, JetDefs.MAIN_EVENTLIST))
    248         self.graph.SetHelpText(GetJetHelpText(JetDefs.AUDITION_CTRLS, JetDefs.AUDITION_GRAPH))
    249 
    250     def initStatusBar(self):
    251         """ Initializes the status bar """
    252         self.statusbar = self.CreateStatusBar()
    253 
    254     def OnSelectAll(self, event):
    255         """ Called from select all button """
    256         num = self.segList.GetItemCount()
    257         for i in range(num-1, -1, -1):
    258             self.segList.CheckItem(i)
    259 
    260     def OnDeselectAll(self, event):
    261         """ Called from deselect all button """
    262         num = self.segList.GetItemCount()
    263         for i in range(num-1, -1, -1):
    264             self.segList.CheckItem(i, False)
    265 
    266     def LoadSegList(self):
    267         """ Loads up the list of segments """
    268         self.seglistSort = (IniGetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_0, 'int', 0), IniGetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_1, 'int', 1))
    269         segments = self.jet_file.GetSegments()
    270         if self.seglistSort[0] == 0:
    271             self.SegSort(segments, "segname")
    272         elif self.seglistSort[0] == 1:
    273             self.SegSort(segments, "filename")
    274         elif self.seglistSort[0] == 2:
    275             self.SegSort(segments, "dlsfile")
    276         elif self.seglistSort[0] == 3:
    277             self.SegSort(segments, "start")
    278         elif self.seglistSort[0] == 4:
    279             self.SegSort(segments, "end")
    280         elif self.seglistSort[0] == 5:
    281             self.SegSort(segments, "quantize")
    282         elif self.seglistSort[0] == 6:
    283             self.SegSort(segments, "transpose")
    284         elif self.seglistSort[0] == 7:
    285             self.SegSort(segments, "repeat")
    286         elif self.seglistSort[0] == 8:
    287             self.SegSort(segments, "mute_flags")
    288         listDataMap = []
    289         self.currentSegmentIndex = None
    290         self.currentSegmentName = None
    291         self.segList.DeleteAllItems()
    292         self.eventList.DeleteAllItems()
    293         self.menuItems[JetDefs.MNU_UPDATE_SEG].Enable(False)
    294         self.menuItems[JetDefs.MNU_DELETE_SEG].Enable(False)
    295         self.menuItems[JetDefs.MNU_MOVE_SEG].Enable(False)
    296         
    297         self.menuItems[JetDefs.MNU_ADD_EVENT].Enable(False)
    298         self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
    299         self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(False)
    300         self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(False)
    301         self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
    302         for segment in self.jet_file.GetSegments():
    303             index = self.segList.InsertStringItem(sys.maxint, StrNoneChk(segment.segname))
    304             self.segList.SetStringItem(index, 1, FileJustName(StrNoneChk(segment.filename)))
    305             self.segList.SetStringItem(index, 2, FileJustName(StrNoneChk(segment.dlsfile)))
    306             self.segList.SetStringItem(index, 3, mbtFct(segment.start, 1))
    307             self.segList.SetStringItem(index, 4, mbtFct(segment.end, 1))
    308             self.segList.SetStringItem(index, 5, StrNoneChk(segment.quantize))
    309             self.segList.SetStringItem(index, 6, StrNoneChk(segment.transpose))
    310             self.segList.SetStringItem(index, 7, StrNoneChk(segment.repeat))
    311             self.segList.SetStringItem(index, 8, StrNoneChk(segment.mute_flags))
    312             
    313             self.segList.SetItemData(index, index)
    314             listDataMap.append((getColumnText(self.segList, index, 0).upper(), getColumnText(self.segList, index, 1).upper(), getColumnText(self.segList, index, 2).upper(), MbtVal(getColumnText(self.segList, index, 3)), MbtVal(getColumnText(self.segList, index, 4)), int(getColumnText(self.segList, index, 5)), int(getColumnText(self.segList, index, 6)), int(getColumnText(self.segList, index, 7)), int(getColumnText(self.segList, index, 8))))
    315             
    316         self.segList.itemDataMap = listDataMap
    317         self.segList.InitSorting(9)
    318         self.graph.ClearGraph()
    319             
    320     def LoadEventsForSeg(self, segName):
    321         """ Loads up the events associated with a segment """
    322         self.currentEventIndex = None
    323         self.eventList.DeleteAllItems()
    324         self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(False)
    325         self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(False)
    326         self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
    327         self.eventlistSort = (IniGetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_0, 'int', 0), IniGetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_1, 'int', 1))
    328         segment = self.jet_file.GetSegment(self.currentSegmentName)
    329         if segment is not None:
    330             if self.eventlistSort[0] == 0:
    331                 self.EventSort(segment.jetevents, "event_name")
    332             elif self.eventlistSort[0] == 1:
    333                 self.EventSort(segment.jetevents, "event_type")
    334             elif self.eventlistSort[0] == 2:
    335                 self.EventSort(segment.jetevents, "event_start")
    336             elif self.eventlistSort[0] == 3:
    337                 self.EventSort(segment.jetevents, "event_end")
    338             elif self.eventlistSort[0] == 4:
    339                 self.EventSort(segment.jetevents, "track_num")
    340             elif self.eventlistSort[0] == 5:
    341                 self.EventSort(segment.jetevents, "channel_num")
    342             elif self.eventlistSort[0] == 6:
    343                 self.EventSort(segment.jetevents, "event_id")
    344             listDataMap = []
    345             for jet_event in self.jet_file.GetEvents(segName):
    346                 index = self.eventList.InsertStringItem(sys.maxint, StrNoneChk(jet_event.event_name))
    347                 self.eventList.SetStringItem(index, 1, StrNoneChk(jet_event.event_type))
    348                 self.eventList.SetStringItem(index, 2, mbtFct(jet_event.event_start, 1))
    349                 self.eventList.SetStringItem(index, 3, mbtFct(jet_event.event_end, 1))
    350                 self.eventList.SetStringItem(index, 4, StrNoneChk(jet_event.track_num))
    351                 self.eventList.SetStringItem(index, 5, StrNoneChk(jet_event.channel_num + 1))
    352                 self.eventList.SetStringItem(index, 6, StrNoneChk(jet_event.event_id))
    353                 
    354                 self.eventList.SetItemData(index, index)
    355                 listDataMap.append((getColumnText(self.eventList, index, 0).upper(), getColumnText(self.eventList, index, 1).upper(), MbtVal(getColumnText(self.eventList, index, 2)), MbtVal(getColumnText(self.eventList, index, 3)), int(getColumnText(self.eventList, index, 4)), int(getColumnText(self.eventList, index, 5)), int(getColumnText(self.eventList, index, 6))))
    356                     
    357             self.eventList.itemDataMap = listDataMap
    358             self.eventList.InitSorting(7)
    359 
    360     def OnEventListClick(self, event):
    361         """ Sets the current event variable when selecting from the list """
    362         self.currentCtrl = "eventList"
    363         self.currentEventIndex = event.m_itemIndex
    364         self.currentEventName = getColumnText(self.eventList, event.m_itemIndex, 0)       
    365         self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(True)
    366         self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(True)
    367         self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(True)
    368                
    369     def OnSegmentChecked(self, index, checked):
    370         """ Selects the segment when checkbox clicked """
    371         ClearRowSelections(self.segList)
    372         SetRowSelection(self.segList, index, True)
    373         
    374     def SelectSegment(self, segName):
    375         """ Selects a segment by segment name """
    376         itm = self.segList.FindItem(-1, segName)
    377         self.segList.EnsureVisible(itm)
    378         ClearRowSelections(self.segList)
    379         SetRowSelection(self.segList, itm, True)
    380         
    381     def SelectEvent(self, eventName):
    382         """ Selects an event by event name """
    383         itm = self.eventList.FindItem(-1, eventName)
    384         self.eventList.EnsureVisible(itm)
    385         ClearRowSelections(self.eventList)
    386         SetRowSelection(self.eventList, itm, True)
    387         
    388     def OnSegListClick(self, event):
    389         """ Loads up a segment when the list is clicked """
    390         self.currentCtrl = "segList"
    391         self.currentSegmentIndex = event.m_itemIndex
    392         self.currentSegmentName = getColumnText(self.segList, event.m_itemIndex, 0)
    393         self.LoadEventsForSeg(getColumnText(self.segList, event.m_itemIndex, 0))
    394         self.menuItems[JetDefs.MNU_UPDATE_SEG].Enable(True)
    395         self.menuItems[JetDefs.MNU_DELETE_SEG].Enable(True)
    396         self.menuItems[JetDefs.MNU_MOVE_SEG].Enable(True)
    397         self.menuItems[JetDefs.MNU_ADD_EVENT].Enable(True)
    398         info = self.graph.LoadSegment(self.jet_file.GetSegment(self.currentSegmentName), 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'))
    399         if info == None:
    400             self.log.SetValue("")
    401         else:
    402             iLength = info.iLengthInMs
    403             if iLength > 0:
    404                 self.log.SetValue("%s      %.2f Seconds" % (self.currentSegmentName, iLength / 1000.00))
    405             else:
    406                 self.log.SetValue("%s" % (self.currentSegmentName))    
    407     
    408     def OnSegmentAdd(self, event):
    409         """ Calls the dialog box for adding a segment """
    410         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    411         
    412         dlg = SegEdit(JetDefs.MAIN_ADDSEGTITLE, self.currentJetConfigFile)
    413        
    414         for filename in self.jet_file.GetMidiFiles():
    415             dlg.je.ctrls[JetDefs.F_MIDIFILE].Append(filename)
    416         for library in self.jet_file.GetLibraries():
    417             dlg.je.ctrls[JetDefs.F_DLSFILE].Append(library)
    418         
    419         result = dlg.ShowModal()
    420         if result == wx.ID_OK:
    421             if len(dlg.lstReplicate) > 0:
    422                 if dlg.chkReplaceMatching:
    423                     self.jet_file.DeleteSegmentsMatchingPrefix(dlg.replicatePrefix) 
    424                 
    425                 for replicate in dlg.lstReplicate:
    426                     self.jet_file.AddSegment(replicate[0], dlg.GetValue(JetDefs.F_MIDIFILE), 
    427                                              mbtFct(replicate[1],-1), mbtFct(replicate[2],-1), 
    428                                              JetDefs.MBT_ZEROSTR, 
    429                                              SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile), 
    430                                              dlg.GetValue(JetDefs.F_QUANTIZE),
    431                                              [], dlg.GetValue(JetDefs.F_DLSFILE),
    432                                              None,
    433                                              dlg.GetValue(JetDefs.F_TRANSPOSE),
    434                                              dlg.GetValue(JetDefs.F_REPEAT),
    435                                              dlg.GetValue(JetDefs.F_MUTEFLAGS))
    436 
    437                 self.LoadSegList()
    438                 self.SelectSegment(dlg.lstReplicate[0][0])
    439             else:
    440                 self.jet_file.AddSegment(dlg.GetValue(JetDefs.F_SEGNAME), dlg.GetValue(JetDefs.F_MIDIFILE), 
    441                                      dlg.GetValue(JetDefs.F_START), dlg.GetValue(JetDefs.F_END), 
    442                                      JetDefs.MBT_ZEROSTR, 
    443                                      SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile), 
    444                                      dlg.GetValue(JetDefs.F_QUANTIZE),
    445                                      [], dlg.GetValue(JetDefs.F_DLSFILE),
    446                                      None,
    447                                      dlg.GetValue(JetDefs.F_TRANSPOSE),
    448                                      dlg.GetValue(JetDefs.F_REPEAT),
    449                                      dlg.GetValue(JetDefs.F_MUTEFLAGS))
    450                 self.LoadSegList()
    451                 self.SelectSegment(dlg.GetValue(JetDefs.F_SEGNAME))
    452             self.UndoAdd(saveState)
    453         dlg.Destroy()
    454         
    455     def OnSegmentUpdate(self, event):
    456         """ Calls the dialog box for updating a segment """
    457         if self.currentSegmentName is None:
    458             return
    459         
    460         segment = self.jet_file.GetSegment(self.currentSegmentName)
    461         if segment == None:
    462             return
    463         
    464         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    465         
    466         dlg = SegEdit(JetDefs.MAIN_REVSEGTITLE, self.currentJetConfigFile)
    467        
    468         for filename in self.jet_file.GetMidiFiles():
    469             dlg.je.ctrls[JetDefs.F_MIDIFILE].Append(filename)
    470         for library in self.jet_file.GetLibraries():
    471             dlg.je.ctrls[JetDefs.F_DLSFILE].Append(library)
    472                     
    473         dlg.SetValue(JetDefs.F_SEGNAME, segment.segname)
    474         dlg.SetValue(JetDefs.F_MUTEFLAGS, segment.mute_flags)
    475         dlg.SetValue(JetDefs.F_MIDIFILE, segment.filename)
    476         dlg.SetValue(JetDefs.F_DLSFILE, segment.dlsfile)
    477         dlg.SetValue(JetDefs.F_START, segment.start)
    478         dlg.SetValue(JetDefs.F_END, segment.end)
    479         dlg.SetValue(JetDefs.F_QUANTIZE, segment.quantize)
    480         dlg.SetValue(JetDefs.F_TRANSPOSE, segment.transpose)
    481         dlg.SetValue(JetDefs.F_REPEAT, segment.repeat)
    482         dlg.jetevents = segment.jetevents
    483         
    484         result = dlg.ShowModal()
    485         if result == wx.ID_OK:
    486             self.jet_file.UpdateSegment(self.currentSegmentName, dlg.GetValue(JetDefs.F_SEGNAME), 
    487                                      dlg.GetValue(JetDefs.F_MIDIFILE), 
    488                                      dlg.GetValue(JetDefs.F_START), dlg.GetValue(JetDefs.F_END), 
    489                                      JetDefs.MBT_ZEROSTR, #dlg.GetValue(JetDefs.F_LENGTH), 

    490                                      SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile), 
    491                                      dlg.GetValue(JetDefs.F_QUANTIZE),
    492                                      [], dlg.GetValue(JetDefs.F_DLSFILE),
    493                                      None,
    494                                      dlg.GetValue(JetDefs.F_TRANSPOSE),
    495                                      dlg.GetValue(JetDefs.F_REPEAT),
    496                                      dlg.GetValue(JetDefs.F_MUTEFLAGS))
    497             
    498             if len(dlg.lstReplicate) > 0:
    499                 if dlg.chkReplaceMatching:
    500                     self.jet_file.DeleteSegmentsMatchingPrefix(dlg.replicatePrefix) 
    501                 
    502                 for replicate in dlg.lstReplicate:
    503                     self.jet_file.AddSegment(replicate[0], dlg.GetValue(JetDefs.F_MIDIFILE), 
    504                                              mbtFct(replicate[1],-1), mbtFct(replicate[2],-1), 
    505                                              JetDefs.MBT_ZEROSTR, 
    506                                              SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile), 
    507                                              dlg.GetValue(JetDefs.F_QUANTIZE),
    508                                              [], dlg.GetValue(JetDefs.F_DLSFILE),
    509                                              None,
    510                                              dlg.GetValue(JetDefs.F_TRANSPOSE),
    511                                              dlg.GetValue(JetDefs.F_REPEAT),
    512                                              dlg.GetValue(JetDefs.F_MUTEFLAGS))
    513     
    514                 self.LoadSegList()
    515                 self.SelectSegment(dlg.lstReplicate[0][0])
    516             else:          
    517                 self.LoadSegList()
    518                 self.SelectSegment(dlg.GetValue(JetDefs.F_SEGNAME))
    519             self.UndoAdd(saveState)
    520         dlg.Destroy()
    521         
    522     def OnSegmentDelete(self, event):
    523         """ Confirms the deletion segment(s) by user action """
    524         if self.currentSegmentName is None:
    525             return
    526         
    527         segment = self.jet_file.GetSegment(self.currentSegmentName)
    528         if segment == None:
    529             return
    530         
    531         count = 0
    532         deleteMsg = ''
    533         item = self.segList.GetFirstSelected()
    534         while item != -1:
    535             if count == 0:
    536                 deleteMsg = getColumnText(self.segList,item,0)
    537             else:
    538                 if count == 40:
    539                     deleteMsg = deleteMsg + "\n" + "....more"
    540                 elif count < 40:
    541                     deleteMsg = deleteMsg + "\n" + getColumnText(self.segList,item,0)
    542             count = count + 1
    543             item = self.segList.GetNextSelected(item)
    544         
    545         if YesNo(JetDefs.MAIN_CONFIRM, deleteMsg + JetDefs.MAIN_CONFIRM_SEG_DLT, False):
    546             item = self.segList.GetFirstSelected()
    547             while item != -1:
    548                 segName = getColumnText(self.segList,item,0)
    549                 self.SegmentDelete(segName)
    550                 item = self.segList.GetNextSelected(item)
    551             
    552             self.graph.ClearGraph()
    553             self.LoadSegList()
    554          
    555     def SegmentDelete(self, segName):
    556         """ Deletes a segment """
    557         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    558         self.jet_file.DeleteSegment(segName)
    559         self.UndoAdd(saveState)
    560     
    561     def OnSegmentsMove(self, event):
    562         """ Move segment(s) """
    563         if self.currentSegmentName is None:
    564             return
    565         
    566         lstMoveItems = []
    567         count = 0
    568         item = self.segList.GetFirstSelected()
    569         while item != -1:
    570             max = GetMidiInfo(self.jet_file.GetSegment(getColumnText(self.segList,item,0)).filename).endMbtStr
    571             lstMoveItems.append((getColumnText(self.segList,item,0), mbtFct(getColumnText(self.segList,item,3),-1), mbtFct(getColumnText(self.segList,item,4),-1), max))
    572             count = count + 1
    573             item = self.segList.GetNextSelected(item)
    574 
    575         if count == 0:
    576             InfoMsg("Move", "Select one or more items to move.")
    577             return
    578         
    579         dlg = JetMove("Move Segments")
    580         dlg.lstMoveItems = lstMoveItems
    581         result = dlg.ShowModal()
    582         if result == wx.ID_OK:
    583             if len(dlg.lstMoveMbt) > 0:
    584                 saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    585                 
    586                 for moveitem in dlg.lstMoveMbt:
    587                     self.jet_file.MoveSegment(moveitem[0], moveitem[1], moveitem[2])
    588                 
    589                 self.LoadSegList()
    590                 self.UndoAdd(saveState)
    591                 
    592         dlg.Destroy()
    593         
    594     def UndoAdd(self, saveState):
    595         """ Adds the current state to the undo stack """
    596         self.UndoStack.append(saveState)
    597         self.menuItems[JetDefs.MNU_UNDO].Enable(True)
    598        
    599     def RedoAdd(self, saveState):
    600         """ Adds the current state the the redo stack """
    601         self.RedoStack.append(saveState)
    602         self.menuItems[JetDefs.MNU_REDO].Enable(True)
    603        
    604     def OnRedo(self, event):
    605         """ Redo if there's one in the stack """
    606         if len(self.RedoStack) > 0:
    607             self.UndoAdd(JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex))
    608             state = self.RedoStack.pop()
    609             self.jet_file = copy.deepcopy(state.jet_file)
    610             self.LoadSegList()
    611             self.currentSegmentIndex = state.currentSegmentIndex
    612             if self.currentSegmentIndex != None:
    613                 SetRowSelection(self.segList, self.currentSegmentIndex, True)
    614             if len(self.RedoStack) == 0:
    615                 self.menuItems[JetDefs.MNU_REDO].Enable(False)
    616                 
    617     def OnUndo(self, event):
    618         """ Undo if there's one in the stack """
    619         if len(self.UndoStack) > 0:
    620             self.RedoAdd(JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex))
    621             state = self.UndoStack.pop()
    622             self.jet_file = copy.deepcopy(state.jet_file)
    623             self.LoadSegList()
    624             self.currentSegmentIndex = state.currentSegmentIndex
    625             if self.currentSegmentIndex != None:
    626                 SetRowSelection(self.segList, self.currentSegmentIndex, True)
    627             if len(self.UndoStack) == 0:
    628                 self.menuItems[JetDefs.MNU_UNDO].Enable(False)
    629 
    630     def OnEventAdd(self, event):
    631         """ Calls a dialog box to add an event to the current segment """
    632         if self.currentSegmentName is None:
    633             return
    634         
    635         segment = self.jet_file.GetSegment(self.currentSegmentName)
    636         if segment == None:
    637             return
    638         
    639         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    640         
    641         dlg = EventEdit(JetDefs.MAIN_ADDEVENTTITLE, self.currentJetConfigFile)
    642         editSegment = copy.deepcopy(segment)
    643         dlg.SetSegment(editSegment)
    644         dlg.SetEventId()
    645                       
    646         result = dlg.ShowModal()
    647         if result == wx.ID_OK:
    648             if dlg.GetValue(JetDefs.F_ETYPE) == JetDefs.E_EOS:
    649                 #check for an existing EOS event

    650                 events = self.jet_file.GetEvents(self.currentSegmentName)
    651                 for evt in events:
    652                     if evt.event_type == JetDefs.E_EOS:
    653                         self.jet_file.DeleteEvent(self.currentSegmentName, evt.event_name)
    654                 dlg.SetValue(JetDefs.F_ESTART, dlg.GetValue(JetDefs.F_EEND))
    655             
    656             if len(dlg.lstReplicate) > 0:
    657                 if dlg.chkReplaceMatching:
    658                     self.jet_file.DeleteEventsMatchingPrefix(self.currentSegmentName, dlg.replicatePrefix) 
    659                 
    660                 for replicate in dlg.lstReplicate:
    661                     self.jet_file.AddEvent(self.currentSegmentName, replicate[0],
    662                                          dlg.GetValue(JetDefs.F_ETYPE), 
    663                                          dlg.GetValue(JetDefs.F_EEVENTID), 
    664                                          dlg.GetValue(JetDefs.F_ETRACK), 
    665                                          dlg.GetValue(JetDefs.F_ECHANNEL), 
    666                                          mbtFct(replicate[1],-1),
    667                                          mbtFct(replicate[2],-1))
    668                 self.SelectSegment(self.currentSegmentName)
    669                 self.SelectEvent(dlg.lstReplicate[0][0])
    670             else:
    671                 self.jet_file.AddEvent(self.currentSegmentName, dlg.GetValue(JetDefs.F_ENAME),
    672                                      dlg.GetValue(JetDefs.F_ETYPE), 
    673                                      dlg.GetValue(JetDefs.F_EEVENTID), 
    674                                      dlg.GetValue(JetDefs.F_ETRACK), 
    675                                      dlg.GetValue(JetDefs.F_ECHANNEL), 
    676                                      dlg.GetValue(JetDefs.F_ESTART),
    677                                      dlg.GetValue(JetDefs.F_EEND))
    678             
    679                 self.SelectSegment(self.currentSegmentName)
    680                 self.SelectEvent(dlg.GetValue(JetDefs.F_ENAME))
    681                 
    682             self.UndoAdd(saveState)
    683         dlg.Destroy()
    684         
    685     def OnEventUpdate(self, event):
    686         """ Calls the dialog box to update the current event """
    687         if self.currentSegmentName is None:
    688             return
    689 
    690         if self.currentEventName  is None:
    691             return
    692         
    693         segment = self.jet_file.GetSegment(self.currentSegmentName)
    694         if segment == None:
    695             return
    696         
    697         curEvent = copy.deepcopy(self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName))
    698         if curEvent == None:
    699             return
    700         
    701         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    702         
    703         #only want the event we are editing to show up in graph

    704         editSegment = copy.deepcopy(segment)
    705         editSegment.jetevents = []
    706         editSegment.jetevents.append(curEvent)
    707         
    708         dlg = EventEdit(JetDefs.MAIN_REVEVENTTITLE, self.currentJetConfigFile)
    709         dlg.SetSegment(editSegment)
    710         dlg.SetValue(JetDefs.F_ENAME, curEvent.event_name)
    711         dlg.SetValue(JetDefs.F_ETYPE, curEvent.event_type)
    712         dlg.SetValue(JetDefs.F_ESTART, curEvent.event_start)
    713         dlg.SetValue(JetDefs.F_EEND, curEvent.event_end)
    714         dlg.SetValue(JetDefs.F_ETRACK, curEvent.track_num)
    715         dlg.SetValue(JetDefs.F_ECHANNEL, curEvent.channel_num)
    716         dlg.SetValue(JetDefs.F_EEVENTID, curEvent.event_id)
    717         dlg.OnEventSelect()   
    718         
    719         result = dlg.ShowModal()
    720         if result == wx.ID_OK:
    721             if dlg.GetValue(JetDefs.F_ETYPE) == JetDefs.E_EOS:
    722                 dlg.SetValue(JetDefs.F_ESTART, dlg.GetValue(JetDefs.F_EEND))
    723                 
    724             self.jet_file.UpdateEvent(self.currentSegmentName, 
    725                                       self.currentEventName, 
    726                                      dlg.GetValue(JetDefs.F_ENAME),
    727                                      dlg.GetValue(JetDefs.F_ETYPE), 
    728                                      dlg.GetValue(JetDefs.F_EEVENTID), 
    729                                      dlg.GetValue(JetDefs.F_ETRACK), 
    730                                      dlg.GetValue(JetDefs.F_ECHANNEL), 
    731                                      dlg.GetValue(JetDefs.F_ESTART),
    732                                      dlg.GetValue(JetDefs.F_EEND))
    733 
    734             if len(dlg.lstReplicate) > 0:
    735                 if dlg.chkReplaceMatching:
    736                     self.jet_file.DeleteEventsMatchingPrefix(self.currentSegmentName, dlg.replicatePrefix) 
    737                 
    738                 for replicate in dlg.lstReplicate:
    739                     self.jet_file.AddEvent(self.currentSegmentName, replicate[0],
    740                                          dlg.GetValue(JetDefs.F_ETYPE), 
    741                                          dlg.GetValue(JetDefs.F_EEVENTID), 
    742                                          dlg.GetValue(JetDefs.F_ETRACK), 
    743                                          dlg.GetValue(JetDefs.F_ECHANNEL), 
    744                                          mbtFct(replicate[1],-1),
    745                                          mbtFct(replicate[2],-1))
    746                 self.SelectSegment(self.currentSegmentName)
    747                 self.SelectEvent(dlg.lstReplicate[0][0])
    748             else:            
    749                 self.SelectSegment(self.currentSegmentName)
    750                 self.SelectEvent(dlg.GetValue(JetDefs.F_ENAME))
    751             self.UndoAdd(saveState)
    752         dlg.Destroy()
    753         
    754     def OnEventDelete(self, event):
    755         """ Confirms the deletion of event(s) """
    756         if self.currentSegmentName is None:
    757             return
    758         
    759         if self.currentEventName  is None:
    760             return
    761         
    762         curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
    763         if curEvent == None:
    764             return
    765 
    766         count = 0
    767         deleteMsg = ''
    768         item = self.eventList.GetFirstSelected()
    769         while item != -1:
    770             if count == 0:
    771                 deleteMsg = getColumnText(self.eventList,item,0)
    772             else:
    773                 if count == 40:
    774                     deleteMsg = deleteMsg + "\n" + "....more"
    775                 elif count < 40:
    776                     deleteMsg = deleteMsg + "\n" + getColumnText(self.eventList,item,0)
    777             count = count + 1
    778             item = self.eventList.GetNextSelected(item)
    779         
    780 
    781         if YesNo(JetDefs.MAIN_CONFIRM, deleteMsg + JetDefs.MAIN_CONRIRM_EVT_DLT, False):
    782             item = self.eventList.GetFirstSelected()
    783             while item != -1:
    784                 eventName = getColumnText(self.eventList,item,0)
    785                 self.EventDelete(eventName)
    786                 item = self.eventList.GetNextSelected(item)
    787 
    788             self.SelectSegment(self.currentSegmentName)
    789             self.LoadEventsForSeg(self.currentSegmentName)
    790           
    791     def EventDelete(self, eventName):
    792         """ Deletes an event """
    793         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    794         self.jet_file.DeleteEvent(self.currentSegmentName, eventName)
    795         self.UndoAdd(saveState)
    796 
    797     def OnEventsMove(self, event):
    798         """ Move event(s) """
    799         if self.currentSegmentName is None:
    800             return
    801         
    802         if self.currentEventName  is None:
    803             return
    804         
    805         segment = self.jet_file.GetSegment(self.currentSegmentName)
    806         if segment == None:
    807             return
    808         
    809         curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
    810         if curEvent == None:
    811             return
    812 
    813         lstMoveItems = []
    814         count = 0
    815         item = self.eventList.GetFirstSelected()
    816         while item != -1:
    817             lstMoveItems.append((getColumnText(self.eventList,item,0), mbtFct(getColumnText(self.eventList,item,2),-1), mbtFct(getColumnText(self.eventList,item,3),-1), segment.end))
    818             count = count + 1
    819             item = self.eventList.GetNextSelected(item)
    820 
    821         if count == 0:
    822             InfoMsg("Move", "Select one or more items to move.")
    823             return
    824         
    825         dlg = JetMove("Move Events")
    826         dlg.lstMoveItems = lstMoveItems
    827         result = dlg.ShowModal()
    828         if result == wx.ID_OK:
    829             if len(dlg.lstMoveMbt) > 0:
    830                 saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
    831                 
    832                 for moveitem in dlg.lstMoveMbt:
    833                     self.jet_file.MoveEvent(self.currentSegmentName, moveitem[0], moveitem[1], moveitem[2])
    834                 
    835                 self.SelectSegment(self.currentSegmentName)
    836                 self.LoadEventsForSeg(self.currentSegmentName)
    837                 
    838                 self.UndoAdd(saveState)
    839                 
    840         dlg.Destroy()
    841         
    842     def OnJetOpen(self, event):
    843         """ Calls a dialog box to get a jet config file to open """
    844         dlg = JetOpen()
    845         result = dlg.ShowModal()
    846         if result == JetDefs.ID_JET_OPEN:
    847             self.jet_file = JetFile(dlg.fileName , "")
    848             if not ValidateConfig(self.jet_file):
    849                 FileKillClean(JetDefs.UNTITLED_FILE)
    850                 self.currentJetConfigFile = JetDefs.UNTITLED_FILE
    851                 self.jet_file = JetFile(self.currentJetConfigFile, "")
    852             else:
    853                 self.SetCurrentFile(dlg.fileName)
    854         elif result == JetDefs.ID_JET_NEW:
    855             self.jet_file = JetFile("" , "")
    856             self.SetCurrentFile(JetDefs.UNTITLED_FILE)
    857             self.LoadDefaultProperties()
    858         elif result == JetDefs.ID_JET_IMPORT:
    859             self.OnJetImportArchive(event)
    860         dlg.Destroy()
    861 
    862     def OnJetSaveAs(self, event): 
    863         """ Calls a dialog box to allow saving the current jet file as another name """
    864         defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.JTC_FILE_SPEC, 'str', str(os.getcwd()))
    865         dialog = wx.FileDialog(None, JetDefs.SAVE_PROMPT, defDir, "", JetDefs.JTC_FILE_SPEC, wx.SAVE | wx.OVERWRITE_PROMPT )
    866         if dialog.ShowModal() == wx.ID_OK:
    867             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.JTC_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
    868             self.currentJetConfigFile = FileJustRoot(dialog.GetPath()) + ".jtc"            
    869             self.jet_file.config.filename = FileJustRoot(self.currentJetConfigFile)  + ".jet"
    870             self.jet_file.SaveJetConfig(self.currentJetConfigFile)
    871             self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
    872             self.SetCurrentFile(self.currentJetConfigFile)
    873         dialog.Destroy()
    874     
    875     def OnJetSave(self, event):
    876         """ Saves the current jet file to disk """
    877         if self.currentJetConfigFile == JetDefs.UNTITLED_FILE:
    878             self.OnJetSaveAs(event)
    879         else:
    880             self.jet_file.SaveJetConfig(self.currentJetConfigFile)
    881             self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
    882         
    883     def OnJetNew(self, event):
    884         """ Initializes the state to a new jet file """
    885         self.jet_file = JetFile("" , "")
    886         self.SetCurrentFile(JetDefs.UNTITLED_FILE)
    887         self.LoadDefaultProperties()
    888                 
    889     def SetCurrentFile(self, fileName):
    890         """ Sets the state for the current jet file """
    891         self.clipBoard = None
    892         self.currentJetConfigFile = fileName
    893         self.SetTitle(JetDefs.MAIN_TITLEPREFIX + FileJustName(fileName))
    894         AppendRecentJetFile(fileName)
    895         self.LoadSegList()
    896         self.graph.ClearGraph()
    897         self.chkGraphLabels.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'))
    898         self.chkGraphClips.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'))
    899         self.chkGraphAppEvts.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
    900 
    901     def createMenuBar(self):
    902         """ Creates a menu bar """
    903         self.menuItems = {}
    904         menuBar = wx.MenuBar()
    905         for eachMenuData in JetDefs.MENU_SPEC:
    906             menuLabel = eachMenuData[0]
    907             menuItems = eachMenuData[1:]
    908             menuBar.Append(self.createMenu(menuItems), menuLabel)
    909         self.SetMenuBar(menuBar)
    910 
    911     def createMenu(self, menuData):
    912         """ Creates a menu from the structure menuData in JetDefs """
    913         menu = wx.Menu()
    914         for eachLabel, eachStatus, eachHandler, eachEnable in menuData:
    915             if not eachLabel:
    916                 menu.AppendSeparator()
    917                 continue
    918             self.menuItems[eachLabel] = menu.Append(-1, eachLabel, eachStatus)
    919             self.menuItems[eachLabel].Enable(eachEnable)
    920             try:
    921                 self.Bind(wx.EVT_MENU, getattr(self, eachHandler) , self.menuItems[eachLabel])
    922             except:
    923                 print("def " + eachHandler + "(self, event): pass")  
    924         return menu
    925 
    926     def createToolbar(self):
    927         """ Creates the toolbar """
    928         toolbar = self.CreateToolBar()
    929         toolbar.SetToolBitmapSize((32,32))
    930         self.toolItems = {}
    931         for eachTool in JetDefs.TOOLBAR_SPEC:
    932             if eachTool[0] == '-':
    933                 toolbar.AddSeparator()
    934             else:
    935                 b = __import__(eachTool[1])
    936                 bitMap = b.getBitmap()
    937                 self.toolItems[eachTool[0]] = toolbar.AddLabelTool(-1, label=eachTool[0], 
    938                         bitmap=bitMap, 
    939                                      shortHelp=eachTool[0], longHelp=eachTool[2])
    940                 self.Bind(wx.EVT_TOOL, getattr(self, eachTool[3]) , self.toolItems[eachTool[0]])
    941         toolbar.Realize()
    942         
    943     def OnAudition(self, event):
    944         """ Calls the audition window for simple preview of jet file """
    945         jet_file = CreateTempJetFile(self.jet_file)
    946 
    947         w, h = self.GetSize()
    948         w = w - 50
    949         if w < 900:
    950             w = 900
    951         h = h - 50
    952         if h < 650:
    953             h = 650
    954         dlg = Audition(jet_file, (w,h))
    955         dlg.ShowModal()   
    956         CleanupTempJetFile(jet_file)
    957         
    958     def SetKeepPlayingFlag(self, val):
    959         """ Sets a flag to communicate playing state to the play thread """
    960         with self.playerLock:
    961             self.keepPlaying = val
    962 
    963     def GetKeepPlayingFlag(self):   
    964         """ Gets the playing state flag """   
    965         with self.playerLock:
    966             return self.keepPlaying
    967         
    968     def GraphTriggerClip(self, sClipName, iEventId):
    969         """ Triggers a clip when they click on the graph """
    970         with self.playerLock:
    971             try:
    972                 self.jet.TriggerClip(iEventId)
    973                 self.log.SetValue(JetDefs.PLAY_TRIGGERCLIP_MSG % (iEventId, sClipName))
    974                 return True
    975             except:
    976                 return False       
    977         
    978     def OnHelpJet(self, event):
    979         """ Loads the jet help file """
    980         import webbrowser
    981         webbrowser.open(JetDefs.MAIN_HELPFILE)
    982         return
    983 
    984     def OnHelpJetGuidelines(self, event):
    985         """ Loads the authoring guidelines file """
    986         import webbrowser
    987         webbrowser.open(JetDefs.MAIN_HELPGUIDELINESFILE)
    988         return
    989             
    990     def OnAbout(self, event): 
    991         """ Loads the about dialog box """
    992         dlg = JetAbout()
    993         result = dlg.ShowModal()
    994         dlg.Destroy()
    995 
    996     def OnJetImportArchive(self, event):
    997         """ Imports a jet archive file """
    998         defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, 'str', str(os.getcwd()))
    999         dialog = wx.FileDialog(None, JetDefs.IMPORT_ARCHIVE_PROMPT, defDir, "", JetDefs.ARCHIVE_FILE_SPEC, wx.OPEN)
   1000         if dialog.ShowModal() == wx.ID_OK:
   1001             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
   1002             defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC + "Dir", 'str', str(os.getcwd()))
   1003             dlg1 = wx.DirDialog(self, JetDefs.IMPORT_ARCHIVEDIR_PROMPT, style=wx.DD_DEFAULT_STYLE, defaultPath=defDir)
   1004             if dlg1.ShowModal() == wx.ID_OK:
   1005                 IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC + "Dir", str(FileJustPath(dlg1.GetPath())))
   1006                 if YesNo(JetDefs.MAIN_IMPORTTITLE, JetDefs.MAIN_IMPORTMSG % (dialog.GetPath(),dlg1.GetPath()), False):
   1007                     projectPath = dlg1.GetPath()
   1008                     zipFile = dialog.GetPath()
   1009                     z = __import__('zipfile')
   1010                     
   1011                     if not z.is_zipfile(zipFile):
   1012                         wx.MessageBox(JetDefs.IMPORT_ARCHIVE_NO_JTC)
   1013                     else:
   1014                         zip = z.ZipFile(zipFile, 'r')
   1015                         
   1016                         jtcFile = ""
   1017                         fileList = zip.namelist()
   1018                         
   1019                         isArchive = False
   1020                         for myFile in fileList:
   1021                             if myFile == 'JetArchive':
   1022                                 isArchive = True
   1023                                 break
   1024                         if not isArchive:
   1025                             wx.MessageBox(JetDefs.IMPORT_NOT_JET_ARCHIVE)
   1026                         else:
   1027                             for myFile in fileList:
   1028                                 if FileJustExt(myFile) == '.JTC':
   1029                                     jtcFile = myFile
   1030                                     break
   1031                             if jtcFile == "":
   1032                                 wx.MessageBox(JetDefs.IMPORT_ARCHIVE_NO_JTC)
   1033                             else:
   1034                                 for name in zip.namelist(): 
   1035                                     ext = FileJustExt(name)
   1036                                     if ext == '.MID' or ext == '.DLS'  or ext == '.JET':
   1037                                         file(FileFixPath(projectPath + "/" + name), 'wb').write(zip.read(name))
   1038                                     else:
   1039                                         if len(ext) > 0 and ext != '.DS_STORE':
   1040                                             file(FileFixPath(projectPath + "/" + name), 'w').write(zip.read(name))
   1041                             zip.close()
   1042                             self.currentJetConfigFile = FileFixPath(projectPath + "/") + jtcFile
   1043                             self.jet_file = JetFile(self.currentJetConfigFile, "")
   1044                             
   1045                             #fix paths

   1046                             self.jet_file.config.filename = FileJustRoot(self.currentJetConfigFile) + ".JET"
   1047                             for index, segment in enumerate(self.jet_file.segments):
   1048                                 self.jet_file.segments[index].filename = FileFixPath(projectPath + "/" + segment.filename)
   1049                                 if segment.dlsfile > "":
   1050                                     self.jet_file.segments[index].dlsfile = FileFixPath(projectPath + "/" + segment.dlsfile)
   1051                                 self.jet_file.segments[index].output = FileFixPath(projectPath + "/" + segment.output)                        
   1052                             
   1053                             for index, library in enumerate(self.jet_file.libraries):
   1054                                 self.jet_file.libraries[index] = FileFixPath(projectPath + "/" + library)
   1055                                 
   1056                             if ValidateConfig(self.jet_file):
   1057                                 self.jet_file.SaveJetConfig(self.currentJetConfigFile)
   1058                                 self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
   1059                                 self.jet_file = JetFile(self.currentJetConfigFile , "")
   1060                                 self.SetCurrentFile(self.currentJetConfigFile)
   1061 
   1062             dlg1.Destroy()
   1063         dialog.Destroy()        
   1064        
   1065     def OnJetExportArchive(self, event):
   1066         """ Exports the current setup to an archive file """
   1067         self.OnJetSave(event)
   1068         defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, 'str', str(os.getcwd()))
   1069         dialog = wx.FileDialog(None, JetDefs.EXPORT_ARCHIVE_PROMPT, defDir, "", JetDefs.ARCHIVE_FILE_SPEC, wx.SAVE | wx.OVERWRITE_PROMPT )
   1070         if dialog.ShowModal() == wx.ID_OK:
   1071             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
   1072             ExportJetArchive(FileJustRoot(dialog.GetPath()) + ".zip", self.currentJetConfigFile, self.jet_file)
   1073         dialog.Destroy()
   1074         
   1075     def OnCopy(self, event):
   1076         """ Copies the current segment or event to the clipboard """
   1077         if self.currentCtrl == JetDefs.MAIN_SEGLIST:
   1078             if self.currentSegmentName is None:
   1079                 return ""
   1080             
   1081             segment = self.jet_file.GetSegment(self.currentSegmentName)
   1082             if segment == None:
   1083                 return ""
   1084             self.clipBoard = JetCutCopy(self.currentCtrl, segment, self.currentSegmentName)
   1085             return self.currentCtrl
   1086         elif self.currentCtrl == JetDefs.MAIN_EVENTLIST:
   1087             if self.currentSegmentName is None:
   1088                 return ""
   1089     
   1090             if self.currentEventName  is None:
   1091                 return ""
   1092             
   1093             segment = self.jet_file.GetSegment(self.currentSegmentName)
   1094             if segment == None:
   1095                 return ""
   1096             
   1097             curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
   1098             if curEvent == None:
   1099                 return ""
   1100             self.clipBoard = JetCutCopy(self.currentCtrl, curEvent, self.currentSegmentName)
   1101             return self.currentCtrl
   1102             
   1103     def OnCut(self, event):
   1104         """ Cuts the current segment or event to the clipboard """
   1105         retCopy = self.OnCopy(event)
   1106         if retCopy == JetDefs.MAIN_SEGLIST:
   1107             self.SegmentDelete(self.currentSegmentName) 
   1108             self.LoadSegList()
   1109         elif retCopy == JetDefs.MAIN_EVENTLIST:
   1110             self.EventDelete(self.currentEventName)
   1111             self.LoadEventsForSeg(self.currentSegmentName)
   1112         
   1113     def OnPaste(self, event):
   1114         """ Pastes the current segment or event from the clipboard """
   1115         if self.clipBoard is not None:
   1116             if self.currentCtrl == JetDefs.MAIN_SEGLIST and self.clipBoard.objType == JetDefs.MAIN_SEGLIST:
   1117                 saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
   1118                 self.jet_file.segments.append(self.clipBoard.GetObj(self.jet_file.segments))
   1119                 self.UndoAdd(saveState)
   1120                 self.LoadSegList()
   1121             elif self.currentCtrl == JetDefs.MAIN_EVENTLIST and self.clipBoard.objType == JetDefs.MAIN_EVENTLIST and self.clipBoard.currentSegmentName == self.currentSegmentName:
   1122                 for segment in self.jet_file.segments:
   1123                     if segment.segname == self.currentSegmentName:
   1124                         saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
   1125                         segment.jetevents.append(self.clipBoard.GetObj(segment.jetevents))
   1126                         self.UndoAdd(saveState)
   1127                         self.LoadEventsForSeg(self.currentSegmentName)
   1128                         self.graph.LoadSegment(self.jet_file.GetSegment(self.currentSegmentName), 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'))
   1129                         
   1130     def OnJetProperties(self, event):
   1131         """ Opens a dialog box for jetfile properties """
   1132         dlg = JetPropertiesDialog()
   1133         dlg.SetValue(JetDefs.F_JETFILENAME, self.jet_file.config.filename)
   1134         dlg.SetValue(JetDefs.F_COPYRIGHT, StrNoneChk(self.jet_file.config.copyright))
   1135         dlg.SetValue(JetDefs.F_CHASECONTROLLERS, StrNoneChk(self.jet_file.config.chase_controllers))
   1136         dlg.SetValue(JetDefs.F_DELETEEMPTYTRACKS, StrNoneChk(self.jet_file.config.delete_empty_tracks))
   1137         
   1138         result = dlg.ShowModal()
   1139         if result == wx.ID_OK:
   1140             self.jet_file.config.filename = dlg.je.ctrls[JetDefs.F_JETFILENAME].GetValue()
   1141             self.jet_file.config.copyright = dlg.je.ctrls[JetDefs.F_COPYRIGHT].GetValue()
   1142             self.jet_file.config.chase_controllers = dlg.je.ctrls[JetDefs.F_CHASECONTROLLERS].GetValue()
   1143             self.jet_file.config.delete_empty_tracks = dlg.je.ctrls[JetDefs.F_DELETEEMPTYTRACKS].GetValue()
   1144         dlg.Destroy()
   1145        
   1146     def OnPreferences(self, event):
   1147         """ Opens a dialog box to capture preferences and saves them to a configuration file """
   1148         dlg = JetPreferences()
   1149         dlg.SetValue(JetDefs.F_COPYRIGHT, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT))
   1150         dlg.SetValue(JetDefs.F_CHASECONTROLLERS, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, 'bool', True))
   1151         dlg.SetValue(JetDefs.F_DELETEEMPTYTRACKS, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, 'bool', False))
   1152         result = dlg.ShowModal()
   1153         if result == wx.ID_OK:
   1154             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT, dlg.GetValue(JetDefs.F_COPYRIGHT))
   1155             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, dlg.GetValue(JetDefs.F_CHASECONTROLLERS))
   1156             IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, dlg.GetValue(JetDefs.F_DELETEEMPTYTRACKS))
   1157         dlg.Destroy()
   1158 
   1159     def LoadDefaultProperties(self):
   1160         """ Loads default properties from the a configuration file """
   1161         self.jet_file.config.copyright = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT)
   1162         self.jet_file.config.chase_controllers = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, 'bool', True)
   1163         self.jet_file.config.delete_empty_tracks = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, 'bool', False)               
   1164                 
   1165     def OnClose(self, event):
   1166         """ Called upon closing the JetCreator main window """
   1167         if self.isDirty():
   1168             ret = YesNoCancel(JetDefs.MAIN_JETCREATOR, JetDefs.MAIN_SAVEBEFOREEXIT, True)
   1169             if ret == wx.ID_YES:
   1170                 self.OnJetSave(None)
   1171             if ret == wx.ID_CANCEL:
   1172                 return
   1173             
   1174         if self.jet is not None:
   1175             SafeJetShutdown(self.playerLock, self.jet)                
   1176         self.Destroy()
   1177         
   1178     def OnPlay(self, event):
   1179         """ Plays the currently queued segments """
   1180         if self.btnPlay.GetLabel() == JetDefs.BUT_PLAY:
   1181             if not ValidateConfig(self.jet_file):
   1182                 return
   1183             
   1184             #make sure something is queued

   1185             iQueued = False
   1186             num = self.segList.GetItemCount()
   1187             for seg_num in range(num):
   1188                 if self.segList.IsChecked(seg_num):
   1189                     iQueued = True
   1190             if not iQueued:
   1191                 InfoMsg(JetDefs.MAIN_PLAYSEG, JetDefs.MAIN_PLAYSEGMSG)
   1192                 return
   1193         
   1194             for segment in self.jet_file.segments:
   1195                 if FileExists(segment.dlsfile):
   1196                     if not segment.dlsfile in self.jet_file.libraries:
   1197                         self.jet_file.libraries.append(segment.dlsfile)
   1198                     
   1199             self.eventList.DeleteAllItems()
   1200             num = self.segList.GetItemCount()
   1201             for seg_num in range(num):
   1202                 if seg_num == 0: self.log.Clear()
   1203                 if self.segList.IsChecked(seg_num):
   1204                     segment = self.jet_file.GetSegment(getColumnText(self.segList, seg_num, 0))
   1205                     if segment != None:
   1206                         #so we can determine which segment is playing, make these the same

   1207                         userID = seg_num
   1208                         if FileExists(segment.dlsfile):
   1209                             dls_num = FindDlsNum(self.jet_file.libraries, segment.dlsfile)
   1210                         else:
   1211                             dls_num = -1
   1212                         self.queueSegs.append(QueueSeg(segment.segname, userID, seg_num, dls_num, segment.repeat, segment.transpose, segment.mute_flags))
   1213                     
   1214             if len(self.queueSegs) == 0:
   1215                 return
   1216             
   1217             self.btnPlay.SetLabel(JetDefs.BUT_STOP)
   1218             
   1219             thread.start_new_thread(self.PlaySegs, ())
   1220         else:
   1221             with self.playerLock:
   1222                 self.jet.Clear_Queue()
   1223             self.SetKeepPlayingFlag(False)
   1224     
   1225     def PlaySegs(self):
   1226         """ Thread writes a temporary copy of the jet file, and calls the library to play it """
   1227         if len(self.queueSegs) == 0:
   1228             return
   1229         
   1230         jet_file = CreateTempJetFile(self.jet_file)
   1231         
   1232         if not ValidateConfig(jet_file):
   1233             CleanupTempJetFile(jet_file)
   1234             return
   1235              
   1236         self.jet = JET()
   1237         self.jet.eas.StartWave()
   1238         self.jet.OpenFile(jet_file.config.filename)
   1239 
   1240         lastID = -1
   1241 
   1242         # queue first segment and start playback

   1243         Queue(self.jet, self.queueSegs[0])
   1244         index = 1
   1245         self.jet.Play()
   1246         self.paused = False
   1247     
   1248         # continue playing until all segments are done

   1249         self.SetKeepPlayingFlag(True)
   1250         while self.GetKeepPlayingFlag():
   1251             self.jet.Render()
   1252             status = self.jet.Status()
   1253             
   1254             if status.currentUserID <> lastID and status.currentUserID <> -1:
   1255                 wx.PostEvent(self, JetStatusEvent(JetDefs.PST_PLAY, status.currentUserID))
   1256                 lastID = status.currentUserID
   1257 
   1258             # if no more segments - we're done

   1259             if status.numQueuedSegments == 0:
   1260                 break
   1261     
   1262             self.jet.GetAppEvent()
   1263     
   1264             # if less than 2 segs queued - queue another one            

   1265             if (index < len(self.queueSegs)) and (status.numQueuedSegments < 2):
   1266                 Queue(self.jet, self.queueSegs[index])
   1267                 index += 1
   1268                 
   1269             wx.PostEvent(self, JetStatusEvent(JetDefs.PST_UPD_LOCATION, status.location))
   1270         
   1271         
   1272         SafeJetShutdown(self.playerLock, self.jet)   
   1273         
   1274         self.queueSegs = []
   1275         
   1276         CleanupTempJetFile(jet_file)
   1277         
   1278         wx.PostEvent(self, JetStatusEvent(JetDefs.PST_DONE, None))
   1279                 
   1280     def OnJetStatusUpdate(self, evt):
   1281         """ These are screen updates called for from within the thread.  Communication 
   1282             is via a postevent call.
   1283         """
   1284         if evt.mode == JetDefs.PST_PLAY:
   1285             segName = getColumnText(self.segList, evt.data, 0)
   1286             self.LoadEventsForSeg(segName)
   1287             self.log.SetValue(segName)
   1288             ClearRowSelections(self.segList)
   1289             SetRowSelection(self.segList, evt.data, True)
   1290         elif evt.mode == JetDefs.PST_UPD_LOCATION:
   1291             self.graph.UpdateLocation(evt.data)
   1292         elif evt.mode == 3:
   1293             self.graph.UpdateLocation(0)
   1294             ClearRowSelections(self.segList)
   1295             self.eventList.DeleteAllItems()
   1296             self.SetKeepPlayingFlag(False)
   1297             self.btnPlay.SetLabel(JetDefs.BUT_PLAY)
   1298             self.btnPause.SetLabel(JetDefs.BUT_PAUSE)            
   1299             
   1300     def OnPause(self, evt):
   1301         """ Pauses the playback """
   1302         if self.jet is None:
   1303             return
   1304         if not self.paused:
   1305             self.jet.Pause()
   1306             self.paused = True
   1307             self.btnPause.SetLabel(JetDefs.BUT_RESUME)
   1308         else:
   1309             self.jet.Play()
   1310             self.paused = False
   1311             self.btnPause.SetLabel(JetDefs.BUT_PAUSE)
   1312            
   1313     def isDirty(self):
   1314         if len(self.UndoStack) == 0 and len(self.RedoStack) == 0:
   1315             return False
   1316         else:
   1317             return True
   1318         
   1319     def OnSetGraphOptions(self, evt):
   1320         """ Sets graph options """
   1321         IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, self.chkGraphLabels.GetValue())
   1322         IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, self.chkGraphClips.GetValue())
   1323         IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, self.chkGraphAppEvts.GetValue())
   1324         self.graph.LoadSegment(self.jet_file.GetSegment(self.currentSegmentName), 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'))
   1325 
   1326     def OnEventSortOrderChanged(self):
   1327         """ Called when sort order has changed """
   1328         IniSetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_0, self.eventList.GetSortState()[0])
   1329         IniSetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_1, self.eventList.GetSortState()[1])
   1330         self.LoadEventsForSeg(self.currentSegmentName)
   1331         self.graph.LoadSegment(self.jet_file.GetSegment(self.currentSegmentName), 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'))
   1332 
   1333     def EventSortCmp(self, a, b):
   1334         """ Sorts based on selected sort order """
   1335         if self.eventlistSort[0] == 0 or self.eventlistSort[0] == 1:
   1336             if self.eventlistSort[1] == 1:
   1337                 return cmp(a[0].upper(), b[0].upper())
   1338             else:
   1339                 return cmp(b[0].upper(), a[0].upper())                
   1340         elif self.eventlistSort[0] == 2 or self.eventlistSort[0] == 3: 
   1341             if self.eventlistSort[1] == 1:
   1342                 return cmp(MbtVal(a[0]), MbtVal(b[0]))
   1343             else:
   1344                 return cmp(MbtVal(b[0]), MbtVal(a[0]))   
   1345         else:
   1346             return cmp(a[0], b[0])             
   1347 
   1348     def EventSort2(self, seq, attr):
   1349         """ Does Sorting """
   1350         intermed = map(None, map(getattr, seq, (attr,)*len(seq)), xrange(len(seq)), seq)
   1351         intermed.sort(self.EventSortCmp)
   1352         return map(operator.getitem, intermed, (-1,) * len(intermed))
   1353 
   1354     def EventSort(self, lst, attr):
   1355         """ Does Sorting """
   1356         lst[:] = self.EventSort2(lst, attr)
   1357         
   1358     def OnSegSortOrderChanged(self):
   1359         """ Called when sort order has changed """
   1360         IniSetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_0, self.segList.GetSortState()[0])
   1361         IniSetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_1, self.segList.GetSortState()[1])
   1362         self.LoadEventsForSeg(self.currentSegmentName)
   1363         self.graph.LoadSegment(self.jet_file.GetSegment(self.currentSegmentName), 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'))
   1364 
   1365     def SegSortCmp(self, a, b):
   1366         """ Sorts based on selected sort order """
   1367         if self.seglistSort[0] == 0:
   1368             if self.seglistSort[1] == 1:
   1369                 return cmp(a[0].upper(), b[0].upper())
   1370             else:
   1371                 return cmp(b[0].upper(), a[0].upper())   
   1372         elif self.seglistSort[0] == 1 or self.seglistSort[0] == 2:   
   1373             if self.seglistSort[1] == 1:
   1374                 return cmp(FileJustName(a[0]).upper(), FileJustName(b[0]).upper())
   1375             else:
   1376                 return cmp(FileJustName(b[0]).upper(), FileJustName(a[0]).upper())   
   1377         elif self.seglistSort[0] == 3 or self.seglistSort[0] == 4: 
   1378             if self.seglistSort[1] == 1:
   1379                 return cmp(MbtVal(a[0]), MbtVal(b[0]))
   1380             else:
   1381                 return cmp(MbtVal(b[0]), MbtVal(a[0]))   
   1382         else:
   1383             return cmp(a[0], b[0])             
   1384 
   1385     def SegSort2(self, seq, attr):
   1386         """ Does Sorting """
   1387         intermed = map(None, map(getattr, seq, (attr,)*len(seq)), xrange(len(seq)), seq)
   1388         intermed.sort(self.SegSortCmp)
   1389         return map(operator.getitem, intermed, (-1,) * len(intermed))
   1390 
   1391     def SegSort(self, lst, attr):
   1392         """ Does Sorting """
   1393         lst[:] = self.SegSort2(lst, attr)
   1394 
   1395 if __name__ == '__main__':
   1396     """ Sets the logging level, then calls the open dialog box before initializing main window"""
   1397     
   1398     logLevel = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_LOGGING, JetDefs.INI_LOGGING)
   1399     if logLevel == 'DEBUG':
   1400         logging.basicConfig(level=logging.DEBUG, format='%(funcName)s[%(lineno)d]: %(message)s')
   1401     elif logLevel == 'INFO':
   1402         logging.basicConfig(level=logging.INFO, format='%(funcName)s[%(lineno)d]: %(message)s')
   1403     elif logLevel == 'ERROR':
   1404         logging.basicConfig(level=logging.ERROR, format='%(funcName)s[%(lineno)d]: %(message)s')
   1405     elif logLevel == 'WARNING':
   1406         logging.basicConfig(level=logging.WARNING, format='%(funcName)s[%(lineno)d]: %(message)s')
   1407     else:
   1408         install_release_loggers()
   1409         
   1410     app = wx.App(None)
   1411     
   1412     if not os.path.isdir(JetDefs.TEMP_JET_DIR):
   1413         os.mkdir(JetDefs.TEMP_JET_DIR)
   1414         
   1415     openFile = ""
   1416     dlg = JetOpen()
   1417     result = dlg.ShowModal()
   1418     if result == wx.ID_CANCEL:
   1419         dlg.Destroy()
   1420     elif result == JetDefs.ID_JET_IMPORT:
   1421         dlg.Destroy()
   1422     
   1423         au = JetCreator(None, -1, "", importFlag=True)
   1424         app.MainLoop()
   1425     else:
   1426         openFile = dlg.fileName
   1427         dlg.Destroy()
   1428     
   1429         au = JetCreator(None, -1, openFile)
   1430         app.MainLoop()
   1431 
   1432