cadence/src/catarina.py

1329 lines
54 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# PatchCanvas test application
# Copyright (C) 2010-2018 Filipe Coelho <falktx@falktx.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# For a full copy of the GNU General Public License see the COPYING file
# ------------------------------------------------------------------------------------------------------------
# Imports (Global)
if True:
from PyQt5.QtCore import pyqtSlot, QSettings
from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QTableWidgetItem
from PyQt5.QtXml import QDomDocument
else:
from PyQt4.QtCore import pyqtSlot, QSettings
from PyQt4.QtGui import QApplication, QDialog, QDialogButtonBox, QTableWidgetItem
from PyQt4.QtXml import QDomDocument
# ------------------------------------------------------------------------------------------------------------
# Imports (Custom Stuff)
import ui_catarina
import ui_catarina_addgroup
import ui_catarina_removegroup
import ui_catarina_renamegroup
import ui_catarina_addport
import ui_catarina_removeport
import ui_catarina_renameport
import ui_catarina_connectports
import ui_catarina_disconnectports
from shared_canvasjack import *
from shared_settings import *
from shared_i18n import *
# ------------------------------------------------------------------------------------------------------------
# Try Import OpenGL
try:
from PyQt5.QtOpenGL import QGLWidget
hasGL = True
except:
hasGL = False
# ------------------------------------------------------------------------------------------------------------
# Static Variables
iGroupId = 0
iGroupName = 1
iGroupSplit = 2
iGroupIcon = 3
iGroupPosId = 0
iGroupPosX_o = 1
iGroupPosY_o = 2
iGroupPosX_i = 3
iGroupPosY_i = 4
iPortGroup = 0
iPortId = 1
iPortName = 2
iPortMode = 3
iPortType = 4
iConnId = 0
iConnOutput = 1
iConnInput = 2
# ------------------------------------------------------------------------------------------------------------
# Add Group Dialog
class CatarinaAddGroupW(QDialog, ui_catarina_addgroup.Ui_CatarinaAddGroupW):
def __init__(self, parent, group_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list_names = []
for group in group_list:
self.m_group_list_names.append(group[iGroupName])
self.accepted.connect(self.slot_setReturn)
self.le_group_name.textChanged.connect(self.slot_checkText)
self.ret_group_name = ""
self.ret_group_split = False
@pyqtSlot(str)
def slot_checkText(self, text):
check = bool(text and text not in self.m_group_list_names)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
self.ret_group_name = self.le_group_name.text()
self.ret_group_split = self.cb_split.isChecked()
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Remove Group Dialog
class CatarinaRemoveGroupW(QDialog, ui_catarina_removegroup.Ui_CatarinaRemoveGroupW):
def __init__(self, parent, group_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
index = 0
for group in group_list:
twi_group_id = QTableWidgetItem(str(group[iGroupId]))
twi_group_name = QTableWidgetItem(group[iGroupName])
twi_group_split = QTableWidgetItem("Yes" if (group[iGroupSplit]) else "No")
self.tw_group_list.insertRow(index)
self.tw_group_list.setItem(index, 0, twi_group_id)
self.tw_group_list.setItem(index, 1, twi_group_name)
self.tw_group_list.setItem(index, 2, twi_group_split)
index += 1
self.accepted.connect(self.slot_setReturn)
self.tw_group_list.cellDoubleClicked.connect(self.accept)
self.tw_group_list.currentCellChanged.connect(self.slot_checkCell)
self.ret_group_id = -1
@pyqtSlot(int)
def slot_checkCell(self, row):
check = bool(row >= 0)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
if self.tw_group_list.rowCount() >= 0:
self.ret_group_id = int(self.tw_group_list.item(self.tw_group_list.currentRow(), 0).text())
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Rename Group Dialog
class CatarinaRenameGroupW(QDialog, ui_catarina_renamegroup.Ui_CatarinaRenameGroupW):
def __init__(self, parent, group_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list_names = []
for group in group_list:
self.cb_group_to_rename.addItem("%i - %s" % (group[iGroupId], group[iGroupName]))
self.m_group_list_names.append(group[iGroupName])
self.accepted.connect(self.slot_setReturn)
self.cb_group_to_rename.currentIndexChanged[int].connect(self.slot_checkItem)
self.le_new_group_name.textChanged.connect(self.slot_checkText)
self.ret_group_id = -1
self.ret_new_group_name = ""
@pyqtSlot(int)
def slot_checkItem(self, ignored):
self.slot_checkText(self.le_new_group_name.text())
@pyqtSlot(str)
def slot_checkText(self, text):
if self.cb_group_to_rename.count() > 0:
group_name = self.cb_group_to_rename.currentText().split(" - ", 1)[1]
check = bool(text and text != group_name and text not in self.m_group_list_names)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
self.ret_group_id = int(self.cb_group_to_rename.currentText().split(" - ", 1)[0])
self.ret_new_group_name = self.le_new_group_name.text()
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Add Port Dialog
class CatarinaAddPortW(QDialog, ui_catarina_addport.Ui_CatarinaAddPortW):
def __init__(self, parent, group_list, port_id):
QDialog.__init__(self, parent)
self.setupUi(self)
self.sb_port_id.setValue(port_id)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
for group in group_list:
self.cb_group.addItem("%i - %s" % (group[iGroupId], group[iGroupName]))
self.accepted.connect(self.slot_setReturn)
self.le_port_name.textChanged.connect(self.slot_checkText)
self.ret_group_id = -1
self.ret_port_name = ""
self.ret_port_mode = patchcanvas.PORT_MODE_NULL
self.ret_port_type = patchcanvas.PORT_TYPE_NULL
@pyqtSlot(str)
def slot_checkText(self, text):
check = bool(text)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
if self.cb_group.count() > 0:
self.ret_group_id = int(self.cb_group.currentText().split(" ", 1)[0])
self.ret_port_name = self.le_port_name.text()
self.ret_port_mode = patchcanvas.PORT_MODE_INPUT if self.rb_flags_input.isChecked() else patchcanvas.PORT_MODE_OUTPUT
self.ret_port_type = self.cb_port_type.currentIndex() + 1 # 1, 2, 3 or 4 for patchcanvas types
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Remove Port Dialog
class CatarinaRemovePortW(QDialog, ui_catarina_removeport.Ui_CatarinaRemovePortW):
def __init__(self, parent, group_list, port_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.tw_port_list.setColumnWidth(0, 25)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list = group_list
self.m_port_list = port_list
self.accepted.connect(self.slot_setReturn)
self.tw_port_list.cellDoubleClicked.connect(self.accept)
self.tw_port_list.currentCellChanged.connect(self.slot_checkCell)
self.rb_input.clicked.connect(self.slot_reAddPorts)
self.rb_output.clicked.connect(self.slot_reAddPorts)
self.rb_audio_jack.clicked.connect(self.slot_reAddPorts)
self.rb_midi_jack.clicked.connect(self.slot_reAddPorts)
self.rb_midi_a2j.clicked.connect(self.slot_reAddPorts)
self.rb_midi_alsa.clicked.connect(self.slot_reAddPorts)
self.ret_port_id = -1
self.reAddPorts()
def reAddPorts(self):
self.tw_port_list.clearContents()
for x in range(self.tw_port_list.rowCount()):
self.tw_port_list.removeRow(0)
port_mode = patchcanvas.PORT_MODE_INPUT if (self.rb_input.isChecked()) else patchcanvas.PORT_MODE_OUTPUT
if self.rb_audio_jack.isChecked():
port_type = patchcanvas.PORT_TYPE_AUDIO_JACK
elif self.rb_midi_jack.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_JACK
elif self.rb_midi_a2j.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_A2J
elif self.rb_midi_alsa.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_ALSA
else:
print("CatarinaRemovePortW::reAddPorts() - Invalid port type")
return
index = 0
for port in self.m_port_list:
if port[iPortMode] == port_mode and port[iPortType] == port_type:
port_name = port[iPortName]
group_name = self.findPortGroupName(port[iPortGroup])
tw_port_id = QTableWidgetItem(str(port[iPortId]))
tw_port_name = QTableWidgetItem("%s:%s" % (group_name, port_name))
self.tw_port_list.insertRow(index)
self.tw_port_list.setItem(index, 0, tw_port_id)
self.tw_port_list.setItem(index, 1, tw_port_name)
index += 1
def findPortGroupName(self, group_id):
for group in self.m_group_list:
if group[iGroupId] == group_id:
return group[iGroupName]
return ""
@pyqtSlot()
def slot_reAddPorts(self):
self.reAddPorts()
@pyqtSlot(int)
def slot_checkCell(self, row):
check = bool(row >= 0)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
if self.tw_port_list.rowCount() > 0:
self.ret_port_id = int(self.tw_port_list.item(self.tw_port_list.currentRow(), 0).text())
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Rename Port Dialog
class CatarinaRenamePortW(QDialog, ui_catarina_renameport.Ui_CatarinaRenamePortW):
def __init__(self, parent, group_list, port_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.tw_port_list.setColumnWidth(0, 25)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list = group_list
self.m_port_list = port_list
self.accepted.connect(self.slot_setReturn)
self.tw_port_list.currentCellChanged.connect(self.slot_checkCell)
self.le_new_name.textChanged.connect(self.slot_checkText)
self.rb_input.clicked.connect(self.slot_reAddPorts)
self.rb_output.clicked.connect(self.slot_reAddPorts)
self.rb_audio_jack.clicked.connect(self.slot_reAddPorts)
self.rb_midi_jack.clicked.connect(self.slot_reAddPorts)
self.rb_midi_a2j.clicked.connect(self.slot_reAddPorts)
self.rb_midi_alsa.clicked.connect(self.slot_reAddPorts)
self.ret_port_id = -1
self.ret_new_port_name = ""
self.reAddPorts()
def reAddPorts(self):
self.tw_port_list.clearContents()
for x in range(self.tw_port_list.rowCount()):
self.tw_port_list.removeRow(0)
port_mode = patchcanvas.PORT_MODE_INPUT if (self.rb_input.isChecked()) else patchcanvas.PORT_MODE_OUTPUT
if self.rb_audio_jack.isChecked():
port_type = patchcanvas.PORT_TYPE_AUDIO_JACK
elif self.rb_midi_jack.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_JACK
elif self.rb_midi_a2j.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_A2J
elif self.rb_midi_alsa.isChecked():
port_type = patchcanvas.PORT_TYPE_MIDI_ALSA
else:
print("CatarinaRenamePortW::reAddPorts() - Invalid port type")
return
index = 0
for port in self.m_port_list:
if port[iPortMode] == port_mode and port[iPortType] == port_type:
port_name = port[iPortName]
group_name = self.findPortGroupName(port[iPortGroup])
tw_port_id = QTableWidgetItem(str(port[iPortId]))
tw_port_name = QTableWidgetItem("%s:%s" % (group_name, port_name))
self.tw_port_list.insertRow(index)
self.tw_port_list.setItem(index, 0, tw_port_id)
self.tw_port_list.setItem(index, 1, tw_port_name)
index += 1
self.tw_port_list.setCurrentCell(0, 0)
def findPortGroupName(self, group_id):
for group in self.m_group_list:
if group[iGroupId] == group_id:
return group[iGroupName]
return ""
@pyqtSlot()
def slot_reAddPorts(self):
self.reAddPorts()
@pyqtSlot()
def slot_checkCell(self):
self.slot_checkText(self.le_new_name.text())
@pyqtSlot(str)
def slot_checkText(self, text):
check = bool(text and self.tw_port_list.currentRow() >= 0)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
if self.tw_port_list.rowCount() > 0:
self.ret_port_id = int(self.tw_port_list.item(self.tw_port_list.currentRow(), 0).text())
self.ret_new_port_name = self.le_new_name.text()
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Connect Ports Dialog
class CatarinaConnectPortsW(QDialog, ui_catarina_connectports.Ui_CatarinaConnectPortsW):
def __init__(self, parent, group_list, port_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list = group_list
self.m_port_list = port_list
self.m_ports_audio_jack = []
self.m_ports_midi_jack = []
self.m_ports_midi_a2j = []
self.m_ports_midi_alsa = []
for port in self.m_port_list:
if port[iPortType] == patchcanvas.PORT_TYPE_AUDIO_JACK:
self.m_ports_audio_jack.append(port)
elif port[iPortType] == patchcanvas.PORT_TYPE_MIDI_JACK:
self.m_ports_midi_jack.append(port)
elif port[iPortType] == patchcanvas.PORT_TYPE_MIDI_A2J:
self.m_ports_midi_a2j.append(port)
elif port[iPortType] == patchcanvas.PORT_TYPE_MIDI_ALSA:
self.m_ports_midi_alsa.append(port)
self.accepted.connect(self.slot_setReturn)
self.rb_audio_jack.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_jack.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_a2j.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_alsa.clicked.connect(self.slot_portTypeChanged)
self.lw_outputs.currentRowChanged.connect(self.slot_checkOutSelection)
self.lw_inputs.currentRowChanged.connect(self.slot_checkInSelection)
self.ret_port_out_id = -1
self.ret_port_in_id = -1
self.slot_portTypeChanged()
def showPorts(self, ports):
self.lw_outputs.clear()
self.lw_inputs.clear()
for port in ports:
if port[iPortMode] == patchcanvas.PORT_MODE_INPUT:
self.lw_inputs.addItem("%i - %s:%s" % (port[iPortId], self.findPortGroupName(port[iPortGroup]), port[iPortName]))
elif port[iPortMode] == patchcanvas.PORT_MODE_OUTPUT:
self.lw_outputs.addItem("%i - %s:%s" % (port[iPortId], self.findPortGroupName(port[iPortGroup]), port[iPortName]))
def findPortGroupName(self, group_id):
for group in self.m_group_list:
if group[iGroupId] == group_id:
return group[iGroupName]
return ""
def checkSelection(self, out_row, in_row):
check = bool(out_row >= 0 and in_row >= 0)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_portTypeChanged(self):
if self.rb_audio_jack.isChecked():
ports = self.m_ports_audio_jack
elif self.rb_midi_jack.isChecked():
ports = self.m_ports_midi_jack
elif self.rb_midi_a2j.isChecked():
ports = self.m_ports_midi_a2j
elif self.rb_midi_alsa.isChecked():
ports = self.m_ports_midi_alsa
else:
print("CatarinaConnectPortstW::portTypeChanged() - Invalid port type")
return
self.showPorts(ports)
@pyqtSlot(int)
def slot_checkOutSelection(self, row):
self.checkSelection(row, self.lw_inputs.currentRow())
@pyqtSlot(int)
def slot_checkInSelection(self, row):
self.checkSelection(self.lw_outputs.currentRow(), row)
@pyqtSlot()
def slot_setReturn(self):
if self.lw_outputs.currentRow() >= 0 and self.lw_inputs.currentRow() >= 0:
self.ret_port_out_id = int(self.lw_outputs.currentItem().text().split(" - ", 1)[0])
self.ret_port_in_id = int(self.lw_inputs.currentItem().text().split(" - ", 1)[0])
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Disconnect Ports Dialog
class CatarinaDisconnectPortsW(QDialog, ui_catarina_disconnectports.Ui_CatarinaDisconnectPortsW):
def __init__(self, parent, group_list, port_list, connection_list):
QDialog.__init__(self, parent)
self.setupUi(self)
self.tw_connections.setColumnWidth(0, 225)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
self.m_group_list = group_list
self.m_port_list = port_list
self.m_connection_list = connection_list
self.accepted.connect(self.slot_setReturn)
self.tw_connections.cellDoubleClicked.connect(self.accept)
self.tw_connections.currentCellChanged.connect(self.slot_checkSelection)
self.rb_audio_jack.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_jack.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_a2j.clicked.connect(self.slot_portTypeChanged)
self.rb_midi_alsa.clicked.connect(self.slot_portTypeChanged)
self.ret_port_out_id = -1
self.ret_port_in_id = -1
self.slot_portTypeChanged()
def showPorts(self, ptype):
self.tw_connections.clearContents()
for x in range(self.tw_connections.rowCount()):
self.tw_connections.removeRow(0)
index = 0
for connection in self.m_connection_list:
if self.findPortType(connection[iConnOutput]) == ptype:
port_out_id = connection[iConnOutput]
port_out_name = self.findPortName(port_out_id)
port_in_id = connection[iConnInput]
port_in_name = self.findPortName(port_in_id)
tw_port_out = QTableWidgetItem("%i - %s" % (port_out_id, port_out_name))
tw_port_in = QTableWidgetItem("%i - %s" % (port_in_id, port_in_name))
self.tw_connections.insertRow(index)
self.tw_connections.setItem(index, 0, tw_port_out)
self.tw_connections.setItem(index, 1, tw_port_in)
index += 1
def findPortName(self, port_id):
for port in self.m_port_list:
if port[iPortId] == port_id:
return "%s:%s" % (self.findPortGroupName(port[iPortGroup]), port[iPortName])
return ""
def findPortType(self, port_id):
for port in self.m_port_list:
if port[iPortId] == port_id:
return port[iPortType]
return patchcanvas.PORT_TYPE_NULL
def findPortGroupName(self, group_id):
for group in self.m_group_list:
if group[iGroupId] == group_id:
return group[iGroupName]
return ""
@pyqtSlot()
def slot_portTypeChanged(self):
if self.rb_audio_jack.isChecked():
ptype = patchcanvas.PORT_TYPE_AUDIO_JACK
elif self.rb_midi_jack.isChecked():
ptype = patchcanvas.PORT_TYPE_MIDI_JACK
elif self.rb_midi_a2j.isChecked():
ptype = patchcanvas.PORT_TYPE_MIDI_A2J
elif self.rb_midi_alsa.isChecked():
ptype = patchcanvas.PORT_TYPE_MIDI_ALSA
else:
print("CatarinaDisconnectPortstW::portTypeChanged() - Invalid port type")
return
self.showPorts(ptype)
@pyqtSlot(int)
def slot_checkSelection(self, row):
check = bool(row >= 0)
self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(check)
@pyqtSlot()
def slot_setReturn(self):
if self.tw_connections.currentRow() >= 0:
self.ret_port_out_id = int(self.tw_connections.item(self.tw_connections.currentRow(), 0).text().split(" - ", 1)[0])
self.ret_port_in_id = int(self.tw_connections.item(self.tw_connections.currentRow(), 1).text().split(" - ", 1)[0])
def done(self, r):
QDialog.done(self, r)
self.close()
# ------------------------------------------------------------------------------------------------------------
# Main Window
class CatarinaMainW(AbstractCanvasJackClass):
def __init__(self, parent=None):
AbstractCanvasJackClass.__init__(self, "Catarina", ui_catarina.Ui_CatarinaMainW, parent)
self.loadSettings(True)
# -------------------------------------------------------------
# Set-up GUI
setIcons(self, ("canvas",))
self.ui.act_project_new.setIcon(getIcon("document-new"))
self.ui.act_project_open.setIcon(getIcon("document-open"))
self.ui.act_project_save.setIcon(getIcon("document-save"))
self.ui.act_project_save_as.setIcon(getIcon("document-save-as"))
self.ui.b_project_new.setIcon(getIcon("document-new"))
self.ui.b_project_open.setIcon(getIcon("document-open"))
self.ui.b_project_save.setIcon(getIcon("document-save"))
self.ui.b_project_save_as.setIcon(getIcon("document-save-as"))
self.ui.act_patchbay_add_group.setIcon(getIcon("list-add"))
self.ui.act_patchbay_remove_group.setIcon(getIcon("edit-delete"))
self.ui.act_patchbay_rename_group.setIcon(getIcon("edit-rename"))
self.ui.act_patchbay_add_port.setIcon(getIcon("list-add"))
self.ui.act_patchbay_remove_port.setIcon(getIcon("list-remove"))
self.ui.act_patchbay_rename_port.setIcon(getIcon("edit-rename"))
self.ui.act_patchbay_connect_ports.setIcon(getIcon("network-connect"))
self.ui.act_patchbay_disconnect_ports.setIcon(getIcon("network-disconnect"))
self.ui.b_group_add.setIcon(getIcon("list-add"))
self.ui.b_group_remove.setIcon(getIcon("edit-delete"))
self.ui.b_group_rename.setIcon(getIcon("edit-rename"))
self.ui.b_port_add.setIcon(getIcon("list-add"))
self.ui.b_port_remove.setIcon(getIcon("list-remove"))
self.ui.b_port_rename.setIcon(getIcon("edit-rename"))
self.ui.b_ports_connect.setIcon(getIcon("network-connect"))
self.ui.b_ports_disconnect.setIcon(getIcon("network-disconnect"))
self.scene = patchcanvas.PatchScene(self, self.ui.graphicsView)
self.ui.graphicsView.setScene(self.scene)
self.ui.graphicsView.setRenderHint(QPainter.Antialiasing, bool(self.fSavedSettings["Canvas/Antialiasing"] == patchcanvas.ANTIALIASING_FULL))
self.ui.graphicsView.setRenderHint(QPainter.TextAntialiasing, self.fSavedSettings["Canvas/TextAntialiasing"])
if self.fSavedSettings["Canvas/UseOpenGL"] and hasGL:
self.ui.graphicsView.setViewport(QGLWidget(self.ui.graphicsView))
self.ui.graphicsView.setRenderHint(QPainter.HighQualityAntialiasing, self.fSavedSettings["Canvas/HighQualityAntialiasing"])
p_options = patchcanvas.options_t()
p_options.theme_name = self.fSavedSettings["Canvas/Theme"]
p_options.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"]
p_options.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"]
p_options.antialiasing = self.fSavedSettings["Canvas/Antialiasing"]
p_options.eyecandy = self.fSavedSettings["Canvas/EyeCandy"]
p_features = patchcanvas.features_t()
p_features.group_info = False
p_features.group_rename = True
p_features.port_info = True
p_features.port_rename = True
p_features.handle_group_pos = True
patchcanvas.setOptions(p_options)
patchcanvas.setFeatures(p_features)
patchcanvas.init("Catarina", self.scene, self.canvasCallback, DEBUG)
self.ui.act_project_new.triggered.connect(self.slot_projectNew)
self.ui.act_project_open.triggered.connect(self.slot_projectOpen)
self.ui.act_project_save.triggered.connect(self.slot_projectSave)
self.ui.act_project_save_as.triggered.connect(self.slot_projectSaveAs)
self.ui.b_project_new.clicked.connect(self.slot_projectNew)
self.ui.b_project_open.clicked.connect(self.slot_projectOpen)
self.ui.b_project_save.clicked.connect(self.slot_projectSave)
self.ui.b_project_save_as.clicked.connect(self.slot_projectSaveAs)
self.ui.act_patchbay_add_group.triggered.connect(self.slot_groupAdd)
self.ui.act_patchbay_remove_group.triggered.connect(self.slot_groupRemove)
self.ui.act_patchbay_rename_group.triggered.connect(self.slot_groupRename)
self.ui.act_patchbay_add_port.triggered.connect(self.slot_portAdd)
self.ui.act_patchbay_remove_port.triggered.connect(self.slot_portRemove)
self.ui.act_patchbay_rename_port.triggered.connect(self.slot_portRename)
self.ui.act_patchbay_connect_ports.triggered.connect(self.slot_connectPorts)
self.ui.act_patchbay_disconnect_ports.triggered.connect(self.slot_disconnectPorts)
self.ui.b_group_add.clicked.connect(self.slot_groupAdd)
self.ui.b_group_remove.clicked.connect(self.slot_groupRemove)
self.ui.b_group_rename.clicked.connect(self.slot_groupRename)
self.ui.b_port_add.clicked.connect(self.slot_portAdd)
self.ui.b_port_remove.clicked.connect(self.slot_portRemove)
self.ui.b_port_rename.clicked.connect(self.slot_portRename)
self.ui.b_ports_connect.clicked.connect(self.slot_connectPorts)
self.ui.b_ports_disconnect.clicked.connect(self.slot_disconnectPorts)
self.setCanvasConnections()
self.ui.act_settings_configure.triggered.connect(self.slot_configureCatarina)
self.ui.act_help_about.triggered.connect(self.slot_aboutCatarina)
self.ui.act_help_about_qt.triggered.connect(app.aboutQt)
self.SIGUSR1.connect(self.slot_projectSave)
# Dummy timer to keep events active
self.fUpdateTimer = self.startTimer(1000)
# Start Empty Project
self.slot_projectNew()
def canvasCallback(self, action, value1, value2, value_str):
if action == patchcanvas.ACTION_GROUP_INFO:
pass
elif action == patchcanvas.ACTION_GROUP_RENAME:
group_id = value1
new_group_name = value_str
for group in self.m_group_list:
if group[iGroupName] == new_group_name:
QMessageBox.warning(self, self.tr("Warning"), self.tr("There is already a group with this name"))
return
patchcanvas.renameGroup(group_id, new_group_name)
for group in self.m_group_list:
if group[iGroupId] == group_id:
group[iGroupName] = new_group_name
break
elif action == patchcanvas.ACTION_GROUP_SPLIT:
group_id = value1
patchcanvas.splitGroup(group_id)
for group in self.m_group_list:
if group[iGroupId] == group_id:
group[iGroupSplit] = True
break
elif action == patchcanvas.ACTION_GROUP_JOIN:
group_id = value1
patchcanvas.joinGroup(group_id)
for group in self.m_group_list:
if group[iGroupId] == group_id:
group[iGroupSplit] = False
break
elif action == patchcanvas.ACTION_PORT_INFO:
port_id = value1
group_id = 0
group_name = ""
port_name = ""
port_mode = patchcanvas.PORT_MODE_NULL
port_type = patchcanvas.PORT_TYPE_NULL
for port in self.m_port_list:
if port[iPortId] == port_id:
group_id = port[iPortGroup]
port_name = port[iPortName]
port_mode = port[iPortMode]
port_type = port[iPortType]
break
for group in self.m_group_list:
if group[iGroupId] == group_id:
group_name = group[iGroupName]
break
if port_mode == patchcanvas.PORT_MODE_INPUT:
mode_text = self.tr("Input")
elif port_mode == patchcanvas.PORT_MODE_OUTPUT:
mode_text = self.tr("Output")
else:
mode_text = self.tr("Unknown")
if port_type == patchcanvas.PORT_TYPE_AUDIO_JACK:
type_text = self.tr("JACK Audio")
elif port_type == patchcanvas.PORT_TYPE_MIDI_JACK:
type_text = self.tr("JACK MIDI")
elif port_type == patchcanvas.PORT_TYPE_MIDI_A2J:
type_text = self.tr("A2J MIDI")
elif port_type == patchcanvas.PORT_TYPE_MIDI_ALSA:
type_text = self.tr("ALSA MIDI")
else:
type_text = self.tr("Unknown")
port_full_name = group_name + ":" + port_name
info = self.tr(""
"<table>"
"<tr><td align='right'><b>Group Name:</b></td><td>&nbsp;%1</td></tr>"
"<tr><td align='right'><b>Group ID:</b></td><td>&nbsp;%2</td></tr>"
"<tr><td align='right'><b>Port Name:</b></td><td>&nbsp;%3</td></tr>"
"<tr><td align='right'><b>Port ID:</b></td><td>&nbsp;%4</i></td></tr>"
"<tr><td align='right'><b>Full Port Name:</b></td><td>&nbsp;%5</td></tr>"
"<tr><td colspan='2'>&nbsp;</td></tr>"
"<tr><td align='right'><b>Port Mode:</b></td><td>&nbsp;%6</td></tr>"
"<tr><td align='right'><b>Port Type:</b></td><td>&nbsp;%7</td></tr>"
"</table>"
).arg(group_name).arg(group_id).arg(port_name).arg(port_id).arg(port_full_name).arg(mode_text).arg(type_text)
QMessageBox.information(self, self.tr("Port Information"), info)
elif action == patchcanvas.ACTION_PORT_RENAME:
port_id = value1
new_port_name = value_str
patchcanvas.renamePort(port_id, new_port_name)
for port in self.m_port_list:
if port[iPortId] == port_id:
port[iPortName] = new_port_name
break
elif action == patchcanvas.ACTION_PORTS_CONNECT:
connection_id = self.m_last_connection_id
port_out_id = value1
port_in_id = value2
patchcanvas.connectPorts(connection_id, port_out_id, port_in_id)
conn_obj = [None, None, None]
conn_obj[iConnId] = connection_id
conn_obj[iConnOutput] = port_out_id
conn_obj[iConnInput] = port_in_id
self.m_connection_list.append(conn_obj)
self.m_last_connection_id += 1
elif action == patchcanvas.ACTION_PORTS_DISCONNECT:
connection_id = value1
patchcanvas.disconnectPorts(connection_id)
for connection in self.m_connection_list:
if connection[iConnId] == connection_id:
self.m_connection_list.remove(connection)
break
def initPorts(self):
for group in self.m_group_list:
patchcanvas.addGroup(group[iGroupId], group[iGroupName], patchcanvas.SPLIT_YES if (group[iGroupSplit]) else patchcanvas.SPLIT_NO, group[iGroupIcon])
for group_pos in self.m_group_list_pos:
patchcanvas.setGroupPosFull(group_pos[iGroupPosId], group_pos[iGroupPosX_o], group_pos[iGroupPosY_o], group_pos[iGroupPosX_i], group_pos[iGroupPosY_i])
for port in self.m_port_list:
patchcanvas.addPort(port[iPortGroup], port[iPortId], port[iPortName], port[iPortMode], port[iPortType])
for connection in self.m_connection_list:
patchcanvas.connectPorts(connection[iConnId], connection[iConnOutput], connection[iConnInput])
self.m_group_list_pos = []
patchcanvas.updateZValues()
def saveFile(self, path):
content = ("<?xml version='1.0' encoding='UTF-8'?>\n"
"<!DOCTYPE CATARINA>\n"
"<CATARINA VERSION='%s'>\n" % VERSION)
content += " <Groups>\n"
for i in range(len(self.m_group_list)):
group = self.m_group_list[i]
group_id = group[iGroupId]
group_name = group[iGroupName]
group_split = group[iGroupSplit]
group_icon = group[iGroupIcon]
group_pos_i = patchcanvas.getGroupPos(group_id, patchcanvas.PORT_MODE_INPUT)
group_pos_o = patchcanvas.getGroupPos(group_id, patchcanvas.PORT_MODE_OUTPUT)
content += " <g%i> <name>%s</name> <data>%i:%i:%i:%f:%f:%f:%f</data> </g%i>\n" % (i, group_name, group_id, group_split, group_icon, group_pos_o.x(), group_pos_o.y(), group_pos_i.x(), group_pos_i.y(), i)
content += " </Groups>\n"
content += " <Ports>\n"
for i in range(len(self.m_port_list)):
port = self.m_port_list[i]
content += " <p%i> <name>%s</name> <data>%i:%i:%i:%i</data> </p%i>\n" % (i, port[iPortName], port[iPortGroup], port[iPortId], port[iPortMode], port[iPortType], i)
content += " </Ports>\n"
content += " <Connections>\n"
for i in range(len(self.m_connection_list)):
connection = self.m_connection_list[i]
content += " <c%i>%i:%i:%i</c%i>\n" % (i, connection[iConnId], connection[iConnOutput], connection[iConnInput], i)
content += " </Connections>\n"
content += "</CATARINA>\n"
try:
fd = uopen(path, "w")
fd.write(content)
fd.close()
except:
QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to save file"))
def loadFile(self, path):
if not os.path.exists(path):
QMessageBox.critical(self, self.tr("Error"), self.tr("The file '%s' does not exist" % path))
self.m_save_path = None
return
try:
fd = uopen(path, "r")
readState = fd.read()
fd.close()
except:
QMessageBox.critical(self, self.tr("Error"), self.tr("Failed to load file"))
self.m_save_path = None
return
self.m_save_path = path
self.m_group_list = []
self.m_group_list_pos = []
self.m_port_list = []
self.m_connection_list = []
self.m_last_group_id = 1
self.m_last_port_id = 1
self.m_last_connection_id = 1
xml = QDomDocument()
xml.setContent(readState.encode("utf-8"))
content = xml.documentElement()
if content.tagName() != "CATARINA":
QMessageBox.critical(self, self.tr("Error"), self.tr("Not a valid Catarina file"))
return
# Get values from XML - the big code
node = content.firstChild()
while not node.isNull():
if node.toElement().tagName() == "Groups":
group_name = ""
groups = node.toElement().firstChild()
while not groups.isNull():
group = groups.toElement().firstChild()
while not group.isNull():
tag = group.toElement().tagName()
text = group.toElement().text()
if tag == "name":
group_name = text
elif tag == "data":
group_data = text.split(":")
if len(group_data) == 7 and group_data[0].isdigit() and group_data[1].isdigit() and group_data[2].isdigit() and isNumber(group_data[3]) and isNumber(group_data[4]) and isNumber(group_data[5]) and isNumber(group_data[6]):
group_obj = [None, None, None, None]
group_obj[iGroupId] = int(group_data[0])
group_obj[iGroupName] = group_name
group_obj[iGroupSplit] = int(group_data[1])
group_obj[iGroupIcon] = int(group_data[2])
group_pos_obj = [None, None, None, None, None]
group_pos_obj[iGroupPosId] = int(group_data[0])
group_pos_obj[iGroupPosX_o] = float(group_data[3])
group_pos_obj[iGroupPosY_o] = float(group_data[4])
group_pos_obj[iGroupPosX_i] = float(group_data[5])
group_pos_obj[iGroupPosY_i] = float(group_data[6])
self.m_group_list.append(group_obj)
self.m_group_list_pos.append(group_pos_obj)
group_id = group_obj[iGroupId]
if group_id > self.m_last_group_id:
self.m_last_group_id = group_id + 1
group = group.nextSibling()
groups = groups.nextSibling()
elif node.toElement().tagName() == "Ports":
port_name = ""
ports = node.toElement().firstChild()
while not ports.isNull():
port = ports.toElement().firstChild()
while not port.isNull():
tag = port.toElement().tagName()
text = port.toElement().text()
if tag == "name":
port_name = text
elif tag == "data":
port_data = text.split(":")
if len(port_data) == 4 and port_data[0].isdigit() and port_data[1].isdigit() and port_data[2].isdigit() and port_data[3].isdigit():
new_port = [None, None, None, None, None]
new_port[iPortGroup] = int(port_data[0])
new_port[iPortId] = int(port_data[1])
new_port[iPortName] = port_name
new_port[iPortMode] = int(port_data[2])
new_port[iPortType] = int(port_data[3])
self.m_port_list.append(new_port)
if new_port[iPortId] > self.m_last_port_id:
self.m_last_port_id = new_port[iPortId] + 1
port = port.nextSibling()
ports = ports.nextSibling()
elif node.toElement().tagName() == "Connections":
conns = node.toElement().firstChild()
while not conns.isNull():
conn_data = conns.toElement().text().split(":")
if len(conn_data) == 3 and conn_data[0].isdigit() and conn_data[1].isdigit() and conn_data[2].isdigit():
conn_obj = [None, None, None]
conn_obj[iConnId] = int(conn_data[0])
conn_obj[iConnOutput] = int(conn_data[1])
conn_obj[iConnInput] = int(conn_data[2])
connection_id = conn_obj[iConnId]
self.m_connection_list.append(conn_obj)
if connection_id >= self.m_last_connection_id:
self.m_last_connection_id = connection_id + 1
conns = conns.nextSibling()
node = node.nextSibling()
self.m_last_group_id += 1
self.m_last_port_id += 1
self.m_last_connection_id += 1
patchcanvas.clear()
self.initPorts()
self.scene.zoom_fit()
self.scene.zoom_reset()
@pyqtSlot()
def slot_projectNew(self):
self.m_group_list = []
self.m_group_list_pos = []
self.m_port_list = []
self.m_connection_list = []
self.m_last_group_id = 1
self.m_last_port_id = 1
self.m_last_connection_id = 1
self.m_save_path = None
patchcanvas.clear()
@pyqtSlot()
def slot_projectOpen(self):
path, _ = QFileDialog.getOpenFileName(self, self.tr("Load State"), filter=self.tr("Catarina XML Document (*.xml)"))
if path:
self.loadFile(path)
@pyqtSlot()
def slot_projectSave(self):
if self.m_save_path:
self.saveFile(self.m_save_path)
else:
self.slot_projectSaveAs()
@pyqtSlot()
def slot_projectSaveAs(self):
path, _ = QFileDialog.getSaveFileName(self, self.tr("Save State"), filter=self.tr("Catarina XML Document (*.xml)"))
if path:
self.m_save_path = path
self.saveFile(path)
@pyqtSlot()
def slot_groupAdd(self):
dialog = CatarinaAddGroupW(self, self.m_group_list)
if dialog.exec_():
group_id = self.m_last_group_id
group_name = dialog.ret_group_name
group_split = dialog.ret_group_split
group_splitR = patchcanvas.SPLIT_YES if group_split else patchcanvas.SPLIT_NO
group_icon = patchcanvas.ICON_HARDWARE if group_split else patchcanvas.ICON_APPLICATION
patchcanvas.addGroup(group_id, group_name, group_splitR, group_icon)
group_obj = [None, None, None, None]
group_obj[iGroupId] = group_id
group_obj[iGroupName] = group_name
group_obj[iGroupSplit] = group_split
group_obj[iGroupIcon] = group_icon
self.m_group_list.append(group_obj)
self.m_last_group_id += 1
@pyqtSlot()
def slot_groupRemove(self):
if len(self.m_group_list) > 0:
dialog = CatarinaRemoveGroupW(self, self.m_group_list)
if dialog.exec_():
group_id = dialog.ret_group_id
# Remove port connections first
for port in self.m_port_list:
if port[iPortGroup] == group_id:
port_id = port[iPortId]
h = 0
for i in range(len(self.m_connection_list)):
connection = self.m_connection_list[i-h]
if connection[iConnOutput] == port_id or connection[iConnInput] == port_id:
patchcanvas.disconnectPorts(connection[iConnId])
self.m_connection_list.pop(i-h)
h += 1
# Remove ports
h = 0
for i in range(len(self.m_port_list)):
port = self.m_port_list[i-h]
if port[iPortGroup] == group_id:
port_id = port[iPortId]
patchcanvas.removePort(port[iPortId])
self.m_port_list.pop(i-h)
h += 1
# Now remove group
patchcanvas.removeGroup(group_id)
for group in self.m_group_list:
if group[iGroupId] == group_id:
self.m_group_list.remove(group)
break
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add a Group first!"))
@pyqtSlot()
def slot_groupRename(self):
if len(self.m_group_list) > 0:
dialog = CatarinaRenameGroupW(self, self.m_group_list)
if dialog.exec_():
group_id = dialog.ret_group_id
new_group_name = dialog.ret_new_group_name
patchcanvas.renameGroup(group_id, new_group_name)
for group in self.m_group_list:
if group[iGroupId] == group_id:
group[iGroupName] = new_group_name
break
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add a Group first!"))
@pyqtSlot()
def slot_portAdd(self):
if len(self.m_group_list) > 0:
dialog = CatarinaAddPortW(self, self.m_group_list, self.m_last_port_id)
if dialog.exec_():
group_id = dialog.ret_group_id
port_name = dialog.ret_port_name
port_mode = dialog.ret_port_mode
port_type = dialog.ret_port_type
patchcanvas.addPort(group_id, self.m_last_port_id, port_name, port_mode, port_type)
new_port = [None, None, None, None, None]
new_port[iPortGroup] = group_id
new_port[iPortId] = self.m_last_port_id
new_port[iPortName] = port_name
new_port[iPortMode] = port_mode
new_port[iPortType] = port_type
self.m_port_list.append(new_port)
self.m_last_port_id += 1
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add a Group first!"))
@pyqtSlot()
def slot_portRemove(self):
if len(self.m_port_list) > 0:
dialog = CatarinaRemovePortW(self, self.m_group_list, self.m_port_list)
if dialog.exec_():
port_id = dialog.ret_port_id
h = 0
for i in range(len(self.m_connection_list)):
connection = self.m_connection_list[i-h]
if connection[iConnOutput] == port_id or connection[iConnInput] == port_id:
patchcanvas.disconnectPorts(connection[iConnId])
self.m_connection_list.pop(i-h)
h += 1
patchcanvas.removePort(port_id)
for port in self.m_port_list:
if port[iPortId] == port_id:
self.m_port_list.remove(port)
break
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add a Port first!"))
@pyqtSlot()
def slot_portRename(self):
if len(self.m_port_list) > 0:
dialog = CatarinaRenamePortW(self, self.m_group_list, self.m_port_list)
if dialog.exec_():
port_id = dialog.ret_port_id
new_port_name = dialog.ret_new_port_name
patchcanvas.renamePort(port_id, new_port_name)
for port in self.m_port_list:
if port[iPortId] == port_id:
port[iPortName] = new_port_name
break
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add a Port first!"))
@pyqtSlot()
def slot_connectPorts(self):
if len(self.m_port_list) > 0:
dialog = CatarinaConnectPortsW(self, self.m_group_list, self.m_port_list)
if dialog.exec_():
connection_id = self.m_last_connection_id
port_out_id = dialog.ret_port_out_id
port_in_id = dialog.ret_port_in_id
for connection in self.m_connection_list:
if connection[iConnOutput] == port_out_id and connection[iConnInput] == port_in_id:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Ports already connected!"))
return
patchcanvas.connectPorts(connection_id, port_out_id, port_in_id)
conn_obj = [None, None, None]
conn_obj[iConnId] = connection_id
conn_obj[iConnOutput] = port_out_id
conn_obj[iConnInput] = port_in_id
self.m_connection_list.append(conn_obj)
self.m_last_connection_id += 1
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please add some Ports first!"))
@pyqtSlot()
def slot_disconnectPorts(self):
if len(self.m_connection_list) > 0:
dialog = CatarinaDisconnectPortsW(self, self.m_group_list, self.m_port_list, self.m_connection_list)
if dialog.exec_():
connection_id = -1
port_out_id = dialog.ret_port_out_id
port_in_id = dialog.ret_port_in_id
for connection in self.m_connection_list:
if connection[iConnOutput] == port_out_id and connection[iConnInput] == port_in_id:
connection_id = connection[iConnId]
self.m_connection_list.remove(connection)
break
patchcanvas.disconnectPorts(connection_id)
else:
QMessageBox.warning(self, self.tr("Warning"), self.tr("Please make some Connections first!"))
@pyqtSlot()
def slot_configureCatarina(self):
dialog = SettingsW(self, "catarina", hasGL)
if dialog.exec_():
self.loadSettings(False)
patchcanvas.clear()
p_options = patchcanvas.options_t()
p_options.theme_name = self.fSavedSettings["Canvas/Theme"]
p_options.auto_hide_groups = self.fSavedSettings["Canvas/AutoHideGroups"]
p_options.use_bezier_lines = self.fSavedSettings["Canvas/UseBezierLines"]
p_options.antialiasing = self.fSavedSettings["Canvas/Antialiasing"]
p_options.eyecandy = self.fSavedSettings["Canvas/EyeCandy"]
patchcanvas.setOptions(p_options)
patchcanvas.init("Catarina", self.scene, self.canvasCallback, DEBUG)
self.initPorts()
@pyqtSlot()
def slot_aboutCatarina(self):
QMessageBox.about(self, self.tr("About Catarina"), self.tr("<h3>Catarina</h3>"
"<br>Version %s"
"<br>Catarina is a testing ground for the 'PatchCanvas' module.<br>"
"<br>Copyright (C) 2010-2022 falkTX") % VERSION)
def saveSettings(self):
settings = QSettings()
settings.setValue("Geometry", self.saveGeometry())
settings.setValue("ShowToolbar", self.ui.frame_toolbar.isVisible())
def loadSettings(self, geometry):
settings = QSettings()
if geometry:
self.restoreGeometry(settings.value("Geometry", b""))
showToolbar = settings.value("ShowToolbar", True, type=bool)
self.ui.act_settings_show_toolbar.setChecked(showToolbar)
self.ui.frame_toolbar.setVisible(showToolbar)
self.fSavedSettings = {
"Canvas/Theme": settings.value("Canvas/Theme", patchcanvas.getDefaultThemeName(), type=str),
"Canvas/AutoHideGroups": settings.value("Canvas/AutoHideGroups", False, type=bool),
"Canvas/UseBezierLines": settings.value("Canvas/UseBezierLines", True, type=bool),
"Canvas/EyeCandy": settings.value("Canvas/EyeCandy", patchcanvas.EYECANDY_SMALL, type=int),
"Canvas/UseOpenGL": settings.value("Canvas/UseOpenGL", False, type=bool),
"Canvas/Antialiasing": settings.value("Canvas/Antialiasing", patchcanvas.ANTIALIASING_SMALL, type=int),
"Canvas/TextAntialiasing": settings.value("Canvas/TextAntialiasing", True, type=bool),
"Canvas/HighQualityAntialiasing": settings.value("Canvas/HighQualityAntialiasing", False, type=bool)
}
def timerEvent(self, event):
if event.timerId() == self.fUpdateTimer:
self.update()
QMainWindow.timerEvent(self, event)
def closeEvent(self, event):
self.saveSettings()
patchcanvas.clear()
QMainWindow.closeEvent(self, event)
#--------------- main ------------------
if __name__ == '__main__':
# App initialization
app = QApplication(sys.argv)
app.setApplicationName("Catarina")
app.setApplicationVersion(VERSION)
app.setOrganizationName("Cadence")
app.setWindowIcon(QIcon(":/scalable/catarina.svg"))
setup_i18n()
# Show GUI
gui = CatarinaMainW()
# Set-up custom signal handling
setUpSignals(gui)
gui.show()
if len(app.arguments()) > 1:
if not app.arguments()[0].endswith("Python.exe"):
gui.loadFile(app.arguments()[1])
elif len(app.arguments()) > 2:
gui.loadFile(app.arguments()[2])
# App-Loop
sys.exit(app.exec_())