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.
593 lines
18 KiB
593 lines
18 KiB
/***************************************************************************
|
|
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 <math.h>
|
|
|
|
#include <tqlistbox.h>
|
|
#include <klistbox.h>
|
|
#include <tqdatetimeedit.h>
|
|
#include <tqlineedit.h>
|
|
#include <tqlabel.h>
|
|
#include <tqspinbox.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqpopupmenu.h>
|
|
#include <tqtoolbutton.h>
|
|
#include <tqwidgetstack.h>
|
|
#include <tqimage.h>
|
|
|
|
#include <kfiledialog.h>
|
|
#include <kstandarddirs.h>
|
|
#include <kurllabel.h>
|
|
#include <tqregexp.h>
|
|
#include <krun.h>
|
|
#include <kurlrequester.h>
|
|
#include <klocale.h>
|
|
|
|
RadioConfiguration::RadioConfiguration (TQWidget *parent, const IErrorLogClient &logger)
|
|
: RadioConfigurationUI(parent),
|
|
ignoreChanges(false),
|
|
devicePopup(NULL),
|
|
m_logger(logger),
|
|
m_dirty(true)
|
|
{
|
|
TQObject::connect(listStations, TQT_SIGNAL(sigCurrentStationChanged(int)),
|
|
this, TQT_SLOT(slotStationSelectionChanged(int)));
|
|
TQObject::connect(buttonSelectPixmapFile, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotSelectPixmap()));
|
|
TQObject::connect(buttonNewStation, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotNewStation()));
|
|
TQObject::connect(buttonDeleteStation, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotDeleteStation()));
|
|
TQObject::connect(editPixmapFile, TQT_SIGNAL(textChanged(const TQString &)),
|
|
this, TQT_SLOT(slotPixmapChanged(const TQString &)));
|
|
TQObject::connect(editStationName, TQT_SIGNAL(textChanged(const TQString &)),
|
|
this, TQT_SLOT(slotStationNameChanged(const TQString &)));
|
|
TQObject::connect(editStationShortName, TQT_SIGNAL(textChanged(const TQString &)),
|
|
this, TQT_SLOT(slotStationShortNameChanged(const TQString &)));
|
|
TQObject::connect(editVolumePreset, TQT_SIGNAL(valueChanged(int)),
|
|
this, TQT_SLOT(slotVolumePresetChanged(int)));
|
|
TQObject::connect(buttonStationUp, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotStationUp()));
|
|
TQObject::connect(buttonStationDown, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotStationDown()));
|
|
TQObject::connect(listStations, TQT_SIGNAL(sigStationActivated(int)),
|
|
this, TQT_SLOT(slotActivateStation( int )));
|
|
TQObject::connect(buttonLoadPresets, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotLoadPresets()));
|
|
TQObject::connect(buttonStorePresets, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotStorePresets()));
|
|
TQObject::connect(buttonLastChangeNow, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotLastChangeNow()));
|
|
|
|
connect(editMaintainer, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editLastChange, TQT_SIGNAL(valueChanged(const TQDateTime &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editCountry, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editCity, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editMedia, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editComment, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
connect(editPresetFile, TQT_SIGNAL(textChanged(const TQString &)), TQT_SLOT(slotSetDirty()));
|
|
|
|
mailLabel->setText("mailto:witte-presets@kawo1.rwth-aachen.de");
|
|
mailLabel->setURL ("mailto:witte-presets@kawo1.rwth-aachen.de");
|
|
TQObject::connect(mailLabel, TQT_SIGNAL(leftClickedURL(const TQString &)),
|
|
this, TQT_SLOT(slotSendPresetsByMail(const TQString &)));
|
|
|
|
TQObject::connect(buttonSearchStations, TQT_SIGNAL(clicked()),
|
|
this, TQT_SLOT(slotSearchStations0()));
|
|
|
|
devicePopup = new TQPopupMenu(buttonSearchStations);
|
|
buttonSearchStations->setPopup(devicePopup);
|
|
TQObject::connect(devicePopup, TQT_SIGNAL(activated(int)),
|
|
this, TQT_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<IRadioDevice> &l)
|
|
{
|
|
TQPtrListIterator<IRadioDevice> it(l);
|
|
devices.clear();
|
|
devicePopup->clear();
|
|
int id = 0;
|
|
for (; it.current(); ++it) {
|
|
IRadioDevice *d = it.current();
|
|
if (dynamic_cast<ISeekRadio*>(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, TQT_SIGNAL(changed(RadioStationConfig*)),
|
|
this, TQT_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", "kradio/presets/"),
|
|
("*.krp|" + i18n("KRadio 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("KRadio 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"
|