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.

2589 lines
106KB

  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. # LADISH frontend
  4. # Copyright (C) 2010-2012 Filipe Coelho <falktx@falktx.com>
  5. #
  6. # This program is free software; you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation; either version 2 of the License, or
  9. # any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # For a full copy of the GNU General Public License see the COPYING file
  17. # ------------------------------------------------------------------------------------------------------------
  18. # Imports (Global)
  19. from time import ctime
  20. from PyQt4.QtCore import QPointF
  21. from PyQt4.QtGui import QAction, QApplication, QVBoxLayout, QTableWidgetItem, QTreeWidgetItem
  22. # ------------------------------------------------------------------------------------------------------------
  23. # Imports (Custom Stuff)
  24. import claudia_launcher, systray
  25. import ui_claudia
  26. import ui_claudia_studioname, ui_claudia_studiolist
  27. import ui_claudia_createroom, ui_claudia_projectname, ui_claudia_projectproperties
  28. import ui_claudia_runcustom
  29. from shared_jack import *
  30. from shared_canvas import *
  31. from shared_settings import *
  32. # ------------------------------------------------------------------------------------------------------------
  33. # Try Import DBus
  34. try:
  35. import dbus
  36. from dbus.mainloop.qt import DBusQtMainLoop
  37. haveDBus = True
  38. except:
  39. haveDBus = False
  40. # ------------------------------------------------------------------------------------------------------------
  41. # Try Import OpenGL
  42. try:
  43. from PyQt4.QtOpenGL import QGLWidget
  44. hasGL = True
  45. except:
  46. hasGL = False
  47. # ------------------------------------------------------------------------------------------------------------
  48. # Static Variables
  49. # NOTE - set to true when supported
  50. USE_CLAUDIA_ADD_NEW = True
  51. # internal indexes
  52. iConnId = 0
  53. iConnOutput = 1
  54. iConnInput = 2
  55. iAppCommand = 0
  56. iAppName = 1
  57. iAppTerminal = 2
  58. iAppLevel = 3
  59. iAppActive = 4
  60. iAppPropName = 0
  61. iAppPropDescription = 1
  62. iAppPropNotes = 2
  63. iAppPropSaveNow = 3
  64. iItemPropNumber = 0
  65. iItemPropName = 1
  66. iItemPropActive = 2
  67. iItemPropTerminal = 3
  68. iItemPropLevel = 4
  69. iItemPropRoomPath = 0
  70. iItemPropRoomName = 1
  71. # jackdbus indexes
  72. iGraphVersion = 0
  73. iJackClientId = 1
  74. iJackClientName = 2
  75. iJackPortId = 3
  76. iJackPortName = 4
  77. iJackPortNewName = 5
  78. iJackPortFlags = 5
  79. iJackPortType = 6
  80. iRenamedId = 1
  81. iRenamedOldName = 2
  82. iRenamedNewName = 3
  83. iSourceClientId = 1
  84. iSourceClientName = 2
  85. iSourcePortId = 3
  86. iSourcePortName = 4
  87. iTargetClientId = 5
  88. iTargetClientName = 6
  89. iTargetPortId = 7
  90. iTargetPortName = 8
  91. iJackConnId = 9
  92. # ladish indexes
  93. iStudioListName = 0
  94. iStudioListDict = 1
  95. iStudioRenamedName = 0
  96. iRoomAppearedPath = 0
  97. iRoomAppearedDict = 1
  98. iProjChangedId = 0
  99. iProjChangedDict = 1
  100. iAppChangedNumber = 1
  101. iAppChangedName = 2
  102. iAppChangedActive = 3
  103. iAppChangedTerminal = 4
  104. iAppChangedLevel = 5
  105. # internal defines
  106. ITEM_TYPE_NULL = 0
  107. ITEM_TYPE_STUDIO = 1
  108. ITEM_TYPE_STUDIO_APP = 2
  109. ITEM_TYPE_ROOM = 3
  110. ITEM_TYPE_ROOM_APP = 4
  111. # C defines
  112. JACKDBUS_PORT_FLAG_INPUT = 0x00000001
  113. JACKDBUS_PORT_FLAG_OUTPUT = 0x00000002
  114. JACKDBUS_PORT_FLAG_PHYSICAL = 0x00000004
  115. JACKDBUS_PORT_FLAG_CAN_MONITOR = 0x00000008
  116. JACKDBUS_PORT_FLAG_TERMINAL = 0x00000010
  117. JACKDBUS_PORT_TYPE_AUDIO = 0
  118. JACKDBUS_PORT_TYPE_MIDI = 1
  119. GRAPH_DICT_OBJECT_TYPE_GRAPH = 0
  120. GRAPH_DICT_OBJECT_TYPE_CLIENT = 1
  121. GRAPH_DICT_OBJECT_TYPE_PORT = 2
  122. GRAPH_DICT_OBJECT_TYPE_CONNECTION = 3
  123. URI_A2J_PORT = "http://ladish.org/ns/a2j"
  124. URI_CANVAS_WIDTH = "http://ladish.org/ns/canvas/width"
  125. URI_CANVAS_HEIGHT = "http://ladish.org/ns/canvas/height"
  126. URI_CANVAS_X = "http://ladish.org/ns/canvas/x"
  127. URI_CANVAS_Y = "http://ladish.org/ns/canvas/y"
  128. URI_CANVAS_SPLIT = "http://kxstudio.sourceforge.net/ns/canvas/split"
  129. URI_CANVAS_X_SPLIT = "http://kxstudio.sourceforge.net/ns/canvas/x_split"
  130. URI_CANVAS_Y_SPLIT = "http://kxstudio.sourceforge.net/ns/canvas/y_split"
  131. DEFAULT_CANVAS_WIDTH = 3100
  132. DEFAULT_CANVAS_HEIGHT = 2400
  133. RECENT_PROJECTS_STORE_MAX_ITEMS = 50
  134. # ------------------------------------------------------------------------------------------------------------
  135. # Set default project folder
  136. DEFAULT_PROJECT_FOLDER = os.path.join(HOME, "ladish-projects")
  137. setDefaultProjectFolder(DEFAULT_PROJECT_FOLDER)
  138. # ------------------------------------------------------------------------------------------------------------
  139. # Studio Name Dialog
  140. class StudioNameW(QDialog, ui_claudia_studioname.Ui_StudioNameW):
  141. NEW = 1
  142. RENAME = 2
  143. SAVE_AS = 3
  144. def __init__(self, parent, mode):
  145. QDialog.__init__(self, parent)
  146. self.setupUi(self)
  147. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  148. if mode == self.NEW:
  149. self.setWindowTitle(self.tr("New studio"))
  150. elif mode == self.RENAME:
  151. self.setWindowTitle(self.tr("Rename studio"))
  152. elif mode == self.SAVE_AS:
  153. self.setWindowTitle(self.tr("Save studio as"))
  154. self.m_mode = mode
  155. self.m_studio_list = []
  156. if mode == self.RENAME and bool(DBus.ladish_control.IsStudioLoaded()):
  157. current_name = str(DBus.ladish_studio.GetName())
  158. self.m_studio_list.append(current_name)
  159. self.le_name.setText(current_name)
  160. studio_list = DBus.ladish_control.GetStudioList()
  161. for studio in studio_list:
  162. self.m_studio_list.append(str(studio[iStudioListName]))
  163. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  164. self.connect(self.le_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText(QString)"))
  165. self.ret_studio_name = ""
  166. @pyqtSlot(str)
  167. def slot_checkText(self, text):
  168. if self.m_mode == self.SAVE_AS:
  169. check = bool(text)
  170. else:
  171. check = bool(text and text not in self.m_studio_list)
  172. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  173. @pyqtSlot()
  174. def slot_setReturn(self):
  175. self.ret_studio_name = self.le_name.text()
  176. def done(self, r):
  177. QDialog.done(self, r)
  178. self.close()
  179. # Studio List Dialog
  180. class StudioListW(QDialog, ui_claudia_studiolist.Ui_StudioListW):
  181. def __init__(self, parent):
  182. QDialog.__init__(self, parent)
  183. self.setupUi(self)
  184. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  185. self.tableWidget.setColumnWidth(0, 125)
  186. index = 0
  187. studio_list = DBus.ladish_control.GetStudioList()
  188. for studio in studio_list:
  189. name = str(studio[iStudioListName])
  190. date = ctime(float(studio[iStudioListDict]["Modification Time"]))
  191. w_name = QTableWidgetItem(name)
  192. w_date = QTableWidgetItem(date)
  193. self.tableWidget.insertRow(index)
  194. self.tableWidget.setItem(index, 0, w_name)
  195. self.tableWidget.setItem(index, 1, w_date)
  196. index += 1
  197. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  198. self.connect(self.tableWidget, SIGNAL("cellDoubleClicked(int, int)"), SLOT("accept()"))
  199. self.connect(self.tableWidget, SIGNAL("currentCellChanged(int, int, int, int)"), SLOT("slot_checkSelection(int)"))
  200. if self.tableWidget.rowCount() > 0:
  201. self.tableWidget.setCurrentCell(0, 0)
  202. self.ret_studio_name = ""
  203. @pyqtSlot(int)
  204. def slot_checkSelection(self, row):
  205. check = bool(row >= 0)
  206. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  207. @pyqtSlot()
  208. def slot_setReturn(self):
  209. if self.tableWidget.rowCount() >= 0:
  210. self.ret_studio_name = self.tableWidget.item(self.tableWidget.currentRow(), 0).text()
  211. def done(self, r):
  212. QDialog.done(self, r)
  213. self.close()
  214. # Create Room Dialog
  215. class CreateRoomW(QDialog, ui_claudia_createroom.Ui_CreateRoomW):
  216. def __init__(self, parent):
  217. QDialog.__init__(self, parent)
  218. self.setupUi(self)
  219. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  220. templates_list = DBus.ladish_control.GetRoomTemplateList()
  221. for template_name, template_dict in templates_list:
  222. self.lw_templates.addItem(template_name)
  223. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  224. self.connect(self.le_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText(QString)"))
  225. if self.lw_templates.count() > 0:
  226. self.lw_templates.setCurrentRow(0)
  227. self.ret_room_name = ""
  228. self.ret_room_template = ""
  229. @pyqtSlot(str)
  230. def slot_checkText(self, text):
  231. check = bool(text and self.lw_templates.currentRow() >= 0)
  232. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  233. @pyqtSlot()
  234. def slot_setReturn(self):
  235. if self.lw_templates.count() > 0:
  236. self.ret_room_name = self.le_name.text()
  237. self.ret_room_template = self.lw_templates.currentItem().text()
  238. def done(self, r):
  239. QDialog.done(self, r)
  240. self.close()
  241. # Project Name Dialog
  242. class ProjectNameW(QDialog, ui_claudia_projectname.Ui_ProjectNameW):
  243. NEW = 1
  244. SAVE_AS = 2
  245. def __init__(self, parent, mode, proj_folder, path="", name=""):
  246. QDialog.__init__(self, parent)
  247. self.setupUi(self)
  248. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  249. if mode == self.NEW:
  250. self.setWindowTitle(self.tr("New project"))
  251. elif mode == self.SAVE_AS:
  252. self.setWindowTitle(self.tr("Save project as"))
  253. self.le_path.setText(path)
  254. self.le_name.setText(name)
  255. self.checkText(path, name)
  256. self.m_proj_folder = proj_folder
  257. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  258. self.connect(self.b_open, SIGNAL("clicked()"), SLOT("slot_checkFolder()"))
  259. self.connect(self.le_path, SIGNAL("textChanged(QString)"), SLOT("slot_checkText_path(QString)"))
  260. self.connect(self.le_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText_name(QString)"))
  261. self.ret_project_name = ""
  262. self.ret_project_path = ""
  263. def checkText(self, name, path):
  264. check = bool(name and path and os.path.exists(path) and os.path.isdir(path))
  265. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  266. @pyqtSlot()
  267. def slot_checkFolder(self):
  268. # Create default project folder if the project has not been set yet
  269. if not self.le_path.text():
  270. if not os.path.exists(self.m_proj_folder):
  271. os.mkdir(self.m_proj_folder)
  272. if self.le_path.text():
  273. proj_path = self.le_path.text()
  274. else:
  275. proj_path = self.m_proj_folder
  276. getAndSetPath(self, proj_path, self.le_path)
  277. @pyqtSlot(str)
  278. def slot_checkText_name(self, text):
  279. self.checkText(text, self.le_path.text())
  280. @pyqtSlot(str)
  281. def slot_checkText_path(self, text):
  282. self.checkText(self.le_name.text(), text)
  283. @pyqtSlot()
  284. def slot_setReturn(self):
  285. self.ret_project_name = self.le_name.text()
  286. self.ret_project_path = self.le_path.text()
  287. def done(self, r):
  288. QDialog.done(self, r)
  289. self.close()
  290. # Project Properties Dialog
  291. class ProjectPropertiesW(QDialog, ui_claudia_projectproperties.Ui_ProjectPropertiesW):
  292. def __init__(self, parent, name, description, notes):
  293. QDialog.__init__(self, parent)
  294. self.setupUi(self)
  295. self.m_default_name = name
  296. self.m_last_name = name
  297. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  298. self.connect(self.le_name, SIGNAL("textChanged(QString)"), SLOT("slot_checkText_name(QString)"))
  299. self.connect(self.cb_save_now, SIGNAL("clicked(bool)"), SLOT("slot_checkSaveNow(bool)"))
  300. self.le_name.setText(name)
  301. self.le_description.setText(description)
  302. self.le_notes.setPlainText(notes)
  303. self.ret_obj = None
  304. @pyqtSlot()
  305. def slot_setReturn(self):
  306. self.ret_obj = [None, None, None, None]
  307. self.ret_obj[iAppPropName] = self.le_name.text()
  308. self.ret_obj[iAppPropDescription] = self.le_description.text()
  309. self.ret_obj[iAppPropNotes] = self.le_notes.toPlainText() # plainText()
  310. self.ret_obj[iAppPropSaveNow] = self.cb_save_now.isChecked()
  311. @pyqtSlot(bool)
  312. def slot_checkSaveNow(self, save):
  313. if save:
  314. self.le_name.setText(self.m_last_name)
  315. else:
  316. self.m_last_name = self.le_name.text()
  317. self.le_name.setText(self.m_default_name)
  318. @pyqtSlot(str)
  319. def slot_checkText_name(self, text):
  320. check = bool(text)
  321. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  322. def done(self, r):
  323. QDialog.done(self, r)
  324. self.close()
  325. # Run Custom App Dialog
  326. class RunCustomW(QDialog, ui_claudia_runcustom.Ui_RunCustomW):
  327. def __init__(self, parent, isRoom, app_obj=None):
  328. QDialog.__init__(self, parent)
  329. self.setupUi(self)
  330. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(bool(app_obj))
  331. if app_obj:
  332. self.le_command.setText(app_obj[iAppCommand])
  333. self.le_name.setText(app_obj[iAppName])
  334. self.cb_terminal.setChecked(app_obj[iAppTerminal])
  335. level = app_obj[iAppLevel]
  336. if level == "0":
  337. self.rb_level_0.setChecked(True)
  338. elif level == "1":
  339. self.rb_level_1.setChecked(True)
  340. elif level == "lash":
  341. self.rb_level_lash.setChecked(True)
  342. elif level == "jacksession":
  343. self.rb_level_js.setChecked(True)
  344. else:
  345. self.rb_level_0.setChecked(True)
  346. if app_obj[iAppActive]:
  347. self.le_command.setEnabled(False)
  348. self.cb_terminal.setEnabled(False)
  349. self.rb_level_0.setEnabled(False)
  350. self.rb_level_1.setEnabled(False)
  351. self.rb_level_lash.setEnabled(False)
  352. self.rb_level_js.setEnabled(False)
  353. else:
  354. self.rb_level_0.setChecked(True)
  355. if not isRoom:
  356. self.rb_level_lash.setEnabled(False)
  357. self.rb_level_js.setEnabled(False)
  358. self.connect(self, SIGNAL("accepted()"), SLOT("slot_setReturn()"))
  359. self.connect(self.le_command, SIGNAL("textChanged(QString)"), SLOT("slot_checkText(QString)"))
  360. self.ret_app_obj = None
  361. @pyqtSlot(str)
  362. def slot_checkText(self, text):
  363. check = bool(text)
  364. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
  365. @pyqtSlot()
  366. def slot_setReturn(self):
  367. if self.rb_level_0.isChecked():
  368. level = "0"
  369. elif self.rb_level_1.isChecked():
  370. level = "1"
  371. elif self.rb_level_lash.isChecked():
  372. level = "lash"
  373. elif self.rb_level_js.isChecked():
  374. level = "jacksession"
  375. else:
  376. return
  377. self.ret_app_obj = [None, None, None, None, None]
  378. self.ret_app_obj[iAppCommand] = self.le_command.text()
  379. self.ret_app_obj[iAppName] = self.le_name.text()
  380. self.ret_app_obj[iAppTerminal] = self.cb_terminal.isChecked()
  381. self.ret_app_obj[iAppLevel] = level
  382. self.ret_app_obj[iAppActive] = False
  383. def done(self, r):
  384. QDialog.done(self, r)
  385. self.close()
  386. # Add Application Dialog
  387. class ClaudiaLauncherW(QDialog):
  388. def __init__(self, parent, appBus, proj_folder, is_room, bpm, sample_rate):
  389. QDialog.__init__(self, parent)
  390. self.launcher = claudia_launcher.ClaudiaLauncher(self)
  391. self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Close, Qt.Horizontal, self)
  392. self.layoutR = QVBoxLayout(self)
  393. self.layoutR.addWidget(self.launcher)
  394. self.layoutR.addWidget(self.buttonBox)
  395. self.settings = QSettings("Cadence", "Claudia-Launcher")
  396. self.launcher.setCallbackApp(self, self.settings, True)
  397. self.loadSettings()
  398. self.m_appBus = appBus
  399. self.m_proj_folder = proj_folder
  400. self.m_is_room = is_room
  401. self.m_bpm = bpm
  402. self.m_sampleRate = sample_rate
  403. self.test_url = True
  404. self.test_selected = False
  405. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  406. self.connect(self.buttonBox.button(QDialogButtonBox.Ok), SIGNAL("clicked()"), SLOT("slot_addAppToLADISH()"))
  407. self.connect(self.buttonBox.button(QDialogButtonBox.Close), SIGNAL("clicked()"), self, SLOT("reject()"))
  408. # ----------------------------------------
  409. # Callbacks
  410. def callback_checkGUI(self, test_selected=None):
  411. if test_selected != None:
  412. self.test_selected = test_selected
  413. if self.test_url and self.test_selected:
  414. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(True)
  415. else:
  416. self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
  417. def callback_getProjectFolder(self):
  418. return self.m_proj_folder
  419. def callback_getAppBus(self):
  420. return self.m_appBus
  421. def callback_getBPM(self):
  422. if self.m_bpm < 30:
  423. return 120.0
  424. else:
  425. return self.m_bpm
  426. def callback_getSampleRate(self):
  427. return self.m_sampleRate
  428. def callback_isLadishRoom(self):
  429. return self.m_is_room
  430. # ----------------------------------------
  431. @pyqtSlot()
  432. def slot_addAppToLADISH(self):
  433. self.launcher.addAppToLADISH()
  434. def saveSettings(self):
  435. self.settings.setValue("Geometry", self.saveGeometry())
  436. self.launcher.saveSettings()
  437. def loadSettings(self):
  438. self.restoreGeometry(self.settings.value("Geometry", ""))
  439. self.launcher.loadSettings()
  440. def closeEvent(self, event):
  441. self.saveSettings()
  442. QDialog.closeEvent(self, event)
  443. def done(self, r):
  444. QDialog.done(self, r)
  445. self.close()
  446. # ------------------------------------------------------------------------------------------------------------
  447. # Claudia Main Window
  448. class ClaudiaMainW(AbstractJackW, ui_claudia.Ui_ClaudiaMainW):
  449. def __init__(self, parent=None):
  450. AbstractJackW.__init__(self, parent, "Claudia")
  451. self.setupUi(self)
  452. self.m_lastItemType = None
  453. self.m_lastRoomPath = None
  454. self.m_crashedJACK = False
  455. self.m_crashedLADISH = False
  456. self.loadSettings(True)
  457. # -------------------------------------------------------------
  458. # Set-up GUI
  459. setIcons(self, ["canvas", "jack", "transport"])
  460. self.act_studio_new.setIcon(getIcon("document-new"))
  461. self.menu_studio_load.setIcon(getIcon("document-open"))
  462. self.act_studio_start.setIcon(getIcon("media-playback-start"))
  463. self.act_studio_stop.setIcon(getIcon("media-playback-stop"))
  464. self.act_studio_rename.setIcon(getIcon("edit-rename"))
  465. self.act_studio_save.setIcon(getIcon("document-save"))
  466. self.act_studio_save_as.setIcon(getIcon("document-save-as"))
  467. self.act_studio_unload.setIcon(getIcon("window-close"))
  468. self.menu_studio_delete.setIcon(getIcon("edit-delete"))
  469. self.b_studio_new.setIcon(getIcon("document-new"))
  470. self.b_studio_load.setIcon(getIcon("document-open"))
  471. self.b_studio_save.setIcon(getIcon("document-save"))
  472. self.b_studio_save_as.setIcon(getIcon("document-save-as"))
  473. self.act_room_create.setIcon(getIcon("list-add"))
  474. self.menu_room_delete.setIcon(getIcon("edit-delete"))
  475. self.act_project_new.setIcon(getIcon("document-new"))
  476. self.menu_project_load.setIcon(getIcon("document-open"))
  477. self.act_project_save.setIcon(getIcon("document-save"))
  478. self.act_project_save_as.setIcon(getIcon("document-save-as"))
  479. self.act_project_unload.setIcon(getIcon("window-close"))
  480. self.act_project_properties.setIcon(getIcon("edit-rename"))
  481. self.b_project_new.setIcon(getIcon("document-new"))
  482. self.b_project_load.setIcon(getIcon("document-open"))
  483. self.b_project_save.setIcon(getIcon("document-save"))
  484. self.b_project_save_as.setIcon(getIcon("document-save-as"))
  485. self.act_app_add_new.setIcon(getIcon("list-add"))
  486. self.act_app_run_custom.setIcon(getIcon("system-run"))
  487. self.act_tools_reactivate_ladishd.setIcon(getIcon("view-refresh"))
  488. self.act_quit.setIcon(getIcon("application-exit"))
  489. self.act_settings_configure.setIcon(getIcon("configure"))
  490. self.cb_buffer_size.clear()
  491. self.cb_sample_rate.clear()
  492. for buffer_size in BUFFER_SIZE_LIST:
  493. self.cb_buffer_size.addItem(str(buffer_size))
  494. for sample_rate in SAMPLE_RATE_LIST:
  495. self.cb_sample_rate.addItem(str(sample_rate))
  496. # -------------------------------------------------------------
  497. # Set-up Systray
  498. if self.m_savedSettings["Main/UseSystemTray"]:
  499. self.systray = systray.GlobalSysTray(self, "Claudia", "claudia")
  500. self.systray.addAction("studio_new", self.tr("New Studio..."))
  501. self.systray.addSeparator("sep1")
  502. self.systray.addAction("studio_start", self.tr("Start Studio"))
  503. self.systray.addAction("studio_stop", self.tr("Stop Studio"))
  504. self.systray.addSeparator("sep2")
  505. self.systray.addAction("studio_save", self.tr("Save Studio"))
  506. self.systray.addAction("studio_save_as", self.tr("Save Studio As..."))
  507. self.systray.addAction("studio_rename", self.tr("Rename Studio..."))
  508. self.systray.addAction("studio_unload", self.tr("Unload Studio"))
  509. self.systray.addSeparator("sep3")
  510. self.systray.addMenu("tools", self.tr("Tools"))
  511. self.systray.addMenuAction("tools", "tools_configure_jack", self.tr("Configure JACK"))
  512. self.systray.addMenuAction("tools", "tools_render", self.tr("JACK Render"))
  513. self.systray.addMenuAction("tools", "tools_logs", self.tr("Logs"))
  514. self.systray.addMenuSeparator("tools", "tools_sep")
  515. self.systray.addMenuAction("tools", "tools_clear_xruns", self.tr("Clear Xruns"))
  516. self.systray.addAction("configure", self.tr("Configure Claudia"))
  517. self.systray.setActionIcon("studio_new", "document-new")
  518. self.systray.setActionIcon("studio_start", "media-playback-start")
  519. self.systray.setActionIcon("studio_stop", "media-playback-stop")
  520. self.systray.setActionIcon("studio_save", "document-save")
  521. self.systray.setActionIcon("studio_save_as", "document-save-as")
  522. self.systray.setActionIcon("studio_rename", "edit-rename")
  523. self.systray.setActionIcon("studio_unload", "dialog-close")
  524. self.systray.setActionIcon("tools_configure_jack", "configure")
  525. self.systray.setActionIcon("tools_render", "media-record")
  526. self.systray.setActionIcon("tools_clear_xruns", "edit-clear")
  527. self.systray.setActionIcon("configure", "configure")
  528. self.systray.connect("studio_new", self.slot_studio_new)
  529. self.systray.connect("studio_start", self.slot_studio_start)
  530. self.systray.connect("studio_stop", self.slot_studio_stop)
  531. self.systray.connect("studio_save", self.slot_studio_save)
  532. self.systray.connect("studio_save_as", self.slot_studio_save_as)
  533. self.systray.connect("studio_rename", self.slot_studio_rename)
  534. self.systray.connect("studio_unload", self.slot_studio_unload)
  535. self.systray.connect("tools_configure_jack", self.slot_showJackSettings)
  536. self.systray.connect("tools_render", self.slot_showRender)
  537. self.systray.connect("tools_logs", self.slot_showLogs)
  538. self.systray.connect("tools_clear_xruns", self.slot_JackClearXruns)
  539. self.systray.connect("configure", self.slot_configureClaudia)
  540. self.systray.setToolTip("LADISH Frontend")
  541. self.systray.show()
  542. else:
  543. self.systray = None
  544. # -------------------------------------------------------------
  545. # Set-up Canvas
  546. self.scene = patchcanvas.PatchScene(self, self.graphicsView)
  547. self.graphicsView.setScene(self.scene)
  548. self.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.m_savedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL))
  549. if self.m_savedSettings["Canvas/UseOpenGL"] and hasGL:
  550. self.graphicsView.setViewport(QGLWidget(self.graphicsView))
  551. self.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.m_savedSettings["Canvas/HighQualityAntialiasing"])
  552. pOptions = patchcanvas.options_t()
  553. pOptions.theme_name = self.m_savedSettings["Canvas/Theme"]
  554. pOptions.auto_hide_groups = self.m_savedSettings["Canvas/AutoHideGroups"]
  555. pOptions.use_bezier_lines = self.m_savedSettings["Canvas/UseBezierLines"]
  556. pOptions.antialiasing = self.m_savedSettings["Canvas/Antialiasing"]
  557. pOptions.eyecandy = self.m_savedSettings["Canvas/EyeCandy"]
  558. pFeatures = patchcanvas.features_t()
  559. pFeatures.group_info = False
  560. pFeatures.group_rename = True
  561. pFeatures.port_info = True
  562. pFeatures.port_rename = True
  563. pFeatures.handle_group_pos = False
  564. patchcanvas.setOptions(pOptions)
  565. patchcanvas.setFeatures(pFeatures)
  566. patchcanvas.init("Claudia", self.scene, self.canvasCallback, DEBUG)
  567. patchcanvas.setCanvasSize(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
  568. patchcanvas.setInitialPos(DEFAULT_CANVAS_WIDTH / 2, DEFAULT_CANVAS_HEIGHT / 2)
  569. self.graphicsView.setSceneRect(0, 0, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
  570. # -------------------------------------------------------------
  571. # Set-up Canvas Preview
  572. self.miniCanvasPreview.setRealParent(self)
  573. self.miniCanvasPreview.setViewTheme(patchcanvas.canvas.theme.rubberband_brush, patchcanvas.canvas.theme.rubberband_pen.color())
  574. self.miniCanvasPreview.init(self.scene, DEFAULT_CANVAS_WIDTH, DEFAULT_CANVAS_HEIGHT)
  575. QTimer.singleShot(100, self, SLOT("slot_miniCanvasInit()"))
  576. # -------------------------------------------------------------
  577. # Check DBus
  578. if DBus.jack.IsStarted():
  579. self.jackStarted()
  580. else:
  581. self.jackStopped()
  582. if DBus.ladish_control.IsStudioLoaded():
  583. self.studioLoaded()
  584. if DBus.ladish_studio.IsStarted():
  585. self.studioStarted()
  586. self.init_ports()
  587. else:
  588. self.studioStopped()
  589. else:
  590. self.studioUnloaded()
  591. # -------------------------------------------------------------
  592. # Set-up Timers
  593. self.m_timer120 = self.startTimer(self.m_savedSettings["Main/RefreshInterval"])
  594. self.m_timer600 = self.startTimer(self.m_savedSettings["Main/RefreshInterval"] * 5)
  595. # -------------------------------------------------------------
  596. # Set-up Connections
  597. setCanvasConnections(self)
  598. setJackConnections(self, ["jack", "transport", "misc"])
  599. self.connect(self.act_studio_new, SIGNAL("triggered()"), SLOT("slot_studio_new()"))
  600. self.connect(self.act_studio_start, SIGNAL("triggered()"), SLOT("slot_studio_start()"))
  601. self.connect(self.act_studio_stop, SIGNAL("triggered()"), SLOT("slot_studio_stop()"))
  602. self.connect(self.act_studio_save, SIGNAL("triggered()"), SLOT("slot_studio_save()"))
  603. self.connect(self.act_studio_save_as, SIGNAL("triggered()"), SLOT("slot_studio_save_as()"))
  604. self.connect(self.act_studio_rename, SIGNAL("triggered()"), SLOT("slot_studio_rename()"))
  605. self.connect(self.act_studio_unload, SIGNAL("triggered()"), SLOT("slot_studio_unload()"))
  606. self.connect(self.b_studio_new, SIGNAL("clicked()"), SLOT("slot_studio_new()"))
  607. self.connect(self.b_studio_load, SIGNAL("clicked()"), SLOT("slot_studio_load_b()"))
  608. self.connect(self.b_studio_save, SIGNAL("clicked()"), SLOT("slot_studio_save()"))
  609. self.connect(self.b_studio_save_as, SIGNAL("clicked()"), SLOT("slot_studio_save_as()"))
  610. self.connect(self.menu_studio_load, SIGNAL("aboutToShow()"), SLOT("slot_updateMenuStudioList_Load()"))
  611. self.connect(self.menu_studio_delete, SIGNAL("aboutToShow()"), SLOT("slot_updateMenuStudioList_Delete()"))
  612. self.connect(self.act_room_create, SIGNAL("triggered()"), SLOT("slot_room_create()"))
  613. self.connect(self.menu_room_delete, SIGNAL("aboutToShow()"), SLOT("slot_updateMenuRoomList()"))
  614. self.connect(self.act_project_new, SIGNAL("triggered()"), SLOT("slot_project_new()"))
  615. self.connect(self.act_project_save, SIGNAL("triggered()"), SLOT("slot_project_save()"))
  616. self.connect(self.act_project_save_as, SIGNAL("triggered()"), SLOT("slot_project_save_as()"))
  617. self.connect(self.act_project_unload, SIGNAL("triggered()"), SLOT("slot_project_unload()"))
  618. self.connect(self.act_project_properties, SIGNAL("triggered()"), SLOT("slot_project_properties()"))
  619. self.connect(self.b_project_new, SIGNAL("clicked()"), SLOT("slot_project_new()"))
  620. self.connect(self.b_project_load, SIGNAL("clicked()"), SLOT("slot_project_load()"))
  621. self.connect(self.b_project_save, SIGNAL("clicked()"), SLOT("slot_project_save()"))
  622. self.connect(self.b_project_save_as, SIGNAL("clicked()"), SLOT("slot_project_save_as()"))
  623. self.connect(self.menu_project_load, SIGNAL("aboutToShow()"), SLOT("slot_updateMenuProjectList()"))
  624. self.connect(self.act_app_add_new, SIGNAL("triggered()"), SLOT("slot_app_add_new()"))
  625. self.connect(self.act_app_run_custom, SIGNAL("triggered()"), SLOT("slot_app_run_custom()"))
  626. self.connect(self.treeWidget, SIGNAL("itemSelectionChanged()"), SLOT("slot_checkCurrentRoom()"))
  627. #self.connect(self.treeWidget, SIGNAL("itemPressed(QTreeWidgetItem*, int)"), SLOT("slot_checkCurrentRoom()"))
  628. self.connect(self.treeWidget, SIGNAL("itemDoubleClicked(QTreeWidgetItem*, int)"), SLOT("slot_doubleClickedAppList(QTreeWidgetItem*, int)"))
  629. self.connect(self.treeWidget, SIGNAL("customContextMenuRequested(QPoint)"), SLOT("slot_showAppListCustomMenu()"))
  630. self.connect(self.miniCanvasPreview, SIGNAL("miniCanvasMoved(double, double)"), SLOT("slot_miniCanvasMoved(double, double)"))
  631. self.connect(self.graphicsView.horizontalScrollBar(), SIGNAL("valueChanged(int)"), SLOT("slot_horizontalScrollBarChanged(int)"))
  632. self.connect(self.graphicsView.verticalScrollBar(), SIGNAL("valueChanged(int)"), SLOT("slot_verticalScrollBarChanged(int)"))
  633. self.connect(self.scene, SIGNAL("sceneGroupMoved(int, int, QPointF)"), SLOT("slot_canvasItemMoved(int, int, QPointF)"))
  634. self.connect(self.scene, SIGNAL("scaleChanged(double)"), SLOT("slot_canvasScaleChanged(double)"))
  635. self.connect(self.act_settings_configure, SIGNAL("triggered()"), SLOT("slot_configureClaudia()"))
  636. self.connect(self.act_help_about, SIGNAL("triggered()"), SLOT("slot_aboutClaudia()"))
  637. self.connect(self.act_help_about_qt, SIGNAL("triggered()"), app, SLOT("aboutQt()"))
  638. # org.freedesktop.DBus
  639. self.connect(self, SIGNAL("DBusCrashCallback(QString)"), SLOT("slot_DBusCrashCallback(QString)"))
  640. # org.jackaudio.JackControl
  641. self.connect(self, SIGNAL("DBusServerStartedCallback()"), SLOT("slot_DBusServerStartedCallback()"))
  642. self.connect(self, SIGNAL("DBusServerStoppedCallback()"), SLOT("slot_DBusServerStoppedCallback()"))
  643. # org.jackaudio.JackPatchbay
  644. self.connect(self, SIGNAL("DBusClientAppearedCallback(int, QString)"), SLOT("slot_DBusClientAppearedCallback(int, QString)"))
  645. self.connect(self, SIGNAL("DBusClientDisappearedCallback(int)"), SLOT("slot_DBusClientDisappearedCallback(int)"))
  646. self.connect(self, SIGNAL("DBusClientRenamedCallback(int, QString)"), SLOT("slot_DBusClientRenamedCallback(int, QString)"))
  647. self.connect(self, SIGNAL("DBusPortAppearedCallback(int, int, QString, int, int)"), SLOT("slot_DBusPortAppearedCallback(int, int, QString, int, int)"))
  648. self.connect(self, SIGNAL("DBusPortDisppearedCallback(int)"), SLOT("slot_DBusPortDisppearedCallback(int)"))
  649. self.connect(self, SIGNAL("DBusPortRenamedCallback(int, QString)"), SLOT("slot_DBusPortRenamedCallback(int, QString)"))
  650. self.connect(self, SIGNAL("DBusPortsConnectedCallback(int, int, int)"), SLOT("slot_DBusPortsConnectedCallback(int, int, int)"))
  651. self.connect(self, SIGNAL("DBusPortsDisconnectedCallback(int)"), SLOT("slot_DBusPortsDisconnectedCallback(int)"))
  652. # org.ladish.Control
  653. self.connect(self, SIGNAL("DBusStudioAppearedCallback()"), SLOT("slot_DBusStudioAppearedCallback()"))
  654. self.connect(self, SIGNAL("DBusStudioDisappearedCallback()"), SLOT("slot_DBusStudioDisappearedCallback()"))
  655. self.connect(self, SIGNAL("DBusQueueExecutionHaltedCallback()"), SLOT("slot_DBusQueueExecutionHaltedCallback()"))
  656. self.connect(self, SIGNAL("DBusCleanExitCallback()"), SLOT("slot_DBusCleanExitCallback()"))
  657. # org.ladish.Studio
  658. self.connect(self, SIGNAL("DBusStudioStartedCallback()"), SLOT("slot_DBusStudioStartedCallback()"))
  659. self.connect(self, SIGNAL("DBusStudioStoppedCallback()"), SLOT("slot_DBusStudioStoppedCallback()"))
  660. self.connect(self, SIGNAL("DBusStudioRenamedCallback(QString)"), SLOT("slot_DBusStudioRenamedCallback(QString)"))
  661. self.connect(self, SIGNAL("DBusStudioCrashedCallback()"), SLOT("slot_DBusStudioCrashedCallback()"))
  662. self.connect(self, SIGNAL("DBusRoomAppearedCallback(QString, QString)"), SLOT("slot_DBusRoomAppearedCallback(QString, QString)"))
  663. self.connect(self, SIGNAL("DBusRoomDisappearedCallback(QString)"), SLOT("slot_DBusRoomDisappearedCallback(QString)"))
  664. #self.connect(self, SIGNAL("DBusRoomChangedCallback()"), SLOT("slot_DBusRoomChangedCallback()"))
  665. # org.ladish.Room
  666. self.connect(self, SIGNAL("DBusProjectPropertiesChanged(QString, QString)"), SLOT("slot_DBusProjectPropertiesChanged(QString, QString)"))
  667. # org.ladish.AppSupervisor
  668. self.connect(self, SIGNAL("DBusAppAdded2Callback(QString, int, QString, bool, bool, QString)"), SLOT("slot_DBusAppAdded2Callback(QString, int, QString, bool, bool, QString)"))
  669. self.connect(self, SIGNAL("DBusAppRemovedCallback(QString, int)"), SLOT("slot_DBusAppRemovedCallback(QString, int)"))
  670. self.connect(self, SIGNAL("DBusAppStateChanged2Callback(QString, int, QString, bool, bool, QString)"), SLOT("slot_DBusAppStateChanged2Callback(QString, int, QString, bool, bool, QString)"))
  671. # JACK
  672. self.connect(self, SIGNAL("JackBufferSizeCallback(int)"), SLOT("slot_JackBufferSizeCallback(int)"))
  673. self.connect(self, SIGNAL("JackSampleRateCallback(int)"), SLOT("slot_JackSampleRateCallback(int)"))
  674. self.connect(self, SIGNAL("JackShutdownCallback()"), SLOT("slot_JackShutdownCallback()"))
  675. # -------------------------------------------------------------
  676. # Set-up DBus
  677. DBus.bus.add_signal_receiver(self.DBusSignalReceiver, destination_keyword='dest', path_keyword='path',
  678. member_keyword='member', interface_keyword='interface', sender_keyword='sender', )
  679. # -------------------------------------------------------------
  680. def canvasCallback(self, action, value1, value2, value_str):
  681. if action == patchcanvas.ACTION_GROUP_INFO:
  682. pass
  683. elif action == patchcanvas.ACTION_GROUP_RENAME:
  684. group_id = value1
  685. group_name = value_str
  686. DBus.ladish_manager.RenameClient(group_id, group_name)
  687. elif action == patchcanvas.ACTION_GROUP_SPLIT:
  688. group_id = value1
  689. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_SPLIT, "true")
  690. patchcanvas.splitGroup(group_id)
  691. self.miniCanvasPreview.update()
  692. elif action == patchcanvas.ACTION_GROUP_JOIN:
  693. group_id = value1
  694. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_SPLIT, "false")
  695. patchcanvas.joinGroup(group_id)
  696. self.miniCanvasPreview.update()
  697. elif action == patchcanvas.ACTION_PORT_INFO:
  698. this_port_id = value1
  699. breakNow = False
  700. port_id = 0
  701. port_flags = 0
  702. port_name = ""
  703. port_type_jack = 0
  704. version, groups, conns = DBus.patchbay.GetGraph(0)
  705. for group in groups:
  706. group_id, group_name, ports = group
  707. for port in ports:
  708. port_id, port_name, port_flags, port_type_jack = port
  709. if this_port_id == port_id:
  710. breakNow = True
  711. break
  712. if breakNow:
  713. break
  714. else:
  715. return
  716. flags = []
  717. if port_flags & JACKDBUS_PORT_FLAG_INPUT:
  718. flags.append(self.tr("Input"))
  719. if port_flags & JACKDBUS_PORT_FLAG_OUTPUT:
  720. flags.append(self.tr("Output"))
  721. if port_flags & JACKDBUS_PORT_FLAG_PHYSICAL:
  722. flags.append(self.tr("Physical"))
  723. if port_flags & JACKDBUS_PORT_FLAG_CAN_MONITOR:
  724. flags.append(self.tr("Can Monitor"))
  725. if port_flags & JACKDBUS_PORT_FLAG_TERMINAL:
  726. flags.append(self.tr("Terminal"))
  727. flags_text = ""
  728. for flag in flags:
  729. if flags_text:
  730. flags_text += " | "
  731. flags_text += flag
  732. if port_type_jack == JACKDBUS_PORT_TYPE_AUDIO:
  733. type_text = self.tr("Audio")
  734. elif port_type_jack == JACKDBUS_PORT_TYPE_MIDI:
  735. type_text = self.tr("MIDI")
  736. else:
  737. type_text = self.tr("Unknown")
  738. port_full_name = "%s:%s" % (group_name, port_name)
  739. info = self.tr(""
  740. "<table>"
  741. "<tr><td align='right'><b>Group ID:</b></td><td>&nbsp;%i</td></tr>"
  742. "<tr><td align='right'><b>Group Name:</b></td><td>&nbsp;%s</td></tr>"
  743. "<tr><td align='right'><b>Port ID:</b></td><td>&nbsp;%i</i></td></tr>"
  744. "<tr><td align='right'><b>Port Name:</b></td><td>&nbsp;%s</td></tr>"
  745. "<tr><td align='right'><b>Full Port Name:</b></td><td>&nbsp;%s</td></tr>"
  746. "<tr><td colspan='2'>&nbsp;</td></tr>"
  747. "<tr><td align='right'><b>Port Flags:</b></td><td>&nbsp;%s</td></tr>"
  748. "<tr><td align='right'><b>Port Type:</b></td><td>&nbsp;%s</td></tr>"
  749. "</table>"
  750. % (group_id, group_name, port_id, port_name, port_full_name, flags_text, type_text))
  751. QMessageBox.information(self, self.tr("Port Information"), info)
  752. elif action == patchcanvas.ACTION_PORT_RENAME:
  753. port_id = value1
  754. port_name = value_str
  755. DBus.ladish_manager.RenamePort(port_id, port_name)
  756. elif action == patchcanvas.ACTION_PORTS_CONNECT:
  757. port_a = value1
  758. port_b = value2
  759. DBus.patchbay.ConnectPortsByID(port_a, port_b)
  760. elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
  761. connection_id = value1
  762. DBus.patchbay.DisconnectPortsByConnectionID(connection_id)
  763. def init_jack(self):
  764. self.m_xruns = -1
  765. self.m_nextSampleRate = 0
  766. self.m_lastBPM = None
  767. self.m_lastTransportState = None
  768. bufferSize = int(jacklib.get_buffer_size(jack.client))
  769. sampleRate = int(jacklib.get_sample_rate(jack.client))
  770. realtime = bool(int(jacklib.is_realtime(jack.client)))
  771. self.setBufferSize(bufferSize)
  772. self.setSampleRate(sampleRate)
  773. self.setRealTime(realtime)
  774. self.refreshDSPLoad()
  775. self.refreshTransport()
  776. self.refreshXruns()
  777. self.init_callbacks()
  778. jacklib.activate(jack.client)
  779. def init_callbacks(self):
  780. jacklib.set_buffer_size_callback(jack.client, self.JackBufferSizeCallback, None)
  781. jacklib.set_sample_rate_callback(jack.client, self.JackSampleRateCallback, None)
  782. jacklib.on_shutdown(jack.client, self.JackShutdownCallback, None)
  783. def init_studio(self):
  784. self.treeWidget.clear()
  785. studio_item = QTreeWidgetItem(ITEM_TYPE_STUDIO)
  786. studio_item.setText(0, str(DBus.ladish_studio.GetName()))
  787. self.treeWidget.insertTopLevelItem(0, studio_item)
  788. self.treeWidget.setCurrentItem(studio_item)
  789. self.m_lastItemType = ITEM_TYPE_STUDIO
  790. self.m_lastRoomPath = None
  791. self.init_apps()
  792. def init_apps(self):
  793. studio_iface = dbus.Interface(DBus.ladish_studio, 'org.ladish.AppSupervisor')
  794. studio_item = self.treeWidget.topLevelItem(0)
  795. graph_version, app_list = studio_iface.GetAll2()
  796. for app in app_list:
  797. number, name, active, terminal, level = app
  798. prop_obj = [None, None, None, None, None]
  799. prop_obj[iItemPropNumber] = int(number)
  800. prop_obj[iItemPropName] = str(name)
  801. prop_obj[iItemPropActive] = bool(active)
  802. prop_obj[iItemPropTerminal] = bool(terminal)
  803. prop_obj[iItemPropLevel] = str(level)
  804. text = "["
  805. if level.isdigit():
  806. text += "L%s" % level
  807. elif level == "jacksession":
  808. text += "JS"
  809. else:
  810. text += level.upper()
  811. text += "] "
  812. if not active:
  813. text += "(inactive) "
  814. text += name
  815. item = QTreeWidgetItem(ITEM_TYPE_STUDIO_APP)
  816. item.properties = prop_obj
  817. item.setText(0, text)
  818. studio_item.addChild(item)
  819. room_list = DBus.ladish_studio.GetRoomList()
  820. for room in room_list:
  821. room_path, room_dict = room
  822. ladish_room = DBus.bus.get_object("org.ladish", room_path)
  823. room_name = ladish_room.GetName()
  824. room_app_iface = dbus.Interface(ladish_room, 'org.ladish.AppSupervisor')
  825. room_item = self.room_add(room_path, room_name)
  826. graph_version, app_list = room_app_iface.GetAll2()
  827. for app in app_list:
  828. number, name, active, terminal, level = app
  829. prop_obj = [None, None, None, None, None]
  830. prop_obj[iItemPropNumber] = int(number)
  831. prop_obj[iItemPropName] = str(name)
  832. prop_obj[iItemPropActive] = bool(active)
  833. prop_obj[iItemPropTerminal] = bool(terminal)
  834. prop_obj[iItemPropLevel] = str(level)
  835. text = "["
  836. if level.isdigit():
  837. text += "L%s" % level
  838. elif level == "jacksession":
  839. text += "JS"
  840. else:
  841. text += level.upper()
  842. text += "] "
  843. if not active:
  844. text += "(inactive) "
  845. text += name
  846. item = QTreeWidgetItem(ITEM_TYPE_ROOM_APP)
  847. item.properties = prop_obj
  848. item.setText(0, text)
  849. room_item.addChild(item)
  850. self.treeWidget.expandAll()
  851. def init_ports(self):
  852. if not (jack.client and DBus.patchbay):
  853. return
  854. version, groups, conns = DBus.patchbay.GetGraph(0)
  855. # Graph Ports
  856. for group in groups:
  857. group_id, group_name, ports = group
  858. self.canvas_add_group(int(group_id), str(group_name))
  859. for port in ports:
  860. port_id, port_name, port_flags, port_type_jack = port
  861. if port_flags & JACKDBUS_PORT_FLAG_INPUT:
  862. port_mode = patchcanvas.PORT_MODE_INPUT
  863. elif port_flags & JACKDBUS_PORT_FLAG_OUTPUT:
  864. port_mode = patchcanvas.PORT_MODE_OUTPUT
  865. else:
  866. port_mode = patchcanvas.PORT_MODE_NULL
  867. if port_type_jack == JACKDBUS_PORT_TYPE_AUDIO:
  868. port_type = patchcanvas.PORT_TYPE_AUDIO_JACK
  869. elif port_type_jack == JACKDBUS_PORT_TYPE_MIDI:
  870. if DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_PORT, port_id, URI_A2J_PORT) == "yes":
  871. port_type = patchcanvas.PORT_TYPE_MIDI_A2J
  872. else:
  873. port_type = patchcanvas.PORT_TYPE_MIDI_JACK
  874. else:
  875. port_type = patchcanvas.PORT_TYPE_NULL
  876. self.canvas_add_port(int(group_id), int(port_id), str(port_name), port_mode, port_type)
  877. # Graph Connections
  878. for conn in conns:
  879. source_group_id, source_group_name, source_port_id, source_port_name, target_group_id, target_group_name, target_port_id, target_port_name, conn_id = conn
  880. self.canvas_connect_ports(int(conn_id), int(source_port_id), int(target_port_id))
  881. QTimer.singleShot(1000 if (self.m_savedSettings['Canvas/EyeCandy']) else 0, self.miniCanvasPreview, SLOT("update()"))
  882. def room_add(self, room_path, room_name):
  883. room_index = int(room_path.replace("/org/ladish/Room", ""))
  884. room_object = DBus.bus.get_object("org.ladish", room_path)
  885. room_project_properties = room_object.GetProjectProperties()
  886. # Remove old unused item if needed
  887. iItem = self.treeWidget.topLevelItem(room_index)
  888. if iItem and not iItem.isVisible():
  889. self.treeWidget.takeTopLevelItem(room_index)
  890. # Insert padding of items if needed
  891. for i in range(room_index):
  892. if not self.treeWidget.topLevelItem(i):
  893. fake_item = QTreeWidgetItem(ITEM_TYPE_NULL)
  894. self.treeWidget.insertTopLevelItem(i, fake_item)
  895. fake_item.setHidden(True)
  896. graph_version, project_properties = room_project_properties
  897. if len(project_properties) > 0:
  898. item_string = " (%s)" % project_properties['name']
  899. else:
  900. item_string = ""
  901. prop_obj = [None, None]
  902. prop_obj[iItemPropRoomPath] = room_path
  903. prop_obj[iItemPropRoomName] = room_name
  904. item = QTreeWidgetItem(ITEM_TYPE_ROOM)
  905. item.properties = prop_obj
  906. item.setText(0, "%s%s" % (room_name, item_string))
  907. self.treeWidget.insertTopLevelItem(room_index, item)
  908. self.treeWidget.expandItem(item)
  909. return item
  910. def canvas_add_group(self, group_id, group_name):
  911. # TODO - request ladish client type
  912. #if (False):
  913. #icon = patchcanvas.ICON_HARDWARE
  914. #split = patchcanvas.SPLIT_NO
  915. #elif (False):
  916. #icon = patchcanvas.ICON_LADISH_ROOM
  917. #split = patchcanvas.SPLIT_NO
  918. #else:
  919. icon = patchcanvas.ICON_APPLICATION
  920. split_try = DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_SPLIT)
  921. if split_try == "true":
  922. split = patchcanvas.SPLIT_YES
  923. elif split_try == "false":
  924. split = patchcanvas.SPLIT_NO
  925. else:
  926. split = patchcanvas.SPLIT_UNDEF
  927. patchcanvas.addGroup(group_id, group_name, split, icon)
  928. x = DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_X)
  929. y = DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_Y)
  930. x2 = DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_X_SPLIT)
  931. y2 = DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_Y_SPLIT)
  932. if x != None and y != None:
  933. if x2 is None: x2 = "%f" % (float(x) + 50)
  934. if y2 is None: y2 = "%f" % (float(y) + 50)
  935. patchcanvas.setGroupPosFull(group_id, float(x), float(y), float(x2), float(y2))
  936. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  937. def canvas_remove_group(self, group_id):
  938. patchcanvas.removeGroup(group_id)
  939. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  940. def canvas_rename_group(self, group_id, new_group_name):
  941. patchcanvas.renameGroup(group_id, new_group_name)
  942. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  943. def canvas_add_port(self, group_id, port_id, port_name, port_mode, port_type):
  944. patchcanvas.addPort(group_id, port_id, port_name, port_mode, port_type)
  945. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  946. def canvas_remove_port(self, port_id):
  947. patchcanvas.removePort(port_id)
  948. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  949. def canvas_rename_port(self, port_id, new_port_name):
  950. patchcanvas.renamePort(port_id, new_port_name)
  951. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  952. def canvas_connect_ports(self, connection_id, port_a, port_b):
  953. patchcanvas.connectPorts(connection_id, port_a, port_b)
  954. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  955. def canvas_disconnect_ports(self, connection_id):
  956. patchcanvas.disconnectPorts(connection_id)
  957. QTimer.singleShot(0, self.miniCanvasPreview, SLOT("update()"))
  958. def jackStarted(self):
  959. if jacksettings.needsInit():
  960. self.DBusReconnect()
  961. if not jack.client:
  962. jack.client = jacklib.client_open("claudia", jacklib.JackNoStartServer, None)
  963. if not jack.client:
  964. return self.jackStopped()
  965. canRender = render.canRender()
  966. self.act_jack_render.setEnabled(canRender)
  967. self.b_jack_render.setEnabled(canRender)
  968. self.menuJackTransport(True)
  969. self.cb_buffer_size.setEnabled(True)
  970. self.cb_sample_rate.setEnabled(True) # jacksettings.getSampleRate() != -1
  971. if self.systray:
  972. self.systray.setActionEnabled("tools_render", canRender)
  973. self.pb_dsp_load.setMaximum(100)
  974. self.pb_dsp_load.setValue(0)
  975. self.pb_dsp_load.update()
  976. self.init_jack()
  977. self.m_crashedJACK = False
  978. def jackStopped(self):
  979. #self.DBusReconnect()
  980. # client already closed
  981. jack.client = None
  982. if self.m_nextSampleRate:
  983. self.jack_setSampleRate(self.m_nextSampleRate)
  984. bufferSize = jacksettings.getBufferSize()
  985. sampleRate = jacksettings.getSampleRate()
  986. bufferSizeTest = bool(bufferSize != -1)
  987. sampleRateTest = bool(sampleRate != -1)
  988. if bufferSizeTest:
  989. self.setBufferSize(bufferSize)
  990. if sampleRateTest:
  991. self.setSampleRate(sampleRate)
  992. self.setRealTime(jacksettings.isRealtime())
  993. self.setXruns(-1)
  994. self.cb_buffer_size.setEnabled(bufferSizeTest)
  995. self.cb_sample_rate.setEnabled(sampleRateTest)
  996. self.act_jack_render.setEnabled(False)
  997. self.b_jack_render.setEnabled(False)
  998. self.menuJackTransport(False)
  999. if self.systray:
  1000. self.systray.setActionEnabled("tools_render", False)
  1001. if self.m_curTransportView == TRANSPORT_VIEW_HMS:
  1002. self.label_time.setText("00:00:00")
  1003. elif self.m_curTransportView == TRANSPORT_VIEW_BBT:
  1004. self.label_time.setText("000|0|0000")
  1005. elif self.m_curTransportView == TRANSPORT_VIEW_FRAMES:
  1006. self.label_time.setText("000'000'000")
  1007. self.pb_dsp_load.setValue(0)
  1008. self.pb_dsp_load.setMaximum(0)
  1009. self.pb_dsp_load.update()
  1010. def studioStarted(self):
  1011. self.act_studio_start.setEnabled(False)
  1012. self.act_studio_stop.setEnabled(True)
  1013. self.act_studio_save.setEnabled(True)
  1014. self.act_studio_save_as.setEnabled(True)
  1015. self.b_studio_save.setEnabled(True)
  1016. self.b_studio_save_as.setEnabled(True)
  1017. if self.systray:
  1018. self.systray.setActionEnabled("studio_start", False)
  1019. self.systray.setActionEnabled("studio_stop", True)
  1020. self.systray.setActionEnabled("studio_save", True)
  1021. self.systray.setActionEnabled("studio_save_as", True)
  1022. def studioStopped(self):
  1023. self.act_studio_start.setEnabled(True)
  1024. self.act_studio_stop.setEnabled(False)
  1025. self.act_studio_save.setEnabled(False)
  1026. self.act_studio_save_as.setEnabled(False)
  1027. self.b_studio_save.setEnabled(False)
  1028. self.b_studio_save_as.setEnabled(False)
  1029. if self.systray:
  1030. self.systray.setActionEnabled("studio_start", True)
  1031. self.systray.setActionEnabled("studio_stop", False)
  1032. self.systray.setActionEnabled("studio_save", False)
  1033. self.systray.setActionEnabled("studio_save_as", False)
  1034. def studioLoaded(self):
  1035. DBus.ladish_studio = DBus.bus.get_object("org.ladish", "/org/ladish/Studio")
  1036. DBus.ladish_graph = dbus.Interface(DBus.ladish_studio, 'org.ladish.GraphDict')
  1037. DBus.ladish_manager = dbus.Interface(DBus.ladish_studio, 'org.ladish.GraphManager')
  1038. DBus.ladish_app_iface = dbus.Interface(DBus.ladish_studio, 'org.ladish.AppSupervisor')
  1039. DBus.patchbay = dbus.Interface(DBus.ladish_studio, 'org.jackaudio.JackPatchbay')
  1040. self.label_first_time.setVisible(False)
  1041. self.graphicsView.setVisible(True)
  1042. self.miniCanvasPreview.setVisible(True)
  1043. #if (self.miniCanvasPreview.is_initiated):
  1044. #self.checkMiniCanvasSize()
  1045. self.menu_Room.setEnabled(True)
  1046. self.menu_Project.setEnabled(False)
  1047. self.menu_Application.setEnabled(True)
  1048. self.group_project.setEnabled(False)
  1049. self.act_studio_rename.setEnabled(True)
  1050. self.act_studio_unload.setEnabled(True)
  1051. if self.systray:
  1052. self.systray.setActionEnabled("studio_rename", True)
  1053. self.systray.setActionEnabled("studio_unload", True)
  1054. self.init_studio()
  1055. self.m_crashedLADISH = False
  1056. def studioUnloaded(self):
  1057. DBus.ladish_studio = None
  1058. DBus.ladish_graph = None
  1059. DBus.ladish_manager = None
  1060. DBus.ladish_app_iface = None
  1061. DBus.patchbay = None
  1062. self.m_lastItemType = None
  1063. self.m_lastRoomPath = None
  1064. self.label_first_time.setVisible(True)
  1065. self.graphicsView.setVisible(False)
  1066. self.miniCanvasPreview.setVisible(False)
  1067. self.menu_Room.setEnabled(False)
  1068. self.menu_Project.setEnabled(False)
  1069. self.menu_Application.setEnabled(False)
  1070. self.group_project.setEnabled(False)
  1071. self.act_studio_start.setEnabled(False)
  1072. self.act_studio_stop.setEnabled(False)
  1073. self.act_studio_rename.setEnabled(False)
  1074. self.act_studio_save.setEnabled(False)
  1075. self.act_studio_save_as.setEnabled(False)
  1076. self.act_studio_unload.setEnabled(False)
  1077. self.b_studio_save.setEnabled(False)
  1078. self.b_studio_save_as.setEnabled(False)
  1079. if self.systray:
  1080. self.systray.setActionEnabled("studio_start", False)
  1081. self.systray.setActionEnabled("studio_stop", False)
  1082. self.systray.setActionEnabled("studio_rename", False)
  1083. self.systray.setActionEnabled("studio_save", False)
  1084. self.systray.setActionEnabled("studio_save_as", False)
  1085. self.systray.setActionEnabled("studio_unload", False)
  1086. self.treeWidget.clear()
  1087. patchcanvas.clear()
  1088. def menuJackTransport(self, enabled):
  1089. self.act_transport_play.setEnabled(enabled)
  1090. self.act_transport_stop.setEnabled(enabled)
  1091. self.act_transport_backwards.setEnabled(enabled)
  1092. self.act_transport_forwards.setEnabled(enabled)
  1093. self.menu_Transport.setEnabled(enabled)
  1094. self.group_transport.setEnabled(enabled)
  1095. def DBusSignalReceiver(self, *args, **kwds):
  1096. if kwds['interface'] == "org.freedesktop.DBus" and kwds['path'] == "/org/freedesktop/DBus" and kwds['member'] == "NameOwnerChanged":
  1097. appInterface, appId, newId = args
  1098. #print("appInterface crashed", appInterface)
  1099. if not newId:
  1100. # Something crashed
  1101. if appInterface in ("org.jackaudio.service", "org.ladish"):
  1102. # Prevent any more dbus calls
  1103. DBus.jack = None
  1104. jack.client = None
  1105. jacksettings.initBus(None)
  1106. self.emit(SIGNAL("DBusCrashCallback(QString)"), appInterface)
  1107. elif kwds['interface'] == "org.jackaudio.JackControl":
  1108. if DEBUG: print("DBus signal @org.jackaudio.JackControl,", kwds['member'])
  1109. if kwds['member'] == "ServerStarted":
  1110. self.emit(SIGNAL("DBusServerStartedCallback()"))
  1111. elif kwds['member'] == "ServerStopped":
  1112. self.emit(SIGNAL("DBusServerStoppedCallback()"))
  1113. elif kwds['interface'] == "org.jackaudio.JackPatchbay":
  1114. if DBus.patchbay and kwds['path'] == DBus.patchbay.object_path:
  1115. if DEBUG: print("DBus signal @org.jackaudio.JackPatchbay,", kwds['member'])
  1116. if kwds['member'] == "ClientAppeared":
  1117. self.emit(SIGNAL("DBusClientAppearedCallback(int, QString)"), args[iJackClientId], args[iJackClientName])
  1118. elif kwds['member'] == "ClientDisappeared":
  1119. self.emit(SIGNAL("DBusClientDisappearedCallback(int)"), args[iJackClientId])
  1120. elif kwds['member'] == "ClientRenamed":
  1121. self.emit(SIGNAL("DBusClientRenamedCallback(int, QString)"), args[iRenamedId], args[iRenamedNewName])
  1122. elif kwds['member'] == "PortAppeared":
  1123. self.emit(SIGNAL("DBusPortAppearedCallback(int, int, QString, int, int)"), args[iJackClientId], args[iJackPortId], args[iJackPortName], args[iJackPortFlags], args[iJackPortType])
  1124. elif kwds['member'] == "PortDisappeared":
  1125. self.emit(SIGNAL("DBusPortDisppearedCallback(int)"), args[iJackPortId])
  1126. elif kwds['member'] == "PortRenamed":
  1127. self.emit(SIGNAL("DBusPortRenamedCallback(int, QString)"), args[iJackPortId], args[iJackPortNewName])
  1128. elif kwds['member'] == "PortsConnected":
  1129. self.emit(SIGNAL("DBusPortsConnectedCallback(int, int, int)"), args[iJackConnId], args[iSourcePortId], args[iTargetPortId])
  1130. elif kwds['member'] == "PortsDisconnected":
  1131. self.emit(SIGNAL("DBusPortsDisconnectedCallback(int)"), args[iJackConnId])
  1132. elif kwds['interface'] == "org.ladish.Control":
  1133. if DEBUG: print("DBus signal @org.ladish.Control,", kwds['member'])
  1134. if kwds['member'] == "StudioAppeared":
  1135. self.emit(SIGNAL("DBusStudioAppearedCallback()"))
  1136. elif kwds['member'] == "StudioDisappeared":
  1137. self.emit(SIGNAL("DBusStudioDisappearedCallback()"))
  1138. elif kwds['member'] == "QueueExecutionHalted":
  1139. self.emit(SIGNAL("DBusQueueExecutionHaltedCallback()"))
  1140. elif kwds['member'] == "CleanExit":
  1141. self.emit(SIGNAL("DBusCleanExitCallback()"))
  1142. elif kwds['interface'] == "org.ladish.Studio":
  1143. if DEBUG: print("DBus signal @org.ladish.Studio,", kwds['member'])
  1144. if kwds['member'] == "StudioStarted":
  1145. self.emit(SIGNAL("DBusStudioStartedCallback()"))
  1146. elif kwds['member'] == "StudioStopped":
  1147. self.emit(SIGNAL("DBusStudioStoppedCallback()"))
  1148. elif kwds['member'] == "StudioRenamed":
  1149. self.emit(SIGNAL("DBusStudioRenamedCallback(QString)"), args[iStudioRenamedName])
  1150. elif kwds['member'] == "StudioCrashed":
  1151. self.emit(SIGNAL("DBusStudioCrashedCallback()"))
  1152. elif kwds['member'] == "RoomAppeared":
  1153. self.emit(SIGNAL("DBusRoomAppearedCallback(QString, QString)"), args[iRoomAppearedPath], args[iRoomAppearedDict]['name'])
  1154. elif kwds['member'] == "RoomDisappeared":
  1155. self.emit(SIGNAL("DBusRoomDisappearedCallback(QString)"), args[iRoomAppearedPath])
  1156. #elif kwds['member'] == "RoomChanged":
  1157. #self.emit(SIGNAL("DBusRoomChangedCallback()"))
  1158. elif kwds['interface'] == "org.ladish.Room":
  1159. if DEBUG: print("DBus signal @org.ladish.Room,", kwds['member'])
  1160. if kwds['member'] == "ProjectPropertiesChanged":
  1161. if "name" in args[iProjChangedDict].keys():
  1162. self.emit(SIGNAL("DBusProjectPropertiesChanged(QString, QString)"), kwds['path'], args[iProjChangedDict]['name'])
  1163. else:
  1164. self.emit(SIGNAL("DBusProjectPropertiesChanged(QString, QString)"), kwds['path'], "")
  1165. elif kwds['interface'] == "org.ladish.AppSupervisor":
  1166. if DEBUG: print("DBus signal @org.ladish.AppSupervisor,", kwds['member'])
  1167. if kwds['member'] == "AppAdded2":
  1168. self.emit(SIGNAL("DBusAppAdded2Callback(QString, int, QString, bool, bool, QString)"), kwds['path'], args[iAppChangedNumber], args[iAppChangedName], args[iAppChangedActive], args[iAppChangedTerminal], args[iAppChangedLevel])
  1169. elif kwds['member'] == "AppRemoved":
  1170. self.emit(SIGNAL("DBusAppRemovedCallback(QString, int)"), kwds['path'], args[iAppChangedNumber])
  1171. elif kwds['member'] == "AppStateChanged2":
  1172. self.emit(SIGNAL("DBusAppStateChanged2Callback(QString, int, QString, bool, bool, QString)"), kwds['path'], args[iAppChangedNumber], args[iAppChangedName], args[iAppChangedActive], args[iAppChangedTerminal], args[iAppChangedLevel])
  1173. def DBusReconnect(self):
  1174. DBus.jack = DBus.bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller")
  1175. DBus.ladish_control = DBus.bus.get_object("org.ladish", "/org/ladish/Control")
  1176. DBus.ladish_studio = None
  1177. DBus.ladish_room = None
  1178. DBus.ladish_graph = None
  1179. DBus.ladish_manager = None
  1180. DBus.ladish_app_iface = None
  1181. DBus.patchbay = None
  1182. try:
  1183. DBus.ladish_app_daemon = DBus.bus.get_object("org.ladish.appdb", "/")
  1184. except:
  1185. DBus.ladish_app_daemon = None
  1186. jacksettings.initBus(DBus.bus)
  1187. def refreshXruns(self):
  1188. if not DBus.jack:
  1189. #if not self.m_crashedJACK:
  1190. #self.DBusReconnect()
  1191. return
  1192. xruns = int(DBus.jack.GetXruns())
  1193. if self.m_xruns != xruns:
  1194. self.setXruns(xruns)
  1195. self.m_xruns = xruns
  1196. def JackBufferSizeCallback(self, buffer_size, arg):
  1197. if DEBUG: print("JackBufferSizeCallback(%i)" % buffer_size)
  1198. self.emit(SIGNAL("JackBufferSizeCallback(int)"), buffer_size)
  1199. return 0
  1200. def JackSampleRateCallback(self, sample_rate, arg):
  1201. if DEBUG: print("JackSampleRateCallback(%i)" % sample_rate)
  1202. self.emit(SIGNAL("JackSampleRateCallback(int)"), sample_rate)
  1203. return 0
  1204. def JackShutdownCallback(self, arg):
  1205. if DEBUG: print("JackShutdownCallback()")
  1206. self.emit(SIGNAL("JackShutdownCallback()"))
  1207. return 0
  1208. @pyqtSlot()
  1209. def slot_studio_new(self):
  1210. dialog = StudioNameW(self, StudioNameW.NEW)
  1211. if dialog.exec_():
  1212. DBus.ladish_control.NewStudio(dialog.ret_studio_name)
  1213. @pyqtSlot()
  1214. def slot_studio_load_b(self):
  1215. dialog = StudioListW(self)
  1216. if dialog.exec_():
  1217. DBus.ladish_control.LoadStudio(dialog.ret_studio_name)
  1218. @pyqtSlot()
  1219. def slot_studio_load_m(self):
  1220. studio_name = self.sender().text()
  1221. if studio_name:
  1222. DBus.ladish_control.LoadStudio(studio_name)
  1223. @pyqtSlot()
  1224. def slot_studio_start(self):
  1225. DBus.ladish_studio.Start()
  1226. @pyqtSlot()
  1227. def slot_studio_stop(self):
  1228. DBus.ladish_studio.Stop()
  1229. @pyqtSlot()
  1230. def slot_studio_rename(self):
  1231. dialog = StudioNameW(self, StudioNameW.RENAME)
  1232. if dialog.exec_():
  1233. DBus.ladish_studio.Rename(dialog.ret_studio_name)
  1234. @pyqtSlot()
  1235. def slot_studio_save(self):
  1236. DBus.ladish_studio.Save()
  1237. @pyqtSlot()
  1238. def slot_studio_save_as(self):
  1239. dialog = StudioNameW(self, StudioNameW.SAVE_AS)
  1240. if dialog.exec_():
  1241. DBus.ladish_studio.SaveAs(dialog.ret_studio_name)
  1242. @pyqtSlot()
  1243. def slot_studio_unload(self):
  1244. DBus.ladish_studio.Unload()
  1245. @pyqtSlot()
  1246. def slot_studio_delete_m(self):
  1247. studio_name = self.sender().text()
  1248. if studio_name:
  1249. DBus.ladish_control.DeleteStudio(studio_name)
  1250. @pyqtSlot()
  1251. def slot_room_create(self):
  1252. dialog = CreateRoomW(self)
  1253. if dialog.exec_():
  1254. DBus.ladish_studio.CreateRoom(dialog.ret_room_name, dialog.ret_room_template)
  1255. @pyqtSlot()
  1256. def slot_room_delete_m(self):
  1257. room_name = self.sender().text()
  1258. if room_name:
  1259. DBus.ladish_studio.DeleteRoom(room_name)
  1260. @pyqtSlot()
  1261. def slot_project_new(self):
  1262. dialog = ProjectNameW(self, ProjectNameW.NEW, self.m_savedSettings["Main/DefaultProjectFolder"])
  1263. if dialog.exec_():
  1264. # Check if a project is already loaded, if yes unload it first
  1265. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1266. if len(project_properties) > 0:
  1267. DBus.ladish_room.UnloadProject()
  1268. DBus.ladish_room.SaveProject(dialog.ret_project_path, dialog.ret_project_name)
  1269. @pyqtSlot()
  1270. def slot_project_load(self):
  1271. project_path = QFileDialog.getExistingDirectory(self, self.tr("Open Project"), self.m_savedSettings["Main/DefaultProjectFolder"])
  1272. if project_path:
  1273. if os.path.exists(os.path.join(project_path, "ladish-project.xml")):
  1274. DBus.ladish_room.LoadProject(project_path)
  1275. else:
  1276. QMessageBox.warning(self, self.tr("Warning"), self.tr("The selected folder does not contain a ladish project"))
  1277. @pyqtSlot()
  1278. def slot_project_load_m(self):
  1279. act_x_text = self.sender().text()
  1280. if act_x_text:
  1281. proj_path = "/" + act_x_text.rsplit("[/", 1)[-1].rsplit("]", 1)[0]
  1282. DBus.ladish_room.LoadProject(proj_path)
  1283. @pyqtSlot()
  1284. def slot_project_save(self):
  1285. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1286. if len(project_properties) > 0:
  1287. path = dbus.String(project_properties['dir'])
  1288. name = dbus.String(project_properties['name'])
  1289. DBus.ladish_room.SaveProject(path, name)
  1290. else:
  1291. self.slot_project_new()
  1292. @pyqtSlot()
  1293. def slot_project_save_as(self):
  1294. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1295. if len(project_properties) > 0:
  1296. path = str(project_properties['dir'])
  1297. name = str(project_properties['name'])
  1298. dialog = ProjectNameW(self, ProjectNameW.SAVE_AS, self.m_savedSettings["Main/DefaultProjectFolder"], path, name)
  1299. if dialog.exec_():
  1300. DBus.ladish_room.SaveProject(dialog.ret_project_path, dialog.ret_project_name)
  1301. else:
  1302. self.slot_project_new()
  1303. @pyqtSlot()
  1304. def slot_project_unload(self):
  1305. DBus.ladish_room.UnloadProject()
  1306. @pyqtSlot()
  1307. def slot_project_properties(self):
  1308. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1309. path = str(project_properties['dir'])
  1310. name = str(project_properties['name'])
  1311. if "description" in project_properties.keys():
  1312. description = str(project_properties['description'])
  1313. else:
  1314. description = ""
  1315. if "notes" in project_properties.keys():
  1316. notes = str(project_properties['notes'])
  1317. else:
  1318. notes = ""
  1319. dialog = ProjectPropertiesW(self, name, description, notes)
  1320. if dialog.exec_():
  1321. DBus.ladish_room.SetProjectDescription(dialog.ret_obj[iAppPropDescription])
  1322. DBus.ladish_room.SetProjectNotes(dialog.ret_obj[iAppPropNotes])
  1323. if dialog.ret_obj[iAppPropSaveNow]:
  1324. DBus.ladish_room.SaveProject(path, dialog.ret_obj[iAppPropName])
  1325. @pyqtSlot()
  1326. def slot_app_add_new(self):
  1327. proj_folder = ""
  1328. if self.m_lastItemType == ITEM_TYPE_STUDIO or self.m_lastItemType == ITEM_TYPE_STUDIO_APP:
  1329. proj_folder = self.m_savedSettings['Main/DefaultProjectFolder']
  1330. is_room = False
  1331. elif self.m_lastItemType == ITEM_TYPE_ROOM or self.m_lastItemType == ITEM_TYPE_ROOM_APP:
  1332. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1333. if len(project_properties) > 0:
  1334. proj_folder = str(project_properties['dir'])
  1335. is_room = True
  1336. else:
  1337. proj_folder = self.m_savedSettings['Main/DefaultProjectFolder']
  1338. is_room = False
  1339. else:
  1340. print("Invalid m_last_item_type value")
  1341. return
  1342. dialog = ClaudiaLauncherW(self, DBus.ladish_app_iface, proj_folder, is_room, self.m_lastBPM, self.m_sampleRate)
  1343. dialog.exec_()
  1344. @pyqtSlot()
  1345. def slot_app_run_custom(self):
  1346. dialog = RunCustomW(self, bool(self.m_lastItemType in (ITEM_TYPE_ROOM, ITEM_TYPE_ROOM_APP)))
  1347. if dialog.exec_() and dialog.ret_app_obj:
  1348. app_obj = dialog.ret_app_obj
  1349. DBus.ladish_app_iface.RunCustom2(app_obj[iAppTerminal], app_obj[iAppCommand], app_obj[iAppName], app_obj[iAppLevel])
  1350. @pyqtSlot()
  1351. def slot_checkCurrentRoom(self):
  1352. item = self.treeWidget.currentItem()
  1353. room_path = None
  1354. if not item:
  1355. return
  1356. if item.type() in (ITEM_TYPE_STUDIO, ITEM_TYPE_STUDIO_APP):
  1357. self.menu_Project.setEnabled(False)
  1358. self.group_project.setEnabled(False)
  1359. self.menu_Application.setEnabled(True)
  1360. DBus.ladish_room = None
  1361. DBus.ladish_app_iface = dbus.Interface(DBus.ladish_studio, "org.ladish.AppSupervisor")
  1362. ITEM_TYPE = ITEM_TYPE_STUDIO
  1363. elif item.type() in (ITEM_TYPE_ROOM, ITEM_TYPE_ROOM_APP):
  1364. self.menu_Project.setEnabled(True)
  1365. self.group_project.setEnabled(True)
  1366. if item.type() == ITEM_TYPE_ROOM:
  1367. room_path = item.properties[iItemPropRoomPath]
  1368. elif item.type() == ITEM_TYPE_ROOM_APP:
  1369. room_path = item.parent().properties[iItemPropRoomPath]
  1370. else:
  1371. return
  1372. DBus.ladish_room = DBus.bus.get_object("org.ladish", room_path)
  1373. DBus.ladish_app_iface = dbus.Interface(DBus.ladish_room, "org.ladish.AppSupervisor")
  1374. ITEM_TYPE = ITEM_TYPE_ROOM
  1375. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1376. has_project = bool(len(project_properties) > 0)
  1377. self.act_project_save.setEnabled(has_project)
  1378. self.act_project_save_as.setEnabled(has_project)
  1379. self.act_project_unload.setEnabled(has_project)
  1380. self.act_project_properties.setEnabled(has_project)
  1381. self.b_project_save.setEnabled(has_project)
  1382. self.b_project_save_as.setEnabled(has_project)
  1383. self.menu_Application.setEnabled(has_project)
  1384. else:
  1385. return
  1386. if ITEM_TYPE != self.m_lastItemType or room_path != self.m_lastRoomPath:
  1387. if ITEM_TYPE == ITEM_TYPE_STUDIO:
  1388. object_path = DBus.ladish_studio
  1389. elif ITEM_TYPE == ITEM_TYPE_ROOM:
  1390. object_path = DBus.ladish_room
  1391. else:
  1392. return
  1393. patchcanvas.clear()
  1394. DBus.patchbay = dbus.Interface(object_path, 'org.jackaudio.JackPatchbay')
  1395. DBus.ladish_graph = dbus.Interface(object_path, 'org.ladish.GraphDict')
  1396. DBus.ladish_manager = dbus.Interface(object_path, 'org.ladish.GraphManager')
  1397. self.init_ports()
  1398. self.m_lastItemType = ITEM_TYPE
  1399. self.m_lastRoomPath = room_path
  1400. @pyqtSlot(QTreeWidgetItem, int)
  1401. def slot_doubleClickedAppList(self, item, row):
  1402. if item.type() in (ITEM_TYPE_STUDIO_APP, ITEM_TYPE_ROOM_APP):
  1403. if item.properties[iItemPropActive]:
  1404. DBus.ladish_app_iface.StopApp(item.properties[iItemPropNumber])
  1405. else:
  1406. DBus.ladish_app_iface.StartApp(item.properties[iItemPropNumber])
  1407. @pyqtSlot()
  1408. def slot_updateMenuStudioList_Load(self):
  1409. self.menu_studio_load.clear()
  1410. studio_list = DBus.ladish_control.GetStudioList()
  1411. if len(studio_list) == 0:
  1412. act_no_studio = QAction(self.tr("Empty studio list"), self.menu_studio_load)
  1413. act_no_studio.setEnabled(False)
  1414. self.menu_studio_load.addAction(act_no_studio)
  1415. else:
  1416. for studio in studio_list:
  1417. studio_name = str(studio[iStudioListName])
  1418. act_x_studio = QAction(studio_name, self.menu_studio_load)
  1419. self.menu_studio_load.addAction(act_x_studio)
  1420. self.connect(act_x_studio, SIGNAL("triggered()"), SLOT("slot_studio_load_m()"))
  1421. @pyqtSlot()
  1422. def slot_updateMenuStudioList_Delete(self):
  1423. self.menu_studio_delete.clear()
  1424. studio_list = DBus.ladish_control.GetStudioList()
  1425. if len(studio_list) == 0:
  1426. act_no_studio = QAction(self.tr("Empty studio list"), self.menu_studio_delete)
  1427. act_no_studio.setEnabled(False)
  1428. self.menu_studio_delete.addAction(act_no_studio)
  1429. else:
  1430. for studio in studio_list:
  1431. studio_name = str(studio[iStudioListName])
  1432. act_x_studio = QAction(studio_name, self.menu_studio_delete)
  1433. self.menu_studio_delete.addAction(act_x_studio)
  1434. self.connect(act_x_studio, SIGNAL("triggered()"), SLOT("slot_studio_delete_m()"))
  1435. @pyqtSlot()
  1436. def slot_updateMenuRoomList(self):
  1437. self.menu_room_delete.clear()
  1438. if DBus.ladish_control.IsStudioLoaded():
  1439. room_list = DBus.ladish_studio.GetRoomList()
  1440. if len(room_list) == 0:
  1441. self.createEmptyMenuRoomActon()
  1442. else:
  1443. for room_path, room_dict in room_list:
  1444. ladish_room = DBus.bus.get_object("org.ladish", room_path)
  1445. room_name = ladish_room.GetName()
  1446. act_x_room = QAction(room_name, self.menu_room_delete)
  1447. self.menu_room_delete.addAction(act_x_room)
  1448. self.connect(act_x_room, SIGNAL("triggered()"), SLOT("slot_room_delete_m()"))
  1449. else:
  1450. self.createEmptyMenuRoomActon()
  1451. def createEmptyMenuRoomActon(self):
  1452. act_no_room = QAction(self.tr("Empty room list"), self.menu_room_delete)
  1453. act_no_room.setEnabled(False)
  1454. self.menu_room_delete.addAction(act_no_room)
  1455. @pyqtSlot()
  1456. def slot_updateMenuProjectList(self):
  1457. self.menu_project_load.clear()
  1458. act_project_load = QAction(self.tr("Load from folder..."), self.menu_project_load)
  1459. self.menu_project_load.addAction(act_project_load)
  1460. self.connect(act_project_load, SIGNAL("triggered()"), SLOT("slot_project_load()"))
  1461. ladish_recent_iface = dbus.Interface(DBus.ladish_room, "org.ladish.RecentItems")
  1462. proj_list = ladish_recent_iface.get(RECENT_PROJECTS_STORE_MAX_ITEMS)
  1463. if len(proj_list) > 0:
  1464. self.menu_project_load.addSeparator()
  1465. for proj_path, proj_dict in proj_list:
  1466. if "name" in proj_dict.keys():
  1467. proj_name = proj_dict['name']
  1468. else:
  1469. continue
  1470. act_x_text = "%s [%s]" % (proj_name, proj_path)
  1471. act_x_proj = QAction(act_x_text, self.menu_project_load)
  1472. self.menu_project_load.addAction(act_x_proj)
  1473. self.connect(act_x_proj, SIGNAL("triggered()"), SLOT("slot_project_load_m()"))
  1474. @pyqtSlot()
  1475. def slot_showAppListCustomMenu(self):
  1476. item = self.treeWidget.currentItem()
  1477. if item:
  1478. cMenu = QMenu()
  1479. if item.type() == ITEM_TYPE_STUDIO:
  1480. act_x_add_new = cMenu.addAction(self.tr("Add New..."))
  1481. act_x_run_custom = cMenu.addAction(self.tr("Run Custom..."))
  1482. cMenu.addSeparator()
  1483. act_x_create_room = cMenu.addAction(self.tr("Create Room..."))
  1484. act_x_add_new.setIcon(QIcon.fromTheme("list-add", QIcon(":/16x16/list-add.png")))
  1485. act_x_run_custom.setIcon(QIcon.fromTheme("system-run", QIcon(":/16x16/system-run.png")))
  1486. act_x_create_room.setIcon(QIcon.fromTheme("list-add", QIcon(":/16x16/list-add.png")))
  1487. act_x_add_new.setEnabled(self.act_app_add_new.isEnabled())
  1488. elif item.type() == ITEM_TYPE_ROOM:
  1489. act_x_add_new = cMenu.addAction(self.tr("Add New..."))
  1490. act_x_run_custom = cMenu.addAction(self.tr("Run Custom..."))
  1491. cMenu.addSeparator()
  1492. act_x_new = cMenu.addAction(self.tr("New Project..."))
  1493. cMenu.addMenu(self.menu_project_load)
  1494. act_x_save = cMenu.addAction(self.tr("Save Project"))
  1495. act_x_save_as = cMenu.addAction(self.tr("Save Project As..."))
  1496. act_x_unload = cMenu.addAction(self.tr("Unload Project"))
  1497. cMenu.addSeparator()
  1498. act_x_properties = cMenu.addAction(self.tr("Project Properties..."))
  1499. cMenu.addSeparator()
  1500. act_x_delete_room = cMenu.addAction(self.tr("Delete Room"))
  1501. act_x_add_new.setIcon(QIcon.fromTheme("list-add", QIcon(":/16x16/list-add.png")))
  1502. act_x_run_custom.setIcon(QIcon.fromTheme("system-run", QIcon(":/16x16/system-run.png")))
  1503. act_x_new.setIcon(QIcon.fromTheme("document-new", QIcon(":/16x16/document-new.png")))
  1504. act_x_save.setIcon(QIcon.fromTheme("document-save", QIcon(":/16x16/document-save.png")))
  1505. act_x_save_as.setIcon(QIcon.fromTheme("document-save-as", QIcon(":/16x16/document-save-as.png")))
  1506. act_x_unload.setIcon(QIcon.fromTheme("window-close", QIcon(":/16x16/dialog-close.png")))
  1507. act_x_properties.setIcon(QIcon.fromTheme("edit-rename", QIcon(":/16x16/edit-rename.png")))
  1508. act_x_delete_room.setIcon(QIcon.fromTheme("edit-delete", QIcon(":/16x16/edit-delete.png")))
  1509. act_x_add_new.setEnabled(self.menu_Application.isEnabled() and self.act_app_add_new.isEnabled())
  1510. project_graph_version, project_properties = DBus.ladish_room.GetProjectProperties()
  1511. if len(project_properties) == 0:
  1512. act_x_run_custom.setEnabled(False)
  1513. act_x_save.setEnabled(False)
  1514. act_x_save_as.setEnabled(False)
  1515. act_x_unload.setEnabled(False)
  1516. act_x_properties.setEnabled(False)
  1517. elif item.type() in (ITEM_TYPE_STUDIO_APP, ITEM_TYPE_ROOM_APP):
  1518. if item.properties[iItemPropActive]:
  1519. act_x_start = None
  1520. act_x_stop = cMenu.addAction(self.tr("Stop"))
  1521. act_x_kill = cMenu.addAction(self.tr("Kill"))
  1522. act_x_stop.setIcon(QIcon.fromTheme("media-playback-stop", QIcon(":/16x16/media-playback-stop.png")))
  1523. act_x_kill.setIcon(QIcon.fromTheme("dialog-close", QIcon(":/16x16/dialog-close.png")))
  1524. else:
  1525. act_x_start = cMenu.addAction(self.tr("Start"))
  1526. act_x_stop = None
  1527. act_x_kill = None
  1528. act_x_start.setIcon(QIcon.fromTheme("media-playback-start", QIcon(":/16x16/media-playback-start.png")))
  1529. act_x_properties = cMenu.addAction(self.tr("Properties"))
  1530. cMenu.addSeparator()
  1531. act_x_remove = cMenu.addAction(self.tr("Remove"))
  1532. act_x_properties.setIcon(QIcon.fromTheme("edit-rename", QIcon(":/16x16/edit-rename.png")))
  1533. act_x_remove.setIcon(QIcon.fromTheme("edit-delete", QIcon(":/16x16/edit-delete.png")))
  1534. else:
  1535. return
  1536. act_x_sel = cMenu.exec_(QCursor.pos())
  1537. if act_x_sel:
  1538. if item.type() == ITEM_TYPE_STUDIO:
  1539. if act_x_sel == act_x_add_new:
  1540. pass #self.slot_app_add_new()
  1541. elif act_x_sel == act_x_run_custom:
  1542. self.slot_app_run_custom()
  1543. elif act_x_sel == act_x_create_room:
  1544. self.slot_room_create()
  1545. elif item.type() == ITEM_TYPE_ROOM:
  1546. if act_x_sel == act_x_add_new:
  1547. pass # self.slot_app_add_new
  1548. elif act_x_sel == act_x_run_custom:
  1549. self.slot_app_run_custom()
  1550. elif act_x_sel == act_x_new:
  1551. self.slot_project_new()
  1552. elif act_x_sel == act_x_save:
  1553. self.slot_project_save()
  1554. elif act_x_sel == act_x_save_as:
  1555. self.slot_project_save_as()
  1556. elif act_x_sel == act_x_unload:
  1557. self.slot_project_unload()
  1558. elif act_x_sel == act_x_properties:
  1559. self.slot_project_properties()
  1560. elif act_x_sel == act_x_delete_room:
  1561. room_name = DBus.ladish_room.GetName()
  1562. DBus.ladish_studio.DeleteRoom(room_name)
  1563. elif item.type() in (ITEM_TYPE_STUDIO_APP, ITEM_TYPE_ROOM_APP):
  1564. number = item.properties[iItemPropNumber]
  1565. if act_x_sel == act_x_start:
  1566. DBus.ladish_app_iface.StartApp(number)
  1567. elif act_x_sel == act_x_stop:
  1568. DBus.ladish_app_iface.StopApp(number)
  1569. elif act_x_sel == act_x_kill:
  1570. DBus.ladish_app_iface.KillApp(number)
  1571. elif act_x_sel == act_x_properties:
  1572. name, command, active, terminal, level = DBus.ladish_app_iface.GetAppProperties2(number)
  1573. app_obj = [None, None, None, None, None]
  1574. app_obj[iAppCommand] = str(command)
  1575. app_obj[iAppName] = str(name)
  1576. app_obj[iAppTerminal] = bool(terminal)
  1577. app_obj[iAppLevel] = str(level)
  1578. app_obj[iAppActive] = bool(active)
  1579. dialog = RunCustomW(self, bool(item.type() == ITEM_TYPE_ROOM_APP), app_obj)
  1580. dialog.setWindowTitle(self.tr("App properties"))
  1581. if dialog.exec_():
  1582. app_obj = dialog.ret_app_obj
  1583. DBus.ladish_app_iface.SetAppProperties2(number, app_obj[iAppName], app_obj[iAppCommand], app_obj[iAppTerminal], app_obj[iAppLevel])
  1584. elif act_x_sel == act_x_remove:
  1585. DBus.ladish_app_iface.RemoveApp(number)
  1586. @pyqtSlot(float)
  1587. def slot_canvasScaleChanged(self, scale):
  1588. self.miniCanvasPreview.setViewScale(scale)
  1589. @pyqtSlot(int, int, QPointF)
  1590. def slot_canvasItemMoved(self, group_id, split_mode, pos):
  1591. if split_mode == patchcanvas.PORT_MODE_INPUT:
  1592. canvas_x = URI_CANVAS_X_SPLIT
  1593. canvas_y = URI_CANVAS_Y_SPLIT
  1594. else:
  1595. canvas_x = URI_CANVAS_X
  1596. canvas_y = URI_CANVAS_Y
  1597. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, canvas_x, str(pos.x()))
  1598. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, canvas_y, str(pos.y()))
  1599. self.miniCanvasPreview.update()
  1600. @pyqtSlot(int)
  1601. def slot_horizontalScrollBarChanged(self, value):
  1602. maximum = self.graphicsView.horizontalScrollBar().maximum()
  1603. if maximum == 0:
  1604. xp = 0
  1605. else:
  1606. xp = float(value) / maximum
  1607. self.miniCanvasPreview.setViewPosX(xp)
  1608. @pyqtSlot(int)
  1609. def slot_verticalScrollBarChanged(self, value):
  1610. maximum = self.graphicsView.verticalScrollBar().maximum()
  1611. if maximum == 0:
  1612. yp = 0
  1613. else:
  1614. yp = float(value) / maximum
  1615. self.miniCanvasPreview.setViewPosY(yp)
  1616. @pyqtSlot()
  1617. def slot_miniCanvasInit(self):
  1618. self.graphicsView.horizontalScrollBar().setValue(self.settings.value("HorizontalScrollBarValue", DEFAULT_CANVAS_WIDTH / 3, type=int))
  1619. self.graphicsView.verticalScrollBar().setValue(self.settings.value("VerticalScrollBarValue", DEFAULT_CANVAS_HEIGHT * 3 / 8, type=int))
  1620. @pyqtSlot(float, float)
  1621. def slot_miniCanvasMoved(self, xp, yp):
  1622. self.graphicsView.horizontalScrollBar().setValue(xp * DEFAULT_CANVAS_WIDTH)
  1623. self.graphicsView.verticalScrollBar().setValue(yp * DEFAULT_CANVAS_HEIGHT)
  1624. @pyqtSlot()
  1625. def slot_miniCanvasCheckAll(self):
  1626. self.slot_miniCanvasCheckSize()
  1627. self.slot_horizontalScrollBarChanged(self.graphicsView.horizontalScrollBar().value())
  1628. self.slot_verticalScrollBarChanged(self.graphicsView.verticalScrollBar().value())
  1629. @pyqtSlot()
  1630. def slot_miniCanvasCheckSize(self):
  1631. self.miniCanvasPreview.setViewSize(float(self.graphicsView.width()) / DEFAULT_CANVAS_WIDTH, float(self.graphicsView.height()) / DEFAULT_CANVAS_HEIGHT)
  1632. @pyqtSlot()
  1633. def slot_handleCrash_jack(self):
  1634. patchcanvas.clear()
  1635. self.DBusReconnect()
  1636. self.studioUnloaded()
  1637. @pyqtSlot()
  1638. def slot_handleCrash_ladish(self):
  1639. self.treeWidget.clear()
  1640. patchcanvas.clear()
  1641. self.DBusReconnect()
  1642. QMessageBox.warning(self, self.tr("Error"), self.tr("ladish daemon has crashed"))
  1643. @pyqtSlot()
  1644. def slot_handleCrash_studio(self):
  1645. QMessageBox.warning(self, self.tr("Error"), self.tr("jackdbus has crashed"))
  1646. @pyqtSlot(str)
  1647. def slot_DBusCrashCallback(self, appInterface):
  1648. if appInterface == "org.jackaudio.service":
  1649. if not (self.m_crashedJACK or self.m_crashedLADISH):
  1650. self.m_crashedJACK = True
  1651. QTimer.singleShot(1000, self, SLOT("slot_handleCrash_jack()"))
  1652. elif appInterface == "org.ladish":
  1653. if not (self.m_crashedJACK or self.m_crashedLADISH):
  1654. self.m_crashedLADISH = True
  1655. QTimer.singleShot(1000, self, SLOT("slot_handleCrash_ladish()"))
  1656. @pyqtSlot()
  1657. def slot_DBusServerStartedCallback(self):
  1658. self.jackStarted()
  1659. @pyqtSlot()
  1660. def slot_DBusServerStoppedCallback(self):
  1661. self.jackStopped()
  1662. @pyqtSlot(int, str)
  1663. def slot_DBusClientAppearedCallback(self, group_id, group_name):
  1664. self.canvas_add_group(group_id, group_name)
  1665. @pyqtSlot(int)
  1666. def slot_DBusClientDisappearedCallback(self, group_id):
  1667. self.canvas_remove_group(group_id)
  1668. @pyqtSlot(int, str)
  1669. def slot_DBusClientRenamedCallback(self, group_id, new_group_name):
  1670. self.canvas_rename_group(group_id, new_group_name)
  1671. @pyqtSlot(int, int, str, int, int)
  1672. def slot_DBusPortAppearedCallback(self, group_id, port_id, port_name, port_flags, port_type_jack):
  1673. if port_flags & JACKDBUS_PORT_FLAG_INPUT:
  1674. port_mode = patchcanvas.PORT_MODE_INPUT
  1675. elif port_flags & JACKDBUS_PORT_FLAG_OUTPUT:
  1676. port_mode = patchcanvas.PORT_MODE_OUTPUT
  1677. else:
  1678. port_mode = patchcanvas.PORT_MODE_NULL
  1679. if port_type_jack == JACKDBUS_PORT_TYPE_AUDIO:
  1680. port_type = patchcanvas.PORT_TYPE_AUDIO_JACK
  1681. elif port_type_jack == JACKDBUS_PORT_TYPE_MIDI:
  1682. if DBus.ladish_graph.Get(GRAPH_DICT_OBJECT_TYPE_PORT, port_id, URI_A2J_PORT) == "yes":
  1683. port_type = patchcanvas.PORT_TYPE_MIDI_A2J
  1684. else:
  1685. port_type = patchcanvas.PORT_TYPE_MIDI_JACK
  1686. else:
  1687. port_type = patchcanvas.PORT_TYPE_NULL
  1688. self.canvas_add_port(group_id, port_id, port_name, port_mode, port_type)
  1689. @pyqtSlot(int)
  1690. def slot_DBusPortDisppearedCallback(self, port_id):
  1691. self.canvas_remove_port(port_id)
  1692. @pyqtSlot(int, str)
  1693. def slot_DBusPortRenamedCallback(self, port_id, new_port_name):
  1694. self.canvas_rename_port(port_id, new_port_name)
  1695. @pyqtSlot(int, int, int)
  1696. def slot_DBusPortsConnectedCallback(self, connection_id, source_port_id, target_port_id):
  1697. self.canvas_connect_ports(connection_id, source_port_id, target_port_id)
  1698. @pyqtSlot(int)
  1699. def slot_DBusPortsDisconnectedCallback(self, connection_id):
  1700. self.canvas_disconnect_ports(connection_id)
  1701. @pyqtSlot()
  1702. def slot_DBusStudioAppearedCallback(self):
  1703. self.studioLoaded()
  1704. if DBus.ladish_studio.IsStarted():
  1705. self.studioStarted()
  1706. else:
  1707. self.studioStopped()
  1708. @pyqtSlot()
  1709. def slot_DBusStudioDisappearedCallback(self):
  1710. self.studioUnloaded()
  1711. @pyqtSlot()
  1712. def slot_DBusQueueExecutionHaltedCallback(self):
  1713. log_path = os.path.join(HOME, ".log", "ladish", "ladish.log")
  1714. if os.path.exists(log_path):
  1715. log_file = open(log_path)
  1716. log_text = logs.fixLogText(log_file.read().split("ERROR: ")[-1].split("\n")[0])
  1717. log_file.close()
  1718. else:
  1719. log_text = None
  1720. msgbox = QMessageBox(QMessageBox.Critical, self.tr("Execution Halted"),
  1721. self.tr("Something went wrong with ladish so the last action was not sucessful.\n"), QMessageBox.Ok, self)
  1722. if log_text:
  1723. msgbox.setInformativeText(self.tr("You can check the ladish log file (or click in the 'Show Details' button) to find out what went wrong."))
  1724. msgbox.setDetailedText(log_text)
  1725. else:
  1726. msgbox.setInformativeText(self.tr("You can check the ladish log file to find out what went wrong."))
  1727. msgbox.show()
  1728. @pyqtSlot()
  1729. def slot_DBusCleanExitCallback(self):
  1730. pass # TODO
  1731. #self.timer1000.stop()
  1732. #QTimer.singleShot(1000, self.DBusReconnect)
  1733. #QTimer.singleShot(1500, self.timer1000.start)
  1734. @pyqtSlot()
  1735. def slot_DBusStudioStartedCallback(self):
  1736. self.studioStarted()
  1737. @pyqtSlot()
  1738. def slot_DBusStudioStoppedCallback(self):
  1739. self.studioStopped()
  1740. @pyqtSlot(str)
  1741. def slot_DBusStudioRenamedCallback(self, new_name):
  1742. self.treeWidget.topLevelItem(0).setText(0, new_name)
  1743. @pyqtSlot()
  1744. def slot_DBusStudioCrashedCallback(self):
  1745. QTimer.singleShot(0, self, SLOT("slot_handleCrash_studio()"))
  1746. @pyqtSlot(str, str)
  1747. def slot_DBusRoomAppearedCallback(self, room_path, room_name):
  1748. self.room_add(room_path, room_name)
  1749. @pyqtSlot(str)
  1750. def slot_DBusRoomDisappearedCallback(self, room_path):
  1751. for i in range(self.treeWidget.topLevelItemCount()):
  1752. item = self.treeWidget.topLevelItem(i)
  1753. if i == 0:
  1754. continue
  1755. if item and item.type() == ITEM_TYPE_ROOM and item.properties[iItemPropRoomPath] == room_path:
  1756. for j in range(item.childCount()):
  1757. item.takeChild(j)
  1758. self.treeWidget.takeTopLevelItem(i)
  1759. break
  1760. else:
  1761. print("Claudia - room delete failed")
  1762. @pyqtSlot()
  1763. def slot_DBusRoomChangedCallback(self):
  1764. # Unused in ladish v1.0
  1765. return
  1766. @pyqtSlot(str, str)
  1767. def slot_DBusProjectPropertiesChanged(self, path, name):
  1768. has_project = bool(name)
  1769. if has_project:
  1770. item_string = " (%s)" % name
  1771. else:
  1772. item_string = ""
  1773. self.act_project_save.setEnabled(has_project)
  1774. self.act_project_save_as.setEnabled(has_project)
  1775. self.act_project_unload.setEnabled(has_project)
  1776. self.act_project_properties.setEnabled(has_project)
  1777. self.b_project_save.setEnabled(has_project)
  1778. self.b_project_save_as.setEnabled(has_project)
  1779. self.menu_Application.setEnabled(has_project)
  1780. if path == "/org/ladish/Studio":
  1781. top_level_item = self.treeWidget.topLevelItem(0)
  1782. room_name = ""
  1783. else:
  1784. for i in range(self.treeWidget.topLevelItemCount()):
  1785. if i == 0:
  1786. continue
  1787. top_level_item = self.treeWidget.topLevelItem(i)
  1788. if top_level_item and top_level_item.type() == ITEM_TYPE_ROOM and top_level_item.properties[iItemPropRoomPath] == path:
  1789. room_name = top_level_item.properties[iItemPropRoomName]
  1790. break
  1791. else:
  1792. return
  1793. top_level_item.setText(0, "%s%s" % (room_name, item_string))
  1794. @pyqtSlot(str, int, str, bool, bool, str)
  1795. def slot_DBusAppAdded2Callback(self, path, number, name, active, terminal, level):
  1796. if path == "/org/ladish/Studio":
  1797. ITEM_TYPE = ITEM_TYPE_STUDIO_APP
  1798. top_level_item = self.treeWidget.topLevelItem(0)
  1799. else:
  1800. ITEM_TYPE = ITEM_TYPE_ROOM_APP
  1801. for i in range(self.treeWidget.topLevelItemCount()):
  1802. if i == 0:
  1803. continue
  1804. top_level_item = self.treeWidget.topLevelItem(i)
  1805. if top_level_item and top_level_item.type() == ITEM_TYPE_ROOM and top_level_item.properties[iItemPropRoomPath] == path:
  1806. break
  1807. else:
  1808. return
  1809. for i in range(top_level_item.childCount()):
  1810. if top_level_item.child(i).properties[iItemPropNumber] == number:
  1811. # App was added before, probably during reload/init
  1812. return
  1813. prop_obj = [None, None, None, None, None]
  1814. prop_obj[iItemPropNumber] = number
  1815. prop_obj[iItemPropName] = name
  1816. prop_obj[iItemPropActive] = active
  1817. prop_obj[iItemPropTerminal] = terminal
  1818. prop_obj[iItemPropLevel] = level
  1819. text = "["
  1820. if level.isdigit():
  1821. text += "L%s" % level
  1822. elif level == "jacksession":
  1823. text += "JS"
  1824. else:
  1825. text += level.upper()
  1826. text += "] "
  1827. if not active:
  1828. text += "(inactive) "
  1829. text += name
  1830. item = QTreeWidgetItem(ITEM_TYPE)
  1831. item.properties = prop_obj
  1832. item.setText(0, text)
  1833. top_level_item.addChild(item)
  1834. @pyqtSlot(str, int)
  1835. def slot_DBusAppRemovedCallback(self, path, number):
  1836. if path == "/org/ladish/Studio":
  1837. top_level_item = self.treeWidget.topLevelItem(0)
  1838. else:
  1839. for i in range(self.treeWidget.topLevelItemCount()):
  1840. if i == 0:
  1841. continue
  1842. top_level_item = self.treeWidget.topLevelItem(i)
  1843. if top_level_item and top_level_item.type() == ITEM_TYPE_ROOM and top_level_item.properties[iItemPropRoomPath] == path:
  1844. break
  1845. else:
  1846. return
  1847. for i in range(top_level_item.childCount()):
  1848. if top_level_item.child(i).properties[iItemPropNumber] == number:
  1849. top_level_item.takeChild(i)
  1850. break
  1851. @pyqtSlot(str, int, str, bool, bool, str)
  1852. def slot_DBusAppStateChanged2Callback(self, path, number, name, active, terminal, level):
  1853. if path == "/org/ladish/Studio":
  1854. top_level_item = self.treeWidget.topLevelItem(0)
  1855. else:
  1856. for i in range(self.treeWidget.topLevelItemCount()):
  1857. if i == 0:
  1858. continue
  1859. top_level_item = self.treeWidget.topLevelItem(i)
  1860. if top_level_item and top_level_item.type() == ITEM_TYPE_ROOM and top_level_item.properties[iItemPropRoomPath] == path:
  1861. break
  1862. else:
  1863. return
  1864. prop_obj = [None, None, None, None, None]
  1865. prop_obj[iItemPropNumber] = number
  1866. prop_obj[iItemPropName] = name
  1867. prop_obj[iItemPropActive] = active
  1868. prop_obj[iItemPropTerminal] = terminal
  1869. prop_obj[iItemPropLevel] = level
  1870. text = "["
  1871. if level.isdigit():
  1872. text += "L%s" % level
  1873. elif level == "jacksession":
  1874. text += "JS"
  1875. else:
  1876. text += level.upper()
  1877. text += "] "
  1878. if not active:
  1879. text += "(inactive) "
  1880. text += name
  1881. for i in range(top_level_item.childCount()):
  1882. item = top_level_item.child(i)
  1883. if item.properties[iItemPropNumber] == number:
  1884. item.properties = prop_obj
  1885. item.setText(0, text)
  1886. break
  1887. @pyqtSlot()
  1888. def slot_JackClearXruns(self):
  1889. if jack.client:
  1890. DBus.jack.ResetXruns()
  1891. @pyqtSlot(int)
  1892. def slot_JackBufferSizeCallback(self, bufferSize):
  1893. self.setBufferSize(bufferSize)
  1894. @pyqtSlot(int)
  1895. def slot_JackSampleRateCallback(self, sampleRate):
  1896. self.setSampleRate(sampleRate)
  1897. @pyqtSlot()
  1898. def slot_JackShutdownCallback(self):
  1899. self.jackStopped()
  1900. @pyqtSlot()
  1901. def slot_configureClaudia(self):
  1902. # Save groups position now
  1903. if DBus.patchbay:
  1904. version, groups, conns = DBus.patchbay.GetGraph(0)
  1905. for group in groups:
  1906. group_id, group_name, ports = group
  1907. group_pos_i = patchcanvas.getGroupPos(group_id, patchcanvas.PORT_MODE_OUTPUT)
  1908. group_pos_o = patchcanvas.getGroupPos(group_id, patchcanvas.PORT_MODE_INPUT)
  1909. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_X, str(group_pos_o.x()))
  1910. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_Y, str(group_pos_o.y()))
  1911. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_X_SPLIT, str(group_pos_i.x()))
  1912. DBus.ladish_graph.Set(GRAPH_DICT_OBJECT_TYPE_CLIENT, group_id, URI_CANVAS_Y_SPLIT, str(group_pos_i.y()))
  1913. try:
  1914. ladish_config = DBus.bus.get_object("org.ladish.conf", "/org/ladish/conf")
  1915. except:
  1916. ladish_config = None
  1917. if ladish_config:
  1918. try:
  1919. key_notify = bool(ladish_config.get(LADISH_CONF_KEY_DAEMON_NOTIFY)[0] == "true")
  1920. except:
  1921. key_notify = LADISH_CONF_KEY_DAEMON_NOTIFY_DEFAULT
  1922. try:
  1923. key_shell = str(ladish_config.get(LADISH_CONF_KEY_DAEMON_SHELL)[0])
  1924. except:
  1925. key_shell = LADISH_CONF_KEY_DAEMON_SHELL_DEFAULT
  1926. try:
  1927. key_terminal = str(ladish_config.get(LADISH_CONF_KEY_DAEMON_TERMINAL)[0])
  1928. except:
  1929. key_terminal = LADISH_CONF_KEY_DAEMON_TERMINAL_DEFAULT
  1930. try:
  1931. key_studio_autostart = bool(ladish_config.get(LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART)[0] == "true")
  1932. except:
  1933. key_studio_autostart = LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART_DEFAULT
  1934. try:
  1935. key_js_save_delay = int(ladish_config.get(LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY)[0])
  1936. except:
  1937. key_js_save_delay = LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY_DEFAULT
  1938. self.settings.setValue(LADISH_CONF_KEY_DAEMON_NOTIFY, key_notify)
  1939. self.settings.setValue(LADISH_CONF_KEY_DAEMON_SHELL, key_shell)
  1940. self.settings.setValue(LADISH_CONF_KEY_DAEMON_TERMINAL, key_terminal)
  1941. self.settings.setValue(LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART, key_studio_autostart)
  1942. self.settings.setValue(LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY, key_js_save_delay)
  1943. dialog = SettingsW(self, "claudia", hasGL)
  1944. if not ladish_config:
  1945. dialog.lw_page.hideRow(2)
  1946. if dialog.exec_():
  1947. if ladish_config:
  1948. ladish_config.set(LADISH_CONF_KEY_DAEMON_NOTIFY, "true" if (self.settings.value(LADISH_CONF_KEY_DAEMON_NOTIFY, LADISH_CONF_KEY_DAEMON_NOTIFY_DEFAULT, type=bool)) else "false")
  1949. ladish_config.set(LADISH_CONF_KEY_DAEMON_SHELL, self.settings.value(LADISH_CONF_KEY_DAEMON_SHELL, LADISH_CONF_KEY_DAEMON_SHELL_DEFAULT, type=str))
  1950. ladish_config.set(LADISH_CONF_KEY_DAEMON_TERMINAL, self.settings.value(LADISH_CONF_KEY_DAEMON_TERMINAL, LADISH_CONF_KEY_DAEMON_TERMINAL_DEFAULT, type=str))
  1951. ladish_config.set(LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART, "true" if (self.settings.value(LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART, LADISH_CONF_KEY_DAEMON_STUDIO_AUTOSTART_DEFAULT, type=bool)) else "false")
  1952. ladish_config.set(LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY, str(self.settings.value(LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY, LADISH_CONF_KEY_DAEMON_JS_SAVE_DELAY_DEFAULT, type=int)))
  1953. self.loadSettings(False)
  1954. patchcanvas.clear()
  1955. pOptions = patchcanvas.options_t()
  1956. pOptions.theme_name = self.m_savedSettings["Canvas/Theme"]
  1957. pOptions.auto_hide_groups = self.m_savedSettings["Canvas/AutoHideGroups"]
  1958. pOptions.use_bezier_lines = self.m_savedSettings["Canvas/UseBezierLines"]
  1959. pOptions.antialiasing = self.m_savedSettings["Canvas/Antialiasing"]
  1960. pOptions.eyecandy = self.m_savedSettings["Canvas/EyeCandy"]
  1961. pFeatures = patchcanvas.features_t()
  1962. pFeatures.group_info = False
  1963. pFeatures.group_rename = True
  1964. pFeatures.port_info = True
  1965. pFeatures.port_rename = True
  1966. pFeatures.handle_group_pos = False
  1967. patchcanvas.setOptions(pOptions)
  1968. patchcanvas.setFeatures(pFeatures)
  1969. patchcanvas.init("Claudia", self.scene, self.canvasCallback, DEBUG)
  1970. self.miniCanvasPreview.setViewTheme(patchcanvas.canvas.theme.rubberband_brush, patchcanvas.canvas.theme.rubberband_pen.color())
  1971. if DBus.ladish_control.IsStudioLoaded() and DBus.ladish_studio and DBus.ladish_studio.IsStarted():
  1972. self.init_ports()
  1973. @pyqtSlot()
  1974. def slot_aboutClaudia(self):
  1975. QMessageBox.about(self, self.tr("About Claudia"), self.tr("<h3>Claudia</h3>"
  1976. "<br>Version %s"
  1977. "<br>Claudia is a Graphical User Interface to LADISH.<br>"
  1978. "<br>Copyright (C) 2010-2012 falkTX" % VERSION))
  1979. def saveSettings(self):
  1980. self.settings.setValue("Geometry", self.saveGeometry())
  1981. self.settings.setValue("SplitterSizes", self.splitter.saveState())
  1982. self.settings.setValue("ShowToolbar", self.frame_toolbar.isEnabled())
  1983. self.settings.setValue("ShowStatusbar", self.frame_statusbar.isEnabled())
  1984. self.settings.setValue("TransportView", self.m_curTransportView)
  1985. self.settings.setValue("HorizontalScrollBarValue", self.graphicsView.horizontalScrollBar().value())
  1986. self.settings.setValue("VerticalScrollBarValue", self.graphicsView.verticalScrollBar().value())
  1987. def loadSettings(self, geometry):
  1988. if geometry:
  1989. self.restoreGeometry(self.settings.value("Geometry", ""))
  1990. splitter_sizes = self.settings.value("SplitterSizes", "")
  1991. if splitter_sizes:
  1992. self.splitter.restoreState(splitter_sizes)
  1993. else:
  1994. self.splitter.setSizes((100, 400))
  1995. show_toolbar = self.settings.value("ShowToolbar", True, type=bool)
  1996. self.act_settings_show_toolbar.setChecked(show_toolbar)
  1997. self.frame_toolbar.setVisible(show_toolbar)
  1998. show_statusbar = self.settings.value("ShowStatusbar", True, type=bool)
  1999. self.act_settings_show_statusbar.setChecked(show_statusbar)
  2000. self.frame_statusbar.setVisible(show_statusbar)
  2001. self.setTransportView(self.settings.value("TransportView", TRANSPORT_VIEW_HMS, type=int))
  2002. self.m_savedSettings = {
  2003. "Main/DefaultProjectFolder": self.settings.value("Main/DefaultProjectFolder", DEFAULT_PROJECT_FOLDER, type=str),
  2004. "Main/UseSystemTray": self.settings.value("Main/UseSystemTray", True, type=bool),
  2005. "Main/CloseToTray": self.settings.value("Main/CloseToTray", False, type=bool),
  2006. "Main/RefreshInterval": self.settings.value("Main/RefreshInterval", 120, type=int),
  2007. "Canvas/Theme": self.settings.value("Canvas/Theme", patchcanvas.getDefaultThemeName(), type=str),
  2008. "Canvas/AutoHideGroups": self.settings.value("Canvas/AutoHideGroups", False, type=bool),
  2009. "Canvas/UseBezierLines": self.settings.value("Canvas/UseBezierLines", True, type=bool),
  2010. "Canvas/EyeCandy": self.settings.value("Canvas/EyeCandy", patchcanvas.EYECANDY_SMALL, type=int),
  2011. "Canvas/UseOpenGL": self.settings.value("Canvas/UseOpenGL", False, type=bool),
  2012. "Canvas/Antialiasing": self.settings.value("Canvas/Antialiasing", patchcanvas.ANTIALIASING_SMALL, type=int),
  2013. "Canvas/HighQualityAntialiasing": self.settings.value("Canvas/HighQualityAntialiasing", False, type=bool)
  2014. }
  2015. self.act_app_add_new.setEnabled(USE_CLAUDIA_ADD_NEW)
  2016. def resizeEvent(self, event):
  2017. QTimer.singleShot(0, self, SLOT("slot_miniCanvasCheckSize()"))
  2018. QMainWindow.resizeEvent(self, event)
  2019. def timerEvent(self, event):
  2020. if event.timerId() == self.m_timer120:
  2021. if jack.client:
  2022. self.refreshTransport()
  2023. self.refreshXruns()
  2024. elif event.timerId() == self.m_timer600:
  2025. if jack.client:
  2026. self.refreshDSPLoad()
  2027. else:
  2028. self.update()
  2029. QMainWindow.timerEvent(self, event)
  2030. def closeEvent(self, event):
  2031. self.saveSettings()
  2032. if self.systray:
  2033. if self.m_savedSettings["Main/CloseToTray"]:
  2034. if self.systray.handleQtCloseEvent(event):
  2035. patchcanvas.clear()
  2036. return
  2037. self.systray.close()
  2038. patchcanvas.clear()
  2039. QMainWindow.closeEvent(self, event)
  2040. #--------------- main ------------------
  2041. if __name__ == '__main__':
  2042. # App initialization
  2043. app = QApplication(sys.argv)
  2044. app.setApplicationName("Claudia")
  2045. app.setApplicationVersion(VERSION)
  2046. app.setOrganizationName("Cadence")
  2047. app.setWindowIcon(QIcon(":/scalable/claudia.svg"))
  2048. if not haveDBus:
  2049. QMessageBox.critical(None, app.translate("ClaudiaMainW", "Error"), app.translate("ClaudiaMainW",
  2050. "DBus is not available, Claudia cannot start without it!"))
  2051. sys.exit(1)
  2052. DBus.loop = DBusQtMainLoop(set_as_default=True)
  2053. DBus.bus = dbus.SessionBus(mainloop=DBus.loop)
  2054. DBus.jack = DBus.bus.get_object("org.jackaudio.service", "/org/jackaudio/Controller")
  2055. DBus.ladish_control = DBus.bus.get_object("org.ladish", "/org/ladish/Control")
  2056. try:
  2057. DBus.ladish_app_daemon = DBus.bus.get_object("org.ladish.appdb", "/")
  2058. except:
  2059. DBus.ladish_app_daemon = None
  2060. jacksettings.initBus(DBus.bus)
  2061. # Show GUI
  2062. gui = ClaudiaMainW()
  2063. if gui.systray and "--minimized" in app.arguments():
  2064. gui.hide()
  2065. gui.systray.setActionText("show", gui.tr("Restore"))
  2066. else:
  2067. gui.show()
  2068. # Set-up custom signal handling
  2069. setUpSignals(gui)
  2070. # App-Loop
  2071. if gui.systray:
  2072. ret = gui.systray.exec_(app)
  2073. else:
  2074. ret = app.exec_()
  2075. # Close Jack
  2076. if jack.client:
  2077. jacklib.deactivate(jack.client)
  2078. jacklib.client_close(jack.client)
  2079. # Exit properly
  2080. sys.exit(ret)