Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/ scipy/PortAudio) kommen nativ aus Debian stretch. Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per .gitignore ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
491 lines
22 KiB
Python
491 lines
22 KiB
Python
# uncompyle6 version 3.9.3
|
|
# Python bytecode version base 2.6 (62161)
|
|
# Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49)
|
|
# [GCC 14.2.0]
|
|
# Embedded file name: configure_group.pyc
|
|
# Compiled at: 2023-01-20 14:42:29
|
|
import wx, os, data_model, traceback, one_unit, ConfigParser, wx.lib.buttons, protocol, sys, select_keys, select_units, d_protocol, mytime, dialog
|
|
mac_names = 'posix'
|
|
|
|
class Dialog(wx.Dialog):
|
|
|
|
def __init__(self, parent, id, title, infotext='', group='', bg=None, size=(460, 315), bgcolour=(220, 220, 220), fgcolour=(70, 70, 70)):
|
|
wx.Dialog.__init__(self, None, wx.ID_ANY, title, size=size, style=wx.STAY_ON_TOP | wx.DEFAULT_DIALOG_STYLE)
|
|
self.parent = parent
|
|
if bg != None:
|
|
self.bg = bg
|
|
self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
|
|
self.frame_height = 2 * wx.SystemSettings.GetMetric(wx.SYS_CAPTION_Y) + wx.SystemSettings.GetMetric(wx.SYS_BORDER_Y)
|
|
if os.name in mac_names:
|
|
self.frame_height = 24
|
|
self.infotext = None
|
|
self.group = group
|
|
if infotext != '':
|
|
textstring = wx.StaticText(self, -1, infotext, style=wx.ALIGN_LEFT, pos=(25,
|
|
10))
|
|
self.infotext = textstring
|
|
self.infostring = infotext
|
|
textstring.Wrap(350)
|
|
try:
|
|
self.support_virtual_units = eval(one_unit.app.main_config.get('ROOT', 'support_virtual_units'))
|
|
except:
|
|
self.support_virtual_units = True
|
|
|
|
self.group_types = one_unit.app.group_types.keys()
|
|
one_unit.app.groupconfig = ConfigParser.ConfigParser()
|
|
if os.path.exists(os.path.join(one_unit.app.asys_config_path, 'grouping.cfg')):
|
|
one_unit.app.groupconfig.read(os.path.join(one_unit.app.asys_config_path, 'grouping.cfg'))
|
|
self.enabled = one_unit.app.groupconfig.get(group, 'enabled')
|
|
if self.enabled == 'yes':
|
|
self.enabled = True
|
|
else:
|
|
self.enabled = False
|
|
try:
|
|
self.members = eval(one_unit.app.groupconfig.get(group, 'members'))
|
|
except:
|
|
self.members = {}
|
|
|
|
for MAC in self.members:
|
|
member = self.members[MAC]
|
|
if MAC in self.parent.parent.parent.parent.peers.units.keys():
|
|
if member[0] != self.parent.parent.parent.parent.peers.units[MAC].name:
|
|
member = (
|
|
self.parent.parent.parent.parent.peers.units[MAC].name, member[1], member[2])
|
|
self.members[MAC] = member
|
|
|
|
try:
|
|
links = eval(one_unit.app.groupconfig.get(group, 'links'))
|
|
except:
|
|
links = []
|
|
|
|
self.links = []
|
|
for tup in links:
|
|
key = data_model.Key(tup[0], tup[1], tup[2], tup[3])
|
|
self.links.append(key)
|
|
|
|
try:
|
|
exceptions = eval(one_unit.app.groupconfig.get(group, 'exceptions'))
|
|
except:
|
|
exceptions = []
|
|
|
|
self.exceptions = []
|
|
for tup in exceptions:
|
|
key = data_model.Key(tup[0], tup[1], tup[2], tup[3])
|
|
self.exceptions.append(key)
|
|
|
|
self.name = one_unit.app.groupconfig.get(group, 'name')
|
|
self.group_type = one_unit.app.groupconfig.get(group, 'type')
|
|
descriptionText = one_unit.app.groupconfig.get(group, 'description')
|
|
print 'desc txt:', descriptionText
|
|
print mytime.displayTime() + ' wxPython version: ' + str(wx.VERSION_STRING)
|
|
descriptionText = descriptionText.decode('utf-8')
|
|
self.name = self.name.decode('utf-8')
|
|
statuslabel = wx.StaticText(self, -1, 'Status:', style=wx.ALIGN_LEFT, pos=(25,
|
|
10))
|
|
if self.enabled == True:
|
|
self.statusindication = wx.StaticText(self, -1, 'Enabled', style=wx.ALIGN_LEFT, pos=(180,
|
|
10))
|
|
self.status_button = wx.lib.buttons.GenButton(self, 3, 'Disable', pos=(350,
|
|
10), size=(100,
|
|
20))
|
|
else:
|
|
self.statusindication = wx.StaticText(self, -1, 'Disabled', style=wx.ALIGN_LEFT, pos=(180,
|
|
10))
|
|
self.status_button = wx.lib.buttons.GenButton(self, 3, 'Enable', pos=(350,
|
|
10), size=(100,
|
|
20))
|
|
self.delete_button = wx.lib.buttons.GenButton(self, 333, 'Delete Group', pos=(10,
|
|
260), size=(140,
|
|
20))
|
|
namelabel = wx.StaticText(self, -1, 'Name (max 20 characters):', style=wx.ALIGN_LEFT, pos=(25,
|
|
35))
|
|
style = wx.TE_PROCESS_ENTER
|
|
self.namefield = wx.TextCtrl(self, 3, self.name, style=style, pos=(180, 32), size=(140,
|
|
20))
|
|
self.namefield.SetMaxLength(20)
|
|
typelabel = wx.StaticText(self, -1, 'Type:', style=wx.ALIGN_LEFT, pos=(25,
|
|
63))
|
|
self.select_type = wx.Choice(self, 30, choices=self.group_types, style=wx.BORDER_NONE, pos=(179,
|
|
60), size=(158,
|
|
26))
|
|
try:
|
|
self.select_type.SetStringSelection(self.group_type)
|
|
except:
|
|
print mytime.displayTime() + ' Unsupported Group Type'
|
|
|
|
self.exceptions_button = wx.lib.buttons.GenButton(self, 4, '-> Exceptions ', pos=(180,
|
|
222), size=(100,
|
|
20))
|
|
self.linkslabel = wx.StaticText(self, -1, 'Links:', style=wx.ALIGN_LEFT, pos=(25,
|
|
222))
|
|
self.links_button = wx.lib.buttons.GenButton(self, 5, '-> Setup Links', pos=(180,
|
|
222), size=(100,
|
|
20))
|
|
self.links_button.Disable()
|
|
self.links_button.Show(False)
|
|
self.exceptions_button.Disable()
|
|
self.exceptions_button.Show(False)
|
|
self.linkslabel.Show(False)
|
|
if self.group_type in ('Advanced', 'Relative'):
|
|
self.linkslabel.Show(True)
|
|
self.links_button.Enable()
|
|
self.links_button.Show(True)
|
|
if self.group_type == 'Carbon Copy':
|
|
self.linkslabel.Show(True)
|
|
self.exceptions_button.Enable()
|
|
self.exceptions_button.Show(True)
|
|
if self.group_type == 'Mute':
|
|
self.linkslabel.Show(False)
|
|
self.exceptions_button.Show(False)
|
|
self.links_button.Show(False)
|
|
descriptionlabel = wx.StaticText(self, -1, 'Description:', style=wx.ALIGN_LEFT, pos=(25,
|
|
86))
|
|
self.description = wx.TextCtrl(self, 4, descriptionText, style=style | wx.TE_MULTILINE, pos=(180,
|
|
88), size=(270,
|
|
100))
|
|
memberslabel = wx.StaticText(self, -1, 'Members:', style=wx.ALIGN_LEFT, pos=(25,
|
|
196))
|
|
self.members_button = wx.lib.buttons.GenButton(self, 6, 'Select...', pos=(180,
|
|
193), size=(100,
|
|
20))
|
|
if self.support_virtual_units == True:
|
|
self.members_button = wx.lib.buttons.GenButton(self, 7, 'Allocate...', pos=(300,
|
|
193), size=(110,
|
|
20))
|
|
if os.name in mac_names:
|
|
font = wx.Font(11, wx.SWISS, wx.NORMAL, wx.NORMAL)
|
|
textstring.SetFont(font)
|
|
namelabel.SetFont(font)
|
|
self.namefield.SetFont(font)
|
|
typelabel.SetFont(font)
|
|
self.exceptions_button.SetFont(font)
|
|
self.links_button.SetFont(font)
|
|
self.linkslabel.SetFont(font)
|
|
descriptionlabel.SetFont(font)
|
|
self.description.SetFont(font)
|
|
memberslabel.SetFont(font)
|
|
self.members_button.SetFont(font)
|
|
statuslabel.SetFont(font)
|
|
self.statusindication.SetFont(font)
|
|
self.status_button.SetFont(font)
|
|
ok_button = wx.lib.buttons.GenButton(self, 1, 'Ok', pos=(295, 260), size=(70,
|
|
20))
|
|
cancel_button = wx.lib.buttons.GenButton(self, 2, 'Cancel', pos=(375, 260), size=(70,
|
|
20))
|
|
self.Centre()
|
|
self.save_group_button = wx.lib.buttons.GenButton(self, 206, 'Save Group', pos=(350,
|
|
61), size=(100,
|
|
20))
|
|
self.SetBackgroundColour(bgcolour)
|
|
self.Bind(wx.EVT_BUTTON, self.OnOK, id=1)
|
|
self.Bind(wx.EVT_BUTTON, self.OnSaveGroup, id=206)
|
|
self.Bind(wx.EVT_BUTTON, self.OnCancel, id=2)
|
|
self.Bind(wx.EVT_BUTTON, self.OnEnable, id=3)
|
|
self.Bind(wx.EVT_BUTTON, self.OnDelete, id=333)
|
|
self.Bind(wx.EVT_BUTTON, self.OnExceptions, id=4)
|
|
self.Bind(wx.EVT_BUTTON, self.OnLinks, id=5)
|
|
self.Bind(wx.EVT_BUTTON, self.OnMembers, id=6)
|
|
self.Bind(wx.EVT_BUTTON, self.OnAllocate, id=7)
|
|
self.Bind(wx.EVT_CHOICE, self.OnChangeType, id=30)
|
|
self.CenterOnScreen()
|
|
self.response = None
|
|
self.last_struct_id = -1
|
|
self.refresh_timer = wx.Timer(self)
|
|
self.Bind(wx.EVT_TIMER, self.on_timer, self.refresh_timer)
|
|
self.refresh_timer.Start(100)
|
|
return
|
|
|
|
def OnDelete(self, e):
|
|
self.parent.mark_for_delete = True
|
|
self.Cancel()
|
|
return
|
|
|
|
def OnChangeType(self, e):
|
|
self.group_type = self.select_type.GetStringSelection()
|
|
self.links_button.Disable()
|
|
self.links_button.Show(False)
|
|
self.exceptions_button.Disable()
|
|
self.exceptions_button.Show(False)
|
|
self.linkslabel.Show(False)
|
|
if self.group_type in ('Advanced', 'Relative'):
|
|
self.linkslabel.Show(True)
|
|
self.links_button.Enable()
|
|
self.links_button.Show(True)
|
|
if self.group_type == 'Carbon Copy':
|
|
self.linkslabel.Show(True)
|
|
self.exceptions_button.Enable()
|
|
self.exceptions_button.Show(True)
|
|
if self.group_type == 'Mute':
|
|
self.linkslabel.Show(False)
|
|
self.exceptions_button.Show(False)
|
|
self.links_button.Show(False)
|
|
return
|
|
|
|
def on_timer(self, e):
|
|
self.refresh_timer.Stop()
|
|
return
|
|
|
|
def OnEnable(self, e):
|
|
if self.enabled == True:
|
|
self.enabled = False
|
|
self.statusindication.SetLabel('Disabled')
|
|
self.status_button.SetLabel('Enable')
|
|
else:
|
|
self.enabled = True
|
|
self.select_type.Enable()
|
|
self.statusindication.SetLabel('Enabled')
|
|
self.status_button.SetLabel('Disable')
|
|
if os.name in mac_names:
|
|
self.namefield.Show(True)
|
|
self.description.Show(True)
|
|
else:
|
|
self.namefield.Enable(True)
|
|
self.description.Enable(True)
|
|
self.members_button.Enable(True)
|
|
self.group_type = self.select_type.GetStringSelection()
|
|
if self.group_type in ('Advanced', 'Relative'):
|
|
self.linkslabel.Show(True)
|
|
self.links_button.Enable()
|
|
self.links_button.Show(True)
|
|
if self.group_type == 'Carbon Copy':
|
|
self.linkslabel.Show(True)
|
|
self.exceptions_button.Enable()
|
|
self.exceptions_button.Show(True)
|
|
if self.group_type == 'Mute':
|
|
self.linkslabel.Show(False)
|
|
self.exceptions_button.Show(False)
|
|
self.links_button.Show(False)
|
|
return
|
|
|
|
def OnExceptions(self, e):
|
|
try:
|
|
lead_member = self.members.keys()[0]
|
|
member_type = self.members[lead_member][1]
|
|
except:
|
|
return
|
|
else:
|
|
dial = select_keys.Dialog(self, -1, 'Select Exceptions for ' + self.namefield.GetValue()[:20], ' ', member_type, self.exceptions, group_type=self.group_type)
|
|
dial.ShowModal()
|
|
if dial.response == 'OK':
|
|
self.exceptions = dial.result
|
|
|
|
dial.Destroy()
|
|
return
|
|
|
|
def OnLinks(self, e):
|
|
try:
|
|
lead_member = self.members.keys()[0]
|
|
member_type = self.members[lead_member][1]
|
|
except:
|
|
return
|
|
else:
|
|
if self.group_type == 'Relative':
|
|
only_numbers = True
|
|
else:
|
|
only_numbers = False
|
|
dial = select_keys.Dialog(self, -1, 'Select Linked items for ' + self.namefield.GetValue()[:20], ' ', member_type, self.links, only_numbers=only_numbers, group_type=self.group_type)
|
|
dial.ShowModal()
|
|
if dial.response == 'OK':
|
|
self.links = dial.result
|
|
|
|
dial.Destroy()
|
|
return
|
|
|
|
def OnAllocate(self, e):
|
|
dial = select_units.Dialog(self, -1, 'Allocate Virtual Units for ' + self.namefield.GetValue()[:20], ' ', '', self.members, allocate=True, groupID=self.group, group_type=self.group_type)
|
|
dial.ShowModal()
|
|
if dial.response == 'OK':
|
|
self.members = dial.result
|
|
dial.Destroy()
|
|
return
|
|
|
|
def OnMembers(self, e):
|
|
if self.support_virtual_units == True:
|
|
dial = select_units.Dialog(self, -1, 'Select Group Members for ' + self.namefield.GetValue()[:20], ' ', '', self.members, add_virtual=True, groupID=self.group, group_type=self.group_type)
|
|
else:
|
|
dial = select_units.Dialog(self, -1, 'Select Group Members for ' + self.namefield.GetValue()[:20], ' ', '', self.members, groupID=self.group, group_type=self.group_type)
|
|
dial.ShowModal()
|
|
if dial.response == 'OK':
|
|
self.members = dial.result
|
|
dial.Destroy()
|
|
return
|
|
|
|
def OnEraseBackground(self, evt):
|
|
"""
|
|
Add a picture to the background
|
|
"""
|
|
dc = evt.GetDC()
|
|
if not dc:
|
|
dc = wx.ClientDC(self)
|
|
rect = self.GetUpdateRegion().GetBox()
|
|
dc.SetClippingRect(rect)
|
|
dc.Clear()
|
|
bmp = wx.Bitmap(self.bg)
|
|
dc.DrawBitmap(bmp, 0, 0)
|
|
return
|
|
|
|
def OnOK(self, evt):
|
|
self.response = 'OK'
|
|
try:
|
|
if self.parent.mark_for_delete == False:
|
|
if not self.saveGroup():
|
|
return
|
|
except:
|
|
pass
|
|
|
|
if self.IsModal() == False:
|
|
self.Destroy()
|
|
else:
|
|
self.Close()
|
|
return
|
|
|
|
def saveGroup(self, file=None):
|
|
if file == None:
|
|
config = one_unit.app.groupconfig
|
|
else:
|
|
config = ConfigParser.ConfigParser()
|
|
config.add_section(self.group)
|
|
name = self.namefield.GetValue()[:20].strip()
|
|
if len(name) < 1:
|
|
name = str(self.group)
|
|
try:
|
|
name = name.encode('utf-8')
|
|
except:
|
|
name = ('').join(c for c in name if c in data_model.validFilenameChars)
|
|
|
|
found = True
|
|
while found == True:
|
|
found = False
|
|
for testgroup in one_unit.app.group_names:
|
|
if one_unit.app.group_names[testgroup] == name and testgroup != self.group:
|
|
dial = dialog.Dialog(self, -1, 'Rename Group', 'This name is already in use. Please choose another name.', textkey='', default_text='', Set=False)
|
|
dial.ShowModal()
|
|
name = dial.textfield.GetValue()
|
|
response = dial.response
|
|
dial.Destroy()
|
|
if response != 'OK':
|
|
return False
|
|
found = True
|
|
|
|
group_type = self.select_type.GetStringSelection()
|
|
description = self.description.GetValue()
|
|
try:
|
|
description = description.encode('utf-8')
|
|
except:
|
|
description = ('').join(c for c in description if c in data_model.validFilenameChars)
|
|
|
|
links = []
|
|
for key in self.links:
|
|
links.append((key.struct_id, key.member_id, key.channel, key.num))
|
|
|
|
if group_type in one_unit.app.fixed_group_links:
|
|
links = one_unit.app.fixed_group_links[group_type]
|
|
exceptions = []
|
|
for key in self.exceptions:
|
|
exceptions.append((key.struct_id, key.member_id, key.channel, key.num))
|
|
|
|
functions = []
|
|
if file == None:
|
|
one_unit.app.groups[self.group] = self.members
|
|
for member in self.members.keys():
|
|
if member not in one_unit.app.server.peers.units.keys():
|
|
print mytime.displayTime() + ' Adding', member, self.members[member]
|
|
unit = one_unit.RemoteUnit()
|
|
unit.name = self.members[member][0]
|
|
unit.type = self.members[member][1]
|
|
unit.MAC = member
|
|
unit.IP = 'No IP'
|
|
unit.link_status = 'Virtual'
|
|
one_unit.app.main_frame.peers.add(unit)
|
|
d_unit = d_protocol.RemoteUnit()
|
|
d_unit.MAC = unit.MAC
|
|
if unit.type.count('_') > 2:
|
|
d_unit.type = unit.type[:unit.type.rfind('_')]
|
|
else:
|
|
d_unit.type = unit.type
|
|
d_unit.link_type = 'virtual'
|
|
d_unit.link_status = 'virtual'
|
|
d_unit.Serial = 'virtual'
|
|
d_unit.IP = 'virtual'
|
|
d_unit.HWVersion = 'virtual'
|
|
d_unit.FWVersion = 'virtual'
|
|
d_unit.PICVersion = 'virtual'
|
|
d_unit.ProductionDate = 'virtual'
|
|
d_unit.originalSwID = d_unit.type
|
|
d_unit.Muted = 'False'
|
|
d_unit.BuildNumber = '99999999'
|
|
d_unit.name = unit.name
|
|
one_unit.app.server.peers.add(d_unit)
|
|
try:
|
|
one_unit.app.server.peers.units[unit.MAC].numericalFWVersion = 10000000000.0
|
|
except:
|
|
pass
|
|
else:
|
|
one_unit.app.main_frame.model.set_unit_name(unit.name, unit.MAC)
|
|
|
|
one_unit.app.group_names[self.group] = name
|
|
one_unit.app.group_enabled[self.group] = self.enabled
|
|
one_unit.app.group_links[self.group] = links
|
|
one_unit.app.group_functions[self.group] = functions
|
|
one_unit.app.group_exceptions[self.group] = exceptions
|
|
one_unit.app.group_type[self.group] = group_type
|
|
group_id = self.group
|
|
config.set(group_id, 'members', self.members)
|
|
config.set(group_id, 'type', group_type)
|
|
config.set(group_id, 'name', name)
|
|
config.set(group_id, 'links', links)
|
|
config.set(group_id, 'functions', functions)
|
|
config.set(group_id, 'exceptions', exceptions)
|
|
config.set(group_id, 'description', description)
|
|
if self.enabled == True:
|
|
self.enabled = 'yes'
|
|
else:
|
|
self.enabled = 'no'
|
|
config.set(group_id, 'enabled', self.enabled)
|
|
if file == None:
|
|
file = os.path.join(one_unit.app.asys_config_path, 'grouping.cfg')
|
|
try:
|
|
groupconfigfile = open(file, 'wb')
|
|
config.write(groupconfigfile)
|
|
groupconfigfile.close()
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
dial = dialog.Dialog(None, -1, 'Folder Rights', 'You do not have sufficient access rights to run this program. Please run this program as administrator.', OK_Only=True)
|
|
dial.ShowModal()
|
|
dial.Destroy()
|
|
return False
|
|
|
|
print 'cg.sg.Saved Group', file
|
|
return True
|
|
|
|
def OnSaveGroup(self, e):
|
|
print mytime.displayTime() + ' dg.Save Group'
|
|
wildcard = 'Group (*.group)|*.group'
|
|
dlg = wx.FileDialog(self, message='Choose a file', defaultDir=one_unit.app.library_path, defaultFile=self.namefield.GetValue(), wildcard=wildcard, style=wx.SAVE | wx.CHANGE_DIR)
|
|
if dlg.ShowModal() == wx.ID_OK:
|
|
path = dlg.GetPath()
|
|
dlg.Destroy()
|
|
if path.endswith('.group') == False:
|
|
path += '.group'
|
|
self.saveGroup(file=path)
|
|
else:
|
|
dlg.Destroy()
|
|
print mytime.displayTime() + ' dg.Save Group Exit'
|
|
return
|
|
|
|
def OnCancel(self, evt):
|
|
self.Cancel()
|
|
return
|
|
|
|
def Cancel(self):
|
|
self.response = 'Cancel'
|
|
if self.IsModal == False:
|
|
self.Destroy()
|
|
else:
|
|
self.Close()
|
|
return
|
|
|
|
|
|
|
|
# okay decompiling pycode/configure_group.pyc
|