Collection of tools useful for audio production
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.

1428 lines
58KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # Imports (Global)
  4. from PyQt4.QtCore import pyqtSlot, Qt, QTimer, QSettings
  5. from PyQt4.QtGui import QMainWindow, QTableWidgetItem, QWidget
  6. from subprocess import getoutput
  7. from random import randint
  8. # Imports (Custom)
  9. import claudia_database as database
  10. import ui_claudia_launcher
  11. from shared import *
  12. # Debug Mode
  13. SHOW_ALL = False
  14. # Tab Indexes
  15. TAB_INDEX_DAW = 0
  16. TAB_INDEX_HOST = 1
  17. TAB_INDEX_INSTRUMENT = 2
  18. TAB_INDEX_BRISTOL = 3
  19. TAB_INDEX_EFFECT = 4
  20. TAB_INDEX_TOOL = 5
  21. EXTRA_ICON_PATHS = [
  22. "/usr/share/icons",
  23. "/usr/share/pixmaps",
  24. "/usr/local/share/pixmaps"
  25. ]
  26. # XIcon class
  27. class XIcon(object):
  28. def __init__(self):
  29. object.__init__(self)
  30. def addIconPath(self, path):
  31. icon_paths = QIcon.themeSearchPaths()
  32. icon_paths.append(path)
  33. QIcon.setThemeSearchPaths(icon_paths)
  34. def getIcon(self, name):
  35. if os.path.exists(name):
  36. icon = QIcon(name)
  37. else:
  38. icon = QIcon.fromTheme(name)
  39. if icon.isNull():
  40. for iEXTRA_PATH in EXTRA_ICON_PATHS:
  41. if os.path.exists(os.path.join(iEXTRA_PATH, name + ".png")):
  42. icon = QIcon(os.path.join(iEXTRA_PATH, name + ".png"))
  43. break
  44. elif os.path.exists(os.path.join(iEXTRA_PATH, name + ".svg")):
  45. icon = QIcon(os.path.join(iEXTRA_PATH, name + ".svg"))
  46. break
  47. elif os.path.exists(os.path.join(iEXTRA_PATH, name + ".xpm")):
  48. icon = QIcon(os.path.join(iEXTRA_PATH, name + ".xpm"))
  49. break
  50. else:
  51. print("XIcon::getIcon(%s) - Failed to find icon" % name)
  52. return icon
  53. # Launcher object
  54. class ClaudiaLauncher(QWidget, ui_claudia_launcher.Ui_ClaudiaLauncherW):
  55. def __init__(self, parent):
  56. QWidget.__init__(self, parent)
  57. self.setupUi(self)
  58. self._parent = None
  59. self._settings = None
  60. self.m_ladish_only = False
  61. self.listDAW.setColumnWidth(0, 22)
  62. self.listDAW.setColumnWidth(1, 150)
  63. self.listDAW.setColumnWidth(2, 125)
  64. self.listHost.setColumnWidth(0, 22)
  65. self.listHost.setColumnWidth(1, 150)
  66. self.listInstrument.setColumnWidth(0, 22)
  67. self.listInstrument.setColumnWidth(1, 150)
  68. self.listInstrument.setColumnWidth(2, 125)
  69. self.listBristol.setColumnWidth(0, 22)
  70. self.listBristol.setColumnWidth(1, 100)
  71. self.listEffect.setColumnWidth(0, 22)
  72. self.listEffect.setColumnWidth(1, 225)
  73. self.listEffect.setColumnWidth(2, 125)
  74. self.listTool.setColumnWidth(0, 22)
  75. self.listTool.setColumnWidth(1, 225)
  76. self.listTool.setColumnWidth(2, 125)
  77. # For the custom icons
  78. self.ClaudiaIcons = XIcon()
  79. self.icon_yes = QIcon(self.getIcon("dialog-ok-apply"))
  80. self.icon_no = QIcon(self.getIcon("dialog-cancel"))
  81. self.m_lastThemeName = QIcon.themeName()
  82. # Copy our icons, so we can then set the fallback icon theme as the current theme
  83. if not os.path.exists("/tmp/.claudia-icons"):
  84. os.mkdir("/tmp/.claudia-icons")
  85. if os.path.exists(os.path.join(sys.path[0], "..", "icons")):
  86. os.system("cp -r '%s' /tmp/.claudia-icons/" % os.path.join(sys.path[0], "..", "icons", "claudia-hicolor"))
  87. elif os.path.exists(os.path.join(sys.path[0], "..", "data", "icons")):
  88. os.system("cp -r '%s' /tmp/.claudia-icons/" % os.path.join(sys.path[0], "..", "data", "icons", "claudia-hicolor"))
  89. os.system("sed -i 's/X-CURRENT-THEME-X/%s/' /tmp/.claudia-icons/claudia-hicolor/index.theme" % self.m_lastThemeName)
  90. self.ClaudiaIcons.addIconPath("/tmp/.claudia-icons")
  91. QIcon.setThemeName("claudia-hicolor")
  92. self.clearInfo_DAW()
  93. self.clearInfo_Host()
  94. self.clearInfo_Intrument()
  95. self.clearInfo_Bristol()
  96. self.clearInfo_Effect()
  97. self.clearInfo_Tool()
  98. self.refreshAll()
  99. self.connect(self.tabWidget, SIGNAL("currentChanged(int)"), SLOT("slot_checkSelectedTab(int)"))
  100. self.connect(self.listDAW, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedDAW(int)"))
  101. self.connect(self.listHost, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedHost(int)"))
  102. self.connect(self.listInstrument, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedInstrument(int)"))
  103. self.connect(self.listBristol, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedBristol(int)"))
  104. self.connect(self.listEffect, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedEffect(int)"))
  105. self.connect(self.listTool, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelectedTool(int)"))
  106. self.connect(self.listDAW, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListDAW(int)"))
  107. self.connect(self.listHost, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListHost(int)"))
  108. self.connect(self.listInstrument, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListInstrument(int)"))
  109. self.connect(self.listBristol, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListBristol(int)"))
  110. self.connect(self.listEffect, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListEffect(int)"))
  111. self.connect(self.listTool, SIGNAL("cellDoubleClicked(int, int)"), SLOT("slot_doubleClickedListTool(int)"))
  112. def getSelectedApp(self):
  113. tab_index = self.tabWidget.currentIndex()
  114. column_name = 2 if (tab_index == TAB_INDEX_BRISTOL) else 1
  115. if tab_index == TAB_INDEX_DAW:
  116. listSel = self.listDAW
  117. elif tab_index == TAB_INDEX_HOST:
  118. listSel = self.listHost
  119. elif tab_index == TAB_INDEX_INSTRUMENT:
  120. listSel = self.listInstrument
  121. elif tab_index == TAB_INDEX_BRISTOL:
  122. listSel = self.listBristol
  123. elif tab_index == TAB_INDEX_EFFECT:
  124. listSel = self.listEffect
  125. elif tab_index == TAB_INDEX_TOOL:
  126. listSel = self.listTool
  127. else:
  128. return ""
  129. return listSel.item(listSel.currentRow(), column_name).text()
  130. def getBinaryFromAppName(self, appname):
  131. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_DAW:
  132. if appname == AppName:
  133. return Binary
  134. for Package, AppName, Instruments, Effects, Binary, Icon, Save, Level, License, Features, Docs in database.list_Host:
  135. if appname == AppName:
  136. return Binary
  137. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Instrument:
  138. if appname == AppName:
  139. return Binary
  140. for Package, AppName, Type, ShortName, Icon, Save, Level, License, Features, Docs in database.list_Bristol:
  141. if appname == AppName:
  142. return "startBristol -audio jack -midi jack -%s" % ShortName
  143. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Effect:
  144. if appname == AppName:
  145. return Binary
  146. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Tool:
  147. if appname == AppName:
  148. return Binary
  149. print("ClaudiaLauncher::getBinaryFromAppName(%s) - Failed to find binary from App name" % appname)
  150. return ""
  151. def startApp(self, app=None):
  152. if not app:
  153. app = self.getSelectedApp()
  154. binary = self.getBinaryFromAppName(app)
  155. os.system("cd '%s' && %s &" % (self.callback_getProjectFolder(), binary))
  156. def addAppToLADISH(self, app=None):
  157. if not app:
  158. app = self.getSelectedApp()
  159. binary = self.getBinaryFromAppName(app)
  160. if binary.startswith("startBristol"):
  161. self.createAppTemplate("bristol", app, binary)
  162. elif app == "Ardour 2.8":
  163. self.createAppTemplate("ardour2", app, binary)
  164. elif app == "Ardour 3.0":
  165. self.createAppTemplate("ardour3", app, binary)
  166. elif app == "Composite":
  167. self.createAppTemplate("composite", app, binary)
  168. #elif app == "EnergyXT2":
  169. #self.createAppTemplate("energyxt2", app, binary)
  170. elif app in ("Hydrogen", "Hydrogen (SVN)"):
  171. self.createAppTemplate("hydrogen", app, binary)
  172. elif app == "Jacker":
  173. self.createAppTemplate("jacker", app, binary)
  174. elif app == "LMMS":
  175. self.createAppTemplate("lmms", app, binary)
  176. elif app == "MusE":
  177. self.createAppTemplate("muse", app, binary)
  178. elif app == "MuseScore":
  179. self.createAppTemplate("musescore", app, binary)
  180. elif app == "Non-DAW":
  181. self.createAppTemplate("non-daw", app, binary)
  182. elif app == "Non-Sequencer":
  183. self.createAppTemplate("non-sequencer", app, binary)
  184. elif app in ("Qtractor", "Qtractor (SVN)"):
  185. self.createAppTemplate("qtractor", app, binary)
  186. #elif app == "REAPER":
  187. #self.createAppTemplate("reaper", app, binary)
  188. elif app == "Renoise":
  189. self.createAppTemplate("renoise", app, binary)
  190. elif app == "Rosegarden":
  191. self.createAppTemplate("rosegarden", app, binary)
  192. elif app == "Seq24":
  193. self.createAppTemplate("seq24", app, binary)
  194. elif app == "Calf Jack Host (GIT)":
  195. self.createAppTemplate("calfjackhost", app, binary)
  196. #elif (app == "Jack Mixer"):
  197. #self.createAppTemplate("jack-mixer", app, binary)
  198. #elif (app == "Jack Rack"):
  199. #self.createAppTemplate("jack-rack", app, binary)
  200. #elif (app == "Jamin"):
  201. #self.createAppTemplate("jamin", app, binary)
  202. #elif (app == "Non-Mixer"):
  203. #self.createAppTemplate("non-mixer", app, binary)
  204. #elif (app == "Qsampler"):
  205. #self.createAppTemplate("qsampler", app, binary)
  206. #elif (app == "Yoshimi"):
  207. #self.createAppTemplate("yoshimi", app, binary)
  208. else:
  209. appBus = self.callback_getAppBus()
  210. appBus.RunCustom2(False, binary, app, "0")
  211. def createAppTemplate(self, app, app_name, binary):
  212. rand_check = randint(1, 99999)
  213. proj_bpm = str(self.callback_getBPM())
  214. proj_srate = str(self.callback_getSampleRate())
  215. proj_folder = self.callback_getProjectFolder()
  216. tmplte_dir = None
  217. tmplte_file = None
  218. tmplte_cmd = ""
  219. tmplte_lvl = "0"
  220. if os.path.exists(os.path.join(sys.path[0], "..", "templates")):
  221. tmplte_dir = os.path.join(sys.path[0], "..", "templates")
  222. elif os.path.exists(os.path.join(sys.path[0], "..", "data", "templates")):
  223. tmplte_dir = os.path.join(sys.path[0], "..", "data", "templates")
  224. else:
  225. app = None
  226. tmplte_cmd = binary
  227. print("ClaudiaLauncher::createAppTemplate() - Failed to find template dir")
  228. if not os.path.exists(proj_folder):
  229. os.mkdir(proj_folder)
  230. if app == "bristol":
  231. module = binary.replace("startBristol -audio jack -midi jack -", "")
  232. tmplte_folder = os.path.join(proj_folder, "bristol_%s_%i" % (module, rand_check))
  233. os.mkdir(tmplte_folder)
  234. if self.callback_isLadishRoom():
  235. tmplte_folder = os.path.basename(tmplte_folder)
  236. tmplte_cmd = binary
  237. tmplte_cmd += " -emulate %s" % module
  238. tmplte_cmd += " -cache '%s'" % tmplte_folder
  239. tmplte_cmd += " -memdump '%s'" % tmplte_folder
  240. tmplte_cmd += " -import '%s'" % os.path.join(tmplte_folder, "memory")
  241. tmplte_cmd += " -exec"
  242. tmplte_lvl = "1"
  243. elif app == "ardour2":
  244. tmplte_folder = os.path.join(proj_folder, "Ardour2_%i" % rand_check)
  245. tmplte_file = os.path.join(tmplte_folder, "Ardour2_%i.ardour" % rand_check)
  246. os.mkdir(tmplte_folder)
  247. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Ardour2", "Ardour2.ardour"), tmplte_file))
  248. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Ardour2", "instant.xml"), tmplte_folder))
  249. os.mkdir(os.path.join(tmplte_folder, "analysis"))
  250. os.mkdir(os.path.join(tmplte_folder, "dead_sounds"))
  251. os.mkdir(os.path.join(tmplte_folder, "export"))
  252. os.mkdir(os.path.join(tmplte_folder, "interchange"))
  253. os.mkdir(os.path.join(tmplte_folder, "interchange", "Ardour"))
  254. os.mkdir(os.path.join(tmplte_folder, "interchange", "Ardour", "audiofiles"))
  255. os.mkdir(os.path.join(tmplte_folder, "peaks"))
  256. tmplte_cmd = binary
  257. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  258. #tmplte_lvl = "1" # TODO - kxstudio only
  259. elif app == "ardour3":
  260. tmplte_folder = os.path.join(proj_folder, "Ardour3_%i" % rand_check)
  261. tmplte_file = os.path.join(tmplte_folder, "Ardour3_%i.ardour" % rand_check)
  262. os.mkdir(tmplte_folder)
  263. # Create template
  264. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Ardour3", "Ardour3.ardour"), tmplte_file))
  265. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Ardour3", "instant.xml"), tmplte_folder))
  266. os.mkdir(os.path.join(tmplte_folder, "analysis"))
  267. os.mkdir(os.path.join(tmplte_folder, "dead"))
  268. os.mkdir(os.path.join(tmplte_folder, "export"))
  269. os.mkdir(os.path.join(tmplte_folder, "externals"))
  270. os.mkdir(os.path.join(tmplte_folder, "interchange"))
  271. os.mkdir(os.path.join(tmplte_folder, "interchange", "Ardour3"))
  272. os.mkdir(os.path.join(tmplte_folder, "interchange", "Ardour3", "audiofiles"))
  273. os.mkdir(os.path.join(tmplte_folder, "interchange", "Ardour3", "midifiles"))
  274. os.mkdir(os.path.join(tmplte_folder, "peaks"))
  275. os.mkdir(os.path.join(tmplte_folder, "plugins"))
  276. tmplte_cmd = binary
  277. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  278. if self.callback_isLadishRoom():
  279. tmplte_lvl = "jacksession"
  280. elif app == "composite":
  281. tmplte_file = os.path.join(proj_folder, "Composite_%i.h2song" % rand_check)
  282. # Create template
  283. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Composite.h2song"), tmplte_file))
  284. tmplte_cmd = binary
  285. tmplte_cmd += " -s '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  286. elif app == "hydrogen":
  287. tmplte_file = os.path.join(proj_folder, "Hydrogen_%i.h2song" % rand_check)
  288. # Create template
  289. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Hydrogen.h2song"), tmplte_file))
  290. tmplte_cmd = binary
  291. tmplte_cmd += " -s '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  292. if self.callback_isLadishRoom():
  293. tmplte_lvl = "jacksession"
  294. else:
  295. tmplte_lvl = "1"
  296. elif app == "jacker":
  297. tmplte_file = os.path.join(proj_folder, "Jacker_%i.jsong" % rand_check)
  298. # Create template
  299. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Jacker.jsong"), tmplte_file))
  300. tmplte_cmd = binary
  301. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  302. #tmplte_lvl = "1" # TODO - kxstudio only
  303. # No decimal bpm support
  304. proj_bpm = proj_bpm.split(".")[0]
  305. elif app == "lmms":
  306. tmplte_file = os.path.join(proj_folder, "LMMS_%i.mmp" % rand_check)
  307. # Create template
  308. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "LMMS.mmp"), tmplte_file))
  309. tmplte_cmd = binary
  310. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  311. # No decimal bpm support
  312. proj_bpm = proj_bpm.split(".")[0]
  313. elif app == "muse":
  314. tmplte_file = os.path.join(proj_folder, "MusE_%i.med" % rand_check)
  315. # Create template
  316. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "MusE.med"), tmplte_file))
  317. tmplte_cmd = binary
  318. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  319. elif app == "non-daw":
  320. tmplte_folder = os.path.join(proj_folder, "Non-DAW_%i" % rand_check)
  321. os.mkdir(tmplte_folder)
  322. # Create template
  323. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Non-DAW", "history"), tmplte_folder))
  324. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Non-DAW", "info"), tmplte_folder))
  325. os.mkdir(os.path.join(tmplte_folder, "sources"))
  326. os.system('sed -i "s/X_SR_X-CLAUDIA-X_SR_X/%s/" "%s"' % (proj_srate, os.path.join(tmplte_folder, "info")))
  327. os.system('sed -i "s/X_BPM_X-CLAUDIA-X_BPM_X/%s/" "%s"' % (proj_bpm, os.path.join(tmplte_folder, "history")))
  328. tmplte_cmd = binary
  329. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  330. elif app == "non-sequencer":
  331. tmplte_file = os.path.join(proj_folder, "Non-Sequencer_%i.non" % rand_check)
  332. # Create template
  333. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Non-Sequencer.non"), tmplte_file))
  334. tmplte_cmd = binary
  335. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  336. elif app == "qtractor":
  337. tmplte_file = os.path.join(proj_folder, "Qtractor_%i.qtr" % rand_check)
  338. # Create template
  339. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Qtractor.qtr"), tmplte_file))
  340. tmplte_cmd = binary
  341. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  342. if self.callback_isLadishRoom():
  343. tmplte_lvl = "jacksession"
  344. else:
  345. tmplte_lvl = "1"
  346. elif app == "renoise":
  347. tmplte_file_r = os.path.join(proj_folder, "Renoise_%i.xrns" % rand_check)
  348. tmplte_folder = os.path.join(proj_folder, "tmp_renoise_%i" % rand_check)
  349. # Create template
  350. os.mkdir(tmplte_folder)
  351. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "Renoise.xml"), tmplte_folder))
  352. os.system('sed -i "s/X_BPM_X-CLAUDIA-X_BPM_X/%s/" "%s"' % (proj_bpm, os.path.join(tmplte_folder, "Renoise.xml")))
  353. os.system("cd '%s' && mv Renoise.xml Song.xml && zip '%s' Song.xml" % (tmplte_folder, tmplte_file_r))
  354. os.system("rm -rf '%s'" % tmplte_folder)
  355. tmplte_cmd = binary
  356. tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  357. elif app == "calfjackhost":
  358. tmplte_file = os.path.join(proj_folder, "CalfJackHost_%i" % rand_check)
  359. # Create template
  360. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "CalfJackHost"), tmplte_file))
  361. tmplte_cmd = binary
  362. tmplte_cmd += " --load '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  363. tmplte_lvl = "1"
  364. #elif (app == "jack-mixer"):
  365. #tmplte_file_r = os.path.join(proj_folder, "Jack-Mixer_%i.xml" % (rand_check))
  366. ## Create template
  367. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jack-Mixer.xml"), tmplte_file_r))
  368. #tmplte_cmd = binary
  369. #tmplte_cmd += " -c '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  370. #tmplte_lvl = "1"
  371. #elif (app == "jack-rack"):
  372. #tmplte_file = os.path.join(proj_folder, "Jack-Rack_%i.xml" % (rand_check))
  373. ## Create template
  374. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jack-Rack.xml"), tmplte_file))
  375. #tmplte_cmd = binary
  376. #tmplte_cmd += " -s '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  377. #elif (app == "jamin"):
  378. #tmplte_file_r = os.path.join(proj_folder, "Jamin_%i.jam" % (rand_check))
  379. ## Create template
  380. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jamin.jam"), tmplte_file_r))
  381. #tmplte_cmd = binary
  382. #tmplte_cmd += " -f '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  383. #elif (app == "non-mixer"):
  384. #tmplte_folder = os.path.join(proj_folder, "Non-Mixer_%i" % (rand_check))
  385. ## Create template
  386. #os.system("cp -r '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Non-Mixer"), tmplte_folder))
  387. #tmplte_cmd = binary
  388. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  389. #elif (app == "qsampler"):
  390. #tmplte_file_r = os.path.join(proj_folder, "Qsampler_%i.lscp" % (rand_check))
  391. ## Create template
  392. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Qsampler.lscp"), tmplte_file_r))
  393. #tmplte_cmd = binary
  394. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  395. #tmplte_lvl = "1" if (app_name == "Qsampler (SVN)") else "0"
  396. #elif (app == "yoshimi"):
  397. #tmplte_file = os.path.join(proj_folder, "Yoshimi_%i.state" % (rand_check))
  398. ## Create template
  399. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Yoshimi.state"), tmplte_file))
  400. #tmplte_cmd = binary
  401. #tmplte_cmd += " --state='%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  402. #tmplte_lvl = "1"
  403. #else:
  404. #print("ERROR: Failed to parse app name")
  405. #return
  406. if tmplte_file != None:
  407. os.system('sed -i "s/X_SR_X-CLAUDIA-X_SR_X/%s/" "%s"' % (proj_srate, tmplte_file))
  408. os.system('sed -i "s/X_BPM_X-CLAUDIA-X_BPM_X/%s/" "%s"' % (proj_bpm, tmplte_file))
  409. os.system('sed -i "s/X_FOLDER_X-CLAUDIA-X_FOLDER_X/%s/" "%s"' % (proj_folder.replace("/", "\/").replace("$", "\$"), tmplte_file))
  410. appBus = self.callback_getAppBus()
  411. appBus.RunCustom2(False, tmplte_cmd, app_name, tmplte_lvl)
  412. def parentR(self):
  413. return self._parent
  414. def settings(self):
  415. return self._settings
  416. def getIcon(self, icon):
  417. return self.ClaudiaIcons.getIcon(icon)
  418. def getIconForYesNo(self, yesno):
  419. return self.icon_yes if yesno else self.icon_no
  420. def setCallbackApp(self, parent, settings, ladish_only):
  421. self._parent = parent
  422. self._settings = settings
  423. self.m_ladish_only = ladish_only
  424. def clearInfo_DAW(self):
  425. self.ico_app_daw.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  426. self.label_name_daw.setText("App Name")
  427. self.ico_ladspa_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  428. self.ico_dssi_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  429. self.ico_lv2_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  430. self.ico_vst_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  431. self.label_vst_mode_daw.setText("")
  432. self.ico_jack_transport_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  433. self.label_midi_mode_daw.setText("---")
  434. self.label_session_level_daw.setText(database.LEVEL_0)
  435. self.frame_DAW.setEnabled(False)
  436. self.showDoc_DAW("", "")
  437. def clearInfo_Host(self):
  438. self.ico_app_host.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  439. self.label_name_host.setText("App Name")
  440. self.ico_ladspa_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  441. self.ico_dssi_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  442. self.ico_lv2_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  443. self.ico_vst_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  444. self.label_vst_mode_host.setText("")
  445. self.label_midi_mode_host.setText("---")
  446. self.label_session_level_host.setText(database.LEVEL_0)
  447. self.frame_Host.setEnabled(False)
  448. self.showDoc_Host("", "")
  449. def clearInfo_Intrument(self):
  450. self.ico_app_ins.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  451. self.label_name_ins.setText("App Name")
  452. self.ico_builtin_fx_ins.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  453. self.ico_audio_input_ins.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  454. self.label_midi_mode_ins.setText("---")
  455. self.label_session_level_ins.setText(database.LEVEL_0)
  456. self.frame_Instrument.setEnabled(False)
  457. self.showDoc_Instrument("", "")
  458. def clearInfo_Bristol(self):
  459. self.ico_app_bristol.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  460. self.label_name_bristol.setText("App Name")
  461. self.ico_builtin_fx_bristol.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  462. self.ico_audio_input_bristol.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  463. self.label_midi_mode_bristol.setText("---")
  464. self.label_session_level_bristol.setText(database.LEVEL_0)
  465. self.frame_Bristol.setEnabled(False)
  466. self.showDoc_Bristol("", "")
  467. def clearInfo_Effect(self):
  468. self.ico_app_effect.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  469. self.label_name_effect.setText("App Name")
  470. self.ico_stereo_effect.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  471. self.label_midi_mode_effect.setText("---")
  472. self.label_session_level_effect.setText(database.LEVEL_0)
  473. self.frame_Effect.setEnabled(False)
  474. self.showDoc_Effect("", "")
  475. def clearInfo_Tool(self):
  476. self.ico_app_tool.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  477. self.label_name_tool.setText("App Name")
  478. self.label_midi_mode_tool.setText("---")
  479. self.label_session_level_tool.setText(database.LEVEL_0)
  480. self.frame_Tool.setEnabled(False)
  481. self.showDoc_Tool("", "")
  482. def showDoc_DAW(self, doc, web):
  483. self.url_documentation_daw.setVisible(bool(doc))
  484. self.url_website_daw.setVisible(bool(web))
  485. self.label_no_help_daw.setVisible(not(doc or web))
  486. if doc: self.setDocUrl(self.url_documentation_daw, doc)
  487. if web: self.setWebUrl(self.url_website_daw, web)
  488. def showDoc_Host(self, doc, web):
  489. self.url_documentation_host.setVisible(bool(doc))
  490. self.url_website_host.setVisible(bool(web))
  491. self.label_no_help_host.setVisible(not(doc or web))
  492. if doc: self.setDocUrl(self.url_documentation_host, doc)
  493. if web: self.setWebUrl(self.url_website_host, web)
  494. def showDoc_Instrument(self, doc, web):
  495. self.url_documentation_ins.setVisible(bool(doc))
  496. self.url_website_ins.setVisible(bool(web))
  497. self.label_no_help_ins.setVisible(not(doc or web))
  498. if doc: self.setDocUrl(self.url_documentation_ins, doc)
  499. if web: self.setWebUrl(self.url_website_ins, web)
  500. def showDoc_Bristol(self, doc, web):
  501. self.url_documentation_bristol.setVisible(bool(doc))
  502. self.url_website_bristol.setVisible(bool(web))
  503. self.label_no_help_bristol.setVisible(not(doc or web))
  504. if doc: self.setDocUrl(self.url_documentation_bristol, doc)
  505. if web: self.setWebUrl(self.url_website_bristol, web)
  506. def showDoc_Effect(self, doc, web):
  507. self.url_documentation_effect.setVisible(bool(doc))
  508. self.url_website_effect.setVisible(bool(web))
  509. self.label_no_help_effect.setVisible(not(doc or web))
  510. if doc: self.setDocUrl(self.url_documentation_effect, doc)
  511. if web: self.setWebUrl(self.url_website_effect, web)
  512. def showDoc_Tool(self, doc, web):
  513. self.url_documentation_tool.setVisible(bool(doc))
  514. self.url_website_tool.setVisible(bool(web))
  515. self.label_no_help_tool.setVisible(not(doc or web))
  516. if doc: self.setDocUrl(self.url_documentation_tool, doc)
  517. if web: self.setWebUrl(self.url_website_tool, web)
  518. def setDocUrl(self, item, link):
  519. item.setText(self.tr("<a href='%s'>Documentation</a>" % link))
  520. def setWebUrl(self, item, link):
  521. item.setText(self.tr("<a href='%s'>WebSite</a>" % link))
  522. def clearAll(self):
  523. self.listDAW.clearContents()
  524. self.listHost.clearContents()
  525. self.listInstrument.clearContents()
  526. self.listBristol.clearContents()
  527. self.listEffect.clearContents()
  528. self.listTool.clearContents()
  529. for x in range(self.listDAW.rowCount()):
  530. self.listDAW.removeRow(0)
  531. for x in range(self.listHost.rowCount()):
  532. self.listHost.removeRow(0)
  533. for x in range(self.listInstrument.rowCount()):
  534. self.listInstrument.removeRow(0)
  535. for x in range(self.listBristol.rowCount()):
  536. self.listBristol.removeRow(0)
  537. for x in range(self.listEffect.rowCount()):
  538. self.listEffect.removeRow(0)
  539. for x in range(self.listTool.rowCount()):
  540. self.listTool.removeRow(0)
  541. def refreshAll(self):
  542. self.clearAll()
  543. pkglist = []
  544. if not SHOW_ALL:
  545. if os.path.exists("/usr/bin/yaourt"):
  546. pkg_out = getoutput("/usr/bin/yaourt -Qsq").split("\n")
  547. for package in pkg_out:
  548. pkglist.append(package)
  549. elif os.path.exists("/usr/bin/pacman"):
  550. pkg_out = getoutput("/usr/bin/pacman -Qsq").split("\n")
  551. for package in pkg_out:
  552. pkglist.append(package)
  553. elif os.path.exists("/usr/bin/dpkg-query"):
  554. pkg_out = getoutput("/usr/bin/dpkg-query -W --showformat='${Package}\n'").split("\n")
  555. for package in pkg_out:
  556. pkglist.append(package)
  557. if not "bristol" in pkglist:
  558. self.tabWidget.setTabEnabled(TAB_INDEX_BRISTOL, False)
  559. last_pos = 0
  560. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_DAW:
  561. if SHOW_ALL or Package in pkglist:
  562. w_icon = QTableWidgetItem("")
  563. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  564. w_name = QTableWidgetItem(AppName)
  565. w_type = QTableWidgetItem(Type)
  566. w_save = QTableWidgetItem(Save)
  567. w_licc = QTableWidgetItem(License)
  568. self.listDAW.insertRow(last_pos)
  569. self.listDAW.setItem(last_pos, 0, w_icon)
  570. self.listDAW.setItem(last_pos, 1, w_name)
  571. self.listDAW.setItem(last_pos, 2, w_type)
  572. self.listDAW.setItem(last_pos, 3, w_save)
  573. self.listDAW.setItem(last_pos, 4, w_licc)
  574. last_pos += 1
  575. last_pos = 0
  576. for Package, AppName, Instruments, Effects, Binary, Icon, Save, Level, License, Features, Docs in database.list_Host:
  577. if SHOW_ALL or Package in pkglist:
  578. w_icon = QTableWidgetItem("")
  579. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  580. w_name = QTableWidgetItem(AppName)
  581. w_h_in = QTableWidgetItem(Instruments)
  582. w_h_ef = QTableWidgetItem(Effects)
  583. w_save = QTableWidgetItem(Save)
  584. w_licc = QTableWidgetItem(License)
  585. self.listHost.insertRow(last_pos)
  586. self.listHost.setItem(last_pos, 0, w_icon)
  587. self.listHost.setItem(last_pos, 1, w_name)
  588. self.listHost.setItem(last_pos, 2, w_h_in)
  589. self.listHost.setItem(last_pos, 3, w_h_ef)
  590. self.listHost.setItem(last_pos, 4, w_save)
  591. self.listHost.setItem(last_pos, 5, w_licc)
  592. last_pos += 1
  593. last_pos = 0
  594. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Instrument:
  595. if SHOW_ALL or Package in pkglist:
  596. w_icon = QTableWidgetItem("")
  597. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  598. w_name = QTableWidgetItem(AppName)
  599. w_type = QTableWidgetItem(Type)
  600. w_save = QTableWidgetItem(Save)
  601. w_licc = QTableWidgetItem(License)
  602. self.listInstrument.insertRow(last_pos)
  603. self.listInstrument.setItem(last_pos, 0, w_icon)
  604. self.listInstrument.setItem(last_pos, 1, w_name)
  605. self.listInstrument.setItem(last_pos, 2, w_type)
  606. self.listInstrument.setItem(last_pos, 3, w_save)
  607. self.listInstrument.setItem(last_pos, 4, w_licc)
  608. last_pos += 1
  609. last_pos = 0
  610. for Package, FullName, Type, ShortName, Icon, Save, Level, License, Features, Docs in database.list_Bristol:
  611. if SHOW_ALL or Package in pkglist:
  612. w_icon = QTableWidgetItem("")
  613. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  614. w_fullname = QTableWidgetItem(FullName)
  615. w_shortname = QTableWidgetItem(ShortName)
  616. self.listBristol.insertRow(last_pos)
  617. self.listBristol.setItem(last_pos, 0, w_icon)
  618. self.listBristol.setItem(last_pos, 1, w_shortname)
  619. self.listBristol.setItem(last_pos, 2, w_fullname)
  620. last_pos += 1
  621. last_pos = 0
  622. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Effect:
  623. if SHOW_ALL or Package in pkglist:
  624. w_icon = QTableWidgetItem("")
  625. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  626. w_name = QTableWidgetItem(AppName)
  627. w_type = QTableWidgetItem(Type)
  628. w_save = QTableWidgetItem(Save)
  629. w_licc = QTableWidgetItem(License)
  630. self.listEffect.insertRow(last_pos)
  631. self.listEffect.setItem(last_pos, 0, w_icon)
  632. self.listEffect.setItem(last_pos, 1, w_name)
  633. self.listEffect.setItem(last_pos, 2, w_type)
  634. self.listEffect.setItem(last_pos, 3, w_save)
  635. self.listEffect.setItem(last_pos, 4, w_licc)
  636. last_pos += 1
  637. last_pos = 0
  638. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Tool:
  639. if SHOW_ALL or Package in pkglist:
  640. w_icon = QTableWidgetItem("")
  641. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  642. w_name = QTableWidgetItem(AppName)
  643. w_type = QTableWidgetItem(Type)
  644. w_save = QTableWidgetItem(Save)
  645. w_licc = QTableWidgetItem(License)
  646. self.listTool.insertRow(last_pos)
  647. self.listTool.setItem(last_pos, 0, w_icon)
  648. self.listTool.setItem(last_pos, 1, w_name)
  649. self.listTool.setItem(last_pos, 2, w_type)
  650. self.listTool.setItem(last_pos, 3, w_save)
  651. self.listTool.setItem(last_pos, 4, w_licc)
  652. last_pos += 1
  653. self.listDAW.setCurrentCell(-1, -1)
  654. self.listHost.setCurrentCell(-1, -1)
  655. self.listInstrument.setCurrentCell(-1, -1)
  656. self.listBristol.setCurrentCell(-1, -1)
  657. self.listEffect.setCurrentCell(-1, -1)
  658. self.listTool.setCurrentCell(-1, -1)
  659. self.listDAW.sortByColumn(1, Qt.AscendingOrder)
  660. self.listHost.sortByColumn(1, Qt.AscendingOrder)
  661. self.listInstrument.sortByColumn(1, Qt.AscendingOrder)
  662. self.listBristol.sortByColumn(2, Qt.AscendingOrder)
  663. self.listEffect.sortByColumn(1, Qt.AscendingOrder)
  664. self.listTool.sortByColumn(1, Qt.AscendingOrder)
  665. @pyqtSlot(int)
  666. def slot_checkSelectedTab(self, tab_index):
  667. if tab_index == TAB_INDEX_DAW:
  668. test_selected = (len(self.listDAW.selectedItems()) > 0)
  669. elif tab_index == TAB_INDEX_HOST:
  670. test_selected = (len(self.listHost.selectedItems()) > 0)
  671. elif tab_index == TAB_INDEX_INSTRUMENT:
  672. test_selected = (len(self.listInstrument.selectedItems()) > 0)
  673. elif tab_index == TAB_INDEX_BRISTOL:
  674. test_selected = (len(self.listBristol.selectedItems()) > 0)
  675. elif tab_index == TAB_INDEX_EFFECT:
  676. test_selected = (len(self.listEffect.selectedItems()) > 0)
  677. elif tab_index == TAB_INDEX_TOOL:
  678. test_selected = (len(self.listTool.selectedItems()) > 0)
  679. else:
  680. test_selected = False
  681. self.callback_checkGUI(test_selected)
  682. @pyqtSlot(int)
  683. def slot_checkSelectedDAW(self, row):
  684. if row >= 0:
  685. selected = True
  686. app_name = self.listDAW.item(row, 1).text()
  687. for DAW in database.list_DAW:
  688. if DAW[1] == app_name:
  689. app_info = DAW
  690. break
  691. else:
  692. print("ERROR: Failed to retrieve app info from database")
  693. return
  694. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  695. self.frame_DAW.setEnabled(True)
  696. self.ico_app_daw.setPixmap(QIcon(self.getIcon(Icon)).pixmap(48, 48))
  697. self.ico_ladspa_daw.setPixmap(QIcon(self.getIconForYesNo(Features[0])).pixmap(16, 16))
  698. self.ico_dssi_daw.setPixmap(QIcon(self.getIconForYesNo(Features[1])).pixmap(16, 16))
  699. self.ico_lv2_daw.setPixmap(QIcon(self.getIconForYesNo(Features[2])).pixmap(16, 16))
  700. self.ico_vst_daw.setPixmap(QIcon(self.getIconForYesNo(Features[3])).pixmap(16, 16))
  701. self.ico_jack_transport_daw.setPixmap(QIcon(self.getIconForYesNo(Features[5])).pixmap(16, 16))
  702. self.label_name_daw.setText(AppName)
  703. self.label_vst_mode_daw.setText(Features[4])
  704. self.ico_midi_mode_daw.setPixmap(QIcon(self.getIconForYesNo(Features[6])).pixmap(16, 16))
  705. self.label_midi_mode_daw.setText(Features[7])
  706. self.label_session_level_daw.setText(Level)
  707. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  708. self.showDoc_DAW(Docs0, Docs[1])
  709. else:
  710. selected = False
  711. self.clearInfo_DAW()
  712. self.callback_checkGUI(selected)
  713. @pyqtSlot(int)
  714. def slot_checkSelectedHost(self, row):
  715. if row >= 0:
  716. selected = True
  717. app_name = self.listHost.item(row, 1).text()
  718. for Host in database.list_Host:
  719. if Host[1] == app_name:
  720. app_info = Host
  721. break
  722. else:
  723. print("ERROR: Failed to retrieve app info from database")
  724. return
  725. Package, AppName, Instruments, Effects, Binary, Icon, Save, Level, License, Features, Docs = app_info
  726. self.frame_Host.setEnabled(True)
  727. self.ico_app_host.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  728. self.ico_internal_host.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  729. self.ico_ladspa_host.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  730. self.ico_dssi_host.setPixmap(self.getIconForYesNo(Features[2]).pixmap(16, 16))
  731. self.ico_lv2_host.setPixmap(self.getIconForYesNo(Features[3]).pixmap(16, 16))
  732. self.ico_vst_host.setPixmap(self.getIconForYesNo(Features[4]).pixmap(16, 16))
  733. self.label_name_host.setText(AppName)
  734. self.label_vst_mode_host.setText(Features[5])
  735. self.label_midi_mode_host.setText(Features[6])
  736. self.label_session_level_host.setText(str(Level))
  737. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  738. self.showDoc_Host(Docs0, Docs[1])
  739. else:
  740. selected = False
  741. self.clearInfo_DAW()
  742. self.callback_checkGUI(selected)
  743. @pyqtSlot(int)
  744. def slot_checkSelectedInstrument(self, row):
  745. if row >= 0:
  746. selected = True
  747. app_name = self.listInstrument.item(row, 1).text()
  748. for Instrument in database.list_Instrument:
  749. if Instrument[1] == app_name:
  750. app_info = Instrument
  751. break
  752. else:
  753. print("ERROR: Failed to retrieve app info from database")
  754. return
  755. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  756. self.frame_Instrument.setEnabled(True)
  757. self.ico_app_ins.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  758. self.ico_builtin_fx_ins.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  759. self.ico_audio_input_ins.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  760. self.label_name_ins.setText(AppName)
  761. self.label_midi_mode_ins.setText(Features[2])
  762. self.label_session_level_ins.setText(str(Level))
  763. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  764. self.showDoc_Instrument(Docs0, Docs[1])
  765. else:
  766. selected = False
  767. self.clearInfo_Intrument()
  768. self.callback_checkGUI(selected)
  769. @pyqtSlot(int)
  770. def slot_checkSelectedBristol(self, row):
  771. if row >= 0:
  772. selected = True
  773. app_name = self.listBristol.item(row, 2).text()
  774. for Bristol in database.list_Bristol:
  775. if Bristol[1] == app_name:
  776. app_info = Bristol
  777. break
  778. else:
  779. print("ERROR: Failed to retrieve app info from database")
  780. return
  781. Package, AppName, Type, ShortName, Icon, Save, Level, License, Features, Docs = app_info
  782. self.frame_Bristol.setEnabled(True)
  783. self.ico_app_bristol.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  784. self.ico_builtin_fx_bristol.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  785. self.ico_audio_input_bristol.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  786. self.label_name_bristol.setText(AppName)
  787. self.label_midi_mode_bristol.setText(Features[2])
  788. self.label_session_level_bristol.setText(str(Level))
  789. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  790. self.showDoc_Bristol(Docs0, Docs[1])
  791. else:
  792. selected = False
  793. self.clearInfo_Bristol()
  794. self.callback_checkGUI(selected)
  795. @pyqtSlot(int)
  796. def slot_checkSelectedEffect(self, row):
  797. if row >= 0:
  798. selected = True
  799. app_name = self.listEffect.item(row, 1).text()
  800. for Effect in database.list_Effect:
  801. if Effect[1] == app_name:
  802. app_info = Effect
  803. break
  804. else:
  805. print("ERROR: Failed to retrieve app info from database")
  806. return
  807. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  808. self.frame_Effect.setEnabled(True)
  809. self.ico_app_effect.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  810. self.ico_stereo_effect.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  811. self.label_name_effect.setText(AppName)
  812. self.label_midi_mode_effect.setText(Features[1])
  813. self.label_session_level_effect.setText(str(Level))
  814. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  815. self.showDoc_Effect(Docs0, Docs[1])
  816. else:
  817. selected = False
  818. self.clearInfo_Effect()
  819. self.callback_checkGUI(selected)
  820. @pyqtSlot(int)
  821. def slot_checkSelectedTool(self, row):
  822. if row >= 0:
  823. selected = True
  824. app_name = self.listTool.item(row, 1).text()
  825. for Tool in database.list_Tool:
  826. if Tool[1] == app_name:
  827. app_info = Tool
  828. break
  829. else:
  830. print("ERROR: Failed to retrieve app info from database")
  831. return
  832. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  833. self.frame_Tool.setEnabled(True)
  834. self.ico_app_tool.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  835. self.label_name_tool.setText(AppName)
  836. self.label_midi_mode_tool.setText(Features[0])
  837. self.ico_jack_transport_tool.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  838. self.label_session_level_tool.setText(str(Level))
  839. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  840. self.showDoc_Tool(Docs0, Docs[1])
  841. else:
  842. selected = False
  843. self.clearInfo_Tool()
  844. self.callback_checkGUI(selected)
  845. @pyqtSlot(int)
  846. def slot_doubleClickedListDAW(self, row):
  847. app = self.listDAW.item(row, 1).text()
  848. if self.m_ladish_only:
  849. self.addAppToLADISH(app)
  850. else:
  851. self.startApp(app)
  852. @pyqtSlot(int)
  853. def slot_doubleClickedListHost(self, row):
  854. app = self.listHost.item(row, 1).text()
  855. if self.m_ladish_only:
  856. self.addAppToLADISH(app)
  857. else:
  858. self.startApp(app)
  859. @pyqtSlot(int)
  860. def slot_doubleClickedListInstrument(self, row):
  861. app = self.listInstrument.item(row, 1).text()
  862. if self.m_ladish_only:
  863. self.addAppToLADISH(app)
  864. else:
  865. self.startApp(app)
  866. @pyqtSlot(int)
  867. def slot_doubleClickedListBristol(self, row):
  868. app = self.listBristol.item(row, 2).text()
  869. if self.m_ladish_only:
  870. self.addAppToLADISH(app)
  871. else:
  872. self.startApp(app)
  873. @pyqtSlot(int)
  874. def slot_doubleClickedListEffect(self, row):
  875. app = self.listEffect.item(row, 1).text()
  876. if self.m_ladish_only:
  877. self.addAppToLADISH(app)
  878. else:
  879. self.startApp(app)
  880. @pyqtSlot(int)
  881. def slot_doubleClickedListTool(self, row):
  882. app = self.listTool.item(row, 1).text()
  883. if self.m_ladish_only:
  884. self.addAppToLADISH(app)
  885. else:
  886. self.startApp(app)
  887. def saveSettings(self):
  888. if self.settings():
  889. self.settings().setValue("SplitterDAW", self.splitter_DAW.saveState())
  890. self.settings().setValue("SplitterHost", self.splitter_Host.saveState())
  891. self.settings().setValue("SplitterInstrument", self.splitter_Instrument.saveState())
  892. self.settings().setValue("SplitterBristol", self.splitter_Bristol.saveState())
  893. self.settings().setValue("SplitterEffect", self.splitter_Effect.saveState())
  894. self.settings().setValue("SplitterTool", self.splitter_Tool.saveState())
  895. QIcon.setThemeName(self.m_lastThemeName)
  896. def loadSettings(self):
  897. if self.settings() and self.settings().contains("SplitterDAW"):
  898. self.splitter_DAW.restoreState(self.settings().value("SplitterDAW", ""))
  899. self.splitter_Host.restoreState(self.settings().value("SplitterHost", ""))
  900. self.splitter_Instrument.restoreState(self.settings().value("SplitterInstrument", ""))
  901. self.splitter_Bristol.restoreState(self.settings().value("SplitterBristol", ""))
  902. self.splitter_Effect.restoreState(self.settings().value("SplitterEffect", ""))
  903. self.splitter_Tool.restoreState(self.settings().value("SplitterTool", ""))
  904. else: # First-Run?
  905. self.splitter_DAW.setSizes([500, 200])
  906. self.splitter_Host.setSizes([500, 200])
  907. self.splitter_Instrument.setSizes([500, 200])
  908. self.splitter_Bristol.setSizes([500, 200])
  909. self.splitter_Effect.setSizes([500, 200])
  910. self.splitter_Tool.setSizes([500, 200])
  911. # ----------------------------------------
  912. # Callbacks
  913. def callback_checkGUI(self, selected):
  914. if self.parentR():
  915. self.parentR().callback_checkGUI(selected)
  916. def callback_getProjectFolder(self):
  917. if self.parentR():
  918. return self.parentR().callback_getProjectFolder()
  919. return HOME
  920. def callback_getAppBus(self):
  921. return self.parentR().callback_getAppBus()
  922. def callback_getBPM(self):
  923. return self.parentR().callback_getBPM()
  924. def callback_getSampleRate(self):
  925. return self.parentR().callback_getSampleRate()
  926. def callback_isLadishRoom(self):
  927. return self.parentR().callback_isLadishRoom()
  928. #--------------- main ------------------
  929. if __name__ == '__main__':
  930. import dbus
  931. from signal import signal, SIG_IGN, SIGUSR1
  932. from PyQt4.QtGui import QApplication
  933. import jacklib, ui_claudia_launcher_app
  934. # DBus connections
  935. class DBus(object):
  936. __slots__ = [
  937. 'loopBus',
  938. 'controlBus',
  939. 'studioBus',
  940. 'appBus',
  941. ]
  942. DBus = DBus()
  943. class ClaudiaLauncherApp(QMainWindow, ui_claudia_launcher_app.Ui_ClaudiaLauncherApp):
  944. def __init__(self, parent=None):
  945. QMainWindow.__init__(self, parent)
  946. self.setupUi(self)
  947. self.settings = QSettings("Cadence", "Claudia-Launcher")
  948. self.launcher.setCallbackApp(self, self.settings, False)
  949. self.loadSettings()
  950. self.test_url = True
  951. self.test_selected = False
  952. self.studio_root_folder = HOME
  953. # Check for JACK
  954. self.jack_client = jacklib.client_open("klaudia", jacklib.JackNoStartServer, None)
  955. if not self.jack_client:
  956. QTimer.singleShot(0, self, SLOT("slot_showJackError()"))
  957. return
  958. # Set-up GUI
  959. self.b_start.setIcon(self.getIcon("go-next"))
  960. self.b_add.setIcon(self.getIcon("list-add"))
  961. self.b_refresh.setIcon(self.getIcon("view-refresh"))
  962. self.b_open.setIcon(self.getIcon("document-open"))
  963. self.b_start.setEnabled(False)
  964. self.b_add.setEnabled(False)
  965. self.le_url.setText(self.studio_root_folder)
  966. self.co_sample_rate.addItem(str(self.getJackSampleRate()))
  967. self.sb_bpm.setValue(self.getJackBPM())
  968. self.refreshStudioList()
  969. if DBus.controlBus:
  970. self.slot_enableLADISH(True)
  971. else:
  972. for iPATH in PATH:
  973. if os.path.exists(os.path.join(iPATH, "ladishd")):
  974. break
  975. else:
  976. self.slot_enableLADISH(False)
  977. self.connect(self.b_start, SIGNAL("clicked()"), SLOT("slot_startApp()"))
  978. self.connect(self.b_add, SIGNAL("clicked()"), SLOT("slot_addAppToLADISH()"))
  979. self.connect(self.b_refresh, SIGNAL("clicked()"), SLOT("slot_refreshStudioList()"))
  980. self.connect(self.co_ladi_room, SIGNAL("currentIndexChanged(int)"), SLOT("slot_checkSelectedRoom(int)"))
  981. self.connect(self.groupLADISH, SIGNAL("toggled(bool)"), SLOT("slot_enableLADISH(bool)"))
  982. self.connect(self.le_url, SIGNAL("textChanged(QString)"), SLOT("slot_checkFolderUrl(QString)"))
  983. self.connect(self.b_open, SIGNAL("clicked()"), SLOT("slot_getAndSetPath()"))
  984. def getIcon(self, icon):
  985. return self.launcher.getIcon(icon)
  986. def getJackBPM(self):
  987. pos = jacklib.jack_position_t()
  988. pos.valid = 0
  989. jacklib.transport_query(self.jack_client, jacklib.pointer(pos))
  990. if pos.valid & jacklib.JackPositionBBT:
  991. return pos.beats_per_minute
  992. return 120.0
  993. def getJackSampleRate(self):
  994. return jacklib.get_sample_rate(self.jack_client)
  995. def refreshStudioList(self):
  996. self.co_ladi_room.clear()
  997. self.co_ladi_room.addItem("<Studio Root>")
  998. if DBus.controlBus:
  999. studio_bus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1000. studio_list_dump = studio_bus.GetRoomList()
  1001. for i in range(len(studio_list_dump)):
  1002. self.co_ladi_room.addItem("%s - %s" % (
  1003. str(studio_list_dump[i][0]).replace("/org/ladish/Room", ""), studio_list_dump[i][1]['name']))
  1004. # ----------------------------------------
  1005. # Callbacks
  1006. def callback_checkGUI(self, test_selected=None):
  1007. if test_selected != None:
  1008. self.test_selected = test_selected
  1009. if self.test_url and self.test_selected:
  1010. self.b_add.setEnabled(bool(DBus.controlBus))
  1011. self.b_start.setEnabled(True)
  1012. else:
  1013. self.b_add.setEnabled(False)
  1014. self.b_start.setEnabled(False)
  1015. def callback_getProjectFolder(self):
  1016. return self.le_url.text()
  1017. def callback_getAppBus(self):
  1018. return DBus.appBus
  1019. def callback_getBPM(self):
  1020. return self.getJackBPM()
  1021. def callback_getSampleRate(self):
  1022. return self.getJackSampleRate()
  1023. def callback_isLadishRoom(self):
  1024. return not self.le_url.isEnabled()
  1025. # ----------------------------------------
  1026. @pyqtSlot(int)
  1027. def slot_checkSelectedRoom(self, co_n):
  1028. if co_n == -1 or not DBus.controlBus:
  1029. pass
  1030. elif co_n == 0:
  1031. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1032. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1033. self.b_open.setEnabled(True)
  1034. self.le_url.setEnabled(True)
  1035. self.le_url.setText(self.studio_root_folder)
  1036. else:
  1037. room_number = self.co_ladi_room.currentText().split(" ")[0]
  1038. room_name = "/org/ladish/Room" + room_number
  1039. DBus.studioBus = DBus.loopBus.get_object("org.ladish", room_name)
  1040. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1041. room_properties = DBus.studioBus.GetProjectProperties()
  1042. if len(room_properties[1]) > 0:
  1043. self.b_open.setEnabled(False)
  1044. self.le_url.setEnabled(False)
  1045. self.le_url.setText(room_properties[1]['dir'])
  1046. else:
  1047. self.b_open.setEnabled(True)
  1048. self.le_url.setEnabled(True)
  1049. self.studio_root_folder = self.le_url.text()
  1050. @pyqtSlot(str)
  1051. def slot_checkFolderUrl(self, url):
  1052. if os.path.exists(url):
  1053. self.test_url = True
  1054. if self.le_url.isEnabled():
  1055. self.studio_root_folder = url
  1056. else:
  1057. self.test_url = False
  1058. self.callback_checkGUI()
  1059. @pyqtSlot(bool)
  1060. def slot_enableLADISH(self, yesno):
  1061. self.groupLADISH.setCheckable(False)
  1062. if yesno:
  1063. try:
  1064. DBus.controlBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Control")
  1065. self.groupLADISH.setTitle(self.tr("LADISH is enabled"))
  1066. except:
  1067. self.groupLADISH.setEnabled(False)
  1068. self.groupLADISH.setTitle(self.tr("LADISH is sick"))
  1069. return
  1070. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1071. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1072. self.refreshStudioList()
  1073. self.callback_checkGUI()
  1074. else:
  1075. self.groupLADISH.setEnabled(False)
  1076. self.groupLADISH.setTitle(self.tr("LADISH is not available"))
  1077. @pyqtSlot()
  1078. def slot_startApp(self):
  1079. self.launcher.startApp()
  1080. @pyqtSlot()
  1081. def slot_addAppToLADISH(self):
  1082. self.launcher.addAppToLADISH()
  1083. @pyqtSlot()
  1084. def slot_getAndSetPath(self):
  1085. getAndSetPath(self, self.le_url.text(), self.le_url)
  1086. @pyqtSlot()
  1087. def slot_refreshStudioList(self):
  1088. self.refreshStudioList()
  1089. @pyqtSlot()
  1090. def slot_showJackError(self):
  1091. QMessageBox.critical(self, self.tr("Error"),
  1092. self.tr("JACK is not started!\nPlease start it first, then re-run Claudia-Launcher again."))
  1093. self.close()
  1094. def saveSettings(self):
  1095. self.settings.setValue("Geometry", self.saveGeometry())
  1096. self.launcher.saveSettings()
  1097. def loadSettings(self):
  1098. self.restoreGeometry(self.settings.value("Geometry", ""))
  1099. self.launcher.loadSettings()
  1100. def closeEvent(self, event):
  1101. self.saveSettings()
  1102. if self.jack_client:
  1103. jacklib.client_close(self.jack_client)
  1104. QMainWindow.closeEvent(self, event)
  1105. # App initialization
  1106. app = QApplication(sys.argv)
  1107. app.setApplicationName("Claudia-Launcher")
  1108. app.setApplicationVersion(VERSION)
  1109. app.setOrganizationName("Cadence")
  1110. app.setWindowIcon(QIcon(":/scalable/claudia-launcher.svg"))
  1111. # Do not close on SIGUSR1
  1112. signal(SIGUSR1, SIG_IGN)
  1113. # Connect to DBus
  1114. DBus.loopBus = dbus.SessionBus()
  1115. if "org.ladish" in DBus.loopBus.list_names():
  1116. DBus.controlBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Control")
  1117. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1118. DBus.appBus = dbus.Interface(DBus.studioBus, "org.ladish.AppSupervisor")
  1119. else:
  1120. DBus.controlBus = None
  1121. DBus.studioBus = None
  1122. DBus.appBus = None
  1123. # Show GUI
  1124. gui = ClaudiaLauncherApp()
  1125. gui.show()
  1126. # App-Loop
  1127. sys.exit(app.exec_())