JetCreator.py revision 8872ef327bd0a801363edf1c6ce8df0b74e51c8d
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
23from __future__ import with_statement
24
25import wx
26import sys
27import thread
28import copy
29import wx.html
30import operator
31
32from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
33from eas import *
34from JetFile import *
35from JetUtils import *
36from JetCtrls import *
37from JetDialogs import *
38from JetSegGraph import SegmentGraph, Marker
39from JetAudition import *
40from JetStatusEvent import *
41
42import img_favicon
43import img_New
44
45provider = wx.SimpleHelpProvider()
46wx.HelpProvider_Set(provider)
47
48
49class 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
1395if __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