diff options
| author | Calvin Morrison <calvin@pobox.com> | 2026-05-15 19:22:41 -0400 |
|---|---|---|
| committer | Calvin Morrison <calvin@pobox.com> | 2026-05-15 19:22:41 -0400 |
| commit | f8fa47123887452f48d0b523289ca6990c8a2e25 (patch) | |
| tree | 1564e6d2d2d53a8c9e9f7c4aface696ea137c480 /src | |
| parent | 4a8a83f223bbc2b9d18ef91423c1ee807b297b35 (diff) | |
Devices tab: per-sink/source port switching
Add Output port / Input port dropdowns in the Devices tab for any
sink or source that has 2+ ports. Selecting a port calls
pa_context_set_sink/source_port_by_index live. Active port selection
updates in-place when PA reports a port change externally.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/model/pulsemodel.cpp | 114 | ||||
| -rw-r--r-- | src/model/pulsemodel.h | 28 | ||||
| -rw-r--r-- | src/ui/devicespage.cpp | 217 | ||||
| -rw-r--r-- | src/ui/devicespage.h | 24 |
4 files changed, 336 insertions, 47 deletions
diff --git a/src/model/pulsemodel.cpp b/src/model/pulsemodel.cpp index 49a17c2..31df0ca 100644 --- a/src/model/pulsemodel.cpp +++ b/src/model/pulsemodel.cpp @@ -31,6 +31,9 @@ struct PAEvent : public TQCustomEvent { TQString iconName; TQString paName; // raw PA name (sinks/sources only, for default tracking) uint32_t parentIndex; // for Playback: parent sink PA index + uint32_t cardIdx; // for Output/Input: owning card PA index + TQString activePortName; + TQValueList<PulseDevicePort> devPorts; PAEvent( Kind k, AudioDevice::Category c, uint32_t idx, const TQString &n = TQString(), int vol = 0, bool m = false, @@ -39,7 +42,8 @@ struct PAEvent : public TQCustomEvent { const TQString &pname = TQString() ) : TQCustomEvent(PA_EVENT), kind(k), cat(c), paIndex(idx), name(n), volume(vol), muted(m), channels(ch), pan(p), - monitorName(mon), iconName(icon), paName(pname), parentIndex(parent) {} + monitorName(mon), iconName(icon), paName(pname), parentIndex(parent), + cardIdx(PA_INVALID_INDEX) {} }; struct PACardEvent : public TQCustomEvent { @@ -297,6 +301,15 @@ void PulseModel::sinkInfoCb( pa_context *, const pa_sink_info *info, int eol, vo TQString::fromUtf8( pa_proplist_gets( info->proplist, PA_PROP_DEVICE_ICON_NAME ) ? : "" ), PA_INVALID_INDEX, TQString::fromUtf8( info->name ) ); + ev->cardIdx = info->card; + ev->activePortName = info->active_port + ? TQString::fromUtf8( info->active_port->name ) : TQString(); + for ( uint32_t i = 0; i < info->n_ports; ++i ) { + PulseDevicePort p; + p.name = TQString::fromUtf8( info->ports[i]->name ); + p.description = TQString::fromUtf8( info->ports[i]->description ); + ev->devPorts.append( p ); + } TQApplication::postEvent( self, ev ); } @@ -306,7 +319,7 @@ void PulseModel::sourceInfoCb( pa_context *, const pa_source_info *info, int eol // Skip monitor sources — they're PA internals, not real inputs. if ( info->monitor_of_sink != PA_INVALID_INDEX ) return; PulseModel *self = static_cast<PulseModel *>(userdata); - TQApplication::postEvent( self, new PAEvent( + PAEvent *ev = new PAEvent( PAEvent::DeviceAdded, AudioDevice::Input, info->index, TQString::fromUtf8( info->description ), paVolumeToPercent( info->volume ), info->mute != 0, @@ -314,7 +327,17 @@ void PulseModel::sourceInfoCb( pa_context *, const pa_source_info *info, int eol TQString::fromUtf8( info->name ), TQString::fromUtf8( pa_proplist_gets( info->proplist, PA_PROP_DEVICE_ICON_NAME ) ? : "" ), PA_INVALID_INDEX, - TQString::fromUtf8( info->name ) ) ); + TQString::fromUtf8( info->name ) ); + ev->cardIdx = info->card; + ev->activePortName = info->active_port + ? TQString::fromUtf8( info->active_port->name ) : TQString(); + for ( uint32_t i = 0; i < info->n_ports; ++i ) { + PulseDevicePort p; + p.name = TQString::fromUtf8( info->ports[i]->name ); + p.description = TQString::fromUtf8( info->ports[i]->description ); + ev->devPorts.append( p ); + } + TQApplication::postEvent( self, ev ); } void PulseModel::sinkInputInfoCb( pa_context *, const pa_sink_input_info *info, int eol, void *userdata ) @@ -585,6 +608,16 @@ void PulseModel::customEvent( TQCustomEvent *e ) for ( it = m_sourcesByName.begin(); it != m_sourcesByName.end(); ++it ) { if ( it.data() == dev ) { m_sourcesByName.remove(it); break; } } + // Clean up port tracking maps. + if ( ev->cat == AudioDevice::Output ) { + m_sinkCard.remove( ev->paIndex ); + m_sinkActivePort.remove( ev->paIndex ); + m_sinkPorts.remove( ev->paIndex ); + } else if ( ev->cat == AudioDevice::Input ) { + m_sourceCard.remove( ev->paIndex ); + m_sourceActivePort.remove( ev->paIndex ); + m_sourcePorts.remove( ev->paIndex ); + } // If a recording stream ended, decrement its parent source's count. if ( ev->cat == AudioDevice::Recording ) { TQMap<uint32_t,uint32_t>::Iterator si = m_sourceOutputToSource.find( ev->paIndex ); @@ -610,6 +643,25 @@ void PulseModel::customEvent( TQCustomEvent *e ) if ( sink ) monitorName = sink->monitorName(); } + // Store / update port data for sinks and sources. + if ( ev->cat == AudioDevice::Output ) { + m_sinkCard[ev->paIndex] = ev->cardIdx; + m_sinkPorts[ev->paIndex] = ev->devPorts; + TQString oldPort = m_sinkActivePort.contains(ev->paIndex) + ? m_sinkActivePort[ev->paIndex] : TQString(); + m_sinkActivePort[ev->paIndex] = ev->activePortName; + if ( ev->activePortName != oldPort ) + emit sinkUpdated( ev->paIndex ); + } else if ( ev->cat == AudioDevice::Input ) { + m_sourceCard[ev->paIndex] = ev->cardIdx; + m_sourcePorts[ev->paIndex] = ev->devPorts; + TQString oldPort = m_sourceActivePort.contains(ev->paIndex) + ? m_sourceActivePort[ev->paIndex] : TQString(); + m_sourceActivePort[ev->paIndex] = ev->activePortName; + if ( ev->activePortName != oldPort ) + emit sourceUpdated( ev->paIndex ); + } + PulseDevice *dev = findDevice( *list, ev->paIndex ); if ( dev ) { dev->update( ev->name, ev->volume, ev->muted, ev->channels, ev->pan, monitorName, ev->iconName ); @@ -734,4 +786,60 @@ void PulseModel::setCardProfile( uint32_t cardIndex, const TQString &profileName pa_threaded_mainloop_unlock( m_mainloop ); } +TQValueList<PulseModel::DevicePortInfo> PulseModel::sinksForCard( uint32_t cardIndex ) const +{ + TQValueList<DevicePortInfo> result; + for ( TQPtrListIterator<PulseDevice> it(m_sinks); *it; ++it ) { + uint32_t idx = (*it)->paIndex(); + if ( !m_sinkCard.contains(idx) || m_sinkCard[idx] != cardIndex ) + continue; + DevicePortInfo info; + info.paIndex = idx; + info.description = (*it)->name(); + info.activePort = m_sinkActivePort.contains(idx) ? m_sinkActivePort[idx] : TQString(); + info.ports = m_sinkPorts.contains(idx) ? m_sinkPorts[idx] + : TQValueList<PulseDevicePort>(); + result.append( info ); + } + return result; +} + +TQValueList<PulseModel::DevicePortInfo> PulseModel::sourcesForCard( uint32_t cardIndex ) const +{ + TQValueList<DevicePortInfo> result; + for ( TQPtrListIterator<PulseDevice> it(m_sources); *it; ++it ) { + uint32_t idx = (*it)->paIndex(); + if ( !m_sourceCard.contains(idx) || m_sourceCard[idx] != cardIndex ) + continue; + DevicePortInfo info; + info.paIndex = idx; + info.description = (*it)->name(); + info.activePort = m_sourceActivePort.contains(idx) ? m_sourceActivePort[idx] : TQString(); + info.ports = m_sourcePorts.contains(idx) ? m_sourcePorts[idx] + : TQValueList<PulseDevicePort>(); + result.append( info ); + } + return result; +} + +void PulseModel::setSinkPort( uint32_t sinkPaIndex, const TQString &portName ) +{ + if ( !m_context || !m_mainloop || portName.isEmpty() ) return; + pa_threaded_mainloop_lock( m_mainloop ); + pa_operation *op = pa_context_set_sink_port_by_index( + m_context, sinkPaIndex, portName.utf8().data(), 0, 0 ); + if ( op ) pa_operation_unref( op ); + pa_threaded_mainloop_unlock( m_mainloop ); +} + +void PulseModel::setSourcePort( uint32_t sourcePaIndex, const TQString &portName ) +{ + if ( !m_context || !m_mainloop || portName.isEmpty() ) return; + pa_threaded_mainloop_lock( m_mainloop ); + pa_operation *op = pa_context_set_source_port_by_index( + m_context, sourcePaIndex, portName.utf8().data(), 0, 0 ); + if ( op ) pa_operation_unref( op ); + pa_threaded_mainloop_unlock( m_mainloop ); +} + #include "pulsemodel.moc" diff --git a/src/model/pulsemodel.h b/src/model/pulsemodel.h index c1d4561..d0e93b4 100644 --- a/src/model/pulsemodel.h +++ b/src/model/pulsemodel.h @@ -11,6 +11,13 @@ class PulseDevice; +// ---- shared port struct ----------------------------------------------------- + +struct PulseDevicePort { + TQString name; + TQString description; +}; + // ---- card data structures --------------------------------------------------- struct PulseCardProfile { @@ -66,6 +73,17 @@ public: const PulseCardInfo *card( uint32_t index ) const; void setCardProfile( uint32_t cardIndex, const TQString &profileName ); + struct DevicePortInfo { + uint32_t paIndex; + TQString description; + TQString activePort; + TQValueList<PulseDevicePort> ports; + }; + TQValueList<DevicePortInfo> sinksForCard( uint32_t cardIndex ) const; + TQValueList<DevicePortInfo> sourcesForCard( uint32_t cardIndex ) const; + void setSinkPort( uint32_t sinkPaIndex, const TQString &portName ); + void setSourcePort( uint32_t sourcePaIndex, const TQString &portName ); + protected: void customEvent( TQCustomEvent *e ); @@ -80,6 +98,9 @@ signals: void cardRemoved( uint32_t index ); void cardUpdated( uint32_t index ); + void sinkUpdated( uint32_t paIndex ); + void sourceUpdated( uint32_t paIndex ); + private slots: void reconnect(); @@ -116,6 +137,13 @@ private: TQValueList<PulseCardInfo> m_cards; + TQMap<uint32_t, uint32_t> m_sinkCard; + TQMap<uint32_t, TQString> m_sinkActivePort; + TQMap<uint32_t, TQValueList<PulseDevicePort>> m_sinkPorts; + TQMap<uint32_t, uint32_t> m_sourceCard; + TQMap<uint32_t, TQString> m_sourceActivePort; + TQMap<uint32_t, TQValueList<PulseDevicePort>> m_sourcePorts; + PulseDevice *findDevice( TQPtrList<PulseDevice> &list, uint32_t paIndex ); PulseCardInfo *findCard( uint32_t index ); }; diff --git a/src/ui/devicespage.cpp b/src/ui/devicespage.cpp index 28cce07..0b39ece 100644 --- a/src/ui/devicespage.cpp +++ b/src/ui/devicespage.cpp @@ -64,9 +64,11 @@ DevicesPage::DevicesPage( PulseModel *model, TQWidget *parent ) rebuild(); - connect( model, TQ_SIGNAL(cardAdded(uint32_t)), this, TQ_SLOT(onCardAdded(uint32_t)) ); - connect( model, TQ_SIGNAL(cardRemoved(uint32_t)), this, TQ_SLOT(onCardRemoved(uint32_t)) ); - connect( model, TQ_SIGNAL(cardUpdated(uint32_t)), this, TQ_SLOT(onCardUpdated(uint32_t)) ); + connect( model, TQ_SIGNAL(cardAdded(uint32_t)), this, TQ_SLOT(onCardAdded(uint32_t)) ); + connect( model, TQ_SIGNAL(cardRemoved(uint32_t)), this, TQ_SLOT(onCardRemoved(uint32_t)) ); + connect( model, TQ_SIGNAL(cardUpdated(uint32_t)), this, TQ_SLOT(onCardUpdated(uint32_t)) ); + connect( model, TQ_SIGNAL(sinkUpdated(uint32_t)), this, TQ_SLOT(onSinkUpdated(uint32_t)) ); + connect( model, TQ_SIGNAL(sourceUpdated(uint32_t)),this, TQ_SLOT(onSourceUpdated(uint32_t)) ); } void DevicesPage::rebuild() @@ -75,6 +77,12 @@ void DevicesPage::rebuild() m_profileNames.clear(); m_cardCombo.clear(); m_cardPorts.clear(); + m_sinkPortComboSink.clear(); + m_sinkPortComboNames.clear(); + m_sinkPortCombos.clear(); + m_sourcePortComboSource.clear(); + m_sourcePortComboNames.clear(); + m_sourcePortCombos.clear(); delete m_container; m_container = new TQWidget( m_scroll->viewport() ); @@ -117,6 +125,7 @@ void DevicesPage::rebuild() if ( !typeparts.isEmpty() ) addTextRow( i18n("Type:"), typeparts.join(" / ") ); + // Profile dropdown TQComboBox *combo = new TQComboBox( false, grp ); combo->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ); addRow( i18n("Profile:"), combo ); @@ -139,6 +148,78 @@ void DevicesPage::rebuild() connect( combo, TQ_SIGNAL(activated(int)), this, TQ_SLOT(onProfileActivated(int)) ); + // Sink port dropdowns — only when a sink has 2+ ports + TQValueList<PulseModel::DevicePortInfo> sinks = m_model->sinksForCard( info.index ); + bool multiSink = false; + for ( TQValueList<PulseModel::DevicePortInfo>::Iterator sit = sinks.begin(); + sit != sinks.end(); ++sit ) + if ( (int)sit->ports.count() >= 2 ) { multiSink = ( sinks.count() > 1 ); break; } + + for ( TQValueList<PulseModel::DevicePortInfo>::Iterator sit = sinks.begin(); + sit != sinks.end(); ++sit ) { + if ( (int)sit->ports.count() < 2 ) continue; + + TQComboBox *pc = new TQComboBox( false, grp ); + pc->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ); + TQString label = multiSink + ? sit->description + i18n(" port:") + : i18n("Output port:"); + addRow( label, pc ); + + TQValueList<TQString> portNames; + int activePort = 0, pi = 0; + for ( TQValueList<PulseDevicePort>::ConstIterator pit = sit->ports.begin(); + pit != sit->ports.end(); ++pit, ++pi ) { + pc->insertItem( (*pit).description ); + portNames.append( (*pit).name ); + if ( (*pit).name == sit->activePort ) + activePort = pi; + } + pc->setCurrentItem( activePort ); + + m_sinkPortComboNames[pc] = portNames; + m_sinkPortComboSink[pc] = sit->paIndex; + m_sinkPortCombos[sit->paIndex] = pc; + + connect( pc, TQ_SIGNAL(activated(int)), this, TQ_SLOT(onSinkPortActivated(int)) ); + } + + // Source port dropdowns — only when a source has 2+ ports + TQValueList<PulseModel::DevicePortInfo> sources = m_model->sourcesForCard( info.index ); + bool multiSource = false; + for ( TQValueList<PulseModel::DevicePortInfo>::Iterator sit = sources.begin(); + sit != sources.end(); ++sit ) + if ( (int)sit->ports.count() >= 2 ) { multiSource = ( sources.count() > 1 ); break; } + + for ( TQValueList<PulseModel::DevicePortInfo>::Iterator sit = sources.begin(); + sit != sources.end(); ++sit ) { + if ( (int)sit->ports.count() < 2 ) continue; + + TQComboBox *pc = new TQComboBox( false, grp ); + pc->setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Fixed ); + TQString label = multiSource + ? sit->description + i18n(" port:") + : i18n("Input port:"); + addRow( label, pc ); + + TQValueList<TQString> portNames; + int activePort = 0, pi = 0; + for ( TQValueList<PulseDevicePort>::ConstIterator pit = sit->ports.begin(); + pit != sit->ports.end(); ++pit, ++pi ) { + pc->insertItem( (*pit).description ); + portNames.append( (*pit).name ); + if ( (*pit).name == sit->activePort ) + activePort = pi; + } + pc->setCurrentItem( activePort ); + + m_sourcePortComboNames[pc] = portNames; + m_sourcePortComboSource[pc] = sit->paIndex; + m_sourcePortCombos[sit->paIndex] = pc; + + connect( pc, TQ_SIGNAL(activated(int)), this, TQ_SLOT(onSourcePortActivated(int)) ); + } + // Ports — 2-column grid to keep tall cards compact if ( !info.ports.isEmpty() ) { TQLabel *portsHdr = new TQLabel( i18n("Ports:"), grp ); @@ -196,42 +277,7 @@ void DevicesPage::rebuild() void DevicesPage::onCardAdded( uint32_t ) { rebuild(); } void DevicesPage::onCardRemoved( uint32_t ) { rebuild(); } - -void DevicesPage::onCardUpdated( uint32_t index ) -{ - TQMap<uint32_t, TQComboBox*>::Iterator cit = m_cardCombo.find( index ); - if ( cit == m_cardCombo.end() ) return; - TQComboBox *combo = cit.data(); - - const PulseCardInfo *info = m_model->card( index ); - if ( !info ) return; - - // Update active profile in combo - TQMap<TQComboBox*, TQValueList<TQString> >::Iterator nit = m_profileNames.find( combo ); - if ( nit != m_profileNames.end() ) { - TQValueList<TQString> &names = nit.data(); - for ( int i = 0; i < (int)names.count(); ++i ) { - if ( names[i] == info->activeProfile ) { - combo->blockSignals( true ); - combo->setCurrentItem( i ); - combo->blockSignals( false ); - break; - } - } - } - - // Update port availability indicators in-place - TQMap<uint32_t, TQValueList<PortWidgets> >::Iterator pit = m_cardPorts.find( index ); - if ( pit == m_cardPorts.end() ) return; - TQValueList<PortWidgets> &portWidgets = pit.data(); - - int i = 0; - for ( TQValueList<PulseCardPort>::ConstIterator p = info->ports.begin(); - p != info->ports.end() && i < (int)portWidgets.count(); ++p, ++i ) { - bool plugged = ( (*p).available != PA_PORT_AVAILABLE_NO ); - portWidgets[i].dot->setPixmap( availDot( plugged, 10 ) ); - } -} +void DevicesPage::onCardUpdated( uint32_t ) { rebuild(); } void DevicesPage::onProfileActivated( int idx ) { @@ -242,10 +288,101 @@ void DevicesPage::onProfileActivated( int idx ) if ( cit == m_comboCard.end() ) return; uint32_t cardIndex = cit.data(); - TQMap<TQComboBox*, TQValueList<TQString> >::Iterator nit = m_profileNames.find( combo ); + TQMap<TQComboBox*, TQValueList<TQString>>::Iterator nit = m_profileNames.find( combo ); if ( nit == m_profileNames.end() || idx >= (int)nit.data().count() ) return; m_model->setCardProfile( cardIndex, nit.data()[idx] ); } +void DevicesPage::onSinkPortActivated( int idx ) +{ + TQComboBox *combo = dynamic_cast<TQComboBox*>( const_cast<TQObject*>( sender() ) ); + if ( !combo ) return; + + TQMap<TQComboBox*, uint32_t>::Iterator cit = m_sinkPortComboSink.find( combo ); + if ( cit == m_sinkPortComboSink.end() ) return; + + TQMap<TQComboBox*, TQValueList<TQString>>::Iterator nit = m_sinkPortComboNames.find( combo ); + if ( nit == m_sinkPortComboNames.end() || idx >= (int)nit.data().count() ) return; + + m_model->setSinkPort( cit.data(), nit.data()[idx] ); +} + +void DevicesPage::onSourcePortActivated( int idx ) +{ + TQComboBox *combo = dynamic_cast<TQComboBox*>( const_cast<TQObject*>( sender() ) ); + if ( !combo ) return; + + TQMap<TQComboBox*, uint32_t>::Iterator cit = m_sourcePortComboSource.find( combo ); + if ( cit == m_sourcePortComboSource.end() ) return; + + TQMap<TQComboBox*, TQValueList<TQString>>::Iterator nit = m_sourcePortComboNames.find( combo ); + if ( nit == m_sourcePortComboNames.end() || idx >= (int)nit.data().count() ) return; + + m_model->setSourcePort( cit.data(), nit.data()[idx] ); +} + +void DevicesPage::onSinkUpdated( uint32_t paIndex ) +{ + TQMap<uint32_t, TQComboBox*>::Iterator cit = m_sinkPortCombos.find( paIndex ); + if ( cit == m_sinkPortCombos.end() ) { + // Sink with ports appeared after last rebuild — refresh. + rebuild(); + return; + } + TQComboBox *combo = cit.data(); + TQMap<TQComboBox*, TQValueList<TQString>>::Iterator nit = m_sinkPortComboNames.find( combo ); + if ( nit == m_sinkPortComboNames.end() ) return; + + // Find current active port from the model's sinksForCard lookup. + // Walk all cards to find this sink. + TQValueList<PulseCardInfo> cards = m_model->cards(); + for ( TQValueList<PulseCardInfo>::ConstIterator it = cards.begin(); it != cards.end(); ++it ) { + TQValueList<PulseModel::DevicePortInfo> sinks = m_model->sinksForCard( (*it).index ); + for ( TQValueList<PulseModel::DevicePortInfo>::ConstIterator sit = sinks.begin(); + sit != sinks.end(); ++sit ) { + if ( (*sit).paIndex != paIndex ) continue; + TQValueList<TQString> &names = nit.data(); + for ( int i = 0; i < (int)names.count(); ++i ) { + if ( names[i] == (*sit).activePort ) { + combo->blockSignals( true ); + combo->setCurrentItem( i ); + combo->blockSignals( false ); + return; + } + } + } + } +} + +void DevicesPage::onSourceUpdated( uint32_t paIndex ) +{ + TQMap<uint32_t, TQComboBox*>::Iterator cit = m_sourcePortCombos.find( paIndex ); + if ( cit == m_sourcePortCombos.end() ) { + rebuild(); + return; + } + TQComboBox *combo = cit.data(); + TQMap<TQComboBox*, TQValueList<TQString>>::Iterator nit = m_sourcePortComboNames.find( combo ); + if ( nit == m_sourcePortComboNames.end() ) return; + + TQValueList<PulseCardInfo> cards = m_model->cards(); + for ( TQValueList<PulseCardInfo>::ConstIterator it = cards.begin(); it != cards.end(); ++it ) { + TQValueList<PulseModel::DevicePortInfo> sources = m_model->sourcesForCard( (*it).index ); + for ( TQValueList<PulseModel::DevicePortInfo>::ConstIterator sit = sources.begin(); + sit != sources.end(); ++sit ) { + if ( (*sit).paIndex != paIndex ) continue; + TQValueList<TQString> &names = nit.data(); + for ( int i = 0; i < (int)names.count(); ++i ) { + if ( names[i] == (*sit).activePort ) { + combo->blockSignals( true ); + combo->setCurrentItem( i ); + combo->blockSignals( false ); + return; + } + } + } + } +} + #include "devicespage.moc" diff --git a/src/ui/devicespage.h b/src/ui/devicespage.h index 49081f4..046b224 100644 --- a/src/ui/devicespage.h +++ b/src/ui/devicespage.h @@ -10,6 +10,7 @@ class TQScrollView; class TQComboBox; class TQLabel; class TQVBoxLayout; +class AudioDevice; struct PortWidgets { TQLabel *dot; @@ -27,6 +28,10 @@ private slots: void onCardRemoved( uint32_t index ); void onCardUpdated( uint32_t index ); void onProfileActivated( int comboIndex ); + void onSinkPortActivated( int comboIndex ); + void onSourcePortActivated( int comboIndex ); + void onSinkUpdated( uint32_t paIndex ); + void onSourceUpdated( uint32_t paIndex ); private: void rebuild(); @@ -35,8 +40,19 @@ private: TQScrollView *m_scroll; TQWidget *m_container; - TQMap<TQComboBox*, uint32_t> m_comboCard; - TQMap<TQComboBox*, TQValueList<TQString> > m_profileNames; - TQMap<uint32_t, TQComboBox*> m_cardCombo; - TQMap<uint32_t, TQValueList<PortWidgets> > m_cardPorts; + // Profile combos + TQMap<TQComboBox*, uint32_t> m_comboCard; + TQMap<TQComboBox*, TQValueList<TQString>> m_profileNames; + TQMap<uint32_t, TQComboBox*> m_cardCombo; + TQMap<uint32_t, TQValueList<PortWidgets>> m_cardPorts; + + // Sink port combos + TQMap<TQComboBox*, uint32_t> m_sinkPortComboSink; + TQMap<TQComboBox*, TQValueList<TQString>> m_sinkPortComboNames; + TQMap<uint32_t, TQComboBox*> m_sinkPortCombos; + + // Source port combos + TQMap<TQComboBox*, uint32_t> m_sourcePortComboSource; + TQMap<TQComboBox*, TQValueList<TQString>> m_sourcePortComboNames; + TQMap<uint32_t, TQComboBox*> m_sourcePortCombos; }; |
