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/radio/radio-configuration.cpp

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 <tdelistbox.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 <tdefiledialog.h>
#include <kstandarddirs.h>
#include <kurllabel.h>
#include <tqregexp.h>
#include <krun.h>
#include <kurlrequester.h>
#include <tdelocale.h>
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<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, 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"