2 Xinloe -- A Python-Based Non-Linear Ogg Editor
3 Copyright (C) 2004 Arc Riley <arc@Xiph.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 class SBTreeCtrl(wxTreeCtrl
):
25 def OnCompareItems(self
, item1
, item2
):
26 t1
= self
.GetItemText(item1
)
27 t2
= self
.GetItemText(item2
)
33 class SandboxPanel(wxPanel
):
34 def __init__(self
, parent
):
35 wxPanel
.__init
__(self
, parent
, -1, style
=wxWANTS_CHARS
)
38 EVT_SIZE(self
, self
.OnSize
)
40 self
.tree
= SBTreeCtrl(self
, self
.tid
, wxDefaultPosition
,
41 wxDefaultSize
, wxTR_HAS_BUTTONS
42 | wxTR_HIDE_ROOT | wxTR_TWIST_BUTTONS
)
44 EVT_RIGHT_DOWN(self
.tree
, self
.OnRightDown
)
45 EVT_TREE_SEL_CHANGED(self
, self
.tid
, self
.OnSelChanged
)
48 il
= wxImageList(isz
[0], isz
[1])
49 self
.lclidx
= il
.Add(geticon('dev-lcl',0))
50 self
.p2pidx
= il
.Add(geticon('dev-p2p',0))
51 self
.webidx
= il
.Add(geticon('dev-web',0))
52 self
.fldridx
= il
.Add(wxArtProvider_GetBitmap(wxART_FOLDER
, wxART_OTHER
, isz
))
53 self
.fldropenidx
= il
.Add(wxArtProvider_GetBitmap(wxART_FILE_OPEN
, wxART_OTHER
, isz
))
54 self
.fileidx
= il
.Add(wxArtProvider_GetBitmap(wxART_REPORT_VIEW
, wxART_OTHER
, isz
))
55 self
.muxpackidx
= il
.Add(geticon('mux-packed',0))
56 self
.muxopenidx
= il
.Add(geticon('mux-opened',0))
58 self
.codecidx
= { 'vorbis' : il
.Add(geticon('vorbis',0)),
59 'theora' : il
.Add(geticon('theora',0)),
60 'speex' : il
.Add(geticon('speex',0)),
61 'flac' : il
.Add(geticon('flac',0)),
62 'nonfree' : il
.Add(geticon('nonfree',0)),
63 '' : il
.Add(geticon('unknown',0))}
65 self
.tree
.SetImageList(il
)
68 self
.root
= self
.tree
.AddRoot("")
69 self
.tree
.SetPyData(self
.root
, None)
71 self
.devlocal
= self
.tree
.AppendItem(self
.root
, 'Local Media')
72 self
.tree
.SetPyData(self
.devlocal
, None)
73 self
.tree
.SetItemImage(self
.devlocal
, self
.lclidx
, which
= wxTreeItemIcon_Normal
)
75 self
.share
= self
.tree
.AppendItem(self
.root
, 'P2P Media')
76 self
.tree
.SetPyData(self
.share
, None)
77 self
.tree
.SetItemImage(self
.share
, self
.p2pidx
, which
= wxTreeItemIcon_Normal
)
79 self
.web
= self
.tree
.AppendItem(self
.root
, 'Web Media')
80 self
.tree
.SetPyData(self
.web
, None)
81 self
.tree
.SetItemImage(self
.web
, self
.webidx
, which
= wxTreeItemIcon_Normal
)
83 self
.tree
.Expand(self
.root
)
86 def OnSize(self
, evt
):
87 self
.tree
.SetSize(self
.GetSize())
89 def OnRightDown(self
, evt
):
90 pt
= evt
.GetPosition()
91 item
, flags
= self
.tree
.HitTest(pt
)
92 if item
== self
.devlocal
:
93 self
.PopupDevLocalMenu(pt
)
95 def PopupDevLocalMenu(self
, pos
) :
96 if not hasattr(self
, "devlocalPopupNew"):
97 self
.devlocalPopupNewFile
= wxNewId()
98 EVT_MENU(self
, self
.devlocalPopupNewFile
, self
.OnNewLocalFile
)
99 #self.devlocalPopupNewDir = wxNewId()
100 #EVT_MENU(self, self.devlocalPopupNewDir, self.OnNewLocalDir)
102 menu
.Append(self
.devlocalPopupNewFile
, "Add New File")
103 self
.PopupMenu(menu
, pos
)
106 def OnNewLocalFile(self
, evt
):
107 dlg
= wxFileDialog(self
, "Choose a file", os
.getcwd(), "",
108 "Ogg Media (.ogg)|*.ogg|All Files (*)|*",
110 # | wxMULTIPLE we're not ready for this yet
111 # | wxCHANGE_DIR this messes up our path!
113 if dlg
.ShowModal() == wxID_OK
:
114 paths
= dlg
.GetPaths()
116 newfile
= LocalFile(self
, path
)
119 def OnSelChanged(self
, evt
):
121 handler
= self
.tree
.GetItemData(item
).GetData()
123 self
.parent
.infoboxWin
.ShowCodec(handler
)
127 def __init__(self
, parent
, path
):
134 self
.name
= os
.path
.split(path
)[1]
135 self
.desc
= 'application/ogg'
136 self
.icon
= 'oggfile'
138 self
.sy
= ogg2
.OggSyncState()
139 self
.fd
= open(path
,'r')
140 if self
.fd
.read(4) != 'OggS' :
143 self
.branch
= parent
.tree
.AppendItem(parent
.devlocal
, self
.name
)
144 parent
.tree
.SetPyData(self
.branch
, self
)
145 parent
.tree
.SetItemImage(self
.branch
, parent
.fileidx
, which
= wxTreeItemIcon_Normal
)
149 self
.chains
.append(self
.Chain(self
))
150 self
.bytes
= self
.bytes
+ self
.chains
[-1].bytes
151 self
.length
= self
.length
+ self
.chains
[-1].length
154 def __init__(self
, parent
):
156 grandparent
= parent
.parent
157 self
.name
= 'Chain %d (%s offset)' % (len(parent
.chains
),
158 timestr(parent
.length
))
164 bitstreams
= self
.GetNewStreams()
165 for handler
in bitstreams
:
166 self
.serials
[handler
.serialno
] = handler
168 while parent
.page
and parent
.page
.pageno
> 0:
169 self
.serials
[parent
.page
.serialno
].PageIn(parent
.page
)
171 while not parent
.page
:
172 if self
.parent
.sy
.input(parent
.fd
) == 0 :
174 break # End of file reached.
175 parent
.page
= parent
.sy
.pageout()
177 if parent
.length
> 0:
178 extra
= ' (%s offset)' % timestr(parent
.length
)
181 if len(bitstreams
) == 1 :
182 chain
= parent
.branch
184 chain
= grandparent
.tree
.AppendItem(parent
.branch
, 'Muxed Stream'+extra
)
185 grandparent
.tree
.SetPyData(chain
, self
)
186 grandparent
.tree
.SetItemImage(chain
, grandparent
.muxpackidx
,
187 which
= wxTreeItemIcon_Normal
)
188 grandparent
.tree
.SetItemImage(chain
, grandparent
.muxopenidx
,
189 which
= wxTreeItemIcon_Expanded
)
191 for handler
in bitstreams
:
192 stream
= grandparent
.tree
.AppendItem(chain
, handler
.name
+extra
)
193 grandparent
.tree
.SetPyData(stream
, handler
)
194 if not grandparent
.codecidx
.has_key(handler
.icon
) :
195 print 'Missing icon for %s' % handler
.name
197 grandparent
.tree
.SetItemImage(stream
,
198 grandparent
.codecidx
[handler
.icon
], which
= wxTreeItemIcon_Normal
)
203 for handler
in bitstreams
:
204 self
.bytes
= self
.bytes
+ handler
.bytes
205 if handler
.length
> self
.length
:
206 self
.length
= handler
.length
209 def GetNewStreams(self
):
215 while not parent
.page
:
216 if parent
.sy
.input(parent
.fd
) == 0 :
219 return bitstreams
# End of file reached.
220 parent
.page
= parent
.sy
.pageout()
221 if parent
.page
.pageno
> 0 :
224 serialno
= parent
.page
.serialno
225 pagesize
= len(parent
.page
)
226 st
= ogg2
.OggStreamState(serialno
)
227 st
.pagein(parent
.page
)
228 packet
= st
.packetout()
229 bp
= ogg2
.OggPackBuff(packet
)
233 if type(byte
) == int : header
= header
+ chr(byte
)
235 for c
in handlers
.codecs
:
237 if handler
.name
: break
238 bitstreams
.append(handler
)
240 handler
.serialno
= serialno
241 handler
.bytes
= pagesize