From 087253a71c1002114732d3e0533366efc5079e64 Mon Sep 17 00:00:00 2001 From: fgerlits Date: Wed, 24 Jan 2007 11:10:08 +0000 Subject: [PATCH] connected the pieces of the RDS thing; next: testing (part of #722) --- .../gLiveSupport/src/GLiveSupport.cxx | 63 ++++++++++++++++++- .../products/gLiveSupport/src/GLiveSupport.h | 49 ++++++++++++++- .../gLiveSupport/src/MasterPanelWindow.cxx | 16 ++--- .../gLiveSupport/src/MasterPanelWindow.h | 18 +++++- .../products/gLiveSupport/src/NowPlaying.cxx | 5 ++ .../products/gLiveSupport/src/NowPlaying.h | 23 ++++++- 6 files changed, 157 insertions(+), 17 deletions(-) diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx index bfbbd1466..b02f7a4b6 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.cxx @@ -1795,7 +1795,7 @@ GLiveSupport :: createScratchpadWindow(void) *----------------------------------------------------------------------------*/ void LiveSupport :: GLiveSupport :: -GLiveSupport :: writeToSerial(Ptr::Ref message) +GLiveSupport :: writeToSerial(Ptr::Ref message) throw () { try { @@ -1809,3 +1809,64 @@ GLiveSupport :: writeToSerial(Ptr::Ref message) } } + +/*------------------------------------------------------------------------------ + * Replace the placeholders in the RDS settings with the current values. + *----------------------------------------------------------------------------*/ +void +LiveSupport :: GLiveSupport :: +GLiveSupport :: substituteRdsData(Ptr::Ref rdsString) + throw () +{ + Ptr::Ref playable = masterPanel->getCurrentInnerPlayable(); + + // these substitutions are documented in the doxygen docs of the + // public updateRds() function + substituteRdsItem(rdsString, "%c", playable, "dc:creator"); + substituteRdsItem(rdsString, "%t", playable, "dc:title"); + substituteRdsItem(rdsString, "%d", playable, "dc:format:extent"); + substituteRdsItem(rdsString, "%s", playable, "dc:source"); + substituteRdsItem(rdsString, "%y", playable, "ls:year"); +} + + +/*------------------------------------------------------------------------------ + * Replace a single placeholders in the RDS settings. + *----------------------------------------------------------------------------*/ +void +LiveSupport :: GLiveSupport :: +GLiveSupport :: substituteRdsItem(Ptr::Ref rdsString, + const std::string & placeholder, + Ptr::Ref playable, + const std::string & metadataKey) + throw () +{ + unsigned int pos; + while ((pos = rdsString->find(placeholder)) != std::string::npos) { + Ptr::Ref value; + if (playable) { + value = playable->getMetadata(metadataKey); + } + if (!value) { + value.reset(new Glib::ustring("?")); + } + rdsString->replace(pos, placeholder.length(), *value); + } +} + + +/*------------------------------------------------------------------------------ + * Read the RDS settings, and send them to the serial port. + *----------------------------------------------------------------------------*/ +void +LiveSupport :: GLiveSupport :: +GLiveSupport :: updateRds(void) throw () +{ + Ptr::Ref + rdsString = optionsContainer->getCompleteRdsString(); + if (rdsString) { + substituteRdsData(rdsString); + writeToSerial(rdsString); + } +} + diff --git a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h index 099b3e460..0137ecb52 100644 --- a/campcaster/src/products/gLiveSupport/src/GLiveSupport.h +++ b/campcaster/src/products/gLiveSupport/src/GLiveSupport.h @@ -368,6 +368,41 @@ class GLiveSupport : public LocalizedConfigurable, refreshPlaylistInLiveMode(Ptr::Ref playlist) throw (); + /** + * Replace the placeholders in the RDS settings with the + * current values. + * + * @param rdsString the string with the placeholders; + * they will be replaced in place. + */ + void + substituteRdsData(Ptr::Ref rdsString) + throw (); + + /** + * Replace a single placeholders in the RDS settings. + * If the corresponding metadata is not found, a "?" character + * is substituted instead. + * + * @param rdsString the string with the placeholders; + * they will be replaced in place. + * @param placeholder the string to be substituted, e.g. "%t". + * @param playable the Playable object whose data is to be used. + * @param metadataKay the kind of metadata to be substituted. + */ + void + substituteRdsItem(Ptr::Ref rdsString, + const std::string & placeholder, + Ptr::Ref playable, + const std::string & metadataKey) + throw (); + + /** + * Write a string to the serial device. + */ + void + writeToSerial(Ptr::Ref message) throw (); + protected: /** @@ -1291,10 +1326,20 @@ class GLiveSupport : public LocalizedConfigurable, createScratchpadWindow(void) throw (); /** - * Write a string to the serial device. + * Read the RDS settings, and send them to the serial port. + * + * The following RDS placeholders will be substituted: + * + * "%c" ---> "dc:creator" (Creator) + * "%t" ---> "dc:title" (Title) + * "%d" ---> "dc:format:extent" (Duration) + * "%s" ---> "dc:source" (Album) + * "%y" ---> "ls:year" (Year) + * + * @see substituteRdsData() */ void - writeToSerial(Ptr::Ref message) throw (); + updateRds(void) throw (); }; /* ================================================= external data structures */ diff --git a/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.cxx b/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.cxx index ea3bfe273..3d9def658 100644 --- a/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.cxx +++ b/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.cxx @@ -441,6 +441,9 @@ MasterPanelWindow :: onUpdateTime(int dummy) throw () // refresh all windows gLiveSupport->runMainLoop(); + // refresh the RDS display + gLiveSupport->updateRds(); + return true; } @@ -780,17 +783,6 @@ MasterPanelWindow :: getNextItemToPlay() throw () } -/*------------------------------------------------------------------------------ - * Set the "now playing" display. - *----------------------------------------------------------------------------*/ -void -MasterPanelWindow :: setNowPlaying(Ptr::Ref playable) - throw () -{ - nowPlayingWidget->setPlayable(playable); -} - - /*------------------------------------------------------------------------------ * Resize an image to fit in a box, preserving its aspect ratio. *----------------------------------------------------------------------------*/ @@ -876,7 +868,7 @@ MasterPanelWindow :: uploadToHub(Ptr::Ref playable) searchButton)); } - bool success = searchWindow->uploadToHub(playable); + searchWindow->uploadToHub(playable); searchWindow->present(); } diff --git a/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.h b/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.h index d7833c568..4a5b18a11 100644 --- a/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.h +++ b/campcaster/src/products/gLiveSupport/src/MasterPanelWindow.h @@ -549,9 +549,25 @@ class MasterPanelWindow : public Gtk::Window, public LocalizedObject /** * Set the "now playing" display. + * + * @param playable the Playable whose data is to be displayed. */ void - setNowPlaying(Ptr::Ref playable) throw (); + setNowPlaying(Ptr::Ref playable) throw () + { + nowPlayingWidget->setPlayable(playable); + } + + /** + * Get the Playable currently shown in the "now playing" display. + * + * @return the currently playing item; 0 if nothing is playing. + */ + Ptr::Ref + getCurrentInnerPlayable(void) throw () + { + return nowPlayingWidget->getCurrentInnerPlayable(); + } /** * Upload a Playable object to the network hub. diff --git a/campcaster/src/products/gLiveSupport/src/NowPlaying.cxx b/campcaster/src/products/gLiveSupport/src/NowPlaying.cxx index 26846e24a..bffacc8ba 100644 --- a/campcaster/src/products/gLiveSupport/src/NowPlaying.cxx +++ b/campcaster/src/products/gLiveSupport/src/NowPlaying.cxx @@ -203,7 +203,10 @@ NowPlaying :: setPlayable(Ptr::Ref playable) throw () playlistLabel->set_text(""); resetRemainsTimeState(); this->playable.reset(); + this->currentInnerPlayable.reset(); } + + gLiveSupport->updateRds(); } @@ -380,6 +383,8 @@ NowPlaying :: onUpdateTime(void) throw () innerElapsed )); remainsTime->set_text(*TimeConversion::timeDurationToHhMmSsString( innerRemains )); + + currentInnerPlayable = innerPlayable; } diff --git a/campcaster/src/products/gLiveSupport/src/NowPlaying.h b/campcaster/src/products/gLiveSupport/src/NowPlaying.h index 28735c359..fa6fc78b4 100644 --- a/campcaster/src/products/gLiveSupport/src/NowPlaying.h +++ b/campcaster/src/products/gLiveSupport/src/NowPlaying.h @@ -84,10 +84,16 @@ class NowPlaying : public Gtk::HBox, bool isPaused; /** - * The item which is currently playing. + * The item which is currently playing (audio clip or playlist). */ Ptr::Ref playable; + /** + * The audio clip which is currently playing (could be nested + * several levels inside the "playable" object). + */ + Ptr::Ref currentInnerPlayable; + /** * The label holding the title of the now playing item. */ @@ -279,6 +285,21 @@ class NowPlaying : public Gtk::HBox, { onStopButtonClicked(); } + + /** + * Get the Playable object which is playing now. + * If a playlist is playing, does not return the playlist, but + * the audio clip inside the playlist (possibly several levels deep). + * + * This is used by GLiveSupport::substituteRdsData(). + * + * @return the currently playing item; 0 if nothing is playing. + */ + Ptr::Ref + getCurrentInnerPlayable(void) throw () + { + return currentInnerPlayable; + } };