You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tderadio/plugins/v4lradio/v4lradio-configuration.cpp

649 lines
20 KiB

/***************************************************************************
v4lradio-configuration.cpp - description
-------------------
begin : Fre Jun 20 2003
copyright : (C) 2003 by Martin Witte
email : witte@kawo1.rwth-aachen.de
***************************************************************************/
/***************************************************************************
* *
* 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 *
* (at your option) any later version. *
* *
***************************************************************************/
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/soundcard.h>
#include <tqspinbox.h>
#include <tqlineedit.h>
#include <tqcombobox.h>
#include <tqlabel.h>
#include <tqfile.h>
#include <tqpushbutton.h>
#include <tqslider.h>
#include <tqcheckbox.h>
#include <tdefiledialog.h>
#include <knuminput.h>
#include <tdelocale.h>
#include <ktabwidget.h>
#include "../../src/include/utils.h"
#include "../../src/include/gui_list_helper.h"
#include "v4lradio-configuration.h"
#include "v4lradio.h"
V4LRadioConfiguration::V4LRadioConfiguration (TQWidget *parent, SoundStreamID ssid)
: V4LRadioConfigurationUI(parent),
m_SoundStreamID(ssid),
m_ignoreGUIChanges(false),
m_myControlChange(0),
m_orgTreble(-1),
m_orgBass(-1),
m_orgBalance(-2),
m_orgDeviceVolume(-1),
m_PlaybackMixerHelper(comboPlaybackMixerDevice, StringListHelper::SORT_BY_DESCR),
m_CaptureMixerHelper (comboCaptureMixerDevice, StringListHelper::SORT_BY_DESCR),
m_PlaybackChannelHelper(comboPlaybackMixerChannel),
m_CaptureChannelHelper (comboCaptureMixerChannel)
{
TQObject::connect(buttonSelectRadioDevice, TQ_SIGNAL(clicked()),
this, TQ_SLOT(selectRadioDevice()));
editRadioDevice->installEventFilter(this);
TQObject::connect(editMinFrequency, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(guiMinFrequencyChanged(int)));
TQObject::connect(editMaxFrequency, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(guiMaxFrequencyChanged(int)));
TQObject::connect(editDeviceVolume, TQ_SIGNAL(valueChanged(double)),
this, TQ_SLOT(slotDeviceVolumeChanged(double)));
TQObject::connect(editTreble, TQ_SIGNAL(valueChanged(double)),
this, TQ_SLOT(slotTrebleChanged(double)));
TQObject::connect(editBass, TQ_SIGNAL(valueChanged(double)),
this, TQ_SLOT(slotBassChanged(double)));
TQObject::connect(editBalance, TQ_SIGNAL(valueChanged(double)),
this, TQ_SLOT(slotBalanceChanged(double)));
TQObject::connect(sliderDeviceVolume, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(slotDeviceVolumeChanged(int)));
TQObject::connect(sliderTreble, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(slotTrebleChanged(int)));
TQObject::connect(sliderBass, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(slotBassChanged(int)));
TQObject::connect(sliderBalance, TQ_SIGNAL(valueChanged(int)),
this, TQ_SLOT(slotBalanceChanged(int)));
TQObject::connect(comboPlaybackMixerDevice, TQ_SIGNAL(activated(int)),
this, TQ_SLOT(slotComboPlaybackMixerSelected(int)));
TQObject::connect(comboCaptureMixerDevice, TQ_SIGNAL(activated(int)),
this, TQ_SLOT(slotComboCaptureMixerSelected(int)));
sliderBalance->installEventFilter(this);
}
V4LRadioConfiguration::~V4LRadioConfiguration ()
{
}
bool V4LRadioConfiguration::connectI (Interface *i)
{
bool a = IV4LCfgClient::connectI(i);
bool b = IFrequencyRadioClient::connectI(i);
bool c = IRadioDeviceClient::connectI(i);
bool d = ISoundStreamClient::connectI(i);
return a || b || c || d;
}
bool V4LRadioConfiguration::disconnectI (Interface *i)
{
bool a = IV4LCfgClient::disconnectI(i);
bool b = IFrequencyRadioClient::disconnectI(i);
bool c = IRadioDeviceClient::disconnectI(i);
bool d = ISoundStreamClient::disconnectI(i);
return a || b || c || d;
}
void V4LRadioConfiguration::noticeConnectedI (ISoundStreamServer *s, bool pointer_valid)
{
ISoundStreamClient::noticeConnectedI(s, pointer_valid);
if (s && pointer_valid) {
s->register4_notifyTrebleChanged(this);
s->register4_notifyBassChanged(this);
s->register4_notifyBalanceChanged(this);
s->register4_notifySignalMinQualityChanged(this);
s->register4_notifyPlaybackChannelsChanged(this);
s->register4_notifyCaptureChannelsChanged(this);
s->register4_notifySoundStreamCreated(this);
}
}
void V4LRadioConfiguration::noticeConnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid)
{
if (i && pointer_valid && i->supportsPlayback()) {
const TQString &org_mid = queryPlaybackMixerID();
bool org_present = m_PlaybackMixerHelper.contains(org_mid);
const TQString &mid = org_present ? m_PlaybackMixerHelper.getCurrentItem() : org_mid;
const TQString &org_ch = queryPlaybackMixerChannel();
const TQString &ch = org_present ? m_PlaybackChannelHelper.getCurrentText() : org_ch;
noticePlaybackMixerChanged(mid, ch);
}
if (i && pointer_valid && i->supportsCapture()) {
const TQString &org_mid = queryCaptureMixerID();
bool org_present = m_CaptureMixerHelper.contains(org_mid);
const TQString &mid = org_present ? m_CaptureMixerHelper.getCurrentItem() : org_mid;
const TQString &org_ch = queryCaptureMixerChannel();
const TQString &ch = org_present ? m_CaptureChannelHelper.getCurrentText() : org_ch;
noticeCaptureMixerChanged(mid, ch);
}
}
void V4LRadioConfiguration::noticeDisconnectedSoundClient(ISoundStreamClient::thisInterface *i, bool pointer_valid)
{
if (i && pointer_valid && i->supportsPlayback()) {
noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
}
if (i && pointer_valid && i->supportsCapture()) {
noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
}
}
// IV4LCfgClient
bool V4LRadioConfiguration::noticeRadioDeviceChanged(const TQString &s)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
editRadioDevice->setText(s);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticePlaybackMixerChanged(const TQString &_mixer_id, const TQString &Channel)
{
TQString mixer_id = _mixer_id;
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
m_PlaybackMixerHelper.setData(getPlaybackClientDescriptions());
m_PlaybackMixerHelper.setCurrentItem(mixer_id);
mixer_id = m_PlaybackMixerHelper.getCurrentItem();
ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id);
if (mixer) {
m_PlaybackChannelHelper.setData(mixer->getPlaybackChannels());
m_PlaybackChannelHelper.setCurrentText(m_PlaybackChannelHelper.contains(Channel) ? Channel : queryPlaybackMixerChannel());
}
labelPlaybackMixerChannel->setEnabled(mixer != NULL);
comboPlaybackMixerChannel->setEnabled(mixer != NULL);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeCaptureMixerChanged(const TQString &_mixer_id, const TQString &Channel)
{
TQString mixer_id = _mixer_id;
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
m_CaptureMixerHelper.setData(getCaptureClientDescriptions());
m_CaptureMixerHelper.setCurrentItem(mixer_id);
mixer_id = m_CaptureMixerHelper.getCurrentItem();
ISoundStreamClient *mixer = getSoundStreamClientWithID(mixer_id);
if (mixer) {
m_CaptureChannelHelper.setData(mixer->getCaptureChannels());
m_CaptureChannelHelper.setCurrentText(m_CaptureChannelHelper.contains(Channel) ? Channel : queryCaptureMixerChannel());
}
labelCaptureMixerChannel->setEnabled(mixer != NULL);
comboCaptureMixerChannel->setEnabled(mixer != NULL);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeDeviceVolumeChanged(float v)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
v = v > 1 ? 1 : v;
v = v < 0 ? 0 : v;
if (!m_myControlChange)
m_orgDeviceVolume = v;
editDeviceVolume ->setValue(v);
sliderDeviceVolume->setValue(m_caps.maxVolume - m_caps.intGetVolume(v));
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeCapabilitiesChanged(const V4LCaps &c)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
labelDeviceVolume ->setEnabled(c.hasVolume);
editDeviceVolume ->setEnabled(c.hasVolume);
editDeviceVolume ->setRange(0, 1, c.volumeStep(), false);
sliderDeviceVolume->setMinValue(0);
sliderDeviceVolume->setMaxValue(c.maxVolume - c.minVolume);
sliderDeviceVolume->setEnabled(c.hasVolume);
labelTreble ->setEnabled(c.hasTreble);
editTreble ->setEnabled(c.hasTreble);
editTreble ->setRange(0, 1, c.trebleStep(), false);
sliderTreble->setMinValue(0);
sliderTreble->setMaxValue(c.maxTreble - c.minTreble);
sliderTreble->setEnabled(c.hasTreble);
labelBass ->setEnabled(c.hasBass);
editBass ->setEnabled(c.hasBass);
editBass ->setRange(0, 1, c.bassStep(), false);
sliderBass->setMinValue(0);
sliderBass->setMaxValue(c.maxBass - c.minBass);
sliderBass->setEnabled(c.hasBass);
labelBalance ->setEnabled(c.hasBalance);
editBalance ->setEnabled(c.hasBalance);
editBalance ->setRange(-1, 1, c.balanceStep(), false);
sliderBalance->setMinValue(0);
sliderBalance->setMaxValue(c.maxBalance - c.minBalance);
sliderBalance->setEnabled(c.hasBalance);
m_caps = c;
float tmp = 0;
noticeDeviceVolumeChanged(queryDeviceVolume());
queryTreble(m_SoundStreamID, tmp);
noticeTrebleChanged(m_SoundStreamID, tmp);
queryBass(m_SoundStreamID, tmp);
noticeBassChanged(m_SoundStreamID, tmp);
queryBalance(m_SoundStreamID, tmp);
noticeBalanceChanged(m_SoundStreamID, tmp);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeActivePlaybackChanged(bool a)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
m_checkboxActivePlayback->setChecked(a);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeMuteOnPowerOffChanged(bool a)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
m_checkboxMuteOnPowerOff->setChecked(a);
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeVolumeZeroOnPowerOffChanged(bool a)
{
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
m_checkboxVolumeZeroOnPowerOff->setChecked(a);
m_ignoreGUIChanges = old;
return true;
}
// IRadioDeviceClient
bool V4LRadioConfiguration::noticeDescriptionChanged (const TQString &s, const IRadioDevice */*sender*/)
{
labelDescription->setText(s);
return true;
}
// IFrequencyRadioClient
bool V4LRadioConfiguration::noticeFrequencyChanged(float /*f*/, const RadioStation */*s*/)
{
return false; // we don't care
}
bool V4LRadioConfiguration::noticeMinMaxFrequencyChanged(float min, float max)
{
editMinFrequency->setValue((int)rint(min*1000));
editMaxFrequency->setValue((int)rint(max*1000));
return true;
}
bool V4LRadioConfiguration::noticeDeviceMinMaxFrequencyChanged(float min, float max)
{
editMinFrequency->setMinValue((int)rint(min*1000));
editMaxFrequency->setMaxValue((int)rint(max*1000));
return true;
}
bool V4LRadioConfiguration::noticeScanStepChanged(float s)
{
editScanStep->setValue((int)rint(s * 1000));
return true;
}
// IRadioSoundClient
bool V4LRadioConfiguration::noticeTrebleChanged(SoundStreamID id, float t)
{
if (id != m_SoundStreamID)
return false;
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
t = t > 1 ? 1 : t;
t = t < 0 ? 0 : t;
if (!m_myControlChange)
m_orgTreble = t;
editTreble ->setValue (t);
sliderTreble->setValue(m_caps.maxTreble - m_caps.intGetTreble(t));
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeBassChanged(SoundStreamID id, float b)
{
if (id != m_SoundStreamID)
return false;
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
b = b > 1 ? 1 : b;
b = b < 0 ? 0 : b;
if (!m_myControlChange)
m_orgBass = b;
editBass ->setValue(b);
sliderBass->setValue(m_caps.maxBass - m_caps.intGetBass(b));
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeBalanceChanged(SoundStreamID id, float b)
{
if (id != m_SoundStreamID)
return false;
bool old = m_ignoreGUIChanges;
m_ignoreGUIChanges = true;
b = b > 1 ? 1 : b;
b = b < -1 ? -1 : b;
if (!m_myControlChange)
m_orgBalance = b;
editBalance ->setValue(b);
sliderBalance->setValue(m_caps.intGetBalance(b));
m_ignoreGUIChanges = old;
return true;
}
bool V4LRadioConfiguration::noticeSignalMinQualityChanged(SoundStreamID id, float q)
{
if (id != m_SoundStreamID)
return false;
editSignalMinQuality->setValue((int)rint(q * 100));
return true;
}
bool V4LRadioConfiguration::noticeSoundStreamCreated(SoundStreamID id)
{
if (id.HasSamePhysicalID(m_SoundStreamID)) {
m_SoundStreamID = id;
}
return true;
}
// GUI Slots
void V4LRadioConfiguration::selectRadioDevice()
{
KFileDialog fd("/dev/",
i18n("any ( * )").ascii(),
this,
i18n("Radio Device Selection").ascii(),
TRUE);
fd.setMode(KFile::File | KFile::ExistingOnly);
fd.setCaption (i18n("Select Radio Device"));
if (fd.exec() == TQDialog::Accepted) {
editRadioDevice->setText(fd.selectedFile());
}
}
bool V4LRadioConfiguration::eventFilter(TQObject *o, TQEvent *e)
{
if (e->type() == TQEvent::FocusOut && o == editRadioDevice) {
slotEditRadioDeviceChanged();
}
if (e->type() == TQEvent::MouseButtonDblClick && o == sliderBalance) {
slotBalanceCenter();
}
return false;
}
void V4LRadioConfiguration::slotEditRadioDeviceChanged()
{
if (m_ignoreGUIChanges) return;
const TQString &s = editRadioDevice->text();
if (s != queryRadioDevice() || !queryIsPowerOn()) {
V4LCaps c = queryCapabilities(s);
noticeDescriptionChanged(c.description);
} else {
noticeDescriptionChanged(queryDescription());
}
}
void V4LRadioConfiguration::slotComboPlaybackMixerSelected(int /*idx*/)
{
if (m_ignoreGUIChanges) return;
TQString id = m_PlaybackMixerHelper.getCurrentItem();
noticePlaybackMixerChanged(id, queryPlaybackMixerChannel());
}
void V4LRadioConfiguration::slotComboCaptureMixerSelected(int /*idx*/)
{
if (m_ignoreGUIChanges) return;
TQString id = m_CaptureMixerHelper.getCurrentItem();
noticeCaptureMixerChanged(id, queryCaptureMixerChannel());
}
void V4LRadioConfiguration::slotOK()
{
sendMinFrequency(((float)editMinFrequency->value()) / 1000.0);
sendMaxFrequency(((float)editMaxFrequency->value()) / 1000.0);
sendSignalMinQuality(m_SoundStreamID, editSignalMinQuality->value() * 0.01);
sendRadioDevice(editRadioDevice->text());
sendScanStep(((float)editScanStep->value()) / 1000.0);
sendCaptureMixer (m_CaptureMixerHelper.getCurrentItem(),
m_CaptureChannelHelper.getCurrentText());
sendPlaybackMixer(m_PlaybackMixerHelper.getCurrentItem(),
m_PlaybackChannelHelper.getCurrentText());
sendActivePlayback(m_checkboxActivePlayback->isChecked());
sendMuteOnPowerOff(m_checkboxMuteOnPowerOff->isChecked());
sendVolumeZeroOnPowerOff(m_checkboxVolumeZeroOnPowerOff->isChecked());
queryTreble (m_SoundStreamID, m_orgTreble);
queryBass (m_SoundStreamID, m_orgBass);
queryBalance(m_SoundStreamID, m_orgBalance);
m_orgDeviceVolume = queryDeviceVolume();
}
void V4LRadioConfiguration::slotCancel()
{
noticeRadioDeviceChanged(queryRadioDevice());
noticePlaybackMixerChanged(queryPlaybackMixerID(), queryPlaybackMixerChannel());
noticeCaptureMixerChanged (queryCaptureMixerID(), queryCaptureMixerChannel());
noticeMinMaxFrequencyChanged(queryMinFrequency(), queryMaxFrequency());
noticeActivePlaybackChanged(queryActivePlayback());
noticeMuteOnPowerOffChanged(queryMuteOnPowerOff());
noticeVolumeZeroOnPowerOffChanged(queryVolumeZeroOnPowerOff());
float q = 0;
querySignalMinQuality(m_SoundStreamID, q);
noticeSignalMinQualityChanged(m_SoundStreamID, q);
noticeScanStepChanged(queryScanStep());
sendTreble (m_SoundStreamID, m_orgTreble);
sendBass (m_SoundStreamID, m_orgBass);
sendBalance (m_SoundStreamID, m_orgBalance);
sendDeviceVolume(m_orgDeviceVolume);
}
void V4LRadioConfiguration::guiMinFrequencyChanged(int v)
{
editMaxFrequency->setMinValue(v);
}
void V4LRadioConfiguration::guiMaxFrequencyChanged(int v)
{
editMinFrequency->setMaxValue(v);
}
void V4LRadioConfiguration::slotDeviceVolumeChanged (double v) // for KDoubleNumInput, 0.0..1.0
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendDeviceVolume(v);
--m_myControlChange;
}
void V4LRadioConfiguration::slotTrebleChanged (double t) // for KDoubleNumInput, 0.0..1.0
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendTreble(m_SoundStreamID, t);
--m_myControlChange;
}
void V4LRadioConfiguration::slotBassChanged (double b) // for KDoubleNumInput, 0.0..1.0
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendBass(m_SoundStreamID, b);
--m_myControlChange;
}
void V4LRadioConfiguration::slotBalanceChanged(double b) // for KDoubleNumInput, -1.0..1.0
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendBalance(m_SoundStreamID, b);
--m_myControlChange;
}
void V4LRadioConfiguration::slotDeviceVolumeChanged (int v)
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendDeviceVolume(m_caps.floatGetVolume(m_caps.maxVolume - v));
--m_myControlChange;
}
void V4LRadioConfiguration::slotTrebleChanged (int t)
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendTreble(m_SoundStreamID, m_caps.floatGetTreble(m_caps.maxTreble - t));
--m_myControlChange;
}
void V4LRadioConfiguration::slotBassChanged (int b)
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendBass(m_SoundStreamID, m_caps.floatGetBass(m_caps.maxBass - b));
--m_myControlChange;
}
void V4LRadioConfiguration::slotBalanceChanged(int b)
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendBalance(m_SoundStreamID, m_caps.floatGetBalance(b));
--m_myControlChange;
}
void V4LRadioConfiguration::slotBalanceCenter()
{
if (m_ignoreGUIChanges) return;
++m_myControlChange;
sendBalance(m_SoundStreamID, 0);
--m_myControlChange;
}
bool V4LRadioConfiguration::noticePlaybackChannelsChanged(const TQString & client_id, const TQStringList &/*channels*/)
{
if (m_PlaybackMixerHelper.getCurrentItem() == client_id) {
noticePlaybackMixerChanged(client_id, m_PlaybackChannelHelper.getCurrentText());
}
return true;
}
bool V4LRadioConfiguration::noticeCaptureChannelsChanged (const TQString & client_id, const TQStringList &/*channels*/)
{
if (m_CaptureMixerHelper.getCurrentItem() == client_id) {
noticeCaptureMixerChanged(client_id, m_CaptureChannelHelper.getCurrentText());
}
return true;
}
#include "v4lradio-configuration.moc"