summaryrefslogtreecommitdiffstats
path: root/tderadio3/src/stationlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tderadio3/src/stationlist.cpp')
-rw-r--r--tderadio3/src/stationlist.cpp494
1 files changed, 494 insertions, 0 deletions
diff --git a/tderadio3/src/stationlist.cpp b/tderadio3/src/stationlist.cpp
new file mode 100644
index 0000000..45ed4ca
--- /dev/null
+++ b/tderadio3/src/stationlist.cpp
@@ -0,0 +1,494 @@
+/***************************************************************************
+ stationlist.cpp - description
+ -------------------
+ begin : Sat March 29 2003
+ copyright : (C) 2003 by Klas Kalass, Ernst Martin Witte
+ email : klas@kde.org, 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 "include/radiostation.h"
+#include "include/errorlog-interfaces.h"
+#include "include/utils.h"
+#include "include/stationlist.h"
+#include "include/stationlistxmlhandler.h"
+#include "include/kradioversion.h"
+
+#include <tqstring.h>
+#include <tqfile.h>
+#include <tqiodevice.h>
+#include <tqmessagebox.h>
+#include <tdeio/netaccess.h>
+#include <ktempfile.h>
+#include <klocale.h>
+
+//////////////////////////////////////////////////////////////////////////////
+
+const StationList emptyStationList;
+
+//////////////////////////////////////////////////////////////////////////////
+
+RawStationList::RawStationList ()
+{
+ setAutoDelete(true);
+}
+
+
+RawStationList::RawStationList (const RawStationList &sl)
+ : TQPtrList<RadioStation>(sl)
+{
+ setAutoDelete(true);
+}
+
+
+RawStationList::~RawStationList ()
+{
+ clear();
+}
+
+
+TQPtrCollection::Item RawStationList::newItem (TQPtrCollection::Item s)
+{
+ if (s)
+ return ((RadioStation*)s)->copy();
+ else
+ return NULL;
+}
+
+
+void RawStationList::deleteItem (TQPtrCollection::Item s)
+{
+ if (autoDelete())
+ delete (RadioStation*)s;
+}
+
+
+int RawStationList::compareItems(TQPtrCollection::Item a, TQPtrCollection::Item b)
+{
+ if (!a && !b)
+ return 0;
+
+ if (!a)
+ return -1;
+
+ if (!b)
+ return 1;
+
+ return ((RadioStation*)a)->compare(*(RadioStation*)b);
+}
+
+
+bool RawStationList::insert (uint index, const RadioStation * item )
+{
+ if (!item) return false;
+ RadioStation *rs = &stationWithID(item->stationID());
+ bool r = true;
+ if (rs != item) {
+ r = BaseClass::insert(index, item);
+ removeRef(rs);
+ }
+ return r;
+}
+
+
+bool RawStationList::insert (const RadioStation * item )
+{
+ if (!item) return false;
+ int idx = idxWithID(item->stationID());
+ if (idx >= 0) {
+ return replace(idx, item);
+ } else {
+ append(item);
+ return true;
+ }
+}
+
+
+void RawStationList::inSort ( const RadioStation * item )
+{
+ if (!item) return;
+ RadioStation *rs = &stationWithID(item->stationID());
+ if (rs != item) {
+ removeRef(rs);
+ }
+ BaseClass::inSort(item);
+}
+
+
+void RawStationList::prepend ( const RadioStation * item )
+{
+ if (!item) return;
+ RadioStation *rs = &stationWithID(item->stationID());
+ if (rs != item) {
+ removeRef(rs);
+ }
+ BaseClass::prepend(item);
+}
+
+
+void RawStationList::append ( const RadioStation * item )
+{
+ if (!item) return;
+ RadioStation *rs = &stationWithID(item->stationID());
+ if (rs != item) {
+ removeRef(rs);
+ }
+ BaseClass::append(item);
+}
+
+
+bool RawStationList::replace ( uint index, const RadioStation * item )
+{
+ bool r = true;
+ RadioStation *rs = &stationWithID(item->stationID());
+ r = BaseClass::replace(index, item);
+ if (rs != item) {
+ BaseClass::removeRef(rs);
+ }
+ return r;
+}
+
+
+const RadioStation &RawStationList::stationWithID(const TQString &sid) const
+{
+ Iterator it(*this);
+ for (; const RadioStation *s = it.current(); ++it) {
+ if (s->stationID() == sid)
+ return *s;
+ }
+ return (RadioStation &) undefinedRadioStation;
+}
+
+
+RadioStation &RawStationList::stationWithID(const TQString &sid)
+{
+ Iterator it(*this);
+ for (; RadioStation *s = it.current(); ++it) {
+ if (s->stationID() == sid)
+ return *s;
+ }
+ return (RadioStation &) undefinedRadioStation;
+}
+
+
+
+int RawStationList::idxWithID(const TQString &sid) const
+{
+ int i = 0;
+ Iterator it(*this);
+ for (; const RadioStation *s = it.current(); ++it, ++i) {
+ if (s->stationID() == sid)
+ return i;
+ }
+ return -1;
+}
+
+
+bool RawStationList::operator == (const RawStationList &l) const
+{
+ TQPtrListIterator<RadioStation> it1(*this);
+ TQPtrListIterator<RadioStation> it2(l);
+ if (count() != l.count())
+ return false;
+ for (; it1.current() && it2.current(); ++it1, ++it2) {
+ if (**it1 != **it2)
+ return false;
+ }
+ return true;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+StationList::StationList()
+{
+ m_all.setAutoDelete(true);
+}
+
+StationList::StationList(const StationList &sl)
+ : m_all (sl.m_all),
+ m_metaData (sl.m_metaData)
+{
+ m_all.setAutoDelete(true);
+}
+
+
+StationList::~StationList()
+{
+}
+
+
+void StationList::merge(const StationList & other)
+{
+ // merge meta information: honor merge in comment
+
+ StationListMetaData const & metaData = other.metaData();
+
+ if (! m_metaData.comment.isEmpty())
+ m_metaData.comment += "\n";
+
+ m_metaData.lastChange = TQDateTime::currentDateTime();
+
+ if (!metaData.maintainer.isEmpty())
+ m_metaData.maintainer += (count() ? TQString(" / ") : TQString()) + metaData.maintainer;
+
+ if (!metaData.country.isEmpty())
+ m_metaData.country += (count() ? TQString(" / ") : TQString()) + metaData.country;
+
+ if (!metaData.city.isEmpty())
+ m_metaData.city = (count() ? TQString(" / ") : TQString()) + metaData.city;
+
+ if (!metaData.media.isEmpty())
+ m_metaData.media += (count() ? TQString(" / ") : TQString()) + metaData.media;
+
+ if (!metaData.comment.isEmpty())
+ m_metaData.comment += (count() ? TQString(" / ") : TQString()) + metaData.comment;
+ if (count() && other.count())
+ m_metaData.comment += " " + i18n("Contains merged Data");
+
+
+ // merge stations
+
+ TQPtrListIterator<RadioStation> it(other.all());
+ for (RadioStation *s = it.current(); s; s = ++it) {
+ m_all.insert(s);
+ }
+}
+
+
+
+StationList &StationList::operator = (const StationList &other)
+{
+ m_metaData = other.metaData();
+ m_all = other.all();
+ return *this;
+}
+
+
+const RadioStation &StationList::at(int idx) const
+{
+ RawStationList::Iterator it(m_all);
+ it += idx;
+ return it.current() ? *it.current() : (const RadioStation &) undefinedRadioStation;
+}
+
+
+RadioStation &StationList::at(int idx)
+{
+ RawStationList::Iterator it(m_all);
+ it += idx;
+ return it.current() ? *it.current() : (RadioStation &) undefinedRadioStation;
+}
+
+
+const RadioStation &StationList::stationWithID(const TQString &sid) const
+{
+ return m_all.stationWithID(sid);
+}
+
+
+RadioStation &StationList::stationWithID(const TQString &sid)
+{
+ return m_all.stationWithID(sid);
+}
+
+
+bool StationList::readXML (const TQString &dat, const IErrorLogClient &logger, bool enableMessageBox)
+{
+ // FIXME: TODO: error handling
+ TQXmlInputSource source;
+ source.setData(dat);
+ TQXmlSimpleReader reader;
+ StationListXmlHandler handler(logger);
+ reader.setContentHandler (&handler);
+ if (reader.parse(source)) {
+ if (handler.wasCompatMode() && enableMessageBox) {
+ TQMessageBox::information(NULL, "TDERadio",
+ i18n("Probably an old station preset file was read.\n"
+ "You have to rebuild your station selections for "
+ "the quickbar and the docking menu.")
+ );
+ }
+
+ m_all = handler.getStations();
+ m_metaData = handler.getMetaData();
+ return true;
+ } else {
+ logger.logError("StationList::readXML: " + i18n("parsing failed"));
+
+ if (enableMessageBox) {
+ TQMessageBox::warning(NULL, "TDERadio",
+ i18n("Parsing the station preset file failed.\n"
+ "See console output for more details."));
+ }
+ return false;
+ }
+}
+
+
+bool StationList::readXML (const KURL &url, const IErrorLogClient &logger, bool enableMessageBox)
+{
+ TQString tmpfile;
+ if (!TDEIO::NetAccess::download(url, tmpfile, NULL)) {
+ if (enableMessageBox) {
+ logger.logError("StationList::readXML: " +
+ i18n("error downloading preset file %1").arg(url.url()));
+ TQMessageBox::warning(NULL, "TDERadio",
+ i18n("Download of the station preset file at %1 failed.")
+ .arg(url.url()));
+ } else {
+ logger.logWarning("StationList::readXML: " +
+ i18n("error downloading preset file %1").arg(url.url()));
+ }
+ return false;
+ }
+
+ logger.logDebug("StationList::readXML: " +
+ i18n("temporary file: ") + tmpfile);
+
+ TQFile presetFile (tmpfile);
+
+ if (! presetFile.open(IO_ReadOnly)) {
+ logger.logError("StationList::readXML: " +
+ i18n("error opening preset file %1").arg(tmpfile));
+ if (enableMessageBox) {
+ TQMessageBox::warning(NULL, "TDERadio",
+ i18n("Opening of the station preset file at %1 failed.")
+ .arg(tmpfile));
+ }
+ return false;
+ }
+
+ TQString xmlData;
+
+ // make sure that qtextstream is gone when we close presetFile
+ TQString tmp;
+ {
+ TQTextStream ins(&presetFile);
+ tmp = ins.read();
+ }
+
+ presetFile.reset();
+
+ // preset file written with kradio <= 0.2.x
+ if (tmp.find("<format>") < 0) {
+ logger.logInfo(i18n("Old Preset File Format detected"));
+ TQTextStream ins(&presetFile);
+ ins.setEncoding(TQTextStream::Locale);
+ xmlData = ins.read();
+ }
+ // preset file written with kradio >= 0.3.0
+ else {
+ TQXmlInputSource tmp(TQT_TQIODEVICE(&presetFile));
+ xmlData = tmp.data();
+ }
+
+ presetFile.close();
+
+ TDEIO::NetAccess::removeTempFile(tmpfile);
+
+ return readXML(xmlData, logger, enableMessageBox);
+}
+
+
+TQString StationList::writeXML (const IErrorLogClient &/*logger*/) const
+{
+ TQString data = TQString();
+
+ // write station list
+
+ TQString t = "\t";
+ TQString tt = "\t\t";
+ TQString ttt = "\t\t\t";
+
+ data += xmlOpenTag(TDERadioConfigElement) +
+ t + xmlOpenTag(StationListElement) +
+ tt + xmlTag(StationListFormat, STATION_LIST_FORMAT) +
+ tt + xmlOpenTag(StationListInfo) +
+ ttt + xmlTag(StationListInfoCreator, "kradio-" KRADIO_VERSION) +
+ ttt + xmlTag(StationListInfoMaintainer, m_metaData.maintainer) +
+ ttt + xmlTag(StationListInfoChanged, m_metaData.lastChange.toString(Qt::ISODate)) +
+ ttt + xmlTag(StationListInfoCountry, m_metaData.country) +
+ ttt + xmlTag(StationListInfoCity, m_metaData.city) +
+ ttt + xmlTag(StationListInfoMedia, m_metaData.media) +
+ ttt + xmlTag(StationListInfoComments, m_metaData.comment) +
+ tt + xmlCloseTag (StationListInfo);
+
+ for (RawStationList::Iterator it(m_all); it.current(); ++it) {
+ RadioStation *s = it.current();
+
+ data += tt + xmlOpenTag (s->getClassName());
+
+ TQStringList properties = s->getPropertyNames();
+ TQStringList::iterator end = properties.end();
+ for (TQStringList::iterator sit = properties.begin(); sit != end; ++sit) {
+ data += ttt + xmlTag (*sit, s->getProperty(*sit));
+ }
+ data += tt + xmlCloseTag(s->getClassName());
+
+ }
+
+ data += t + xmlCloseTag(StationListElement) +
+ xmlCloseTag(TDERadioConfigElement);
+
+ return data;
+}
+
+
+bool StationList::writeXML (const KURL &url, const IErrorLogClient &logger, bool enableMessageBox) const
+{
+ KTempFile tmpFile;
+ tmpFile.setAutoDelete(true);
+ TQFile *outf = tmpFile.file();
+
+ TQTextStream outs(outf);
+ outs.setEncoding(TQTextStream::UnicodeUTF8);
+ outs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
+
+ TQString output = writeXML(logger);
+
+ outs << output;
+ if (outf->status() != IO_Ok) {
+ logger.logError("StationList::writeXML: " +
+ i18n("error writing to tempfile %1").arg(tmpFile.name()));
+ if (enableMessageBox) {
+ TQMessageBox::warning(NULL, "TDERadio",
+ i18n("Writing station preset file %1 failed.")
+ .arg(tmpFile.name()));
+ }
+ return false;
+ }
+
+ // close hopefully flushes buffers ;)
+ outf->close();
+
+ if (count() <= 1) {
+ logger.logWarning("StationList::writeXML: " +
+ i18n("uploading preset file %1: ").arg(url.url()));
+ logger.logWarning("StationList::writeXML: " +
+ i18n("something strange happend, station list has only %1 entries. Writing station preset file skipped").arg(count()));
+ } else {
+
+ if (!TDEIO::NetAccess::upload(tmpFile.name(), url, NULL)) {
+ logger.logError("StationList::writeXML: " +
+ i18n("error uploading preset file %1").arg(url.url()));
+
+ if (enableMessageBox) {
+ TQMessageBox::warning(NULL, "TDERadio",
+ i18n("Upload of station preset file to %1 failed.")
+ .arg(url.url()));
+ }
+ return false;
+ }
+ }
+
+ return true;
+}