You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1432 lines
69 KiB

"""
File:
JetCreator.py
Contents and purpose:
Jet file creation utility for JET sound engine
Copyright (c) 2008 Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from __future__ import with_statement
import wx
import sys
import thread
import copy
import wx.html
import operator
from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
from eas import *
from JetFile import *
from JetUtils import *
from JetCtrls import *
from JetDialogs import *
from JetSegGraph import SegmentGraph, Marker
from JetAudition import *
from JetStatusEvent import *
import img_favicon
import img_New
provider = wx.SimpleHelpProvider()
wx.HelpProvider_Set(provider)
class JetCreator(wx.Frame):
""" Main window of JetCreator utility """
def __init__(self, parent, id, jetConfigFile, importFlag=False):
wx.Frame.__init__(self, parent, id, size=(1050, 720), style=wx.DEFAULT_FRAME_STYLE | wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX)
self.myicon = img_favicon.getIcon()
self.SetIcon(self.myicon)
self.UndoStack = []
self.RedoStack = []
self.queueSegs = []
self.clipBoard = None
self.jet = None
self.playerLock = threading.RLock()
self.SetKeepPlayingFlag(True)
self.currentSegmentName = None
self.currentSegmentIndex = None
self.currentEventName = None
self.currentEventIndex = None
self.currentCtrl = ""
self.currentJetConfigFile = jetConfigFile
self.paused = False
self.eventlistSort = (0, 1)
self.seglistSort = (0, 1)
if self.currentJetConfigFile == "":
FileKillClean(JetDefs.UNTITLED_FILE)
self.currentJetConfigFile = JetDefs.UNTITLED_FILE
self.jet_file = JetFile(self.currentJetConfigFile, "")
if not ValidateConfig(self.jet_file):
FileKillClean(JetDefs.UNTITLED_FILE)
self.currentJetConfigFile = JetDefs.UNTITLED_FILE
self.jet_file = JetFile(self.currentJetConfigFile, "")
if self.currentJetConfigFile == JetDefs.UNTITLED_FILE:
self.LoadDefaultProperties()
self.initLayout()
self.initStatusBar()
self.createMenuBar()
self.createToolbar()
self.SetCurrentFile(self.currentJetConfigFile)
self.initHelp()
self.graph.ClickCallbackFct = self.GraphTriggerClip
EVT_JET_STATUS(self, self.OnJetStatusUpdate)
wx.EVT_CLOSE(self, self.OnClose)
self.Centre()
self.Show(True)
if importFlag:
self.OnJetImportArchive(None)
self.eventList.OnSortOrderChangedAlert = self.OnEventSortOrderChanged
self.segList.OnSortOrderChangedAlert = self.OnSegSortOrderChanged
def initLayout(self):
""" Initializes the screen layout """
panel = wx.Panel(self, -1)
hboxMain = wx.BoxSizer(wx.HORIZONTAL)
leftPanel = wx.Panel(panel, -1)
leftTopPanel = wx.Panel(leftPanel, -1)
leftBotPanel = wx.Panel(leftPanel, -1)
rightPanel = wx.Panel(panel, -1)
self.segList = JetCheckListCtrl(rightPanel)
for title, width, fld in JetDefs.SEGMENT_GRID:
self.segList.AddCol(title, width)
self.eventList = JetListCtrl(rightPanel)
for title, width, fld in JetDefs.CLIPS_GRID:
self.eventList.AddCol(title, width)
self.eventList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnEventListClick)
self.segList.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSegListClick)
self.segList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnSegmentUpdate)
self.eventList.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnEventUpdate)
self.segList.BindCheckBox(self.OnSegmentChecked)
BUT_SIZE = (95, 25)
self.btnAddSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_ADD, size=BUT_SIZE)
self.btnRevSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_REVISE, size=BUT_SIZE)
self.btnDelSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_DELETE, size=BUT_SIZE)
self.btnMoveSeg = wx.Button(leftTopPanel, -1, JetDefs.BUT_MOVE, size=BUT_SIZE)
self.btnQueueAll = wx.Button(leftTopPanel, -1, JetDefs.BUT_QUEUEALL, size=BUT_SIZE)
self.btnDequeueAll = wx.Button(leftTopPanel, -1, JetDefs.BUT_DEQUEUEALL, size=BUT_SIZE)
self.btnPlay = wx.Button(leftTopPanel, -1, JetDefs.BUT_PLAY, size=BUT_SIZE)
self.btnPause = wx.Button(leftTopPanel, -1, JetDefs.BUT_PAUSE, size=BUT_SIZE)
self.btnAudition = wx.Button(leftTopPanel, -1, JetDefs.BUT_AUDITION, size=BUT_SIZE)
self.btnAddEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_ADD, size=BUT_SIZE)
self.btnRevEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_REVISE, size=BUT_SIZE)
self.btnDelEvt = wx.Button(leftBotPanel, -1, JetDefs.BUT_DELETE, size=BUT_SIZE)
self.btnMoveEvents = wx.Button(leftBotPanel, -1, JetDefs.BUT_MOVE, size=BUT_SIZE)
self.Bind(wx.EVT_BUTTON, self.OnSegmentAdd, id=self.btnAddSeg.GetId())
self.Bind(wx.EVT_BUTTON, self.OnSegmentUpdate, id=self.btnRevSeg.GetId())
self.Bind(wx.EVT_BUTTON, self.OnSegmentDelete, id=self.btnDelSeg.GetId())
self.Bind(wx.EVT_BUTTON, self.OnSegmentsMove, id=self.btnMoveSeg.GetId())
self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id=self.btnQueueAll.GetId())
self.Bind(wx.EVT_BUTTON, self.OnDeselectAll, id=self.btnDequeueAll.GetId())
self.Bind(wx.EVT_BUTTON, self.OnPlay, id=self.btnPlay.GetId())
self.Bind(wx.EVT_BUTTON, self.OnPause, id=self.btnPause.GetId())
self.Bind(wx.EVT_BUTTON, self.OnAudition, id=self.btnAudition.GetId())
self.Bind(wx.EVT_BUTTON, self.OnEventAdd, id=self.btnAddEvt.GetId())
self.Bind(wx.EVT_BUTTON, self.OnEventUpdate, id=self.btnRevEvt.GetId())
self.Bind(wx.EVT_BUTTON, self.OnEventDelete, id=self.btnDelEvt.GetId())
self.Bind(wx.EVT_BUTTON, self.OnEventsMove, id=self.btnMoveEvents.GetId())
BORDER = 5
BUT_SPACE = 3
vBoxLeftTop = wx.BoxSizer(wx.VERTICAL)
vBoxLeftBot = wx.BoxSizer(wx.VERTICAL)
vBoxLeftTop.Add(self.btnAddSeg, 0, wx.TOP, BORDER)
vBoxLeftTop.Add(self.btnRevSeg, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnDelSeg, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnMoveSeg, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add((-1, 12))
vBoxLeftTop.Add(self.btnQueueAll, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnDequeueAll, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnPlay, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnPause, 0, wx.TOP, BUT_SPACE)
vBoxLeftTop.Add(self.btnAudition, 0, wx.TOP, BUT_SPACE)
vBoxLeftBot.Add(self.btnAddEvt, 0)
vBoxLeftBot.Add(self.btnRevEvt, 0, wx.TOP, BUT_SPACE)
vBoxLeftBot.Add(self.btnDelEvt, 0, wx.TOP, BUT_SPACE)
vBoxLeftBot.Add(self.btnMoveEvents, 0, wx.TOP, BUT_SPACE)
leftTopPanel.SetSizer(vBoxLeftTop)
leftBotPanel.SetSizer(vBoxLeftBot)
vboxLeft = wx.BoxSizer(wx.VERTICAL)
vboxLeft.Add(leftTopPanel, 1, wx.EXPAND)
vboxLeft.Add(leftBotPanel, 1, wx.EXPAND)
vboxLeft.Add((-1, 25))
leftPanel.SetSizer(vboxLeft)
self.log = wx.TextCtrl(rightPanel, -1)
self.graph = SegmentGraph(rightPanel, size=(-1, 50))
vboxRight = wx.BoxSizer(wx.VERTICAL)
vboxRight.Add(self.segList, 4, wx.EXPAND | wx.TOP, BORDER)
vboxRight.Add((-1, 10))
vboxRight.Add(self.eventList, 3, wx.EXPAND | wx.TOP, BORDER)
vboxRight.Add((-1, 10))
vboxRight.Add(self.log, 0, wx.EXPAND)
vboxRight.Add((-1, 5))
vboxRight.Add(self.graph, 1, wx.EXPAND)
vboxRight.Add((-1, 10))
rightPanel.SetSizer(vboxRight)
hboxMain.Add(leftPanel, 0, wx.EXPAND | wx.RIGHT | wx.LEFT, BORDER)
hboxMain.Add(rightPanel, 1, wx.EXPAND)
hboxMain.Add((BORDER, -1))
panel.SetSizer(hboxMain)
pnlGraph = wx.Panel(leftBotPanel, -1)
graphSizer1 = wx.BoxSizer(wx.VERTICAL)
pnlGraph.SetSizer(graphSizer1)
graphBox = wx.StaticBox(pnlGraph, wx.ID_ANY, label='Graph')
graphSizer2 = wx.StaticBoxSizer(graphBox, wx.VERTICAL)
self.chkGraphLabels = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_LBLS)
self.chkGraphClips = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_TRIGGER)
self.chkGraphAppEvts = wx.CheckBox(pnlGraph, -1, JetDefs.GRAPH_APP)
graphSizer2.Add(self.chkGraphLabels, 0, wx.TOP, BUT_SPACE)
graphSizer2.Add(self.chkGraphClips, 0, wx.TOP, BUT_SPACE)
graphSizer2.Add(self.chkGraphAppEvts, 0, wx.TOP | wx.BOTTOM, BUT_SPACE)
graphSizer1.Add((-1, 10))
graphSizer1.Add(graphSizer2)
vBoxLeftBot.Add(pnlGraph, 0, wx.TOP, BUT_SPACE)
self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphLabels.GetId())
self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphClips.GetId())
self.Bind(wx.EVT_CHECKBOX, self.OnSetGraphOptions, id=self.chkGraphAppEvts.GetId())
def initHelp(self):
""" Initializes the help text for screen elements """
self.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, ''))
self.segList.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, JetDefs.MAIN_SEGLIST))
self.eventList.SetHelpText(GetJetHelpText(JetDefs.MAIN_DLG_CTRLS, JetDefs.MAIN_EVENTLIST))
self.graph.SetHelpText(GetJetHelpText(JetDefs.AUDITION_CTRLS, JetDefs.AUDITION_GRAPH))
def initStatusBar(self):
""" Initializes the status bar """
self.statusbar = self.CreateStatusBar()
def OnSelectAll(self, event):
""" Called from select all button """
num = self.segList.GetItemCount()
for i in range(num-1, -1, -1):
self.segList.CheckItem(i)
def OnDeselectAll(self, event):
""" Called from deselect all button """
num = self.segList.GetItemCount()
for i in range(num-1, -1, -1):
self.segList.CheckItem(i, False)
def LoadSegList(self):
""" Loads up the list of segments """
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))
segments = self.jet_file.GetSegments()
if self.seglistSort[0] == 0:
self.SegSort(segments, "segname")
elif self.seglistSort[0] == 1:
self.SegSort(segments, "filename")
elif self.seglistSort[0] == 2:
self.SegSort(segments, "dlsfile")
elif self.seglistSort[0] == 3:
self.SegSort(segments, "start")
elif self.seglistSort[0] == 4:
self.SegSort(segments, "end")
elif self.seglistSort[0] == 5:
self.SegSort(segments, "quantize")
elif self.seglistSort[0] == 6:
self.SegSort(segments, "transpose")
elif self.seglistSort[0] == 7:
self.SegSort(segments, "repeat")
elif self.seglistSort[0] == 8:
self.SegSort(segments, "mute_flags")
listDataMap = []
self.currentSegmentIndex = None
self.currentSegmentName = None
self.segList.DeleteAllItems()
self.eventList.DeleteAllItems()
self.menuItems[JetDefs.MNU_UPDATE_SEG].Enable(False)
self.menuItems[JetDefs.MNU_DELETE_SEG].Enable(False)
self.menuItems[JetDefs.MNU_MOVE_SEG].Enable(False)
self.menuItems[JetDefs.MNU_ADD_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
for segment in self.jet_file.GetSegments():
index = self.segList.InsertStringItem(sys.maxint, StrNoneChk(segment.segname))
self.segList.SetStringItem(index, 1, FileJustName(StrNoneChk(segment.filename)))
self.segList.SetStringItem(index, 2, FileJustName(StrNoneChk(segment.dlsfile)))
self.segList.SetStringItem(index, 3, mbtFct(segment.start, 1))
self.segList.SetStringItem(index, 4, mbtFct(segment.end, 1))
self.segList.SetStringItem(index, 5, StrNoneChk(segment.quantize))
self.segList.SetStringItem(index, 6, StrNoneChk(segment.transpose))
self.segList.SetStringItem(index, 7, StrNoneChk(segment.repeat))
self.segList.SetStringItem(index, 8, StrNoneChk(segment.mute_flags))
self.segList.SetItemData(index, index)
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))))
self.segList.itemDataMap = listDataMap
self.segList.InitSorting(9)
self.graph.ClearGraph()
def LoadEventsForSeg(self, segName):
""" Loads up the events associated with a segment """
self.currentEventIndex = None
self.eventList.DeleteAllItems()
self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(False)
self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(False)
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))
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment is not None:
if self.eventlistSort[0] == 0:
self.EventSort(segment.jetevents, "event_name")
elif self.eventlistSort[0] == 1:
self.EventSort(segment.jetevents, "event_type")
elif self.eventlistSort[0] == 2:
self.EventSort(segment.jetevents, "event_start")
elif self.eventlistSort[0] == 3:
self.EventSort(segment.jetevents, "event_end")
elif self.eventlistSort[0] == 4:
self.EventSort(segment.jetevents, "track_num")
elif self.eventlistSort[0] == 5:
self.EventSort(segment.jetevents, "channel_num")
elif self.eventlistSort[0] == 6:
self.EventSort(segment.jetevents, "event_id")
listDataMap = []
for jet_event in self.jet_file.GetEvents(segName):
index = self.eventList.InsertStringItem(sys.maxint, StrNoneChk(jet_event.event_name))
self.eventList.SetStringItem(index, 1, StrNoneChk(jet_event.event_type))
self.eventList.SetStringItem(index, 2, mbtFct(jet_event.event_start, 1))
self.eventList.SetStringItem(index, 3, mbtFct(jet_event.event_end, 1))
self.eventList.SetStringItem(index, 4, StrNoneChk(jet_event.track_num))
self.eventList.SetStringItem(index, 5, StrNoneChk(jet_event.channel_num + 1))
self.eventList.SetStringItem(index, 6, StrNoneChk(jet_event.event_id))
self.eventList.SetItemData(index, index)
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))))
self.eventList.itemDataMap = listDataMap
self.eventList.InitSorting(7)
def OnEventListClick(self, event):
""" Sets the current event variable when selecting from the list """
self.currentCtrl = "eventList"
self.currentEventIndex = event.m_itemIndex
self.currentEventName = getColumnText(self.eventList, event.m_itemIndex, 0)
self.menuItems[JetDefs.MNU_UPDATE_EVENT].Enable(True)
self.menuItems[JetDefs.MNU_DELETE_EVENT].Enable(True)
self.menuItems[JetDefs.MNU_MOVE_EVENT].Enable(True)
def OnSegmentChecked(self, index, checked):
""" Selects the segment when checkbox clicked """
ClearRowSelections(self.segList)
SetRowSelection(self.segList, index, True)
def SelectSegment(self, segName):
""" Selects a segment by segment name """
itm = self.segList.FindItem(-1, segName)
self.segList.EnsureVisible(itm)
ClearRowSelections(self.segList)
SetRowSelection(self.segList, itm, True)
def SelectEvent(self, eventName):
""" Selects an event by event name """
itm = self.eventList.FindItem(-1, eventName)
self.eventList.EnsureVisible(itm)
ClearRowSelections(self.eventList)
SetRowSelection(self.eventList, itm, True)
def OnSegListClick(self, event):
""" Loads up a segment when the list is clicked """
self.currentCtrl = "segList"
self.currentSegmentIndex = event.m_itemIndex
self.currentSegmentName = getColumnText(self.segList, event.m_itemIndex, 0)
self.LoadEventsForSeg(getColumnText(self.segList, event.m_itemIndex, 0))
self.menuItems[JetDefs.MNU_UPDATE_SEG].Enable(True)
self.menuItems[JetDefs.MNU_DELETE_SEG].Enable(True)
self.menuItems[JetDefs.MNU_MOVE_SEG].Enable(True)
self.menuItems[JetDefs.MNU_ADD_EVENT].Enable(True)
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'))
if info == None:
self.log.SetValue("")
else:
iLength = info.iLengthInMs
if iLength > 0:
self.log.SetValue("%s %.2f Seconds" % (self.currentSegmentName, iLength / 1000.00))
else:
self.log.SetValue("%s" % (self.currentSegmentName))
def OnSegmentAdd(self, event):
""" Calls the dialog box for adding a segment """
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
dlg = SegEdit(JetDefs.MAIN_ADDSEGTITLE, self.currentJetConfigFile)
for filename in self.jet_file.GetMidiFiles():
dlg.je.ctrls[JetDefs.F_MIDIFILE].Append(filename)
for library in self.jet_file.GetLibraries():
dlg.je.ctrls[JetDefs.F_DLSFILE].Append(library)
result = dlg.ShowModal()
if result == wx.ID_OK:
if len(dlg.lstReplicate) > 0:
if dlg.chkReplaceMatching:
self.jet_file.DeleteSegmentsMatchingPrefix(dlg.replicatePrefix)
for replicate in dlg.lstReplicate:
self.jet_file.AddSegment(replicate[0], dlg.GetValue(JetDefs.F_MIDIFILE),
mbtFct(replicate[1],-1), mbtFct(replicate[2],-1),
JetDefs.MBT_ZEROSTR,
SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile),
dlg.GetValue(JetDefs.F_QUANTIZE),
[], dlg.GetValue(JetDefs.F_DLSFILE),
None,
dlg.GetValue(JetDefs.F_TRANSPOSE),
dlg.GetValue(JetDefs.F_REPEAT),
dlg.GetValue(JetDefs.F_MUTEFLAGS))
self.LoadSegList()
self.SelectSegment(dlg.lstReplicate[0][0])
else:
self.jet_file.AddSegment(dlg.GetValue(JetDefs.F_SEGNAME), dlg.GetValue(JetDefs.F_MIDIFILE),
dlg.GetValue(JetDefs.F_START), dlg.GetValue(JetDefs.F_END),
JetDefs.MBT_ZEROSTR,
SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile),
dlg.GetValue(JetDefs.F_QUANTIZE),
[], dlg.GetValue(JetDefs.F_DLSFILE),
None,
dlg.GetValue(JetDefs.F_TRANSPOSE),
dlg.GetValue(JetDefs.F_REPEAT),
dlg.GetValue(JetDefs.F_MUTEFLAGS))
self.LoadSegList()
self.SelectSegment(dlg.GetValue(JetDefs.F_SEGNAME))
self.UndoAdd(saveState)
dlg.Destroy()
def OnSegmentUpdate(self, event):
""" Calls the dialog box for updating a segment """
if self.currentSegmentName is None:
return
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
dlg = SegEdit(JetDefs.MAIN_REVSEGTITLE, self.currentJetConfigFile)
for filename in self.jet_file.GetMidiFiles():
dlg.je.ctrls[JetDefs.F_MIDIFILE].Append(filename)
for library in self.jet_file.GetLibraries():
dlg.je.ctrls[JetDefs.F_DLSFILE].Append(library)
dlg.SetValue(JetDefs.F_SEGNAME, segment.segname)
dlg.SetValue(JetDefs.F_MUTEFLAGS, segment.mute_flags)
dlg.SetValue(JetDefs.F_MIDIFILE, segment.filename)
dlg.SetValue(JetDefs.F_DLSFILE, segment.dlsfile)
dlg.SetValue(JetDefs.F_START, segment.start)
dlg.SetValue(JetDefs.F_END, segment.end)
dlg.SetValue(JetDefs.F_QUANTIZE, segment.quantize)
dlg.SetValue(JetDefs.F_TRANSPOSE, segment.transpose)
dlg.SetValue(JetDefs.F_REPEAT, segment.repeat)
dlg.jetevents = segment.jetevents
result = dlg.ShowModal()
if result == wx.ID_OK:
self.jet_file.UpdateSegment(self.currentSegmentName, dlg.GetValue(JetDefs.F_SEGNAME),
dlg.GetValue(JetDefs.F_MIDIFILE),
dlg.GetValue(JetDefs.F_START), dlg.GetValue(JetDefs.F_END),
JetDefs.MBT_ZEROSTR, #dlg.GetValue(JetDefs.F_LENGTH),
SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile),
dlg.GetValue(JetDefs.F_QUANTIZE),
[], dlg.GetValue(JetDefs.F_DLSFILE),
None,
dlg.GetValue(JetDefs.F_TRANSPOSE),
dlg.GetValue(JetDefs.F_REPEAT),
dlg.GetValue(JetDefs.F_MUTEFLAGS))
if len(dlg.lstReplicate) > 0:
if dlg.chkReplaceMatching:
self.jet_file.DeleteSegmentsMatchingPrefix(dlg.replicatePrefix)
for replicate in dlg.lstReplicate:
self.jet_file.AddSegment(replicate[0], dlg.GetValue(JetDefs.F_MIDIFILE),
mbtFct(replicate[1],-1), mbtFct(replicate[2],-1),
JetDefs.MBT_ZEROSTR,
SegmentOutputFile(dlg.GetValue(JetDefs.F_SEGNAME), self.currentJetConfigFile),
dlg.GetValue(JetDefs.F_QUANTIZE),
[], dlg.GetValue(JetDefs.F_DLSFILE),
None,
dlg.GetValue(JetDefs.F_TRANSPOSE),
dlg.GetValue(JetDefs.F_REPEAT),
dlg.GetValue(JetDefs.F_MUTEFLAGS))
self.LoadSegList()
self.SelectSegment(dlg.lstReplicate[0][0])
else:
self.LoadSegList()
self.SelectSegment(dlg.GetValue(JetDefs.F_SEGNAME))
self.UndoAdd(saveState)
dlg.Destroy()
def OnSegmentDelete(self, event):
""" Confirms the deletion segment(s) by user action """
if self.currentSegmentName is None:
return
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return
count = 0
deleteMsg = ''
item = self.segList.GetFirstSelected()
while item != -1:
if count == 0:
deleteMsg = getColumnText(self.segList,item,0)
else:
if count == 40:
deleteMsg = deleteMsg + "\n" + "....more"
elif count < 40:
deleteMsg = deleteMsg + "\n" + getColumnText(self.segList,item,0)
count = count + 1
item = self.segList.GetNextSelected(item)
if YesNo(JetDefs.MAIN_CONFIRM, deleteMsg + JetDefs.MAIN_CONFIRM_SEG_DLT, False):
item = self.segList.GetFirstSelected()
while item != -1:
segName = getColumnText(self.segList,item,0)
self.SegmentDelete(segName)
item = self.segList.GetNextSelected(item)
self.graph.ClearGraph()
self.LoadSegList()
def SegmentDelete(self, segName):
""" Deletes a segment """
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
self.jet_file.DeleteSegment(segName)
self.UndoAdd(saveState)
def OnSegmentsMove(self, event):
""" Move segment(s) """
if self.currentSegmentName is None:
return
lstMoveItems = []
count = 0
item = self.segList.GetFirstSelected()
while item != -1:
max = GetMidiInfo(self.jet_file.GetSegment(getColumnText(self.segList,item,0)).filename).endMbtStr
lstMoveItems.append((getColumnText(self.segList,item,0), mbtFct(getColumnText(self.segList,item,3),-1), mbtFct(getColumnText(self.segList,item,4),-1), max))
count = count + 1
item = self.segList.GetNextSelected(item)
if count == 0:
InfoMsg("Move", "Select one or more items to move.")
return
dlg = JetMove("Move Segments")
dlg.lstMoveItems = lstMoveItems
result = dlg.ShowModal()
if result == wx.ID_OK:
if len(dlg.lstMoveMbt) > 0:
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
for moveitem in dlg.lstMoveMbt:
self.jet_file.MoveSegment(moveitem[0], moveitem[1], moveitem[2])
self.LoadSegList()
self.UndoAdd(saveState)
dlg.Destroy()
def UndoAdd(self, saveState):
""" Adds the current state to the undo stack """
self.UndoStack.append(saveState)
self.menuItems[JetDefs.MNU_UNDO].Enable(True)
def RedoAdd(self, saveState):
""" Adds the current state the the redo stack """
self.RedoStack.append(saveState)
self.menuItems[JetDefs.MNU_REDO].Enable(True)
def OnRedo(self, event):
""" Redo if there's one in the stack """
if len(self.RedoStack) > 0:
self.UndoAdd(JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex))
state = self.RedoStack.pop()
self.jet_file = copy.deepcopy(state.jet_file)
self.LoadSegList()
self.currentSegmentIndex = state.currentSegmentIndex
if self.currentSegmentIndex != None:
SetRowSelection(self.segList, self.currentSegmentIndex, True)
if len(self.RedoStack) == 0:
self.menuItems[JetDefs.MNU_REDO].Enable(False)
def OnUndo(self, event):
""" Undo if there's one in the stack """
if len(self.UndoStack) > 0:
self.RedoAdd(JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex))
state = self.UndoStack.pop()
self.jet_file = copy.deepcopy(state.jet_file)
self.LoadSegList()
self.currentSegmentIndex = state.currentSegmentIndex
if self.currentSegmentIndex != None:
SetRowSelection(self.segList, self.currentSegmentIndex, True)
if len(self.UndoStack) == 0:
self.menuItems[JetDefs.MNU_UNDO].Enable(False)
def OnEventAdd(self, event):
""" Calls a dialog box to add an event to the current segment """
if self.currentSegmentName is None:
return
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
dlg = EventEdit(JetDefs.MAIN_ADDEVENTTITLE, self.currentJetConfigFile)
editSegment = copy.deepcopy(segment)
dlg.SetSegment(editSegment)
dlg.SetEventId()
result = dlg.ShowModal()
if result == wx.ID_OK:
if dlg.GetValue(JetDefs.F_ETYPE) == JetDefs.E_EOS:
#check for an existing EOS event
events = self.jet_file.GetEvents(self.currentSegmentName)
for evt in events:
if evt.event_type == JetDefs.E_EOS:
self.jet_file.DeleteEvent(self.currentSegmentName, evt.event_name)
dlg.SetValue(JetDefs.F_ESTART, dlg.GetValue(JetDefs.F_EEND))
if len(dlg.lstReplicate) > 0:
if dlg.chkReplaceMatching:
self.jet_file.DeleteEventsMatchingPrefix(self.currentSegmentName, dlg.replicatePrefix)
for replicate in dlg.lstReplicate:
self.jet_file.AddEvent(self.currentSegmentName, replicate[0],
dlg.GetValue(JetDefs.F_ETYPE),
dlg.GetValue(JetDefs.F_EEVENTID),
dlg.GetValue(JetDefs.F_ETRACK),
dlg.GetValue(JetDefs.F_ECHANNEL),
mbtFct(replicate[1],-1),
mbtFct(replicate[2],-1))
self.SelectSegment(self.currentSegmentName)
self.SelectEvent(dlg.lstReplicate[0][0])
else:
self.jet_file.AddEvent(self.currentSegmentName, dlg.GetValue(JetDefs.F_ENAME),
dlg.GetValue(JetDefs.F_ETYPE),
dlg.GetValue(JetDefs.F_EEVENTID),
dlg.GetValue(JetDefs.F_ETRACK),
dlg.GetValue(JetDefs.F_ECHANNEL),
dlg.GetValue(JetDefs.F_ESTART),
dlg.GetValue(JetDefs.F_EEND))
self.SelectSegment(self.currentSegmentName)
self.SelectEvent(dlg.GetValue(JetDefs.F_ENAME))
self.UndoAdd(saveState)
dlg.Destroy()
def OnEventUpdate(self, event):
""" Calls the dialog box to update the current event """
if self.currentSegmentName is None:
return
if self.currentEventName is None:
return
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return
curEvent = copy.deepcopy(self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName))
if curEvent == None:
return
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
#only want the event we are editing to show up in graph
editSegment = copy.deepcopy(segment)
editSegment.jetevents = []
editSegment.jetevents.append(curEvent)
dlg = EventEdit(JetDefs.MAIN_REVEVENTTITLE, self.currentJetConfigFile)
dlg.SetSegment(editSegment)
dlg.SetValue(JetDefs.F_ENAME, curEvent.event_name)
dlg.SetValue(JetDefs.F_ETYPE, curEvent.event_type)
dlg.SetValue(JetDefs.F_ESTART, curEvent.event_start)
dlg.SetValue(JetDefs.F_EEND, curEvent.event_end)
dlg.SetValue(JetDefs.F_ETRACK, curEvent.track_num)
dlg.SetValue(JetDefs.F_ECHANNEL, curEvent.channel_num)
dlg.SetValue(JetDefs.F_EEVENTID, curEvent.event_id)
dlg.OnEventSelect()
result = dlg.ShowModal()
if result == wx.ID_OK:
if dlg.GetValue(JetDefs.F_ETYPE) == JetDefs.E_EOS:
dlg.SetValue(JetDefs.F_ESTART, dlg.GetValue(JetDefs.F_EEND))
self.jet_file.UpdateEvent(self.currentSegmentName,
self.currentEventName,
dlg.GetValue(JetDefs.F_ENAME),
dlg.GetValue(JetDefs.F_ETYPE),
dlg.GetValue(JetDefs.F_EEVENTID),
dlg.GetValue(JetDefs.F_ETRACK),
dlg.GetValue(JetDefs.F_ECHANNEL),
dlg.GetValue(JetDefs.F_ESTART),
dlg.GetValue(JetDefs.F_EEND))
if len(dlg.lstReplicate) > 0:
if dlg.chkReplaceMatching:
self.jet_file.DeleteEventsMatchingPrefix(self.currentSegmentName, dlg.replicatePrefix)
for replicate in dlg.lstReplicate:
self.jet_file.AddEvent(self.currentSegmentName, replicate[0],
dlg.GetValue(JetDefs.F_ETYPE),
dlg.GetValue(JetDefs.F_EEVENTID),
dlg.GetValue(JetDefs.F_ETRACK),
dlg.GetValue(JetDefs.F_ECHANNEL),
mbtFct(replicate[1],-1),
mbtFct(replicate[2],-1))
self.SelectSegment(self.currentSegmentName)
self.SelectEvent(dlg.lstReplicate[0][0])
else:
self.SelectSegment(self.currentSegmentName)
self.SelectEvent(dlg.GetValue(JetDefs.F_ENAME))
self.UndoAdd(saveState)
dlg.Destroy()
def OnEventDelete(self, event):
""" Confirms the deletion of event(s) """
if self.currentSegmentName is None:
return
if self.currentEventName is None:
return
curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
if curEvent == None:
return
count = 0
deleteMsg = ''
item = self.eventList.GetFirstSelected()
while item != -1:
if count == 0:
deleteMsg = getColumnText(self.eventList,item,0)
else:
if count == 40:
deleteMsg = deleteMsg + "\n" + "....more"
elif count < 40:
deleteMsg = deleteMsg + "\n" + getColumnText(self.eventList,item,0)
count = count + 1
item = self.eventList.GetNextSelected(item)
if YesNo(JetDefs.MAIN_CONFIRM, deleteMsg + JetDefs.MAIN_CONRIRM_EVT_DLT, False):
item = self.eventList.GetFirstSelected()
while item != -1:
eventName = getColumnText(self.eventList,item,0)
self.EventDelete(eventName)
item = self.eventList.GetNextSelected(item)
self.SelectSegment(self.currentSegmentName)
self.LoadEventsForSeg(self.currentSegmentName)
def EventDelete(self, eventName):
""" Deletes an event """
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
self.jet_file.DeleteEvent(self.currentSegmentName, eventName)
self.UndoAdd(saveState)
def OnEventsMove(self, event):
""" Move event(s) """
if self.currentSegmentName is None:
return
if self.currentEventName is None:
return
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return
curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
if curEvent == None:
return
lstMoveItems = []
count = 0
item = self.eventList.GetFirstSelected()
while item != -1:
lstMoveItems.append((getColumnText(self.eventList,item,0), mbtFct(getColumnText(self.eventList,item,2),-1), mbtFct(getColumnText(self.eventList,item,3),-1), segment.end))
count = count + 1
item = self.eventList.GetNextSelected(item)
if count == 0:
InfoMsg("Move", "Select one or more items to move.")
return
dlg = JetMove("Move Events")
dlg.lstMoveItems = lstMoveItems
result = dlg.ShowModal()
if result == wx.ID_OK:
if len(dlg.lstMoveMbt) > 0:
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
for moveitem in dlg.lstMoveMbt:
self.jet_file.MoveEvent(self.currentSegmentName, moveitem[0], moveitem[1], moveitem[2])
self.SelectSegment(self.currentSegmentName)
self.LoadEventsForSeg(self.currentSegmentName)
self.UndoAdd(saveState)
dlg.Destroy()
def OnJetOpen(self, event):
""" Calls a dialog box to get a jet config file to open """
dlg = JetOpen()
result = dlg.ShowModal()
if result == JetDefs.ID_JET_OPEN:
self.jet_file = JetFile(dlg.fileName , "")
if not ValidateConfig(self.jet_file):
FileKillClean(JetDefs.UNTITLED_FILE)
self.currentJetConfigFile = JetDefs.UNTITLED_FILE
self.jet_file = JetFile(self.currentJetConfigFile, "")
else:
self.SetCurrentFile(dlg.fileName)
elif result == JetDefs.ID_JET_NEW:
self.jet_file = JetFile("" , "")
self.SetCurrentFile(JetDefs.UNTITLED_FILE)
self.LoadDefaultProperties()
elif result == JetDefs.ID_JET_IMPORT:
self.OnJetImportArchive(event)
dlg.Destroy()
def OnJetSaveAs(self, event):
""" Calls a dialog box to allow saving the current jet file as another name """
defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.JTC_FILE_SPEC, 'str', str(os.getcwd()))
dialog = wx.FileDialog(None, JetDefs.SAVE_PROMPT, defDir, "", JetDefs.JTC_FILE_SPEC, wx.SAVE | wx.OVERWRITE_PROMPT )
if dialog.ShowModal() == wx.ID_OK:
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.JTC_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
self.currentJetConfigFile = FileJustRoot(dialog.GetPath()) + ".jtc"
self.jet_file.config.filename = FileJustRoot(self.currentJetConfigFile) + ".jet"
self.jet_file.SaveJetConfig(self.currentJetConfigFile)
self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
self.SetCurrentFile(self.currentJetConfigFile)
dialog.Destroy()
def OnJetSave(self, event):
""" Saves the current jet file to disk """
if self.currentJetConfigFile == JetDefs.UNTITLED_FILE:
self.OnJetSaveAs(event)
else:
self.jet_file.SaveJetConfig(self.currentJetConfigFile)
self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
def OnJetNew(self, event):
""" Initializes the state to a new jet file """
self.jet_file = JetFile("" , "")
self.SetCurrentFile(JetDefs.UNTITLED_FILE)
self.LoadDefaultProperties()
def SetCurrentFile(self, fileName):
""" Sets the state for the current jet file """
self.clipBoard = None
self.currentJetConfigFile = fileName
self.SetTitle(JetDefs.MAIN_TITLEPREFIX + FileJustName(fileName))
AppendRecentJetFile(fileName)
self.LoadSegList()
self.graph.ClearGraph()
self.chkGraphLabels.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, 'bool', 'True'))
self.chkGraphClips.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, 'bool', 'True'))
self.chkGraphAppEvts.SetValue(IniGetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, 'bool', 'True'))
def createMenuBar(self):
""" Creates a menu bar """
self.menuItems = {}
menuBar = wx.MenuBar()
for eachMenuData in JetDefs.MENU_SPEC:
menuLabel = eachMenuData[0]
menuItems = eachMenuData[1:]
menuBar.Append(self.createMenu(menuItems), menuLabel)
self.SetMenuBar(menuBar)
def createMenu(self, menuData):
""" Creates a menu from the structure menuData in JetDefs """
menu = wx.Menu()
for eachLabel, eachStatus, eachHandler, eachEnable in menuData:
if not eachLabel:
menu.AppendSeparator()
continue
self.menuItems[eachLabel] = menu.Append(-1, eachLabel, eachStatus)
self.menuItems[eachLabel].Enable(eachEnable)
try:
self.Bind(wx.EVT_MENU, getattr(self, eachHandler) , self.menuItems[eachLabel])
except:
print("def " + eachHandler + "(self, event): pass")
return menu
def createToolbar(self):
""" Creates the toolbar """
toolbar = self.CreateToolBar()
toolbar.SetToolBitmapSize((32,32))
self.toolItems = {}
for eachTool in JetDefs.TOOLBAR_SPEC:
if eachTool[0] == '-':
toolbar.AddSeparator()
else:
b = __import__(eachTool[1])
bitMap = b.getBitmap()
self.toolItems[eachTool[0]] = toolbar.AddLabelTool(-1, label=eachTool[0],
bitmap=bitMap,
shortHelp=eachTool[0], longHelp=eachTool[2])
self.Bind(wx.EVT_TOOL, getattr(self, eachTool[3]) , self.toolItems[eachTool[0]])
toolbar.Realize()
def OnAudition(self, event):
""" Calls the audition window for simple preview of jet file """
jet_file = CreateTempJetFile(self.jet_file)
w, h = self.GetSize()
w = w - 50
if w < 900:
w = 900
h = h - 50
if h < 650:
h = 650
dlg = Audition(jet_file, (w,h))
dlg.ShowModal()
CleanupTempJetFile(jet_file)
def SetKeepPlayingFlag(self, val):
""" Sets a flag to communicate playing state to the play thread """
with self.playerLock:
self.keepPlaying = val
def GetKeepPlayingFlag(self):
""" Gets the playing state flag """
with self.playerLock:
return self.keepPlaying
def GraphTriggerClip(self, sClipName, iEventId):
""" Triggers a clip when they click on the graph """
with self.playerLock:
try:
self.jet.TriggerClip(iEventId)
self.log.SetValue(JetDefs.PLAY_TRIGGERCLIP_MSG % (iEventId, sClipName))
return True
except:
return False
def OnHelpJet(self, event):
""" Loads the jet help file """
import webbrowser
webbrowser.open(JetDefs.MAIN_HELPFILE)
return
def OnHelpJetGuidelines(self, event):
""" Loads the authoring guidelines file """
import webbrowser
webbrowser.open(JetDefs.MAIN_HELPGUIDELINESFILE)
return
def OnAbout(self, event):
""" Loads the about dialog box """
dlg = JetAbout()
result = dlg.ShowModal()
dlg.Destroy()
def OnJetImportArchive(self, event):
""" Imports a jet archive file """
defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, 'str', str(os.getcwd()))
dialog = wx.FileDialog(None, JetDefs.IMPORT_ARCHIVE_PROMPT, defDir, "", JetDefs.ARCHIVE_FILE_SPEC, wx.OPEN)
if dialog.ShowModal() == wx.ID_OK:
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC + "Dir", 'str', str(os.getcwd()))
dlg1 = wx.DirDialog(self, JetDefs.IMPORT_ARCHIVEDIR_PROMPT, style=wx.DD_DEFAULT_STYLE, defaultPath=defDir)
if dlg1.ShowModal() == wx.ID_OK:
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC + "Dir", str(FileJustPath(dlg1.GetPath())))
if YesNo(JetDefs.MAIN_IMPORTTITLE, JetDefs.MAIN_IMPORTMSG % (dialog.GetPath(),dlg1.GetPath()), False):
projectPath = dlg1.GetPath()
zipFile = dialog.GetPath()
z = __import__('zipfile')
if not z.is_zipfile(zipFile):
wx.MessageBox(JetDefs.IMPORT_ARCHIVE_NO_JTC)
else:
zip = z.ZipFile(zipFile, 'r')
jtcFile = ""
fileList = zip.namelist()
isArchive = False
for myFile in fileList:
if myFile == 'JetArchive':
isArchive = True
break
if not isArchive:
wx.MessageBox(JetDefs.IMPORT_NOT_JET_ARCHIVE)
else:
for myFile in fileList:
if FileJustExt(myFile) == '.JTC':
jtcFile = myFile
break
if jtcFile == "":
wx.MessageBox(JetDefs.IMPORT_ARCHIVE_NO_JTC)
else:
for name in zip.namelist():
ext = FileJustExt(name)
if ext == '.MID' or ext == '.DLS' or ext == '.JET':
file(FileFixPath(projectPath + "/" + name), 'wb').write(zip.read(name))
else:
if len(ext) > 0 and ext != '.DS_STORE':
file(FileFixPath(projectPath + "/" + name), 'w').write(zip.read(name))
zip.close()
self.currentJetConfigFile = FileFixPath(projectPath + "/") + jtcFile
self.jet_file = JetFile(self.currentJetConfigFile, "")
#fix paths
self.jet_file.config.filename = FileJustRoot(self.currentJetConfigFile) + ".JET"
for index, segment in enumerate(self.jet_file.segments):
self.jet_file.segments[index].filename = FileFixPath(projectPath + "/" + segment.filename)
if segment.dlsfile > "":
self.jet_file.segments[index].dlsfile = FileFixPath(projectPath + "/" + segment.dlsfile)
self.jet_file.segments[index].output = FileFixPath(projectPath + "/" + segment.output)
for index, library in enumerate(self.jet_file.libraries):
self.jet_file.libraries[index] = FileFixPath(projectPath + "/" + library)
if ValidateConfig(self.jet_file):
self.jet_file.SaveJetConfig(self.currentJetConfigFile)
self.jet_file.WriteJetFileFromConfig(self.currentJetConfigFile)
self.jet_file = JetFile(self.currentJetConfigFile , "")
self.SetCurrentFile(self.currentJetConfigFile)
dlg1.Destroy()
dialog.Destroy()
def OnJetExportArchive(self, event):
""" Exports the current setup to an archive file """
self.OnJetSave(event)
defDir = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, 'str', str(os.getcwd()))
dialog = wx.FileDialog(None, JetDefs.EXPORT_ARCHIVE_PROMPT, defDir, "", JetDefs.ARCHIVE_FILE_SPEC, wx.SAVE | wx.OVERWRITE_PROMPT )
if dialog.ShowModal() == wx.ID_OK:
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_DEFAULTDIRS, JetDefs.ARCHIVE_FILE_SPEC, str(FileJustPath(dialog.GetPath())))
ExportJetArchive(FileJustRoot(dialog.GetPath()) + ".zip", self.currentJetConfigFile, self.jet_file)
dialog.Destroy()
def OnCopy(self, event):
""" Copies the current segment or event to the clipboard """
if self.currentCtrl == JetDefs.MAIN_SEGLIST:
if self.currentSegmentName is None:
return ""
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return ""
self.clipBoard = JetCutCopy(self.currentCtrl, segment, self.currentSegmentName)
return self.currentCtrl
elif self.currentCtrl == JetDefs.MAIN_EVENTLIST:
if self.currentSegmentName is None:
return ""
if self.currentEventName is None:
return ""
segment = self.jet_file.GetSegment(self.currentSegmentName)
if segment == None:
return ""
curEvent = self.jet_file.GetEvent(self.currentSegmentName, self.currentEventName)
if curEvent == None:
return ""
self.clipBoard = JetCutCopy(self.currentCtrl, curEvent, self.currentSegmentName)
return self.currentCtrl
def OnCut(self, event):
""" Cuts the current segment or event to the clipboard """
retCopy = self.OnCopy(event)
if retCopy == JetDefs.MAIN_SEGLIST:
self.SegmentDelete(self.currentSegmentName)
self.LoadSegList()
elif retCopy == JetDefs.MAIN_EVENTLIST:
self.EventDelete(self.currentEventName)
self.LoadEventsForSeg(self.currentSegmentName)
def OnPaste(self, event):
""" Pastes the current segment or event from the clipboard """
if self.clipBoard is not None:
if self.currentCtrl == JetDefs.MAIN_SEGLIST and self.clipBoard.objType == JetDefs.MAIN_SEGLIST:
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
self.jet_file.segments.append(self.clipBoard.GetObj(self.jet_file.segments))
self.UndoAdd(saveState)
self.LoadSegList()
elif self.currentCtrl == JetDefs.MAIN_EVENTLIST and self.clipBoard.objType == JetDefs.MAIN_EVENTLIST and self.clipBoard.currentSegmentName == self.currentSegmentName:
for segment in self.jet_file.segments:
if segment.segname == self.currentSegmentName:
saveState = JetState(self.jet_file, self.currentSegmentIndex, self.currentEventIndex)
segment.jetevents.append(self.clipBoard.GetObj(segment.jetevents))
self.UndoAdd(saveState)
self.LoadEventsForSeg(self.currentSegmentName)
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'))
def OnJetProperties(self, event):
""" Opens a dialog box for jetfile properties """
dlg = JetPropertiesDialog()
dlg.SetValue(JetDefs.F_JETFILENAME, self.jet_file.config.filename)
dlg.SetValue(JetDefs.F_COPYRIGHT, StrNoneChk(self.jet_file.config.copyright))
dlg.SetValue(JetDefs.F_CHASECONTROLLERS, StrNoneChk(self.jet_file.config.chase_controllers))
dlg.SetValue(JetDefs.F_DELETEEMPTYTRACKS, StrNoneChk(self.jet_file.config.delete_empty_tracks))
result = dlg.ShowModal()
if result == wx.ID_OK:
self.jet_file.config.filename = dlg.je.ctrls[JetDefs.F_JETFILENAME].GetValue()
self.jet_file.config.copyright = dlg.je.ctrls[JetDefs.F_COPYRIGHT].GetValue()
self.jet_file.config.chase_controllers = dlg.je.ctrls[JetDefs.F_CHASECONTROLLERS].GetValue()
self.jet_file.config.delete_empty_tracks = dlg.je.ctrls[JetDefs.F_DELETEEMPTYTRACKS].GetValue()
dlg.Destroy()
def OnPreferences(self, event):
""" Opens a dialog box to capture preferences and saves them to a configuration file """
dlg = JetPreferences()
dlg.SetValue(JetDefs.F_COPYRIGHT, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT))
dlg.SetValue(JetDefs.F_CHASECONTROLLERS, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, 'bool', True))
dlg.SetValue(JetDefs.F_DELETEEMPTYTRACKS, IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, 'bool', False))
result = dlg.ShowModal()
if result == wx.ID_OK:
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT, dlg.GetValue(JetDefs.F_COPYRIGHT))
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, dlg.GetValue(JetDefs.F_CHASECONTROLLERS))
IniSetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, dlg.GetValue(JetDefs.F_DELETEEMPTYTRACKS))
dlg.Destroy()
def LoadDefaultProperties(self):
""" Loads default properties from the a configuration file """
self.jet_file.config.copyright = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_COPYRIGHT)
self.jet_file.config.chase_controllers = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_CHASECONTROLLERS, 'bool', True)
self.jet_file.config.delete_empty_tracks = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_PREF_SECTION, JetDefs.F_DELETEEMPTYTRACKS, 'bool', False)
def OnClose(self, event):
""" Called upon closing the JetCreator main window """
if self.isDirty():
ret = YesNoCancel(JetDefs.MAIN_JETCREATOR, JetDefs.MAIN_SAVEBEFOREEXIT, True)
if ret == wx.ID_YES:
self.OnJetSave(None)
if ret == wx.ID_CANCEL:
return
if self.jet is not None:
SafeJetShutdown(self.playerLock, self.jet)
self.Destroy()
def OnPlay(self, event):
""" Plays the currently queued segments """
if self.btnPlay.GetLabel() == JetDefs.BUT_PLAY:
if not ValidateConfig(self.jet_file):
return
#make sure something is queued
iQueued = False
num = self.segList.GetItemCount()
for seg_num in range(num):
if self.segList.IsChecked(seg_num):
iQueued = True
if not iQueued:
InfoMsg(JetDefs.MAIN_PLAYSEG, JetDefs.MAIN_PLAYSEGMSG)
return
for segment in self.jet_file.segments:
if FileExists(segment.dlsfile):
if not segment.dlsfile in self.jet_file.libraries:
self.jet_file.libraries.append(segment.dlsfile)
self.eventList.DeleteAllItems()
num = self.segList.GetItemCount()
for seg_num in range(num):
if seg_num == 0: self.log.Clear()
if self.segList.IsChecked(seg_num):
segment = self.jet_file.GetSegment(getColumnText(self.segList, seg_num, 0))
if segment != None:
#so we can determine which segment is playing, make these the same
userID = seg_num
if FileExists(segment.dlsfile):
dls_num = FindDlsNum(self.jet_file.libraries, segment.dlsfile)
else:
dls_num = -1
self.queueSegs.append(QueueSeg(segment.segname, userID, seg_num, dls_num, segment.repeat, segment.transpose, segment.mute_flags))
if len(self.queueSegs) == 0:
return
self.btnPlay.SetLabel(JetDefs.BUT_STOP)
thread.start_new_thread(self.PlaySegs, ())
else:
with self.playerLock:
self.jet.Clear_Queue()
self.SetKeepPlayingFlag(False)
def PlaySegs(self):
""" Thread writes a temporary copy of the jet file, and calls the library to play it """
if len(self.queueSegs) == 0:
return
jet_file = CreateTempJetFile(self.jet_file)
if not ValidateConfig(jet_file):
CleanupTempJetFile(jet_file)
return
self.jet = JET()
self.jet.eas.StartWave()
self.jet.OpenFile(jet_file.config.filename)
lastID = -1
# queue first segment and start playback
Queue(self.jet, self.queueSegs[0])
index = 1
self.jet.Play()
self.paused = False
# continue playing until all segments are done
self.SetKeepPlayingFlag(True)
while self.GetKeepPlayingFlag():
self.jet.Render()
status = self.jet.Status()
if status.currentUserID <> lastID and status.currentUserID <> -1:
wx.PostEvent(self, JetStatusEvent(JetDefs.PST_PLAY, status.currentUserID))
lastID = status.currentUserID
# if no more segments - we're done
if status.numQueuedSegments == 0:
break
self.jet.GetAppEvent()
# if less than 2 segs queued - queue another one
if (index < len(self.queueSegs)) and (status.numQueuedSegments < 2):
Queue(self.jet, self.queueSegs[index])
index += 1
wx.PostEvent(self, JetStatusEvent(JetDefs.PST_UPD_LOCATION, status.location))
SafeJetShutdown(self.playerLock, self.jet)
self.queueSegs = []
CleanupTempJetFile(jet_file)
wx.PostEvent(self, JetStatusEvent(JetDefs.PST_DONE, None))
def OnJetStatusUpdate(self, evt):
""" These are screen updates called for from within the thread. Communication
is via a postevent call.
"""
if evt.mode == JetDefs.PST_PLAY:
segName = getColumnText(self.segList, evt.data, 0)
self.LoadEventsForSeg(segName)
self.log.SetValue(segName)
ClearRowSelections(self.segList)
SetRowSelection(self.segList, evt.data, True)
elif evt.mode == JetDefs.PST_UPD_LOCATION:
self.graph.UpdateLocation(evt.data)
elif evt.mode == 3:
self.graph.UpdateLocation(0)
ClearRowSelections(self.segList)
self.eventList.DeleteAllItems()
self.SetKeepPlayingFlag(False)
self.btnPlay.SetLabel(JetDefs.BUT_PLAY)
self.btnPause.SetLabel(JetDefs.BUT_PAUSE)
def OnPause(self, evt):
""" Pauses the playback """
if self.jet is None:
return
if not self.paused:
self.jet.Pause()
self.paused = True
self.btnPause.SetLabel(JetDefs.BUT_RESUME)
else:
self.jet.Play()
self.paused = False
self.btnPause.SetLabel(JetDefs.BUT_PAUSE)
def isDirty(self):
if len(self.UndoStack) == 0 and len(self.RedoStack) == 0:
return False
else:
return True
def OnSetGraphOptions(self, evt):
""" Sets graph options """
IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHLABELS, JetDefs.F_GRAPHLABELS, self.chkGraphLabels.GetValue())
IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHCLIPS, JetDefs.F_GRAPHCLIPS, self.chkGraphClips.GetValue())
IniSetValue(self.currentJetConfigFile, JetDefs.F_GRAPHAPPEVTS, JetDefs.F_GRAPHAPPEVTS, self.chkGraphAppEvts.GetValue())
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'))
def OnEventSortOrderChanged(self):
""" Called when sort order has changed """
IniSetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_0, self.eventList.GetSortState()[0])
IniSetValue(self.currentJetConfigFile, JetDefs.INI_EVENTSORT, JetDefs.INI_EVENTSORT_1, self.eventList.GetSortState()[1])
self.LoadEventsForSeg(self.currentSegmentName)
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'))
def EventSortCmp(self, a, b):
""" Sorts based on selected sort order """
if self.eventlistSort[0] == 0 or self.eventlistSort[0] == 1:
if self.eventlistSort[1] == 1:
return cmp(a[0].upper(), b[0].upper())
else:
return cmp(b[0].upper(), a[0].upper())
elif self.eventlistSort[0] == 2 or self.eventlistSort[0] == 3:
if self.eventlistSort[1] == 1:
return cmp(MbtVal(a[0]), MbtVal(b[0]))
else:
return cmp(MbtVal(b[0]), MbtVal(a[0]))
else:
return cmp(a[0], b[0])
def EventSort2(self, seq, attr):
""" Does Sorting """
intermed = map(None, map(getattr, seq, (attr,)*len(seq)), xrange(len(seq)), seq)
intermed.sort(self.EventSortCmp)
return map(operator.getitem, intermed, (-1,) * len(intermed))
def EventSort(self, lst, attr):
""" Does Sorting """
lst[:] = self.EventSort2(lst, attr)
def OnSegSortOrderChanged(self):
""" Called when sort order has changed """
IniSetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_0, self.segList.GetSortState()[0])
IniSetValue(self.currentJetConfigFile, JetDefs.INI_SEGSORT, JetDefs.INI_SEGSORT_1, self.segList.GetSortState()[1])
self.LoadEventsForSeg(self.currentSegmentName)
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'))
def SegSortCmp(self, a, b):
""" Sorts based on selected sort order """
if self.seglistSort[0] == 0:
if self.seglistSort[1] == 1:
return cmp(a[0].upper(), b[0].upper())
else:
return cmp(b[0].upper(), a[0].upper())
elif self.seglistSort[0] == 1 or self.seglistSort[0] == 2:
if self.seglistSort[1] == 1:
return cmp(FileJustName(a[0]).upper(), FileJustName(b[0]).upper())
else:
return cmp(FileJustName(b[0]).upper(), FileJustName(a[0]).upper())
elif self.seglistSort[0] == 3 or self.seglistSort[0] == 4:
if self.seglistSort[1] == 1:
return cmp(MbtVal(a[0]), MbtVal(b[0]))
else:
return cmp(MbtVal(b[0]), MbtVal(a[0]))
else:
return cmp(a[0], b[0])
def SegSort2(self, seq, attr):
""" Does Sorting """
intermed = map(None, map(getattr, seq, (attr,)*len(seq)), xrange(len(seq)), seq)
intermed.sort(self.SegSortCmp)
return map(operator.getitem, intermed, (-1,) * len(intermed))
def SegSort(self, lst, attr):
""" Does Sorting """
lst[:] = self.SegSort2(lst, attr)
if __name__ == '__main__':
""" Sets the logging level, then calls the open dialog box before initializing main window"""
logLevel = IniGetValue(JetDefs.JETCREATOR_INI, JetDefs.INI_LOGGING, JetDefs.INI_LOGGING)
if logLevel == 'DEBUG':
logging.basicConfig(level=logging.DEBUG, format='%(funcName)s[%(lineno)d]: %(message)s')
elif logLevel == 'INFO':
logging.basicConfig(level=logging.INFO, format='%(funcName)s[%(lineno)d]: %(message)s')
elif logLevel == 'ERROR':
logging.basicConfig(level=logging.ERROR, format='%(funcName)s[%(lineno)d]: %(message)s')
elif logLevel == 'WARNING':
logging.basicConfig(level=logging.WARNING, format='%(funcName)s[%(lineno)d]: %(message)s')
else:
install_release_loggers()
app = wx.App(None)
if not os.path.isdir(JetDefs.TEMP_JET_DIR):
os.mkdir(JetDefs.TEMP_JET_DIR)
openFile = ""
dlg = JetOpen()
result = dlg.ShowModal()
if result == wx.ID_CANCEL:
dlg.Destroy()
elif result == JetDefs.ID_JET_IMPORT:
dlg.Destroy()
au = JetCreator(None, -1, "", importFlag=True)
app.MainLoop()
else:
openFile = dlg.fileName
dlg.Destroy()
au = JetCreator(None, -1, openFile)
app.MainLoop()