5
# Copyright 2004-2005, under the GPL
10
from twisted.internet import gtk2reactor
12
from twisted.internet import reactor, protocol
13
import twisted.internet.error
19
#standard python2.2 libraries
27
import xml.dom.minidom
31
def get_header_size(filename):
33
file = open(filename, 'r')
39
return size + 4 #include the size chunk after "data"
44
def append_empty_data(self, filename, size):
45
file = open(filename, 'a')
50
def get_sound_list(snapshot):
51
doc = xml.dom.minidom.parse(snapshot)
54
playlists_tag = doc.getElementsByTagName('Playlists')
55
playlists = playlists_tag[0].getElementsByTagName('Playlist')
56
for play in playlists:
57
regions = play.getElementsByTagName('Region')
58
for region in regions:
59
regionlist.append(region.getAttribute('source-0'))
60
regionlist.append(region.getAttribute('source-1'))
61
regionlist.append(region.getAttribute('source-2'))
62
regionlist.append(region.getAttribute('source-3'))
63
regionlist.append(region.getAttribute('source-4'))
64
regionlist.append(region.getAttribute('source-5'))
67
sources = doc.getElementsByTagName('Source')
68
for source in sources:
69
sourcelist[source.getAttribute('id')] = str(source.getAttribute('name'))
73
if sourcelist.has_key(id):
74
soundlist.append(sourcelist[id])
78
def raise_error(string, parent):
79
dialog = gtk.MessageDialog(parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
80
gtk.MESSAGE_WARNING, gtk.BUTTONS_OK, string)
86
def delete_snap(self, session, collab, snap):
87
sessions = self._data['sessions']
88
sessions[session]['collabs'][collab]['snaps'].remove(snap)
89
self._data['sessions'] = sessions
91
def delete_collab(self,session, collab):
92
sessions = self._data['sessions']
93
del sessions[session]['collabs'][collab]
94
self._data['sessions'] = sessions
96
def delete_session(self, session):
97
sessions = self._data['sessions']
99
self._data['sessions'] = sessions
101
def add_snap(self, session_name, collab_name, snap_name):
102
sessions = self._data['sessions']
103
sessions[session_name]['collabs'][collab_name]['snaps'].append(snap_name)
104
sessions[session_name]['collabs'][collab_name]['snaps'].sort()
105
self._data['sessions'] = sessions
107
g_display.update_snap_view()
109
def add_collab(self, session_name, collab_name, ip_address, port):
110
sessions = self._data['sessions']
111
sessions[session_name]['collabs'][collab_name] = {}
112
sessions[session_name]['collabs'][collab_name]['snaps'] = []
113
sessions[session_name]['collabs'][collab_name]['sounds'] = []
114
sessions[session_name]['collabs'][collab_name]['ip'] = ip_address
115
sessions[session_name]['collabs'][collab_name]['port'] = port
116
sessions[session_name]['collabs'][collab_name]['v2paths'] = True
117
self._data['sessions'] = sessions
119
client = ExchangeClientFactory(session_name, collab_name, None, self.debug_mode)
120
reactor.connectTCP(ip_address, port, client)
121
g_display.show_status("connecting")
123
g_display.update_collab_view()
125
def add_session(self, session_path):
126
sessions = self._data['sessions']
128
session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: -1]
129
sessions[session_name] = {}
130
sessions[session_name]['path'] = session_path
131
sessions[session_name]['collabs'] = {}
132
sessions[session_name]['collabs'][self._data['user']] = {}
133
sessions[session_name]['collabs'][self._data['user']]['snaps'] = []
134
sessions[session_name]['collabs'][self._data['user']]['sounds'] = []
135
if os.path.isdir (os.path.join (session_path,'sounds')):
136
sessions[session_name]['collabs'][self._data['user']]['v2paths'] = False
139
sessions[session_name]['collabs'][self._data['user']]['v2paths'] = True
141
self._data['sessions'] = sessions
143
self.rescan_session(session_name)
145
def rescan_session(self, session_name):
146
sessions = self._data['sessions']
148
session_path = sessions[session_name]['path']
149
sessions[session_name]['collabs'][self._data['user']]['snaps'] = self._scan_snapshots(session_path)
150
sessions[session_name]['collabs'][self._data['user']]['sounds'] = self._scan_sounds(session_name)
152
self._data['sessions'] = sessions
154
g_display.update_snap_view()
156
print self._data['sessions']
158
def create_session(self, session_path):
159
sessions = self._data['sessions']
161
session_name = session_path[session_path.rfind('/', 0, len(session_path)-2)+1: ]
163
os.mkdir(session_path)
164
os.mkdir(os.path.join (session_path,'interchange'))
165
os.mkdir(os.path.join (session_path,'interchange',session_name))
166
os.mkdir(os.path.join (session_path,'interchange',session_name,'audiofiles'))
168
raise_error("Could not create session directory", g_display.window)
171
sessions[session_name] = {}
172
sessions[session_name]['path'] = session_path
173
sessions[session_name]['collabs'] = {}
174
sessions[session_name]['collabs'][self._data['user']] = {}
175
sessions[session_name]['collabs'][self._data['user']]['snaps'] = []
176
sessions[session_name]['collabs'][self._data['user']]['sounds'] = []
178
self._data['sessions'] = sessions
179
print self._data['sessions']
181
def get_session_path(self, session):
182
sessions = self._data['sessions']
183
return sessions[session]['path']
186
return self._data['user']
188
def set_user(self, username):
189
self._data['user'] = username
191
def get_collab_ip(self, session, collab):
192
sessions = self._data['sessions']
193
return sessions[session]['collabs'][collab]['ip']
198
def get_sessions(self):
199
sessions = self._data['sessions']
200
sess = sessions.keys()
204
def get_collabs(self, session):
206
sessions = self._data['sessions']
207
collabs = sessions[session]['collabs'].keys()
213
def get_snaps(self, session, collab):
214
if session and collab:
215
sessions = self._data['sessions']
216
snaps = sessions[session]['collabs'][collab]['snaps']
222
def get_sounds(self, session, collab):
223
if session and collab:
224
sessions = self._data['sessions']
225
sounds = sessions[session]['collabs'][self._data['user']]['sounds']
231
def _scan_snapshots(self, session):
233
files = os.listdir(session)
234
pattern = re.compile(r'\.ardour$')
236
if pattern.search(file):
237
snaps.append(file[0:-7])
241
def _scan_sounds(self, session):
242
sessions = self._data['sessions']
247
print os.path.join (sessions[session]['path'],'interchange', session, 'audiofiles')
248
files = os.listdir(os.path.join (sessions[session]['path'],'interchange', session, 'audiofiles'))
250
files = os.listdir(os.path.join (session,'sounds'))
251
pattern = re.compile(r'\.peak$')
253
if not pattern.search(file):
257
def __init__(self, *args):
258
self._data = shelve.open(os.path.expanduser('~/.session_exchange'), 'c')
260
self.debug_mode = False
261
if len(self._data.keys()) < 1:
262
self._data['sessions'] = {}
263
self._data['user'] = ''
267
from twisted.protocols.basic import FileSender
268
class FileSenderLimited(FileSender):
269
def beginFileTransfer(self, file, consumer, limit, transform = None):
271
self.consumer = consumer
272
self.CHUNK_SIZE = limit
273
self.transform = transform
275
self.consumer.registerProducer(self, False)
276
self.deferred = defer.Deferred()
279
def resumeProducing(self):
281
chunk = self.file.read(self.CHUNK_SIZE)
284
chunk = self.transform(chunk)
286
self.consumer.write(chunk)
287
self.lastSent = chunk[-1]
289
self.consumer.unregisterProducer()
290
self.deferred.callback(self.lastSent)
293
from twisted.protocols.basic import LineReceiver
294
class ExchangeServer (LineReceiver):
298
def error(self, message):
299
self.sendLine("ERROR")
300
self.sendLine(message)
301
self.transport.loseConnection()
303
def connectionLost(self, reason):
304
print "server: connection lost: ", reason
306
def connectionMade(self):
307
print "server: connection made"
309
def lineReceived(self, data):
310
print "server: ", data
312
if self.state == "SESSION":
313
if g_data.get_sessions().count(data):
314
self.session_name = data
318
self.error(data + " doesn't exist on server")
319
elif self.state == "SNAPSHOT":
320
if g_data.get_snaps(self.session_name, g_data.get_user()).count(data):
321
filename = g_data.get_session_path(self.session_name)+data+'.ardour'
323
self.sendLine(str(os.stat(filename).st_size))
325
self.file = open(filename, 'r')
326
file_sender = FileSender()
327
cb = file_sender.beginFileTransfer(self.file, self.transport)
328
cb.addCallback(self.file_done)
330
self.error("snapshot: " + data + " doesn't exist on server")
331
elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
332
if g_data.get_sounds(self.session_name, g_data.get_user()).count(data):
333
filename = g_data.get_session_path(self.session_name)+"/interchange/"+self.session_name+"/audiofiles/"+data
335
if self.state == "SOUNDFILE":
336
self.sendLine(str(os.stat(filename).st_size))
337
else: #SOUNDFILE_HEADER
338
header_size = get_header_size(filename)
340
self.sendLine(str(header_size))
342
self.error('soundfile: ' + data + 'doesn\'t have "data" chunk')
344
self.file = open(filename, 'r')
345
if self.state == "SOUNDFILE":
346
file_sender = FileSender()
347
cb = file_sender.beginFileTransfer(self.file, self.transport)
348
else: # SOUNDFILE_HEADER
349
file_sender = FileSenderLimited()
350
cb = file_sender.beginFileTransfer(self.file, self.transport, header_size)
351
cb.addCallback(self.file_done)
353
self.error("soundfile: " + data + "doesn't exist on server")
354
elif self.state == "SOUNDFILE_SIZE":
355
if g_data.get_sounds(self.session_name, g_data.get_user()).count(data):
356
filename = g_data.get_session_path(self.session_name)+"/sounds/"+data
358
self.sendLine(str(os.stat(filename).st_size))
360
elif data == "SESSION":
361
self.state = "SESSION"
362
elif data == "SNAPS":
364
for snap in g_data.get_snaps(self.session_name, g_data.get_user()):
368
elif data == "SNAPSHOT":
369
self.state = "SNAPSHOT"
370
elif data == "SOUNDFILE":
371
self.state = "SOUNDFILE"
372
elif data == "SOUNDFILE_HEADER":
373
self.state = "SOUNDFILE_HEADER"
374
elif data == "SOUNDFILE_SIZE":
375
self.state = "SOUNDFILE_SIZE"
377
def file_done(self, data):
378
print "server: file done"
382
class ExchangeServerFactory(protocol.ServerFactory):
383
protocol = ExchangeServer
388
class ExchangeClient (LineReceiver):
389
def __init__(self, session_name, collab_name, snap_name, debug_mode):
390
self.session_name = session_name
391
self.collab_name = collab_name
392
self.snap_name = snap_name
393
self.debug_mode = debug_mode
396
def connectionLost(self, reason):
397
g_display.show_status("Connection lost")
399
def connectionMade(self):
400
g_display.show_status("Connection made")
401
self.state = "SESSION"
402
self.sendLine("SESSION")
403
self.sendLine(self.session_name)
405
def rawDataReceived(self, data):
406
self.file.write(data)
407
self.received += len(data)
408
print self.received, self.filesize
409
if self.received >= self.filesize:
412
g_data.rescan_session(self.session_name)
413
if self.state == "SNAPSHOT":
414
self.sounds = get_sound_list(self.filename)
418
self.state = "SOUNDFILE_HEADER"
419
self.sendLine("SOUNDFILE_HEADER")
421
self.state = "SOUNDFILE"
422
self.sendLine("SOUNDFILE")
423
self.sendLine(self.sounds[self.sound_index])
425
self.transport.loseConnection()
426
elif self.state == "SOUNDFILE":
427
self.sound_index += 1
428
if self.sound_index > len(self.sounds)-1:
429
self.transport.loseConnection()
431
self.sendLine("SOUNDFILE")
432
self.sendLine(self.sounds[self.sound_index])
433
elif self.state == "SOUNDFILE_HEADER":
434
self.state = "SOUNDFILE_SIZE"
435
self.sendLine("SOUNDFILE_SIZE")
436
self.sendLine(self.sounds[self.sound_index])
438
def lineReceived(self, data):
439
print "client: ", data
444
if self.state == "SESSION":
446
self.state = "SNAPSHOT"
447
self.sendLine("SNAPSHOT")
448
self.sendLine(self.snap_name)
451
self.sendLine("SNAPS")
452
elif self.state == "SNAPS":
453
self.transport.loseConnection()
454
elif self.state == "SNAPSHOT":
456
self.filename = g_data.get_session_path(self.session_name)+'/'+self.snap_name+'.ardour'
457
self.file = open(self.filename, 'w')
459
elif self.state == "SOUNDFILE" or self.state == "SOUNDFILE_HEADER":
461
self.filename = g_data.get_session_path(self.session_name)+"/interchange/"+self.session_name+"/audiofiles/"+self.sounds[self.sound_index]
462
self.file = open(self.filename, 'w')
464
elif self.state == "ERROR":
465
raise_error(data, g_display.window)
466
elif self.state == "SNAPS":
467
g_data.add_snap(self.session_name, self.collab_name, data)
468
elif self.state == "SNAPSHOT":
469
self.filesize = int(data)
470
elif self.state == "SOUNDFILE":
471
self.filesize = int(data)
472
elif self.state == "SOUNDFILE_HEADER":
473
self.filesize = int(data)
474
elif self.state == "SOUNDFILE_SIZE":
475
append_empty_data(self.filename, int(data))
476
self.sound_index += 1
477
if self.sound_index > len(self.sounds)-1:
478
self.transport.loseConnection()
480
self.state = "SOUNDFILE_HEADER"
481
self.sendLine("SOUNDFILE_HEADER")
482
self.sendLine(self.sounds[self.sound_index])
484
class ExchangeClientFactory(protocol.ClientFactory):
485
def buildProtocol(self, addr):
486
return ExchangeClient(self.session_name, self.collab_name, self.snap_name, self.debug_mode)
488
def clientConnectionFailed(self, connector, reason):
489
raise_error('Connection failed: ' + reason.getErrorMessage(), g_display.window)
490
g_display.show_status('Connection failed')
492
def __init__(self, session_name, collab_name, snap_name, debug_mode):
493
self.session_name = session_name
494
self.collab_name = collab_name
495
self.snap_name = snap_name
496
self.debug_mode = debug_mode
498
class HelperWin(object):
499
def delete_me(self, window):
502
class Preferences(HelperWin):
504
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
505
self.window.set_title('Preferences')
506
self.window.connect('destroy', self.delete_me)
507
self.window.set_position(gtk.WIN_POS_MOUSE)
509
main_box = gtk.VBox()
510
self.window.add(main_box)
513
label1 = gtk.Label("User")
514
self.user = gtk.Entry()
515
self.user.set_text(g_data.get_user())
516
hbox1.pack_start(label1)
517
hbox1.pack_start(self.user)
518
main_box.pack_start(hbox1)
520
ok_btn = gtk.Button("Ok")
521
ok_btn.connect('clicked', self.ok_clicked)
522
main_box.pack_start(ok_btn)
524
self.window.show_all()
526
def ok_clicked(self, btn):
527
g_data.set_user(self.user.get_text())
528
self.window.hide_all()
531
self.window.show_all()
533
class AddCollaborator(HelperWin):
534
def __init__(self, session):
535
self.session_name = session
537
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
538
self.window.set_title('Fetch Session')
539
self.window.connect('destroy', self.delete_me)
540
self.window.set_position(gtk.WIN_POS_MOUSE)
542
main_box = gtk.VBox()
543
self.window.add(main_box)
546
label0 = gtk.Label("Collaborator")
547
self.collab = gtk.Entry()
548
self.collab.connect('key-release-event', self.key_press)
549
hbox0.pack_start(label0)
550
hbox0.pack_start(self.collab)
551
main_box.pack_start(hbox0)
554
label1 = gtk.Label("IP Address")
555
self.address = gtk.Entry()
556
self.address.connect('key-release-event', self.key_press)
557
hbox1.pack_start(label1)
558
hbox1.pack_start(self.address)
559
main_box.pack_start(hbox1)
562
label2 = gtk.Label("Port Number")
563
self.port = gtk.Entry()
564
self.port.connect('key-release-event', self.key_press)
565
self.port.set_text(str(g_data.port))
566
hbox2.pack_start(label2)
567
hbox2.pack_start(self.port)
568
main_box.pack_start(hbox2)
571
label3 = gtk.Label("Username")
572
label3.set_sensitive(False)
573
self.username = gtk.Entry()
574
self.username.set_sensitive(False)
575
hbox3.pack_start(label3)
576
hbox3.pack_start(self.username)
577
main_box.pack_start(hbox3)
580
label4 = gtk.Label("Password")
581
label4.set_sensitive(False)
582
self.password = gtk.Entry()
583
self.password.set_sensitive(False)
584
hbox4.pack_start(label4)
585
hbox4.pack_start(self.password)
586
main_box.pack_start(hbox4)
588
self.ok_btn = gtk.Button(gtk.STOCK_OK)
589
self.ok_btn.set_use_stock(True)
590
self.ok_btn.connect('clicked', self.ok_clicked)
591
self.ok_btn.set_sensitive(False)
592
main_box.pack_start(self.ok_btn)
594
self.window.show_all()
596
def key_press(self, event, data):
597
if self.collab.get_text() and self.address.get_text() and self.port.get_text():
598
self.ok_btn.set_sensitive(True)
600
self.ok_btn.set_sensitive(False)
603
def ok_clicked(self, btn):
604
self.window.hide_all()
605
g_data.add_collab(self.session_name, self.collab.get_text(), self.address.get_text(), int(self.port.get_text()))
606
self.collab.set_text('')
607
self.address.set_text('')
608
self.port.set_text('')
609
self.username.set_text('')
610
self.password.set_text('')
613
self.window.show_all()
615
class ArdourShareWindow(object):
616
def menuitem_cb(self, window, action, widget):
617
print self, window, action, widget
619
def add_collaborator_cb(self, window, action, widget):
621
self.add_session = AddCollaborator(self.session)
623
def fetch_snapshot_cb(self, window, action, widget):
624
if self.session and self.collab and self.collab != g_data.get_user():
625
client = ExchangeClientFactory(self.session, self.collab, self.snap, g_data.debug_mode)
626
reactor.connectTCP(g_data.get_collab_ip(self.session, self.collab), g_data.port, client)
628
def preferences_cb(self, window, action, widget):
629
self.preferences = Preferences()
631
def add_session_ok_file_btn_clicked(self, w):
632
filename = self.file_sel.get_filename()
633
if filename.endswith(".ardour"):
634
g_data.add_session(filename[0:filename.rfind("/")+1])
635
self.update_session_view()
637
raise_error("Not an Ardour session", self.window)
638
self.file_sel.destroy()
640
def add_session_cb(self, window, action, widget):
641
if g_data.get_user():
642
self.file_sel = gtk.FileSelection("Add Session...")
643
self.file_sel.ok_button.connect("clicked", self.add_session_ok_file_btn_clicked)
644
self.file_sel.cancel_button.connect("clicked", lambda w: self.file_sel.destroy())
645
self.file_sel.connect("destroy", lambda w: self.file_sel.destroy())
648
raise_error("Set the user name in the preferences first", self.window)
650
def create_session_cb(self, window, action, widget):
651
if g_data.get_user():
652
self.file_sel = gtk.FileSelection("Create Session...")
653
self.file_sel.ok_button.connect("clicked", self.create_file_ok_btn_clicked)
654
self.file_sel.cancel_button.connect("clicked", lambda w: self.file_sel.destroy())
655
self.file_sel.connect("destroy", lambda w: self.file_sel.destroy())
658
raise_error("Set the user name in the preferences first", self.window)
660
def create_file_ok_btn_clicked(self, w):
661
filename = self.file_sel.get_filename()
662
if len(filename) > 0:
663
g_data.create_session(filename)
664
self.update_session_view()
666
raise_error("Not an Ardour session", self.window)
667
self.file_sel.destroy()
669
def update_session_view(self):
670
self.session_model.clear()
671
for session in g_data.get_sessions():
672
self.session_model.set(self.session_model.append(), 0, session)
674
def update_collab_view(self):
675
self.collab_model.clear()
676
for collab in g_data.get_collabs(self.session):
677
self.collab_model.set(self.collab_model.append(), 0, collab)
679
def update_snap_view(self):
680
self.snap_model.clear()
681
for snap in g_data.get_snaps(self.session, self.collab):
682
self.snap_model.set(self.snap_model.append(), 0, snap)
684
def cb_session_selection_changed(self, selection_object):
686
selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
688
self.session = self.session_model[x][0]
689
self.selected_type = "session"
690
self.update_collab_view()
692
def cb_collab_selection_changed(self, selection_object):
694
selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
696
self.collab = self.collab_model[x][0]
697
self.selected_type = "collab"
698
self.update_snap_view()
700
def cb_snap_selection_changed(self, selection_object):
702
selection_object.selected_foreach(lambda model, path, iter, sel = selected: sel.append(path))
704
self.snap = self.snap_model[x][0]
705
self.selected_type = "snap"
707
def delete_cb(self, window, action, widget):
708
if self.selected_type == "session":
709
g_data.delete_session(self.session)
713
elif self.selected_type == "collab":
714
g_data.delete_collab(self.session, self.collab)
717
elif self.selected_type == "snap":
718
g_data.delete_snap(self.session, self.collab, self.snap)
721
self.update_session_view()
722
self.update_collab_view()
723
self.update_snap_view()
724
self.selected_type = ""
726
def show_status(self, text):
727
mid = self.status_bar.push(self._status_cid, text)
729
self.status_bar.remove(self._status_cid, self._status_mid)
730
self._status_mid = mid
733
self.selected_type = ""
735
self.collab = g_data.get_user()
742
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
743
self.window.set_title('Session Exchange')
744
self.window.set_size_request(400, 200)
745
self.window.connect('destroy', lambda win: gtk.main_quit())
746
self.window.set_position(gtk.WIN_POS_MOUSE)
748
accel_group = gtk.AccelGroup()
749
self.window.add_accel_group(accel_group)
751
main_box = gtk.VBox()
752
self.window.add(main_box)
755
('/_File', None, None, 0, '<Branch>'),
756
('/File/_Add Session...','<control>A', self.add_session_cb, 0, ''),
757
('/File/Create _Session...', '<control>S', self.create_session_cb, 0, ''),
758
('/File/sep1', None, None, 0, '<Separator>'),
759
('/File/_Quit', '<control>Q', gtk.main_quit, 0, '<StockItem>', gtk.STOCK_QUIT),
760
('/_Edit', None, None, 0, '<Branch>' ),
761
('/Edit/Cu_t', '<control>X', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_CUT),
762
('/Edit/_Copy', '<control>C', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_COPY),
763
('/Edit/_Paste', '<control>V', self.menuitem_cb, 0, '<StockItem>', gtk.STOCK_PASTE),
764
('/Edit/_Delete', None, self.delete_cb, 0, '<StockItem>', gtk.STOCK_DELETE),
765
('/Edit/sep1', None, None, 0, '<Separator>'),
766
('/Edit/Add Colla_borator...','<control>B', self.add_collaborator_cb,0,''),
767
('/Edit/_Fetch Snapshot','<control>F', self.fetch_snapshot_cb,0,''),
768
('/Edit/sep1', None, None, 0, '<Separator>'),
769
('/Edit/_Preferences...','<control>P', self.preferences_cb, 0, '')
772
#need to hold a reference to the item_factory or the menubar will disappear.
773
self.item_factory = gtk.ItemFactory(gtk.MenuBar, '<main>', accel_group)
774
self.item_factory.create_items(menu_items, self.window)
775
main_box.pack_start(self.item_factory.get_widget('<main>'), False)
779
pane1.pack2(pane2, True, False)
781
scroll1 = gtk.ScrolledWindow()
782
scroll1.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
783
pane1.pack1(scroll1, True, False)
784
scroll2 = gtk.ScrolledWindow()
785
scroll2.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
786
pane2.pack1(scroll2, True, False)
787
scroll3 = gtk.ScrolledWindow()
788
scroll3.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
789
pane2.pack2(scroll3, True, False)
791
self.session_model = gtk.ListStore(gobject.TYPE_STRING)
792
view1 = gtk.TreeView(self.session_model)
793
column1 = gtk.TreeViewColumn('Sessions', gtk.CellRendererText(), text=0)
794
view1.append_column(column1)
795
self.session_selection = view1.get_selection()
796
self.session_selection.connect("changed", self.cb_session_selection_changed)
799
self.update_session_view()
801
self.collab_model = gtk.ListStore(gobject.TYPE_STRING)
802
view2 = gtk.TreeView(self.collab_model)
803
column2 = gtk.TreeViewColumn('Collaborators', gtk.CellRendererText(), text=0)
804
view2.append_column(column2)
805
self.collab_selection = view2.get_selection()
806
self.collab_selection.connect("changed", self.cb_collab_selection_changed)
809
self.snap_model = gtk.ListStore(gobject.TYPE_STRING)
810
view3 = gtk.TreeView(self.snap_model)
811
column3 = gtk.TreeViewColumn('Snapshots', gtk.CellRendererText(), text=0)
812
view3.append_column(column3)
813
self.snap_selection = view3.get_selection()
814
self.snap_selection.connect("changed", self.cb_snap_selection_changed)
817
main_box.pack_start(pane1, True, True)
819
self.status_bar = gtk.Statusbar()
820
main_box.pack_start(self.status_bar, False)
821
self._status_cid = self.status_bar.get_context_id('display')
822
self._status_mid = ''
824
self.window.show_all()
829
-n, --no-server Only act as a client
830
-p, --port <port number> Defaults to 8970
831
-d, --debug Infers audio files. For debugging Ardour.
832
-v, --version Version
838
opts, args = getopt.getopt(sys.argv[1:], "hp:ndv", ["help", "port=", "no-server", "debug", "version"])
839
except getopt.GetoptError:
844
if o in ("-h", "--help"):
846
if o in ("-d", "--debug"):
847
g_display.window.set_title('Session Exchange: Debug Mode')
848
g_data.debug_mode = True
849
if o in ("-p", "--port"):
851
if o in ("-n", "--no-server"):
853
if o in ("-v", "--version"):
859
reactor.listenTCP(g_data.port, ExchangeServerFactory())
860
except twisted.internet.error.CannotListenError:
861
print "Can not listen on a port number under 1024 unless run as root"
870
g_display = ArdourShareWindow()
872
if __name__ == '__main__':