| @@ -773,6 +773,11 @@ class CarlaMainW(QMainWindow): | |||||
| self.scene.render(painter) | self.scene.render(painter) | ||||
| self.fExportImage.save(newPath, imgFormat, 100) | self.fExportImage.save(newPath, imgFormat, 100) | ||||
| def showLastError(self, isProject): | |||||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), | |||||
| self.tr("Failed to load %s" % (self.tr("project") if isProject else self.tr("plugin"))), | |||||
| cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) | |||||
| @pyqtSlot(QModelIndex) | @pyqtSlot(QModelIndex) | ||||
| def slot_fileTreeDoubleClicked(self, modelIndex): | def slot_fileTreeDoubleClicked(self, modelIndex): | ||||
| filename = self.fDirModel.filePath(modelIndex) | filename = self.fDirModel.filePath(modelIndex) | ||||
| @@ -787,16 +792,20 @@ class CarlaMainW(QMainWindow): | |||||
| extension = filename.rsplit(".", 1)[-1].lower() | extension = filename.rsplit(".", 1)[-1].lower() | ||||
| if extension == "carxp": | if extension == "carxp": | ||||
| Carla.host.load_project(filename) | |||||
| if not Carla.host.load_project(filename): | |||||
| self.showLastError(True) | |||||
| elif extension == "gig": | elif extension == "gig": | ||||
| Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_GIG, filename, None, basename, None) | |||||
| if not Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_GIG, filename, None, basename, None): | |||||
| self.showLastError(False) | |||||
| elif extension == "sf2": | elif extension == "sf2": | ||||
| Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SF2, filename, None, basename, None) | |||||
| if not Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SF2, filename, None, basename, None): | |||||
| self.showLastError(False) | |||||
| elif extension == "sfz": | elif extension == "sfz": | ||||
| Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SFZ, filename, None, basename, None) | |||||
| if not Carla.host.add_plugin(BINARY_NATIVE, PLUGIN_SFZ, filename, None, basename, None): | |||||
| self.showLastError(False) | |||||
| elif extension in ("aac", "flac", "oga", "ogg", "mp3", "wav"): | elif extension in ("aac", "flac", "oga", "ogg", "mp3", "wav"): | ||||
| self.fLastLoadedPluginId = -2 | self.fLastLoadedPluginId = -2 | ||||
| @@ -807,8 +816,7 @@ class CarlaMainW(QMainWindow): | |||||
| Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file00", filename) | Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file00", filename) | ||||
| else: | else: | ||||
| self.fLastLoadedPluginId = -1 | self.fLastLoadedPluginId = -1 | ||||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), | |||||
| cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) | |||||
| self.showLastError(False) | |||||
| elif extension in ("mid", "midi"): | elif extension in ("mid", "midi"): | ||||
| self.fLastLoadedPluginId = -2 | self.fLastLoadedPluginId = -2 | ||||
| @@ -819,8 +827,7 @@ class CarlaMainW(QMainWindow): | |||||
| Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file", filename) | Carla.host.set_custom_data(idx, CUSTOM_DATA_STRING, "file", filename) | ||||
| else: | else: | ||||
| self.fLastLoadedPluginId = -1 | self.fLastLoadedPluginId = -1 | ||||
| CustomMessageBox(self, QMessageBox.Critical, self.tr("Error"), self.tr("Failed to load plugin"), | |||||
| cString(Carla.host.get_last_error()), QMessageBox.Ok, QMessageBox.Ok) | |||||
| self.showLastError(False) | |||||
| @pyqtSlot(float) | @pyqtSlot(float) | ||||
| def slot_canvasScaleChanged(self, scale): | def slot_canvasScaleChanged(self, scale): | ||||
| @@ -51,6 +51,9 @@ struct StateParameter { | |||||
| if (symbol != nullptr) | if (symbol != nullptr) | ||||
| delete[] symbol; | delete[] symbol; | ||||
| } | } | ||||
| StateParameter(StateParameter&) = delete; | |||||
| StateParameter(const StateParameter&) = delete; | |||||
| }; | }; | ||||
| struct StateCustomData { | struct StateCustomData { | ||||
| @@ -72,6 +75,9 @@ struct StateCustomData { | |||||
| if (value != nullptr) | if (value != nullptr) | ||||
| delete[] value; | delete[] value; | ||||
| } | } | ||||
| StateCustomData(StateCustomData&) = delete; | |||||
| StateCustomData(const StateCustomData&) = delete; | |||||
| }; | }; | ||||
| typedef QVector<StateParameter*> StateParameterVector; | typedef QVector<StateParameter*> StateParameterVector; | ||||
| @@ -190,6 +196,9 @@ struct SaveState { | |||||
| parameters.clear(); | parameters.clear(); | ||||
| customData.clear(); | customData.clear(); | ||||
| } | } | ||||
| SaveState(SaveState&) = delete; | |||||
| SaveState(const SaveState&) = delete; | |||||
| }; | }; | ||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| @@ -307,7 +316,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| short value = text.toShort(&ok); | short value = text.toShort(&ok); | ||||
| if (ok && value < INT8_MAX) | |||||
| if (ok && value >= 1 && value < INT8_MAX) | |||||
| saveState.ctrlChannel = static_cast<int8_t>(value-1); | saveState.ctrlChannel = static_cast<int8_t>(value-1); | ||||
| } | } | ||||
| @@ -318,7 +327,8 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| int value = text.toInt(&ok); | int value = text.toInt(&ok); | ||||
| if (ok) saveState.currentProgramIndex = value-1; | |||||
| if (ok && value >= 1) | |||||
| saveState.currentProgramIndex = value-1; | |||||
| } | } | ||||
| else if (tag.compare("CurrentProgramName", Qt::CaseInsensitive) == 0) | else if (tag.compare("CurrentProgramName", Qt::CaseInsensitive) == 0) | ||||
| { | { | ||||
| @@ -332,13 +342,15 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| int value = text.toInt(&ok); | int value = text.toInt(&ok); | ||||
| if (ok) saveState.currentMidiBank = value-1; | |||||
| if (ok && value >= 1) | |||||
| saveState.currentMidiBank = value-1; | |||||
| } | } | ||||
| else if (tag.compare("CurrentMidiProgram", Qt::CaseInsensitive) == 0) | else if (tag.compare("CurrentMidiProgram", Qt::CaseInsensitive) == 0) | ||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| int value = text.toInt(&ok); | int value = text.toInt(&ok); | ||||
| if (ok) saveState.currentMidiProgram = value-1; | |||||
| if (ok && value >= 1) | |||||
| saveState.currentMidiProgram = value-1; | |||||
| } | } | ||||
| // ---------------------------------------------- | // ---------------------------------------------- | ||||
| @@ -379,14 +391,14 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| ushort channel = pText.toUShort(&ok); | ushort channel = pText.toUShort(&ok); | ||||
| if (ok && channel > 0 && channel < MAX_MIDI_CHANNELS) | |||||
| if (ok && channel >= 1 && channel < MAX_MIDI_CHANNELS) | |||||
| stateParameter->midiChannel = static_cast<uint8_t>(channel-1); | stateParameter->midiChannel = static_cast<uint8_t>(channel-1); | ||||
| } | } | ||||
| else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | ||||
| { | { | ||||
| bool ok; | bool ok; | ||||
| int cc = pText.toInt(&ok); | int cc = pText.toInt(&ok); | ||||
| if (ok && cc > 0 && cc < INT16_MAX) | |||||
| if (ok && cc >= 1 && cc < INT16_MAX) | |||||
| stateParameter->midiCC = static_cast<int16_t>(cc); | stateParameter->midiCC = static_cast<int16_t>(cc); | ||||
| } | } | ||||