diff options
Diffstat (limited to 'plugins/radio/radio.cpp')
-rw-r--r-- | plugins/radio/radio.cpp | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/plugins/radio/radio.cpp b/plugins/radio/radio.cpp new file mode 100644 index 0000000..4e853ce --- /dev/null +++ b/plugins/radio/radio.cpp @@ -0,0 +1,497 @@ +/*************************************************************************** + radio.cpp - description + ------------------- + begin : Sat March 29 2003 + copyright : (C) 2003 by Klas Kalass, Ernst Martin Witte + email : [email protected], [email protected] + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "../../src/include/radiostation.h" +#include "../../src/include/aboutwidget.h" +#include "../../src/include/radiodevice_interfaces.h" +#include "radio.h" +#include "radio-configuration.h" + +#include <kstandarddirs.h> +#include <kurl.h> +#include <tdeaboutdata.h> +#include <tdeconfig.h> + +#include "../../src/include/debug-profiler.h" + +/////////////////////////////////////////////////////////////////////// +//// plugin library functions + +PLUGIN_LIBRARY_FUNCTIONS(Radio, "tderadio-radio", i18n("Central Radio Device Multiplexer")); + +///////////////////////////////////////////////////////////////////////////// + +Radio::Radio(const TQString &name) + : PluginBase(name, i18n("Radio Multiplexer Plugin")), + IRadioDeviceClient(-1), + m_presetFile(locateLocal("data", "tderadio/stations.krp")), + m_activeDevice (NULL) +{ +} + + +Radio::~Radio() +{ +} + + +bool Radio::connectI (Interface *i) +{ + bool a = IRadio::connectI(i); + bool b = IRadioDeviceClient::connectI(i); + bool c = IRadioDevicePool::connectI(i); + bool d = PluginBase::connectI(i); + bool e = ISoundStreamClient::connectI(i); + + // no "return IA::connectI() | return IB::connnectI to + // prevent "early termination" optimization in boolean expressions + return a || b || c || d || e; +} + + +bool Radio::disconnectI (Interface *i) +{ + bool a = IRadio::disconnectI(i); + bool b = IRadioDeviceClient::disconnectI(i); + bool c = IRadioDevicePool::disconnectI(i); + bool d = PluginBase::disconnectI(i); + bool e = ISoundStreamClient::disconnectI(i); + + // no "return IA::disconnectI() | return IB::disconnnectI to + // prevent "early termination" optimization in boolean expressions + return a || b || c || d || e; +} + + +void Radio::saveState (TDEConfig *config) const +{ + config->setGroup(TQString("radio-") + name()); + + config->writeEntry("presetfile", m_presetFile); + + m_stationList.writeXML(m_presetFile, *this); +} + + +void Radio::restoreState (TDEConfig *config) +{ + config->setGroup(TQString("radio-") + name()); + + m_presetFile = config->readEntry("presetfile", + TQString()); + bool first_restore = false; + if (m_presetFile.isNull() || m_presetFile.length() == 0) { + m_presetFile = locateLocal("data", "tderadio/stations.krp"); + first_restore = true; + } + + m_stationList.readXML(KURL(m_presetFile), *this, /*enable-messagebox*/ !first_restore); + + notifyStationsChanged(m_stationList); + notifyPresetFileChanged(m_presetFile); +} + + + +ConfigPageInfo Radio::createConfigurationPage() +{ + RadioConfiguration *conf = new RadioConfiguration (NULL, *this); + connectI (conf); + return ConfigPageInfo( + conf, + i18n("Radio Stations"), + i18n("Setup Radio Stations"), + "tderadio" + ); +} + + +AboutPageInfo Radio::createAboutPage() +{ +/* TDEAboutData aboutData("tderadio", + NULL, + NULL, + I18N_NOOP("Radio Device Multiplexer and Station Management for TDERadio"), + TDEAboutData::License_GPL, + "(c) 2002-2005 Martin Witte, Klas Kalass", + 0, + "http://sourceforge.net/projects/tderadio", + 0); + aboutData.addAuthor("Martin Witte", "", "[email protected]"); + aboutData.addAuthor("Klas Kalass", "", "[email protected]"); + + return AboutPageInfo( + new TDERadioAboutWidget(aboutData, TDERadioAboutWidget::AbtTabbed), + i18n("Device and Station Management"), + i18n("Radio Device Multiplexer and Station Management"), + "tderadio" + ); +*/ + return AboutPageInfo(); +} + + + + + + +/* IRadio Interface Methods +*/ + +/* offer new station to current device. + if that does not accept, try all other devices. + Any device will be powered off if it does not accept the station +*/ + +bool Radio::activateStation (const RadioStation &rs) { + + if (sendActivateStation(rs)) { // first try activeDevice + + return true; + + } else { // hmm... active device did not want it. Try others... + + int n = 0; + + for (IRadioDeviceClient::IFIterator it(IRadioDeviceClient::iConnections); it.current(); ++it) { + + if (it.current()->activateStation(rs)) { + + setActiveDevice(it.current()); // select new device + ++n; + + } else { + + it.current()->powerOff(); + + } + } + + return n > 0; + } +} + + +bool Radio::activateStation(int index) +{ + if (index < 0 || index >= m_stationList.count()) + return false; + + return activateStation(m_stationList.at(index)); +} + + +bool Radio::setStations(const StationList &sl) +{ + if (true/*m_stationList != sl*/) { + BlockProfiler("Radio::setStations"); + m_stationList = sl; + notifyStationsChanged(m_stationList); + } + return true; +} + +bool Radio::setPresetFile(const TQString &presetFile) +{ + if (m_presetFile != presetFile) { + m_presetFile = presetFile; + notifyPresetFileChanged(m_presetFile); + } + return true; +} + +int Radio::getStationIdx(const RadioStation &rs) const +{ + RawStationList &sl = const_cast<RawStationList&>(m_stationList.all()); + return sl.find(&rs); +} + +int Radio::getCurrentStationIdx() const +{ + return getStationIdx(getCurrentStation()); +} + +SoundStreamID Radio::getCurrentSoundStreamID() const +{ + return queryCurrentSoundStreamID(); +} + + +/* IRadioDevicePool Interface Methods + +*/ + + +bool Radio::setActiveDevice(IRadioDevice *rd, bool keepPower) +{ + // do nothing if old == new + if (m_activeDevice == rd) + return true; + + // check if new station is in "connections" + // special case: rd == NULL: power off active device, new active device = NULL + + if (!rd || IRadioDeviceClient::iConnections.containsRef(rd)) { // new device is ok + + // save old power state and power off old device + bool oldPowerOn = false; + if (m_activeDevice) { + oldPowerOn = m_activeDevice->isPowerOn(); + m_activeDevice->powerOff(); + } + + // setup new active device && send notifications + m_activeDevice = rd; + + // send notifications + notifyActiveDeviceChanged(m_activeDevice); + notifyCurrentSoundStreamIDChanged(queryCurrentSoundStreamID()); + const RadioStation &rs = queryCurrentStation(); + notifyStationChanged(rs, getStationIdx(rs)); + + if (keepPower) + oldPowerOn ? sendPowerOn() : sendPowerOff(); + + return true; + + } else { + return false; + } +} + + +IRadioDevice *Radio::getActiveDevice() const +{ + return m_activeDevice; +} + + +const TQPtrList<IRadioDevice> &Radio::getDevices() const +{ + return IRadioDeviceClient::iConnections; +} + + +const TQString &Radio::getDeviceDescription() const +{ + return queryDescription(); +} + + + +/* IRadioDeviceClient Interface Methods + + Many things are overwritten, particularly all sending methods + +*/ + +int Radio::sendPowerOn() const +{ + return m_activeDevice ? m_activeDevice->powerOn() : 0; +} + + +int Radio::sendPowerOff() const +{ + return m_activeDevice ? m_activeDevice->powerOff() : 0; +} + +int Radio::sendActivateStation (const RadioStation &rs) const +{ + return m_activeDevice ? m_activeDevice->activateStation(rs) : 0; +} + + + +bool Radio::queryIsPowerOn() const +{ + return m_activeDevice ? m_activeDevice->isPowerOn() : false; +} + + +bool Radio::queryIsPowerOff() const +{ + return m_activeDevice ? m_activeDevice->isPowerOff() : true; +} + + +const RadioStation & Radio::queryCurrentStation() const +{ + if (m_activeDevice) { + RadioStation &rs = const_cast<RadioStation&>(m_activeDevice->getCurrentStation()); + int idx = getStationIdx(rs); + + if (idx >= 0) { + rs.copyDescriptionFrom(m_stationList.at(idx)); + } else { + rs.copyDescriptionFrom(undefinedRadioStation); + } + + return rs; + } else { + return undefinedRadioStation; + } +} + + +static TQString qstrUnknown(I18N_NOOP("unknown")); +static TQString i18nqstrUnknown; +const TQString &Radio::queryDescription() const +{ + return m_activeDevice ? m_activeDevice->getDescription() : (i18nqstrUnknown = i18n(qstrUnknown.ascii())); +} + + + +bool Radio::noticePowerChanged (bool on, const IRadioDevice *sender) +{ + if (on) { + setActiveDevice(const_cast<IRadioDevice*>(sender), false); + // false: do not set power state on new device + // constcast valid because power-state of sender is not changed + notifyPowerChanged(true); + return true; + + } else { + if (sender == m_activeDevice) { + sendStopCountdown(); + notifyPowerChanged(false); + return true; + } + return false; + } +} + + +bool Radio::noticeStationChanged (const RadioStation &_rs, const IRadioDevice *sender) +{ + RadioStation &rs = const_cast<RadioStation&>(_rs); + int idx = getStationIdx(rs); + + RadioStation &known = (idx >= 0) ? (RadioStation&)m_stationList.at(idx) : + (RadioStation&)undefinedRadioStation; + rs.copyDescriptionFrom(known); + + if (sender == m_activeDevice) + notifyStationChanged(rs, idx); + return true; +} + + +bool Radio::noticeDescriptionChanged (const TQString &s, const IRadioDevice *sender) +{ + if (sender == m_activeDevice) + notifyDeviceDescriptionChanged(s); + return true; +} + + +bool Radio::noticeCurrentSoundStreamIDChanged(SoundStreamID id, const IRadioDevice *sender) +{ + if (sender == m_activeDevice) + notifyCurrentSoundStreamIDChanged(id); + return true; +} + + +SoundStreamID Radio::queryCurrentSoundStreamID() const +{ + return m_activeDevice ? m_activeDevice->getCurrentSoundStreamID() : SoundStreamID::InvalidID; +} + + + +void Radio::noticeConnectedI(IRadioDeviceClient::cmplInterface *dev, bool pointer_valid) +{ + IRadioDeviceClient::noticeConnectedI(dev, pointer_valid); + + if (! m_activeDevice && pointer_valid) + setActiveDevice (dev, false); + + notifyDevicesChanged(IRadioDeviceClient::iConnections); +} + + +void Radio::noticeDisconnectI(IRadioDeviceClient::cmplInterface *rd, bool pointer_valid) +{ + IRadioDeviceClient::noticeDisconnectI(rd, pointer_valid); + + if (rd == m_activeDevice) { + + // search a new active device + if (IRadioDeviceClient::iConnections.findRef(rd) >= 0) { + + IRadioDevice *new_rd = NULL; + + new_rd = IRadioDeviceClient::iConnections.next(); // choose next device as active device if next exists + if (!new_rd) { + IRadioDeviceClient::iConnections.findRef(rd); + new_rd = IRadioDeviceClient::iConnections.prev(); // otherwise try prev then, may be NULL (no connections) + } + setActiveDevice(new_rd); + + } else { + // strange error occurred, m_activeDevice not in connections... set to first. + + setActiveDevice(IRadioDeviceClient::iConnections.first()); + } + } + notifyDevicesChanged(IRadioDeviceClient::iConnections); +} + + +// ITimeControlClient + +bool Radio::noticeAlarm(const Alarm &a) +{ + if (a.alarmType() == Alarm::StartPlaying || + a.alarmType() == Alarm::StartRecording) + { + const RawStationList &sl = getStations().all(); + const RadioStation &rs = sl.stationWithID(a.stationID()); + activateStation(rs); + powerOn(); + + if (a.volumePreset() >= 0) + sendPlaybackVolume(getCurrentSoundStreamID(), a.volumePreset()); + + SoundStreamID id = getCurrentSoundStreamID(); + bool r = false; + SoundFormat sf; + queryIsRecordingRunning(id, r, sf); + if (a.alarmType() == Alarm::StartRecording && !r) + sendStartRecording(id); + + } else { + powerOff(); + } + return true; +} + + +bool Radio::noticeCountdownZero() +{ + powerOff(); + return true; +} + + +void Radio::aboutToQuit() +{ + sendPowerOff(); +} + |