From c307dd9d8a4ba81ea99d456db345db09edb600f1 Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 24 Oct 2019 12:19:59 +0200 Subject: [PATCH] Rework add-plugin dialog --- resources/16x16/edit-clear.svgz | Bin 0 -> 32098 bytes resources/resources.qrc | 1 + resources/ui/carla_database.ui | 1031 ++++++++++++++++-------- source/backend/engine/CarlaEngine.cpp | 5 +- source/backend/utils/CachedPlugins.cpp | 12 + source/frontend/carla_database.py | 192 +++-- 6 files changed, 822 insertions(+), 419 deletions(-) create mode 100644 resources/16x16/edit-clear.svgz diff --git a/resources/16x16/edit-clear.svgz b/resources/16x16/edit-clear.svgz new file mode 100644 index 0000000000000000000000000000000000000000..481aa597f2762becd3be3428cd9da5d09834a740 GIT binary patch literal 32098 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 literal 0 HcmV?d00001 diff --git a/resources/resources.qrc b/resources/resources.qrc index 246dddd4b..479416f29 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -15,6 +15,7 @@ 16x16/document-open.svgz 16x16/document-save.svgz 16x16/document-save-as.svgz + 16x16/edit-clear.svgz 16x16/edit-delete.svgz 16x16/edit-rename.svgz 16x16/list-add.svgz diff --git a/resources/ui/carla_database.ui b/resources/ui/carla_database.ui index 7fdd04582..9f94290ff 100644 --- a/resources/ui/carla_database.ui +++ b/resources/ui/carla_database.ui @@ -6,39 +6,345 @@ 0 0 - 929 - 565 + 1100 + 683 Carla - Add New - - - + + + + + 0 + + + + + 0 + 0 + 164 + 268 + + + + Format + + + + + + Internal + + + + + + + LADSPA + + + + + + + DSSI + + + + + + + LV2 + + + + + + + VST2 + + + + + + + VST3 + + + + + + + AU + + + + + + + Sound Kits + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 164 + 164 + + + + Type + + + + + + Effects + + + + + + + Instruments + + + + + + + MIDI Plugins + + + + + + + Other/Misc + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + 0 + 0 + 164 + 136 + + + + Architecture + + + + + + Native + + + + + + + Bridged + + + + + + + Bridged (Wine) + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + + 75 + true + + + + Requirements + + + + + + + With Inline Display + + + + + + + Stereo only + + + + + + + Real-time safe only + + + + + + + With Custom GUI + + + + + + + With CV Ports + + + + + + + + + - + + + (Number of Plugins go here) + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + - + - Special Filters: + &Add Plugin - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + :/16x16/list-add.svgz:/16x16/list-add.svgz - - - true + + + Cancel - - Qt::UpArrow + + + :/16x16/dialog-cancel.svgz:/16x16/dialog-cancel.svgz + + + + + + + @@ -50,214 +356,378 @@ + + + + Clear filters + + + + :/16x16/edit-clear.svgz:/16x16/edit-clear.svgz + + + - - - - QFrame::StyledPanel - - - QFrame::Sunken + + + + true - - - - - VST2 - - - - - - - Real-time safe only - - - - - - - Other/Misc - - - - - - - - 75 - true - - - - Requirements - - - - - - - LADSPA - - - - - - - - 75 - true - - - - Architecture - - - - - - - Instruments - - - - - - - Bridged (Wine) - - - - - - - - 75 - true - - - - Plugin format - - - - - - - - 75 - true - - - - Category - - - - - - - LV2 - - - - - - - VST3 - - - - - - - Sound Kits - - - - - - - DSSI - - - - - - - Stereo only - - - - - - - Effects - - - - - - - Bridged - - - - - - - Internal - - - - - - - MIDI Plugins - - - - - - - Native - - - - - - - AU - - - - - - - With Inline Display - - - - - - - With CV Ports - - - - - - - With Custom GUI - - - - + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + TextLabel + + + + + + + Format: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Architecture: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + TextLabel + + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + TextLabel + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + MIDI Ins: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Audio Ins: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + CV Outs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + MIDI Outs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Parameter Ins: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Parameter Outs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Audio Outs: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + CV Ins: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + UniqueID: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Has Inline Display: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Has Custom GUI: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Is Synth: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Is Bridged: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + TextLabel + + + + + + + + 75 + true + + + + Information + + + + + + + 0 + + + 1 + + + Qt::Horizontal + + + + + + + 0 + + + 1 + + + Qt::Horizontal + + + + + - + + + + 1 + 0 + + QAbstractItemView::NoEditTriggers @@ -294,12 +764,12 @@ false - - 22 - 12 + + 22 + Name @@ -317,138 +787,21 @@ - ID - - - - - Audio Ins - - - - - Audio Outs - - - - - Param Ins - - - - - Param Outs - - - - - Programs - - - - - Has GUI - - - - - Is Synth - - - - - Is Bridged - - - - - Type - - - - - Binary + Binary/Filename - - - - - - (Number of Plugins go here) - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - &Add Plugin - - - - :/16x16/list-add.svgz:/16x16/list-add.svgz - - - - - - - Cancel - - - - :/16x16/dialog-cancel.svgz:/16x16/dialog-cancel.svgz - - - - - lineEdit b_add - tb_filters b_refresh tableWidget - - - tb_filters - toggled(bool) - frame - setVisible(bool) - - - 723 - 21 - - - 736 - 39 - - - - + diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 7c05310e0..702713e75 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -431,10 +431,11 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, CARLA_SAFE_ASSERT_RETURN_ERR(btype != BINARY_NONE, "Invalid plugin binary mode"); CARLA_SAFE_ASSERT_RETURN_ERR(ptype != PLUGIN_NONE, "Invalid plugin type"); CARLA_SAFE_ASSERT_RETURN_ERR((filename != nullptr && filename[0] != '\0') || (label != nullptr && label[0] != '\0'), "Invalid plugin filename and label"); - carla_debug("CarlaEngine::addPlugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), filename, name, label, uniqueId, extra, options); + carla_debug("CarlaEngine::addPlugin(%i:%s, %i:%s, \"%s\", \"%s\", \"%s\", " P_INT64 ", %p, %u)", + btype, BinaryType2Str(btype), ptype, PluginType2Str(ptype), filename, name, label, uniqueId, extra, options); #ifndef CARLA_OS_WIN - if (ptype != PLUGIN_JACK && filename != nullptr && filename[0] != '\0') { + if (ptype != PLUGIN_JACK && ptype != PLUGIN_LV2 && filename != nullptr && filename[0] != '\0') { CARLA_SAFE_ASSERT_RETURN_ERR(filename[0] == CARLA_OS_SEP || filename[0] == '.' || filename[0] == '~', "Invalid plugin filename"); } #endif diff --git a/source/backend/utils/CachedPlugins.cpp b/source/backend/utils/CachedPlugins.cpp index 37f42b3aa..7a03e700b 100644 --- a/source/backend/utils/CachedPlugins.cpp +++ b/source/backend/utils/CachedPlugins.cpp @@ -154,6 +154,18 @@ static const CarlaCachedPluginInfo* get_cached_plugin_lv2(Lv2WorldClass& lv2Worl suri = lilvPlugin.get_uri().as_uri(); + if (char* const bundle = lilv_file_uri_parse(lilvPlugin.get_bundle_uri().as_uri(), nullptr)) + { + File fbundle(bundle); + lilv_free(bundle); + + suri = (fbundle.getFileName() + CARLA_OS_SEP).toRawUTF8() + suri; + } + else + { + suri = CARLA_OS_SEP_STR + suri; + } + #if 0 // def HAVE_FLUIDSYNTH // If we have fluidsynth support built-in, loading these plugins will lead to issues if (suri == "urn:ardour:a-fluidsynth") diff --git a/source/frontend/carla_database.py b/source/frontend/carla_database.py index 606fa95f1..3890d8967 100755 --- a/source/frontend/carla_database.py +++ b/source/frontend/carla_database.py @@ -34,6 +34,7 @@ import ui_carla_database import ui_carla_refresh from carla_shared import * +from carla_utils import getPluginTypeAsString # --------------------------------------------------------------------------------------------------------------------- # Try Import LADSPA-RDF @@ -338,13 +339,16 @@ def checkPluginCached(desc, ptype): pinfo['cv.ins'] = desc['cvIns'] pinfo['cv.outs'] = desc['cvOuts'] - pinfo['midi.ins'] = desc['midiIns'] - pinfo['midi.outs'] = desc['midiOuts'] + pinfo['midi.ins'] = desc['midiIns'] + pinfo['midi.outs'] = desc['midiOuts'] pinfo['parameters.ins'] = desc['parameterIns'] pinfo['parameters.outs'] = desc['parameterOuts'] - if ptype == PLUGIN_SFZ: + if ptype == PLUGIN_LV2: + pinfo['filename'], pinfo['label'] = pinfo['label'].split('/',1) + + elif ptype == PLUGIN_SFZ: pinfo['filename'] = pinfo['label'] pinfo['label'] = pinfo['name'] @@ -1376,6 +1380,11 @@ class PluginRefreshW(QDialog): # Plugin Database Dialog class PluginDatabaseW(QDialog): + TABLEWIDGET_ITEM_NAME = 0 + TABLEWIDGET_ITEM_LABEL = 1 + TABLEWIDGET_ITEM_MAKER = 2 + TABLEWIDGET_ITEM_BINARY = 3 + def __init__(self, parent, host): QDialog.__init__(self, parent) self.host = host @@ -1394,6 +1403,10 @@ class PluginDatabaseW(QDialog): self.fRetPlugin = None self.fRealParent = parent + self.fTrYes = self.tr("Yes") + self.fTrNo = self.tr("No") + self.fTrNative = self.tr("Native") + # ---------------------------------------------------------------------------------------------------- # Set-up GUI @@ -1413,6 +1426,10 @@ class PluginDatabaseW(QDialog): self.ui.ch_au.setEnabled(False) self.ui.ch_au.setVisible(False) + self.ui.tab_info.tabBar().hide() + self.ui.tab_reqs.tabBar().hide() + # FIXME, why /2 needed? + self.ui.tab_info.setMinimumWidth(self.ui.la_id.width()/2 + self.ui.l_id.fontMetrics().width("9999999999") + 6*3) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) # ---------------------------------------------------------------------------------------------------- @@ -1448,7 +1465,6 @@ class PluginDatabaseW(QDialog): self.ui.b_add.clicked.connect(self.slot_addPlugin) self.ui.b_cancel.clicked.connect(self.reject) self.ui.b_refresh.clicked.connect(self.slot_refreshPlugins) - self.ui.tb_filters.clicked.connect(self.slot_maybeShowFilters) self.ui.lineEdit.textChanged.connect(self.slot_checkFilters) self.ui.tableWidget.currentCellChanged.connect(self.slot_checkPlugin) self.ui.tableWidget.cellDoubleClicked.connect(self.slot_addPlugin) @@ -1484,23 +1500,86 @@ class PluginDatabaseW(QDialog): @pyqtSlot() def slot_addPlugin(self): if self.ui.tableWidget.currentRow() >= 0: - self.fRetPlugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(), 0).data(Qt.UserRole) + self.fRetPlugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(), 0).data(Qt.UserRole+1) self.accept() else: self.reject() @pyqtSlot(int) def slot_checkPlugin(self, row): - self.ui.b_add.setEnabled(row >= 0) + if row >= 0: + self.ui.b_add.setEnabled(True) + plugin = self.ui.tableWidget.item(self.ui.tableWidget.currentRow(), 0).data(Qt.UserRole+1) + + isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH) + isEffect = bool(plugin['audio.ins'] > 0 < plugin['audio.outs'] and not isSynth) + isMidi = bool(plugin['audio.ins'] == 0 and plugin['audio.outs'] == 0 and plugin['midi.ins'] > 0 < plugin['midi.outs']) + isKit = bool(plugin['type'] in (PLUGIN_SF2, PLUGIN_SFZ)) + isOther = bool(not (isEffect or isSynth or isMidi or isKit)) + + if isSynth: + ptype = "Instrument" + elif isEffect: + ptype = "Effect" + elif isMidi: + ptype = "MIDI Plugin" + else: + ptype = "Other" + + if plugin['build'] == BINARY_NATIVE: + parch = self.fTrNative + elif plugin['build'] == BINARY_POSIX32: + parch = "posix32" + elif plugin['build'] == BINARY_POSIX64: + parch = "posix64" + elif plugin['build'] == BINARY_WIN32: + parch = "win32" + elif plugin['build'] == BINARY_WIN64: + parch = "win64" + elif plugin['build'] == BINARY_OTHER: + parch = self.tr("Other") + elif plugin['build'] == BINARY_WIN32: + parch = self.tr("Unknown") + + self.ui.l_format.setText(getPluginTypeAsString(plugin['type'])) + self.ui.l_type.setText(ptype) + self.ui.l_arch.setText(parch) + self.ui.l_id.setText(str(plugin['uniqueId'])) + self.ui.l_ains.setText(str(plugin['audio.ins'])) + self.ui.l_aouts.setText(str(plugin['audio.outs'])) + self.ui.l_cvins.setText(str(plugin['cv.ins'])) + self.ui.l_cvouts.setText(str(plugin['cv.outs'])) + self.ui.l_mins.setText(str(plugin['midi.ins'])) + self.ui.l_mouts.setText(str(plugin['midi.outs'])) + self.ui.l_pins.setText(str(plugin['parameters.ins'])) + self.ui.l_pouts.setText(str(plugin['parameters.outs'])) + self.ui.l_gui.setText(self.fTrYes if plugin['hints'] & PLUGIN_HAS_CUSTOM_UI else self.fTrNo) + self.ui.l_idisp.setText(self.fTrYes if plugin['hints'] & PLUGIN_HAS_INLINE_DISPLAY else self.fTrNo) + self.ui.l_bridged.setText(self.fTrYes if plugin['hints'] & PLUGIN_IS_BRIDGE else self.fTrNo) + self.ui.l_synth.setText(self.fTrYes if isSynth else self.fTrNo) + else: + self.ui.b_add.setEnabled(False) + self.ui.l_format.setText("---") + self.ui.l_type.setText("---") + self.ui.l_arch.setText("---") + self.ui.l_id.setText("---") + self.ui.l_ains.setText("---") + self.ui.l_aouts.setText("---") + self.ui.l_cvins.setText("---") + self.ui.l_cvouts.setText("---") + self.ui.l_mins.setText("---") + self.ui.l_mouts.setText("---") + self.ui.l_pins.setText("---") + self.ui.l_pouts.setText("---") + self.ui.l_gui.setText("---") + self.ui.l_idisp.setText("---") + self.ui.l_bridged.setText("---") + self.ui.l_synth.setText("---") @pyqtSlot() def slot_checkFilters(self): self._checkFilters() - @pyqtSlot() - def slot_maybeShowFilters(self): - self._showFilters(not self.ui.frame.isVisible()) - @pyqtSlot() def slot_refreshPlugins(self): if PluginRefreshW(self, self.host).exec_(): @@ -1516,7 +1595,6 @@ class PluginDatabaseW(QDialog): settings = QSettings("falkTX", "CarlaDatabase2") settings.setValue("PluginDatabase/Geometry", self.saveGeometry()) settings.setValue("PluginDatabase/TableGeometry_5", self.ui.tableWidget.horizontalHeader().saveState()) - settings.setValue("PluginDatabase/ShowFilters", (self.ui.tb_filters.arrowType() == Qt.UpArrow)) settings.setValue("PluginDatabase/ShowEffects", self.ui.ch_effects.isChecked()) settings.setValue("PluginDatabase/ShowInstruments", self.ui.ch_instruments.isChecked()) settings.setValue("PluginDatabase/ShowMIDI", self.ui.ch_midi.isChecked()) @@ -1572,8 +1650,6 @@ class PluginDatabaseW(QDialog): else: self.ui.tableWidget.sortByColumn(0, Qt.AscendingOrder) - self._showFilters(settings.value("PluginDatabase/ShowFilters", False, type=bool)) - # -------------------------------------------------------------------------------------------------------- def _checkFilters(self): @@ -1616,25 +1692,27 @@ class PluginDatabaseW(QDialog): rowCount = self.ui.tableWidget.rowCount() for i in range(self.fLastTableIndex): - plugin = self.ui.tableWidget.item(i, 0).data(Qt.UserRole) + plugin = self.ui.tableWidget.item(i, 0).data(Qt.UserRole+1) + ptext = self.ui.tableWidget.item(i, 0).data(Qt.UserRole+2) aIns = plugin['audio.ins'] aOuts = plugin['audio.outs'] cvIns = plugin['cv.ins'] cvOuts = plugin['cv.outs'] mIns = plugin['midi.ins'] mOuts = plugin['midi.outs'] - ptype = self.ui.tableWidget.item(i, 12).text() - isSynth = bool(plugin['hints'] & PLUGIN_IS_SYNTH) + phints = plugin['hints'] + ptype = plugin['type'] + isSynth = bool(phints & PLUGIN_IS_SYNTH) isEffect = bool(aIns > 0 < aOuts and not isSynth) isMidi = bool(aIns == 0 and aOuts == 0 and mIns > 0 < mOuts) - isKit = bool(ptype in ("SF2", "SFZ")) + isKit = bool(ptype in (PLUGIN_SF2, PLUGIN_SFZ)) isOther = bool(not (isEffect or isSynth or isMidi or isKit)) isNative = bool(plugin['build'] == BINARY_NATIVE) - isRtSafe = bool(plugin['hints'] & PLUGIN_IS_RTSAFE) + isRtSafe = bool(phints & PLUGIN_IS_RTSAFE) isStereo = bool(aIns == 2 and aOuts == 2) or (isSynth and aOuts == 2) hasCV = bool(cvIns + cvOuts > 0) - hasGui = bool(plugin['hints'] & PLUGIN_HAS_CUSTOM_UI) - hasIDisp = bool(plugin['hints'] & PLUGIN_HAS_INLINE_DISPLAY) + hasGui = bool(phints & PLUGIN_HAS_CUSTOM_UI) + hasIDisp = bool(phints & PLUGIN_HAS_INLINE_DISPLAY) isBridged = bool(not isNative and plugin['build'] in nativeBins) isBridgedWine = bool(not isNative and plugin['build'] in wineBins) @@ -1649,19 +1727,19 @@ class PluginDatabaseW(QDialog): self.ui.tableWidget.hideRow(i) elif hideKits and isKit: self.ui.tableWidget.hideRow(i) - elif hideInternal and ptype == self.tr("Internal"): + elif hideInternal and ptype == PLUGIN_INTERNAL: self.ui.tableWidget.hideRow(i) - elif hideLadspa and ptype == "LADSPA": + elif hideLadspa and ptype == PLUGIN_LADSPA: self.ui.tableWidget.hideRow(i) - elif hideDssi and ptype == "DSSI": + elif hideDssi and ptype == PLUGIN_DSSI: self.ui.tableWidget.hideRow(i) - elif hideLV2 and ptype == "LV2": + elif hideLV2 and ptype == PLUGIN_LV2: self.ui.tableWidget.hideRow(i) - elif hideVST2 and ptype == "VST2": + elif hideVST2 and ptype == PLUGIN_VST2: self.ui.tableWidget.hideRow(i) - elif hideVST3 and ptype == "VST3": + elif hideVST3 and ptype == PLUGIN_VST3: self.ui.tableWidget.hideRow(i) - elif hideAU and ptype == "AU": + elif hideAU and ptype == PLUGIN_AU: self.ui.tableWidget.hideRow(i) elif hideNative and isNative: self.ui.tableWidget.hideRow(i) @@ -1679,24 +1757,13 @@ class PluginDatabaseW(QDialog): self.ui.tableWidget.hideRow(i) elif hideNonStereo and not isStereo: self.ui.tableWidget.hideRow(i) - elif (text and not ( - text in self.ui.tableWidget.item(i, 0).text().lower() or - text in self.ui.tableWidget.item(i, 1).text().lower() or - text in self.ui.tableWidget.item(i, 2).text().lower() or - text in self.ui.tableWidget.item(i, 3).text().lower() or - text in self.ui.tableWidget.item(i, 13).text().lower())): + elif text and text not in ptext: self.ui.tableWidget.hideRow(i) else: self.ui.tableWidget.showRow(i) # -------------------------------------------------------------------------------------------------------- - def _showFilters(self, yesNo): - self.ui.tb_filters.setArrowType(Qt.UpArrow if yesNo else Qt.DownArrow) - self.ui.frame.setVisible(yesNo) - - # -------------------------------------------------------------------------------------------------------- - def _addPluginToTable(self, plugin, ptype): if plugin['API'] != PLUGIN_QUERY_API_VERSION: return @@ -1705,45 +1772,13 @@ class PluginDatabaseW(QDialog): index = self.fLastTableIndex - if plugin['build'] == BINARY_NATIVE: - bridgeText = self.tr("No") - - else: - if WINDOWS: - if plugin['build'] == BINARY_WIN32: - typeText = "32bit" - elif plugin['build'] == BINARY_WIN64: - typeText = "64bit" - else: - typeText = self.tr("Unknown") - else: - if plugin['build'] == BINARY_POSIX32: - typeText = "32bit" - elif plugin['build'] == BINARY_POSIX64: - typeText = "64bit" - elif plugin['build'] == BINARY_WIN32: - typeText = "Windows 32bit" - elif plugin['build'] == BINARY_WIN64: - typeText = "Windows 64bit" - else: - typeText = self.tr("Unknown") - - bridgeText = self.tr("Yes (%s)" % typeText) - - self.ui.tableWidget.setItem(index, 0, QTableWidgetItem(str(plugin['name']))) - self.ui.tableWidget.setItem(index, 1, QTableWidgetItem(str(plugin['label']))) - self.ui.tableWidget.setItem(index, 2, QTableWidgetItem(str(plugin['maker']))) - self.ui.tableWidget.setItem(index, 3, QTableWidgetItem(str(plugin['uniqueId']))) - self.ui.tableWidget.setItem(index, 4, QTableWidgetItem(str(plugin['audio.ins']))) - self.ui.tableWidget.setItem(index, 5, QTableWidgetItem(str(plugin['audio.outs']))) - self.ui.tableWidget.setItem(index, 6, QTableWidgetItem(str(plugin['parameters.ins']))) - self.ui.tableWidget.setItem(index, 7, QTableWidgetItem(str(plugin['parameters.outs']))) - self.ui.tableWidget.setItem(index, 9, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_HAS_CUSTOM_UI) else self.tr("No"))) - self.ui.tableWidget.setItem(index, 10, QTableWidgetItem(self.tr("Yes") if (plugin['hints'] & PLUGIN_IS_SYNTH) else self.tr("No"))) - self.ui.tableWidget.setItem(index, 11, QTableWidgetItem(bridgeText)) - self.ui.tableWidget.setItem(index, 12, QTableWidgetItem(ptype)) - self.ui.tableWidget.setItem(index, 13, QTableWidgetItem(str(plugin['filename']))) - self.ui.tableWidget.item(index, 0).setData(Qt.UserRole, plugin) + pluginText = plugin['name']+plugin['label']+plugin['maker']+plugin['filename'] + self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_NAME, QTableWidgetItem(plugin['name'])) + self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_LABEL, QTableWidgetItem(plugin['label'])) + self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_MAKER, QTableWidgetItem(plugin['maker'])) + self.ui.tableWidget.setItem(index, self.TABLEWIDGET_ITEM_BINARY, QTableWidgetItem(os.path.basename(plugin['filename']))) + self.ui.tableWidget.item(index, 0).setData(Qt.UserRole+1, plugin) + self.ui.tableWidget.item(index, 0).setData(Qt.UserRole+2, pluginText) self.fLastTableIndex += 1 @@ -1943,6 +1978,7 @@ class PluginDatabaseW(QDialog): self.ui.tableWidget.setSortingEnabled(True) self._checkFilters() + self.slot_checkPlugin(self.ui.tableWidget.currentRow()) # --------------------------------------------------------------------------------------------------------