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.

1446 lines
59KB

  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 == "calfjackhost":
  320. tmplte_file = os.path.join(proj_folder, "CalfJackHost_%i" % rand_check)
  321. # Create template
  322. os.system("cp '%s' '%s'" % (os.path.join(tmplte_dir, "CalfJackHost"), tmplte_file))
  323. tmplte_cmd = binary
  324. tmplte_cmd += " --load '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  325. tmplte_lvl = "1"
  326. #elif (app == "jack-mixer"):
  327. #tmplte_file_r = os.path.join(proj_folder, "Jack-Mixer_%i.xml" % (rand_check))
  328. ## Create template
  329. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jack-Mixer.xml"), tmplte_file_r))
  330. #tmplte_cmd = binary
  331. #tmplte_cmd += " -c '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  332. #tmplte_lvl = "1"
  333. #elif (app == "jack-rack"):
  334. #tmplte_file = os.path.join(proj_folder, "Jack-Rack_%i.xml" % (rand_check))
  335. ## Create template
  336. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jack-Rack.xml"), tmplte_file))
  337. #tmplte_cmd = binary
  338. #tmplte_cmd += " -s '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  339. #elif (app == "jamin"):
  340. #tmplte_file_r = os.path.join(proj_folder, "Jamin_%i.jam" % (rand_check))
  341. ## Create template
  342. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Jamin.jam"), tmplte_file_r))
  343. #tmplte_cmd = binary
  344. #tmplte_cmd += " -f '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  345. #elif (app == "non-daw"):
  346. #tmplte_folder = os.path.join(proj_folder, "Non-DAW_%i" % (rand_check))
  347. ## Create template
  348. #os.system("cp -r '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Non-DAW"), tmplte_folder))
  349. #os.mkdir(os.path.join(tmplte_folder, "sources"))
  350. #os.system('sed -i "s/X_SR_X-KLAUDIA-X_SR_X/%s/" "%s"' % (proj_srate, os.path.join(tmplte_folder, "info")))
  351. #os.system('sed -i "s/X_BPM_X-KLAUDIA-X_BPM_X/%s/" "%s"' % (proj_bpm, os.path.join(tmplte_folder, "history")))
  352. #tmplte_cmd = binary
  353. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  354. #elif (app == "non-mixer"):
  355. #tmplte_folder = os.path.join(proj_folder, "Non-Mixer_%i" % (rand_check))
  356. ## Create template
  357. #os.system("cp -r '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Non-Mixer"), tmplte_folder))
  358. #tmplte_cmd = binary
  359. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_folder) if self.callback_isLadishRoom() else tmplte_folder)
  360. #elif (app == "non-sequencer"):
  361. #tmplte_file_r = os.path.join(proj_folder, "Non-Sequencer_%i.non" % (rand_check))
  362. ## Create template
  363. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Non-Sequencer.non"), tmplte_file_r))
  364. #tmplte_cmd = binary
  365. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  366. #elif (app == "qsampler"):
  367. #tmplte_file_r = os.path.join(proj_folder, "Qsampler_%i.lscp" % (rand_check))
  368. ## Create template
  369. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Qsampler.lscp"), tmplte_file_r))
  370. #tmplte_cmd = binary
  371. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  372. #tmplte_lvl = "1" if (app_name == "Qsampler (SVN)") else "0"
  373. #elif (app == "qtractor"):
  374. #tmplte_file = os.path.join(proj_folder, "Qtractor_%i.qtr" % (rand_check))
  375. ## Create template
  376. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Qtractor.qtr"), tmplte_file))
  377. #tmplte_cmd = binary
  378. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  379. #tmplte_lvl = "1"
  380. #elif (app == "renoise"):
  381. #tmplte_file_r = os.path.join(proj_folder, "Renoise_%i.xrns" % (rand_check))
  382. #tmplte_folder = os.path.join(proj_folder, "tmp_renoise_%i" % (rand_check))
  383. ## Create template
  384. #os.mkdir(tmplte_folder)
  385. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Renoise.xml"), tmplte_folder))
  386. #os.system('sed -i "s/X_SR_X-KLAUDIA-X_SR_X/%s/" "%s"' % (proj_srate, os.path.join(tmplte_folder, "Renoise.xml")))
  387. #os.system("cd '%s' && mv Renoise.xml Song.xml && zip '%s' Song.xml" % (tmplte_folder, tmplte_file_r))
  388. #os.system("rm -rf '%s'" % (tmplte_folder))
  389. #tmplte_cmd = binary
  390. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  391. #elif (app == "rosegarden"):
  392. #tmplte_file = os.path.join(proj_folder, "Rosegarden_%i.rg" % (rand_check))
  393. ## Create template
  394. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Rosegarden.rg"), tmplte_file))
  395. #tmplte_cmd = binary
  396. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  397. #tmplte_lvl = "1"
  398. #elif (app == "seq24"):
  399. #tmplte_file_r = os.path.join(proj_folder, "Seq24_%i.midi" % (rand_check))
  400. ## Create template
  401. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Seq24.midi"), tmplte_file_r))
  402. #tmplte_cmd = binary
  403. #tmplte_cmd += " '%s'" % (os.path.basename(tmplte_file_r) if self.callback_isLadishRoom() else tmplte_file_r)
  404. #tmplte_lvl = "1"
  405. #elif (app == "yoshimi"):
  406. #tmplte_file = os.path.join(proj_folder, "Yoshimi_%i.state" % (rand_check))
  407. ## Create template
  408. #os.system("cp '%s' '%s'" % (os.path.join(sys.path[0], "..", "templates", "Yoshimi.state"), tmplte_file))
  409. #tmplte_cmd = binary
  410. #tmplte_cmd += " --state='%s'" % (os.path.basename(tmplte_file) if self.callback_isLadishRoom() else tmplte_file)
  411. #tmplte_lvl = "1"
  412. #else:
  413. #print("ERROR: Failed to parse app name")
  414. #return
  415. if tmplte_file != None:
  416. os.system('sed -i "s/X_SR_X-CLAUDIA-X_SR_X/%s/" "%s"' % (proj_srate, tmplte_file))
  417. os.system('sed -i "s/X_BPM_X-CLAUDIA-X_BPM_X/%s/" "%s"' % (proj_bpm, tmplte_file))
  418. os.system('sed -i "s/X_FOLDER_X-CLAUDIA-X_FOLDER_X/%s/" "%s"' % (
  419. proj_folder.replace("/", "\/").replace("$", "\$"), tmplte_file))
  420. appBus = self.callback_getAppBus()
  421. appBus.RunCustom2(False, tmplte_cmd, app_name, tmplte_lvl)
  422. def parentR(self):
  423. return self._parent
  424. def settings(self):
  425. return self._settings
  426. def getIcon(self, icon):
  427. return self.ClaudiaIcons.getIcon(icon)
  428. def getIconForYesNo(self, yesno):
  429. return self.icon_yes if yesno else self.icon_no
  430. def setCallbackApp(self, parent, settings, ladish_only):
  431. self._parent = parent
  432. self._settings = settings
  433. self.m_ladish_only = ladish_only
  434. def clearInfo_DAW(self):
  435. self.ico_app_daw.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  436. self.label_name_daw.setText("App Name")
  437. self.ico_ladspa_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  438. self.ico_dssi_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  439. self.ico_lv2_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  440. self.ico_vst_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  441. self.label_vst_mode_daw.setText("")
  442. self.ico_jack_transport_daw.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  443. self.label_midi_mode_daw.setText("---")
  444. self.label_session_level_daw.setText(database.LEVEL_0)
  445. self.frame_DAW.setEnabled(False)
  446. self.showDoc_DAW("", "")
  447. def clearInfo_Host(self):
  448. self.ico_app_host.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  449. self.label_name_host.setText("App Name")
  450. self.ico_ladspa_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  451. self.ico_dssi_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  452. self.ico_lv2_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  453. self.ico_vst_host.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  454. self.label_vst_mode_host.setText("")
  455. self.label_midi_mode_host.setText("---")
  456. self.label_session_level_host.setText(database.LEVEL_0)
  457. self.frame_Host.setEnabled(False)
  458. self.showDoc_Host("", "")
  459. def clearInfo_Intrument(self):
  460. self.ico_app_ins.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  461. self.label_name_ins.setText("App Name")
  462. self.ico_builtin_fx_ins.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  463. self.ico_audio_input_ins.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  464. self.label_midi_mode_ins.setText("---")
  465. self.label_session_level_ins.setText(database.LEVEL_0)
  466. self.frame_Instrument.setEnabled(False)
  467. self.showDoc_Instrument("", "")
  468. def clearInfo_Bristol(self):
  469. self.ico_app_bristol.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  470. self.label_name_bristol.setText("App Name")
  471. self.ico_builtin_fx_bristol.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  472. self.ico_audio_input_bristol.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  473. self.label_midi_mode_bristol.setText("---")
  474. self.label_session_level_bristol.setText(database.LEVEL_0)
  475. self.frame_Bristol.setEnabled(False)
  476. self.showDoc_Bristol("", "")
  477. def clearInfo_Effect(self):
  478. self.ico_app_effect.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  479. self.label_name_effect.setText("App Name")
  480. self.ico_stereo_effect.setPixmap(self.getIconForYesNo(False).pixmap(16, 16))
  481. self.label_midi_mode_effect.setText("---")
  482. self.label_session_level_effect.setText(database.LEVEL_0)
  483. self.frame_Effect.setEnabled(False)
  484. self.showDoc_Effect("", "")
  485. def clearInfo_Tool(self):
  486. self.ico_app_tool.setPixmap(self.getIcon("start-here").pixmap(48, 48))
  487. self.label_name_tool.setText("App Name")
  488. self.label_midi_mode_tool.setText("---")
  489. self.label_session_level_tool.setText(database.LEVEL_0)
  490. self.frame_Tool.setEnabled(False)
  491. self.showDoc_Tool("", "")
  492. def showDoc_DAW(self, doc, web):
  493. self.url_documentation_daw.setVisible(bool(doc))
  494. self.url_website_daw.setVisible(bool(web))
  495. self.label_no_help_daw.setVisible(not(doc or web))
  496. if doc: self.setDocUrl(self.url_documentation_daw, doc)
  497. if web: self.setWebUrl(self.url_website_daw, web)
  498. def showDoc_Host(self, doc, web):
  499. self.url_documentation_host.setVisible(bool(doc))
  500. self.url_website_host.setVisible(bool(web))
  501. self.label_no_help_host.setVisible(not(doc or web))
  502. if doc: self.setDocUrl(self.url_documentation_host, doc)
  503. if web: self.setWebUrl(self.url_website_host, web)
  504. def showDoc_Instrument(self, doc, web):
  505. self.url_documentation_ins.setVisible(bool(doc))
  506. self.url_website_ins.setVisible(bool(web))
  507. self.label_no_help_ins.setVisible(not(doc or web))
  508. if doc: self.setDocUrl(self.url_documentation_ins, doc)
  509. if web: self.setWebUrl(self.url_website_ins, web)
  510. def showDoc_Bristol(self, doc, web):
  511. self.url_documentation_bristol.setVisible(bool(doc))
  512. self.url_website_bristol.setVisible(bool(web))
  513. self.label_no_help_bristol.setVisible(not(doc or web))
  514. if doc: self.setDocUrl(self.url_documentation_bristol, doc)
  515. if web: self.setWebUrl(self.url_website_bristol, web)
  516. def showDoc_Effect(self, doc, web):
  517. self.url_documentation_effect.setVisible(bool(doc))
  518. self.url_website_effect.setVisible(bool(web))
  519. self.label_no_help_effect.setVisible(not(doc or web))
  520. if doc: self.setDocUrl(self.url_documentation_effect, doc)
  521. if web: self.setWebUrl(self.url_website_effect, web)
  522. def showDoc_Tool(self, doc, web):
  523. self.url_documentation_tool.setVisible(bool(doc))
  524. self.url_website_tool.setVisible(bool(web))
  525. self.label_no_help_tool.setVisible(not(doc or web))
  526. if doc: self.setDocUrl(self.url_documentation_tool, doc)
  527. if web: self.setWebUrl(self.url_website_tool, web)
  528. def setDocUrl(self, item, link):
  529. item.setText(self.tr("<a href='%s'>Documentation</a>" % link))
  530. def setWebUrl(self, item, link):
  531. item.setText(self.tr("<a href='%s'>WebSite</a>" % link))
  532. def clearAll(self):
  533. self.listDAW.clearContents()
  534. self.listHost.clearContents()
  535. self.listInstrument.clearContents()
  536. self.listBristol.clearContents()
  537. self.listEffect.clearContents()
  538. self.listTool.clearContents()
  539. for x in range(self.listDAW.rowCount()):
  540. self.listDAW.removeRow(0)
  541. for x in range(self.listHost.rowCount()):
  542. self.listHost.removeRow(0)
  543. for x in range(self.listInstrument.rowCount()):
  544. self.listInstrument.removeRow(0)
  545. for x in range(self.listBristol.rowCount()):
  546. self.listBristol.removeRow(0)
  547. for x in range(self.listEffect.rowCount()):
  548. self.listEffect.removeRow(0)
  549. for x in range(self.listTool.rowCount()):
  550. self.listTool.removeRow(0)
  551. def refreshAll(self):
  552. self.clearAll()
  553. pkglist = []
  554. if not SHOW_ALL:
  555. if os.path.exists("/usr/bin/yaourt"):
  556. pkg_out = getoutput("/usr/bin/yaourt -Qsq").split("\n")
  557. for package in pkg_out:
  558. pkglist.append(package)
  559. elif os.path.exists("/usr/bin/pacman"):
  560. pkg_out = getoutput("/usr/bin/pacman -Qsq").split("\n")
  561. for package in pkg_out:
  562. pkglist.append(package)
  563. elif os.path.exists("/usr/bin/dpkg-query"):
  564. pkg_out = getoutput("/usr/bin/dpkg-query -W --showformat='${Package}\n'").split("\n")
  565. for package in pkg_out:
  566. pkglist.append(package)
  567. if not "bristol" in pkglist:
  568. self.tabWidget.setTabEnabled(TAB_INDEX_BRISTOL, False)
  569. last_pos = 0
  570. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_DAW:
  571. if SHOW_ALL or Package in pkglist:
  572. w_icon = QTableWidgetItem("")
  573. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  574. w_name = QTableWidgetItem(AppName)
  575. w_type = QTableWidgetItem(Type)
  576. w_save = QTableWidgetItem(Save)
  577. w_licc = QTableWidgetItem(License)
  578. self.listDAW.insertRow(last_pos)
  579. self.listDAW.setItem(last_pos, 0, w_icon)
  580. self.listDAW.setItem(last_pos, 1, w_name)
  581. self.listDAW.setItem(last_pos, 2, w_type)
  582. self.listDAW.setItem(last_pos, 3, w_save)
  583. self.listDAW.setItem(last_pos, 4, w_licc)
  584. last_pos += 1
  585. last_pos = 0
  586. for Package, AppName, Instruments, Effects, Binary, Icon, Save, Level, License, Features, Docs in database.list_Host:
  587. if SHOW_ALL or Package in pkglist:
  588. w_icon = QTableWidgetItem("")
  589. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  590. w_name = QTableWidgetItem(AppName)
  591. w_h_in = QTableWidgetItem(Instruments)
  592. w_h_ef = QTableWidgetItem(Effects)
  593. w_save = QTableWidgetItem(Save)
  594. w_licc = QTableWidgetItem(License)
  595. self.listHost.insertRow(last_pos)
  596. self.listHost.setItem(last_pos, 0, w_icon)
  597. self.listHost.setItem(last_pos, 1, w_name)
  598. self.listHost.setItem(last_pos, 2, w_h_in)
  599. self.listHost.setItem(last_pos, 3, w_h_ef)
  600. self.listHost.setItem(last_pos, 4, w_save)
  601. self.listHost.setItem(last_pos, 5, w_licc)
  602. last_pos += 1
  603. last_pos = 0
  604. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Instrument:
  605. if SHOW_ALL or Package in pkglist:
  606. w_icon = QTableWidgetItem("")
  607. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  608. w_name = QTableWidgetItem(AppName)
  609. w_type = QTableWidgetItem(Type)
  610. w_save = QTableWidgetItem(Save)
  611. w_licc = QTableWidgetItem(License)
  612. self.listInstrument.insertRow(last_pos)
  613. self.listInstrument.setItem(last_pos, 0, w_icon)
  614. self.listInstrument.setItem(last_pos, 1, w_name)
  615. self.listInstrument.setItem(last_pos, 2, w_type)
  616. self.listInstrument.setItem(last_pos, 3, w_save)
  617. self.listInstrument.setItem(last_pos, 4, w_licc)
  618. last_pos += 1
  619. last_pos = 0
  620. for Package, FullName, Type, ShortName, Icon, Save, Level, License, Features, Docs in database.list_Bristol:
  621. if SHOW_ALL or Package in pkglist:
  622. w_icon = QTableWidgetItem("")
  623. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  624. w_fullname = QTableWidgetItem(FullName)
  625. w_shortname = QTableWidgetItem(ShortName)
  626. self.listBristol.insertRow(last_pos)
  627. self.listBristol.setItem(last_pos, 0, w_icon)
  628. self.listBristol.setItem(last_pos, 1, w_shortname)
  629. self.listBristol.setItem(last_pos, 2, w_fullname)
  630. last_pos += 1
  631. last_pos = 0
  632. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Effect:
  633. if SHOW_ALL or Package in pkglist:
  634. w_icon = QTableWidgetItem("")
  635. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  636. w_name = QTableWidgetItem(AppName)
  637. w_type = QTableWidgetItem(Type)
  638. w_save = QTableWidgetItem(Save)
  639. w_licc = QTableWidgetItem(License)
  640. self.listEffect.insertRow(last_pos)
  641. self.listEffect.setItem(last_pos, 0, w_icon)
  642. self.listEffect.setItem(last_pos, 1, w_name)
  643. self.listEffect.setItem(last_pos, 2, w_type)
  644. self.listEffect.setItem(last_pos, 3, w_save)
  645. self.listEffect.setItem(last_pos, 4, w_licc)
  646. last_pos += 1
  647. last_pos = 0
  648. for Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs in database.list_Tool:
  649. if SHOW_ALL or Package in pkglist:
  650. w_icon = QTableWidgetItem("")
  651. w_icon.setIcon(QIcon(self.getIcon(Icon)))
  652. w_name = QTableWidgetItem(AppName)
  653. w_type = QTableWidgetItem(Type)
  654. w_save = QTableWidgetItem(Save)
  655. w_licc = QTableWidgetItem(License)
  656. self.listTool.insertRow(last_pos)
  657. self.listTool.setItem(last_pos, 0, w_icon)
  658. self.listTool.setItem(last_pos, 1, w_name)
  659. self.listTool.setItem(last_pos, 2, w_type)
  660. self.listTool.setItem(last_pos, 3, w_save)
  661. self.listTool.setItem(last_pos, 4, w_licc)
  662. last_pos += 1
  663. self.listDAW.setCurrentCell(-1, -1)
  664. self.listHost.setCurrentCell(-1, -1)
  665. self.listInstrument.setCurrentCell(-1, -1)
  666. self.listBristol.setCurrentCell(-1, -1)
  667. self.listEffect.setCurrentCell(-1, -1)
  668. self.listTool.setCurrentCell(-1, -1)
  669. self.listDAW.sortByColumn(1, Qt.AscendingOrder)
  670. self.listHost.sortByColumn(1, Qt.AscendingOrder)
  671. self.listInstrument.sortByColumn(1, Qt.AscendingOrder)
  672. self.listBristol.sortByColumn(2, Qt.AscendingOrder)
  673. self.listEffect.sortByColumn(1, Qt.AscendingOrder)
  674. self.listTool.sortByColumn(1, Qt.AscendingOrder)
  675. @pyqtSlot(int)
  676. def slot_checkSelectedTab(self, tab_index):
  677. if tab_index == TAB_INDEX_DAW:
  678. test_selected = (len(self.listDAW.selectedItems()) > 0)
  679. elif tab_index == TAB_INDEX_HOST:
  680. test_selected = (len(self.listHost.selectedItems()) > 0)
  681. elif tab_index == TAB_INDEX_INSTRUMENT:
  682. test_selected = (len(self.listInstrument.selectedItems()) > 0)
  683. elif tab_index == TAB_INDEX_BRISTOL:
  684. test_selected = (len(self.listBristol.selectedItems()) > 0)
  685. elif tab_index == TAB_INDEX_EFFECT:
  686. test_selected = (len(self.listEffect.selectedItems()) > 0)
  687. elif tab_index == TAB_INDEX_TOOL:
  688. test_selected = (len(self.listTool.selectedItems()) > 0)
  689. else:
  690. test_selected = False
  691. self.callback_checkGUI(test_selected)
  692. @pyqtSlot(int)
  693. def slot_checkSelectedDAW(self, row):
  694. if row >= 0:
  695. selected = True
  696. app_name = self.listDAW.item(row, 1).text()
  697. for DAW in database.list_DAW:
  698. if DAW[1] == app_name:
  699. app_info = DAW
  700. break
  701. else:
  702. print("ERROR: Failed to retrieve app info from database")
  703. return
  704. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  705. self.frame_DAW.setEnabled(True)
  706. self.ico_app_daw.setPixmap(QIcon(self.getIcon(Icon)).pixmap(48, 48))
  707. self.ico_ladspa_daw.setPixmap(QIcon(self.getIconForYesNo(Features[0])).pixmap(16, 16))
  708. self.ico_dssi_daw.setPixmap(QIcon(self.getIconForYesNo(Features[1])).pixmap(16, 16))
  709. self.ico_lv2_daw.setPixmap(QIcon(self.getIconForYesNo(Features[2])).pixmap(16, 16))
  710. self.ico_vst_daw.setPixmap(QIcon(self.getIconForYesNo(Features[3])).pixmap(16, 16))
  711. self.ico_jack_transport_daw.setPixmap(QIcon(self.getIconForYesNo(Features[5])).pixmap(16, 16))
  712. self.label_name_daw.setText(AppName)
  713. self.label_vst_mode_daw.setText(Features[4])
  714. self.ico_midi_mode_daw.setPixmap(QIcon(self.getIconForYesNo(Features[6])).pixmap(16, 16))
  715. self.label_midi_mode_daw.setText(Features[7])
  716. self.label_session_level_daw.setText(Level)
  717. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  718. self.showDoc_DAW(Docs0, Docs[1])
  719. else:
  720. selected = False
  721. self.clearInfo_DAW()
  722. self.callback_checkGUI(selected)
  723. @pyqtSlot(int)
  724. def slot_checkSelectedHost(self, row):
  725. if row >= 0:
  726. selected = True
  727. app_name = self.listHost.item(row, 1).text()
  728. for Host in database.list_Host:
  729. if Host[1] == app_name:
  730. app_info = Host
  731. break
  732. else:
  733. print("ERROR: Failed to retrieve app info from database")
  734. return
  735. Package, AppName, Instruments, Effects, Binary, Icon, Save, Level, License, Features, Docs = app_info
  736. self.frame_Host.setEnabled(True)
  737. self.ico_app_host.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  738. self.ico_internal_host.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  739. self.ico_ladspa_host.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  740. self.ico_dssi_host.setPixmap(self.getIconForYesNo(Features[2]).pixmap(16, 16))
  741. self.ico_lv2_host.setPixmap(self.getIconForYesNo(Features[3]).pixmap(16, 16))
  742. self.ico_vst_host.setPixmap(self.getIconForYesNo(Features[4]).pixmap(16, 16))
  743. self.label_name_host.setText(AppName)
  744. self.label_vst_mode_host.setText(Features[5])
  745. self.label_midi_mode_host.setText(Features[6])
  746. self.label_session_level_host.setText(str(Level))
  747. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  748. self.showDoc_Host(Docs0, Docs[1])
  749. else:
  750. selected = False
  751. self.clearInfo_DAW()
  752. self.callback_checkGUI(selected)
  753. @pyqtSlot(int)
  754. def slot_checkSelectedInstrument(self, row):
  755. if row >= 0:
  756. selected = True
  757. app_name = self.listInstrument.item(row, 1).text()
  758. for Instrument in database.list_Instrument:
  759. if Instrument[1] == app_name:
  760. app_info = Instrument
  761. break
  762. else:
  763. print("ERROR: Failed to retrieve app info from database")
  764. return
  765. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  766. self.frame_Instrument.setEnabled(True)
  767. self.ico_app_ins.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  768. self.ico_builtin_fx_ins.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  769. self.ico_audio_input_ins.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  770. self.label_name_ins.setText(AppName)
  771. self.label_midi_mode_ins.setText(Features[2])
  772. self.label_session_level_ins.setText(str(Level))
  773. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  774. self.showDoc_Instrument(Docs0, Docs[1])
  775. else:
  776. selected = False
  777. self.clearInfo_Intrument()
  778. self.callback_checkGUI(selected)
  779. @pyqtSlot(int)
  780. def slot_checkSelectedBristol(self, row):
  781. if row >= 0:
  782. selected = True
  783. app_name = self.listBristol.item(row, 2).text()
  784. for Bristol in database.list_Bristol:
  785. if Bristol[1] == app_name:
  786. app_info = Bristol
  787. break
  788. else:
  789. print("ERROR: Failed to retrieve app info from database")
  790. return
  791. Package, AppName, Type, ShortName, Icon, Save, Level, License, Features, Docs = app_info
  792. self.frame_Bristol.setEnabled(True)
  793. self.ico_app_bristol.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  794. self.ico_builtin_fx_bristol.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  795. self.ico_audio_input_bristol.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  796. self.label_name_bristol.setText(AppName)
  797. self.label_midi_mode_bristol.setText(Features[2])
  798. self.label_session_level_bristol.setText(str(Level))
  799. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  800. self.showDoc_Bristol(Docs0, Docs[1])
  801. else:
  802. selected = False
  803. self.clearInfo_Bristol()
  804. self.callback_checkGUI(selected)
  805. @pyqtSlot(int)
  806. def slot_checkSelectedEffect(self, row):
  807. if row >= 0:
  808. selected = True
  809. app_name = self.listEffect.item(row, 1).text()
  810. for Effect in database.list_Effect:
  811. if Effect[1] == app_name:
  812. app_info = Effect
  813. break
  814. else:
  815. print("ERROR: Failed to retrieve app info from database")
  816. return
  817. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  818. self.frame_Effect.setEnabled(True)
  819. self.ico_app_effect.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  820. self.ico_stereo_effect.setPixmap(self.getIconForYesNo(Features[0]).pixmap(16, 16))
  821. self.label_name_effect.setText(AppName)
  822. self.label_midi_mode_effect.setText(Features[1])
  823. self.label_session_level_effect.setText(str(Level))
  824. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  825. self.showDoc_Effect(Docs0, Docs[1])
  826. else:
  827. selected = False
  828. self.clearInfo_Effect()
  829. self.callback_checkGUI(selected)
  830. @pyqtSlot(int)
  831. def slot_checkSelectedTool(self, row):
  832. if row >= 0:
  833. selected = True
  834. app_name = self.listTool.item(row, 1).text()
  835. for Tool in database.list_Tool:
  836. if Tool[1] == app_name:
  837. app_info = Tool
  838. break
  839. else:
  840. print("ERROR: Failed to retrieve app info from database")
  841. return
  842. Package, AppName, Type, Binary, Icon, Save, Level, License, Features, Docs = app_info
  843. self.frame_Tool.setEnabled(True)
  844. self.ico_app_tool.setPixmap(self.getIcon(Icon).pixmap(48, 48))
  845. self.label_name_tool.setText(AppName)
  846. self.label_midi_mode_tool.setText(Features[0])
  847. self.ico_jack_transport_tool.setPixmap(self.getIconForYesNo(Features[1]).pixmap(16, 16))
  848. self.label_session_level_tool.setText(str(Level))
  849. Docs0 = Docs[0] if (os.path.exists(Docs[0].replace("file://", ""))) else ""
  850. self.showDoc_Tool(Docs0, Docs[1])
  851. else:
  852. selected = False
  853. self.clearInfo_Tool()
  854. self.callback_checkGUI(selected)
  855. @pyqtSlot(int)
  856. def slot_doubleClickedListDAW(self, row):
  857. app = self.listDAW.item(row, 1).text()
  858. if self.m_ladish_only:
  859. self.addAppToLADISH(app)
  860. else:
  861. self.startApp(app)
  862. @pyqtSlot(int)
  863. def slot_doubleClickedListHost(self, row):
  864. app = self.listHost.item(row, 1).text()
  865. if self.m_ladish_only:
  866. self.addAppToLADISH(app)
  867. else:
  868. self.startApp(app)
  869. @pyqtSlot(int)
  870. def slot_doubleClickedListInstrument(self, row):
  871. app = self.listInstrument.item(row, 1).text()
  872. if self.m_ladish_only:
  873. self.addAppToLADISH(app)
  874. else:
  875. self.startApp(app)
  876. @pyqtSlot(int)
  877. def slot_doubleClickedListBristol(self, row):
  878. app = self.listBristol.item(row, 2).text()
  879. if self.m_ladish_only:
  880. self.addAppToLADISH(app)
  881. else:
  882. self.startApp(app)
  883. @pyqtSlot(int)
  884. def slot_doubleClickedListEffect(self, row):
  885. app = self.listEffect.item(row, 1).text()
  886. if self.m_ladish_only:
  887. self.addAppToLADISH(app)
  888. else:
  889. self.startApp(app)
  890. @pyqtSlot(int)
  891. def slot_doubleClickedListTool(self, row):
  892. app = self.listTool.item(row, 1).text()
  893. if self.m_ladish_only:
  894. self.addAppToLADISH(app)
  895. else:
  896. self.startApp(app)
  897. def saveSettings(self):
  898. if self.settings():
  899. self.settings().setValue("SplitterDAW", self.splitter_DAW.saveState())
  900. self.settings().setValue("SplitterHost", self.splitter_Host.saveState())
  901. self.settings().setValue("SplitterInstrument", self.splitter_Instrument.saveState())
  902. self.settings().setValue("SplitterBristol", self.splitter_Bristol.saveState())
  903. self.settings().setValue("SplitterEffect", self.splitter_Effect.saveState())
  904. self.settings().setValue("SplitterTool", self.splitter_Tool.saveState())
  905. QIcon.setThemeName(self.m_lastThemeName)
  906. def loadSettings(self):
  907. if self.settings() and self.settings().contains("SplitterDAW"):
  908. self.splitter_DAW.restoreState(self.settings().value("SplitterDAW", ""))
  909. self.splitter_Host.restoreState(self.settings().value("SplitterHost", ""))
  910. self.splitter_Instrument.restoreState(self.settings().value("SplitterInstrument", ""))
  911. self.splitter_Bristol.restoreState(self.settings().value("SplitterBristol", ""))
  912. self.splitter_Effect.restoreState(self.settings().value("SplitterEffect", ""))
  913. self.splitter_Tool.restoreState(self.settings().value("SplitterTool", ""))
  914. else: # First-Run?
  915. self.splitter_DAW.setSizes([500, 200])
  916. self.splitter_Host.setSizes([500, 200])
  917. self.splitter_Instrument.setSizes([500, 200])
  918. self.splitter_Bristol.setSizes([500, 200])
  919. self.splitter_Effect.setSizes([500, 200])
  920. self.splitter_Tool.setSizes([500, 200])
  921. # ----------------------------------------
  922. # Callbacks
  923. def callback_checkGUI(self, selected):
  924. if self.parentR():
  925. self.parentR().callback_checkGUI(selected)
  926. def callback_getProjectFolder(self):
  927. if self.parentR():
  928. return self.parentR().callback_getProjectFolder()
  929. return HOME
  930. def callback_getAppBus(self):
  931. return self.parentR().callback_getAppBus()
  932. def callback_getBPM(self):
  933. return self.parentR().callback_getBPM()
  934. def callback_getSampleRate(self):
  935. return self.parentR().callback_getSampleRate()
  936. def callback_isLadishRoom(self):
  937. return self.parentR().callback_isLadishRoom()
  938. #--------------- main ------------------
  939. if __name__ == '__main__':
  940. import dbus
  941. from signal import signal, SIG_IGN, SIGUSR1
  942. from PyQt4.QtGui import QApplication
  943. import jacklib, ui_claudia_launcher_app
  944. # DBus connections
  945. class DBus(object):
  946. __slots__ = [
  947. 'loopBus',
  948. 'controlBus',
  949. 'studioBus',
  950. 'appBus',
  951. ]
  952. DBus = DBus()
  953. class ClaudiaLauncherApp(QMainWindow, ui_claudia_launcher_app.Ui_ClaudiaLauncherApp):
  954. def __init__(self, parent=None):
  955. QMainWindow.__init__(self, parent)
  956. self.setupUi(self)
  957. self.settings = QSettings("Cadence", "Claudia-Launcher")
  958. self.launcher.setCallbackApp(self, self.settings, False)
  959. self.loadSettings()
  960. self.test_url = True
  961. self.test_selected = False
  962. self.studio_root_folder = HOME
  963. # Check for JACK
  964. self.jack_client = jacklib.client_open("klaudia", jacklib.JackNoStartServer, None)
  965. if not self.jack_client:
  966. QTimer.singleShot(0, self, SLOT("slot_showJackError()"))
  967. return
  968. # Set-up GUI
  969. self.b_start.setIcon(self.getIcon("go-next"))
  970. self.b_add.setIcon(self.getIcon("list-add"))
  971. self.b_refresh.setIcon(self.getIcon("view-refresh"))
  972. self.b_open.setIcon(self.getIcon("document-open"))
  973. self.b_start.setEnabled(False)
  974. self.b_add.setEnabled(False)
  975. self.le_url.setText(self.studio_root_folder)
  976. self.co_sample_rate.addItem(str(self.getJackSampleRate()))
  977. self.sb_bpm.setValue(self.getJackBPM())
  978. self.refreshStudioList()
  979. if DBus.controlBus:
  980. self.slot_enableLADISH(True)
  981. else:
  982. for iPATH in PATH:
  983. if os.path.exists(os.path.join(iPATH, "ladishd")):
  984. break
  985. else:
  986. self.slot_enableLADISH(False)
  987. self.connect(self.b_start, SIGNAL("clicked()"), SLOT("slot_startApp()"))
  988. self.connect(self.b_add, SIGNAL("clicked()"), SLOT("slot_addAppToLADISH()"))
  989. self.connect(self.b_refresh, SIGNAL("clicked()"), SLOT("slot_refreshStudioList()"))
  990. self.connect(self.co_ladi_room, SIGNAL("currentIndexChanged(int)"), SLOT("slot_checkSelectedRoom(int)"))
  991. self.connect(self.groupLADISH, SIGNAL("toggled(bool)"), SLOT("slot_enableLADISH(bool)"))
  992. self.connect(self.le_url, SIGNAL("textChanged(QString)"), SLOT("slot_checkFolderUrl(QString)"))
  993. self.connect(self.b_open, SIGNAL("clicked()"), SLOT("slot_getAndSetPath()"))
  994. def getIcon(self, icon):
  995. return self.launcher.getIcon(icon)
  996. def getJackBPM(self):
  997. pos = jacklib.jack_position_t()
  998. pos.valid = 0
  999. jacklib.transport_query(self.jack_client, jacklib.pointer(pos))
  1000. if pos.valid & jacklib.JackPositionBBT:
  1001. return pos.beats_per_minute
  1002. return 120.0
  1003. def getJackSampleRate(self):
  1004. return jacklib.get_sample_rate(self.jack_client)
  1005. def refreshStudioList(self):
  1006. self.co_ladi_room.clear()
  1007. self.co_ladi_room.addItem("<Studio Root>")
  1008. if DBus.controlBus:
  1009. studio_bus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1010. studio_list_dump = studio_bus.GetRoomList()
  1011. for i in range(len(studio_list_dump)):
  1012. self.co_ladi_room.addItem("%s - %s" % (
  1013. str(studio_list_dump[i][0]).replace("/org/ladish/Room", ""), studio_list_dump[i][1]['name']))
  1014. # ----------------------------------------
  1015. # Callbacks
  1016. def callback_checkGUI(self, test_selected=None):
  1017. if test_selected != None:
  1018. self.test_selected = test_selected
  1019. if self.test_url and self.test_selected:
  1020. self.b_add.setEnabled(bool(DBus.controlBus))
  1021. self.b_start.setEnabled(True)
  1022. else:
  1023. self.b_add.setEnabled(False)
  1024. self.b_start.setEnabled(False)
  1025. def callback_getProjectFolder(self):
  1026. return self.le_url.text()
  1027. def callback_getAppBus(self):
  1028. return DBus.appBus
  1029. def callback_getBPM(self):
  1030. return self.getJackBPM()
  1031. def callback_getSampleRate(self):
  1032. return self.getJackSampleRate()
  1033. def callback_isLadishRoom(self):
  1034. return not self.le_url.isEnabled()
  1035. # ----------------------------------------
  1036. @pyqtSlot(int)
  1037. def slot_checkSelectedRoom(self, co_n):
  1038. if co_n == -1 or not DBus.controlBus:
  1039. pass
  1040. elif co_n == 0:
  1041. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1042. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1043. self.b_open.setEnabled(True)
  1044. self.le_url.setEnabled(True)
  1045. self.le_url.setText(self.studio_root_folder)
  1046. else:
  1047. room_number = self.co_ladi_room.currentText().split(" ")[0]
  1048. room_name = "/org/ladish/Room" + room_number
  1049. DBus.studioBus = DBus.loopBus.get_object("org.ladish", room_name)
  1050. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1051. room_properties = DBus.studioBus.GetProjectProperties()
  1052. if len(room_properties[1]) > 0:
  1053. self.b_open.setEnabled(False)
  1054. self.le_url.setEnabled(False)
  1055. self.le_url.setText(room_properties[1]['dir'])
  1056. else:
  1057. self.b_open.setEnabled(True)
  1058. self.le_url.setEnabled(True)
  1059. self.studio_root_folder = self.le_url.text()
  1060. @pyqtSlot(str)
  1061. def slot_checkFolderUrl(self, url):
  1062. if os.path.exists(url):
  1063. self.test_url = True
  1064. if self.le_url.isEnabled():
  1065. self.studio_root_folder = url
  1066. else:
  1067. self.test_url = False
  1068. self.callback_checkGUI()
  1069. @pyqtSlot(bool)
  1070. def slot_enableLADISH(self, yesno):
  1071. self.groupLADISH.setCheckable(False)
  1072. if yesno:
  1073. try:
  1074. DBus.controlBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Control")
  1075. self.groupLADISH.setTitle(self.tr("LADISH is enabled"))
  1076. except:
  1077. self.groupLADISH.setEnabled(False)
  1078. self.groupLADISH.setTitle(self.tr("LADISH is sick"))
  1079. return
  1080. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1081. DBus.appBus = dbus.Interface(DBus.studioBus, 'org.ladish.AppSupervisor')
  1082. self.refreshStudioList()
  1083. self.callback_checkGUI()
  1084. else:
  1085. self.groupLADISH.setEnabled(False)
  1086. self.groupLADISH.setTitle(self.tr("LADISH is not available"))
  1087. @pyqtSlot()
  1088. def slot_startApp(self):
  1089. self.launcher.startApp()
  1090. @pyqtSlot()
  1091. def slot_addAppToLADISH(self):
  1092. self.launcher.addAppToLADISH()
  1093. @pyqtSlot()
  1094. def slot_getAndSetPath(self):
  1095. getAndSetPath(self, self.le_url.text(), self.le_url)
  1096. @pyqtSlot()
  1097. def slot_refreshStudioList(self):
  1098. self.refreshStudioList()
  1099. @pyqtSlot()
  1100. def slot_showJackError(self):
  1101. QMessageBox.critical(self, self.tr("Error"),
  1102. self.tr("JACK is not started!\nPlease start it first, then re-run Claudia-Launcher again."))
  1103. self.close()
  1104. def saveSettings(self):
  1105. self.settings.setValue("Geometry", self.saveGeometry())
  1106. self.launcher.saveSettings()
  1107. def loadSettings(self):
  1108. self.restoreGeometry(self.settings.value("Geometry", ""))
  1109. self.launcher.loadSettings()
  1110. def closeEvent(self, event):
  1111. self.saveSettings()
  1112. if self.jack_client:
  1113. jacklib.client_close(self.jack_client)
  1114. QMainWindow.closeEvent(self, event)
  1115. # App initialization
  1116. app = QApplication(sys.argv)
  1117. app.setApplicationName("Claudia-Launcher")
  1118. app.setApplicationVersion(VERSION)
  1119. app.setOrganizationName("Cadence")
  1120. app.setWindowIcon(QIcon(":/scalable/claudia-launcher.svg"))
  1121. # Do not close on SIGUSR1
  1122. signal(SIGUSR1, SIG_IGN)
  1123. # Connect to DBus
  1124. DBus.loopBus = dbus.SessionBus()
  1125. if "org.ladish" in DBus.loopBus.list_names():
  1126. DBus.controlBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Control")
  1127. DBus.studioBus = DBus.loopBus.get_object("org.ladish", "/org/ladish/Studio")
  1128. DBus.appBus = dbus.Interface(DBus.studioBus, "org.ladish.AppSupervisor")
  1129. else:
  1130. DBus.controlBus = None
  1131. DBus.studioBus = None
  1132. DBus.appBus = None
  1133. # Show GUI
  1134. gui = ClaudiaLauncherApp()
  1135. gui.show()
  1136. # App-Loop
  1137. sys.exit(app.exec_())