/*************************************************************************** radio-configuration.cpp - description ------------------- begin : Son Aug 3 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 "../../src/include/radiostation.h" #include "../../src/include/stationlist.h" #include "../../src/include/plugins.h" #include "../../src/include/radiodevice_interfaces.h" #include "../../src/include/standardscandialog.h" #include "../../src/include/radiostation-listview.h" #include "../../src/include/radiostation-config.h" #include "../../src/include/errorlog-interfaces.h" #include "radio-configuration.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include RadioConfiguration::RadioConfiguration (TQWidget *parent, const IErrorLogClient &logger) : RadioConfigurationUI(parent), ignoreChanges(false), devicePopup(NULL), m_logger(logger), m_dirty(true) { TQObject::connect(listStations, TQ_SIGNAL(sigCurrentStationChanged(int)), this, TQ_SLOT(slotStationSelectionChanged(int))); TQObject::connect(buttonSelectPixmapFile, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotSelectPixmap())); TQObject::connect(buttonNewStation, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotNewStation())); TQObject::connect(buttonDeleteStation, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotDeleteStation())); TQObject::connect(editPixmapFile, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(slotPixmapChanged(const TQString &))); TQObject::connect(editStationName, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(slotStationNameChanged(const TQString &))); TQObject::connect(editStationShortName, TQ_SIGNAL(textChanged(const TQString &)), this, TQ_SLOT(slotStationShortNameChanged(const TQString &))); TQObject::connect(editVolumePreset, TQ_SIGNAL(valueChanged(int)), this, TQ_SLOT(slotVolumePresetChanged(int))); TQObject::connect(buttonStationUp, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotStationUp())); TQObject::connect(buttonStationDown, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotStationDown())); TQObject::connect(listStations, TQ_SIGNAL(sigStationActivated(int)), this, TQ_SLOT(slotActivateStation( int ))); TQObject::connect(buttonLoadPresets, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotLoadPresets())); TQObject::connect(buttonStorePresets, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotStorePresets())); TQObject::connect(buttonLastChangeNow, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotLastChangeNow())); connect(editMaintainer, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); connect(editLastChange, TQ_SIGNAL(valueChanged(const TQDateTime &)), TQ_SLOT(slotSetDirty())); connect(editCountry, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); connect(editCity, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); connect(editMedia, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); connect(editComment, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); connect(editPresetFile, TQ_SIGNAL(textChanged(const TQString &)), TQ_SLOT(slotSetDirty())); mailLabel->setText("mailto:witte-presets@kawo1.rwth-aachen.de"); mailLabel->setURL ("mailto:witte-presets@kawo1.rwth-aachen.de"); TQObject::connect(mailLabel, TQ_SIGNAL(leftClickedURL(const TQString &)), this, TQ_SLOT(slotSendPresetsByMail(const TQString &))); TQObject::connect(buttonSearchStations, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotSearchStations0())); devicePopup = new TQPopupMenu(buttonSearchStations); buttonSearchStations->setPopup(devicePopup); TQObject::connect(devicePopup, TQ_SIGNAL(activated(int)), this, TQ_SLOT(slotSearchStations(int))); } RadioConfiguration::~RadioConfiguration () { } bool RadioConfiguration::connectI (Interface *i) { bool a = IRadioClient::connectI(i); bool b = IRadioDevicePoolClient::connectI(i); return a || b; } bool RadioConfiguration::disconnectI (Interface *i) { bool a = IRadioClient::disconnectI(i); bool b = IRadioDevicePoolClient::disconnectI(i); return a || b; } // IRadioDevicePoolClient bool RadioConfiguration::noticeDevicesChanged(const TQPtrList &l) { TQPtrListIterator it(l); devices.clear(); devicePopup->clear(); int id = 0; for (; it.current(); ++it) { IRadioDevice *d = it.current(); if (dynamic_cast(d)) { devicePopup->insertItem(d->getDescription(), id++); devices.append(d); } } return true; } bool RadioConfiguration::noticeDeviceDescriptionChanged(const TQString &) { noticeDevicesChanged(queryDevices()); return true; } // IRadioClient bool RadioConfiguration::noticeStationsChanged(const StationList &sl) { ignoreChanges = true; m_stations = sl; listStations->setStations(sl); StationListMetaData &info = m_stations.metaData(); editMaintainer->setText(info.maintainer); editLastChange->setDateTime(info.lastChange); editCountry->setText(info.country); editCity->setText(info.city); editMedia->setText(info.media); editComment->setText(info.comment); ignoreChanges = false; slotStationSelectionChanged(listStations->currentStationIndex()); return true; } bool RadioConfiguration::noticePresetFileChanged(const TQString &f) { ignoreChanges = true; editPresetFile->setURL(f); ignoreChanges = false; return true; } void RadioConfiguration::slotStationSelectionChanged(int idx) { RadioStation *s = NULL; if (idx >= 0 && idx < m_stations.count()) { s = &m_stations.at(idx); } editStationName ->setDisabled(!s); labelStationName ->setDisabled(!s); editPixmapFile ->setDisabled(!s); labelPixmapFile ->setDisabled(!s); editStationShortName ->setDisabled(!s); labelStationShortName ->setDisabled(!s); editVolumePreset ->setDisabled(!s); labelVolumePreset ->setDisabled(!s); buttonSelectPixmapFile->setDisabled(!s); buttonDeleteStation ->setDisabled(!s); buttonStationUp ->setDisabled(!s || idx == 0); buttonStationDown ->setDisabled(!s || idx == m_stations.count()-1); if (ignoreChanges) return; ignoreChanges = true; editStationName ->setText (s ? s->name() : TQString()); editStationShortName ->setText (s ? s->shortName() : TQString()); editPixmapFile ->setText (s ? s->iconName() : TQString()); editVolumePreset ->setValue (s ? (int)rint(s->initialVolume()*100) : -1); TQPixmap pixmap(s ? s->iconName() : TQString()); if (!pixmap.isNull()) { pixmapStation->setPixmap(pixmap); } else { pixmapStation->setText(""); } stackStationEdit->setDisabled(!s); if (s) { RadioStationConfig *c = stationEditors.find(s->getClassName()); if (!c) { c = s->createEditor(); if (c) { c->reparent(this, TQPoint(0,0), true); TQObject::connect(c, TQ_SIGNAL(changed(RadioStationConfig*)), this, TQ_SLOT(slotStationEditorChanged(RadioStationConfig*))); stationEditors.insert(s->getClassName(), c); stackStationEdit->addWidget(c); } } if (c) { c->setStationData(*s); stackStationEdit->raiseWidget(c); } } ignoreChanges = false; } void RadioConfiguration::slotNewStation() { slotSetDirty(); const RadioStation *st = &queryCurrentStation(); int n = m_stations.count(); m_stations.all().append(st); if (m_stations.count() == n) { st = st->copyNewID(); m_stations.all().append(st); } if (m_stations.count() > n) { listStations->appendStation(*st); listStations->setCurrentStation (listStations->count()-1); slotStationSelectionChanged(listStations->count()-1); listStations->ensureItemVisible(listStations->selectedItem()); } } void RadioConfiguration::slotDeleteStation() { int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); m_stations.all().remove(idx); listStations->removeStation(idx); } } void RadioConfiguration::slotStationEditorChanged(RadioStationConfig *c) { if (!c) return; if (ignoreChanges) return; int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); RadioStation &st = m_stations.at(idx); ignoreChanges = true; bool o = listStations->signalsBlocked(); listStations->blockSignals(true); c->storeStationData(st); listStations->setStation(idx, st); listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotStationNameChanged( const TQString & s) { if (ignoreChanges) return; int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); RadioStation &st = m_stations.at(idx); st.setName(s); ignoreChanges = true; bool o = listStations->signalsBlocked(); listStations->blockSignals(true); listStations->setStation(idx, st); listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotStationShortNameChanged( const TQString & sn) { if (ignoreChanges) return; int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); RadioStation &st = m_stations.at(idx); st.setShortName(sn); ignoreChanges = true; bool o = listStations->signalsBlocked(); listStations->blockSignals(true); listStations->setStation(idx, st); listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotSelectPixmap() { KURL url = KFileDialog::getImageOpenURL(TQString(), this, i18n("Image Selection")); if (!url.isEmpty()) { if (url.isLocalFile()) { editPixmapFile->setText(url.path()); } else { m_logger.logWarning(i18n("ignoring non-local image")); } } } void RadioConfiguration::slotPixmapChanged( const TQString &s ) { if (ignoreChanges) return; int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); RadioStation &st = m_stations.at(idx); st.setIconName(s); ignoreChanges = true; pixmapStation->setPixmap(TQPixmap(s)); bool o = listStations->signalsBlocked(); listStations->blockSignals(true); listStations->setStation(idx, st); listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotVolumePresetChanged(int v) { int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count()) { slotSetDirty(); RadioStation &s = m_stations.at(idx); s.setInitialVolume(0.01 * (double)v); } } void RadioConfiguration::slotStationUp() { int idx = listStations->currentStationIndex(); if (idx > 0 && idx < m_stations.count()) { slotSetDirty(); RawStationList &sl = m_stations.all(); RadioStation *st = sl.take(idx-1); sl.insert(idx, st); delete st; ignoreChanges = true; // bool o = listStations->signalsBlocked(); // listStations->blockSignals(true); listStations->setStation(idx-1, *sl.at(idx-1)); listStations->setStation(idx, *sl.at(idx)); listStations->setCurrentStation(idx-1); // listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotStationDown() { int idx = listStations->currentStationIndex(); if (idx >= 0 && idx < m_stations.count() - 1) { slotSetDirty(); RawStationList &sl = m_stations.all(); RadioStation *st = sl.take(idx); sl.insert(idx+1, st); delete st; ignoreChanges = true; // bool o = listStations->signalsBlocked(); // listStations->blockSignals(true); listStations->setStation(idx, *sl.at(idx)); listStations->setStation(idx+1, *sl.at(idx+1)); listStations->setCurrentStation(idx+1); // listStations->blockSignals(o); ignoreChanges = false; } } void RadioConfiguration::slotActivateStation(int idx) { if (idx >= 0 && idx < m_stations.count()) { sendActivateStation(m_stations.at(idx)); sendPowerOn(); } } void RadioConfiguration::slotLoadPresets() { KFileDialog fd(locate("data", "tderadio/presets/"), ("*.krp|" + i18n("TDERadio Preset Files")).ascii(), this, i18n("Preset File Selection").ascii(), true); fd.setMode(KFile::File | KFile::ExistingOnly); fd.setCaption (i18n("Select Preset File")); if (fd.exec() == TQDialog::Accepted) { slotSetDirty(); StationList sl; if (sl.readXML(fd.selectedURL(), m_logger)) { noticeStationsChanged(sl); } } } void RadioConfiguration::slotStorePresets() { KFileDialog fd("", ("*.krp|" + i18n("TDERadio Preset Files")).ascii(), this, i18n("Preset File Selection").ascii(), true); fd.setMode(KFile::File); fd.setCaption (i18n("Store Preset File")); if (fd.exec() == TQDialog::Accepted) { editPresetFile->setURL(fd.selectedURL().url()); m_stations.writeXML(fd.selectedURL(), m_logger); } } void RadioConfiguration::slotLastChangeNow() { slotSetDirty(); editLastChange->setDateTime(TQDateTime::currentDateTime()); } static TQString &urlEscapes(TQString &s) { s.replace(TQRegExp("%"), "%25"); s.replace(TQRegExp("\t"), "%09"); s.replace(TQRegExp("\n"), "%0A"); s.replace(TQRegExp("\n"), "%0D"); s.replace(TQRegExp(" "), "%20"); s.replace(TQRegExp("\\!"), "%21"); s.replace(TQRegExp("\""), "%22"); s.replace(TQRegExp("#"), "%23"); s.replace(TQRegExp("\\$"), "%24"); s.replace(TQRegExp("\\&"), "%26"); s.replace(TQRegExp("'"), "%27"); s.replace(TQRegExp(","), "%2C"); s.replace(TQRegExp(":"), "%3A"); s.replace(TQRegExp(";"), "%3B"); s.replace(TQRegExp("="), "%3D"); s.replace(TQRegExp("\\?"), "%3F"); return s; } void RadioConfiguration::slotSendPresetsByMail( const TQString &url ) { TQString presets = m_stations.writeXML(m_logger); urlEscapes(presets); // documentation says, krun object deletes itself, // so we do not need to store the pointer TQString country = m_stations.metaData().country; TQString city = m_stations.metaData().city; TQString location = city + "/" + country; urlEscapes(location); TQString cmd = url + "?subject=station preset file for " + location + "&body="; cmd += presets; new KRun (cmd); } void RadioConfiguration::slotSearchStations(int idev) { if (idev >= 0 && (unsigned)idev < devices.count()) { IRadioDevice *dev = devices.at(idev); StandardScanDialog *x = new StandardScanDialog(NULL); x->connectI(dev); // connect device x->connectI(IRadioDevicePoolClient::iConnections.at(0)); // connect radio to get verbous station information sendActiveDevice(dev); x->show(); x->start(); if (x->exec() == TQDialog::Accepted) { slotSetDirty(); m_stations.merge(x->getStations()); noticeStationsChanged(m_stations); } delete x; // logDebug("scan finished"); } // logDebug("scan finished completely"); } void RadioConfiguration::slotOK() { if (m_dirty) { StationListMetaData &i = m_stations.metaData(); i.maintainer = editMaintainer->text(); i.lastChange = editLastChange->dateTime(); i.country = editCountry->text(); i.city = editCity->text(); i.media = editMedia->text(); i.comment = editComment->text(); sendStations(m_stations); sendPresetFile(editPresetFile->url()); m_dirty = false; } } void RadioConfiguration::slotCancel() { if (m_dirty) { noticeStationsChanged(queryStations()); noticePresetFileChanged(queryPresetFile()); m_dirty = false; } } void RadioConfiguration::slotSetDirty() { if (!ignoreChanges) { m_dirty = true; } } #include "radio-configuration.moc"