fixed #936, mostly

This commit is contained in:
fgerlits 2006-11-13 19:52:18 +00:00
parent 54308f13e4
commit fc76b78a84
6 changed files with 157 additions and 19 deletions

View File

@ -883,6 +883,23 @@ class Playlist : public Configurable,
*/
virtual bool
eliminateGaps(void) throw ();
/**
* Find the playlist element at the specified offset.
*
* This is used by the Master Panel to display the contents
* of the currently playing Playlist.
* When there are more than one playlist elements at the given
* offset, the one with the greatest relativeOffset is chosen.
* Can return a 0 pointer if there is no playlist element at
* the given offset.
*
* @param offset the elapsed time relative to the Playlist.
* @return the playlist element at the given offset.
*/
Ptr<PlaylistElement>::Ref
findAtOffset(Ptr<const time_duration>::Ref offset) const
throw ();
};

View File

@ -901,3 +901,33 @@ Playlist :: eliminateGaps(void) throw ()
}
}
/*------------------------------------------------------------------------------
* Find the playlist element at the specified offset.
*----------------------------------------------------------------------------*/
Ptr<PlaylistElement>::Ref
Playlist :: findAtOffset(Ptr<const time_duration>::Ref offset) const
throw ()
{
Ptr<PlaylistElement>::Ref playlistElement;
PlaylistElementListType::const_reverse_iterator it;
PlaylistElementListType::const_reverse_iterator rend
= elementList->rend();
for (it = elementList->rbegin(); it != rend; ++it) {
time_duration currentStart = it->first;
if (currentStart <= *offset) {
Ptr<PlaylistElement>::Ref
currentElement = it->second;
time_duration currentEnd = currentStart
+ *currentElement->getPlayable()
->getPlaylength();
if (currentEnd > *offset) {
playlistElement = currentElement;
}
}
}
return playlistElement;
}

View File

@ -481,3 +481,46 @@ PlaylistTest :: eliminateGapsLastItemTest(void)
}
/*------------------------------------------------------------------------------
* Test the findAtOffset() method.
*----------------------------------------------------------------------------*/
void
PlaylistTest :: findAtOffsetTest(void) throw (CPPUNIT_NS::Exception)
{
Ptr<time_duration>::Ref offset(new time_duration());
Ptr<const PlaylistElement>::Ref playlistElement;
*offset = seconds(-1);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(!playlistElement);
*offset = seconds(0);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(playlistElement);
CPPUNIT_ASSERT(playlistElement->getPlayable()->getId()->getId() == 0x10001);
*offset = seconds(11);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(playlistElement);
CPPUNIT_ASSERT(playlistElement->getPlayable()->getId()->getId() == 0x10002);
*offset = seconds(20);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(playlistElement);
CPPUNIT_ASSERT(playlistElement->getPlayable()->getId()->getId() == 0x10002);
*offset = microseconds(30123456);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(playlistElement);
CPPUNIT_ASSERT(playlistElement->getPlayable()->getId()->getId() == 0x2);
*offset = seconds(34);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(!playlistElement);
*offset = hours(1);
playlistElement = playlist->findAtOffset(offset);
CPPUNIT_ASSERT(!playlistElement);
}

View File

@ -73,6 +73,7 @@ class PlaylistTest : public CPPUNIT_NS::TestFixture
CPPUNIT_TEST(addPlayableTest);
CPPUNIT_TEST(eliminateGapsTest);
CPPUNIT_TEST(eliminateGapsLastItemTest);
CPPUNIT_TEST(findAtOffsetTest);
CPPUNIT_TEST_SUITE_END();
private:
@ -156,6 +157,14 @@ class PlaylistTest : public CPPUNIT_NS::TestFixture
void
eliminateGapsLastItemTest(void) throw (CPPUNIT_NS::Exception);
/**
* Test the findAtOffset() method.
*
* @exception CPPUNIT_NS::Exception on test failures.
*/
void
findAtOffsetTest(void) throw (CPPUNIT_NS::Exception);
public:

View File

@ -183,22 +183,11 @@ NowPlaying :: setPlayable(Ptr<Playable>::Ref playable) throw ()
pack_end(*pauseButton, Gtk::PACK_SHRINK, 2);
pauseButton->show();
}
this->playable = playable;
isActive = true;
isPaused = false;
titleLabel->set_text(*playable->getTitle());
Ptr<Glib::ustring>::Ref
creator = playable->getMetadata("dc:creator");
if (creator) {
creatorLabel->set_text(*creator);
} else {
creatorLabel->set_text("");
}
audioLength = TimeConversion::roundToNearestSecond(
playable->getPlaylength());
resetRemainsTimeState();
onUpdateTime();
} else {
if (isActive && !isPaused) {
@ -211,8 +200,9 @@ NowPlaying :: setPlayable(Ptr<Playable>::Ref playable) throw ()
creatorLabel->set_text("");
elapsedTime->set_text("");
remainsTime->set_text("");
playlistLabel->set_text("");
resetRemainsTimeState();
audioLength.reset();
this->playable.reset();
}
}
@ -317,8 +307,11 @@ NowPlaying :: onUpdateTime(void) throw ()
return;
}
Ptr<time_duration>::Ref totalLength
= TimeConversion::roundToNearestSecond(
playable->getPlaylength());
Ptr<time_duration>::Ref remains(new time_duration(
*audioLength - *elapsed ));
*totalLength - *elapsed));
switch (remainsTimeState) {
case TIME_GREEN :
if (*remains <= seconds(20)) {
@ -337,10 +330,56 @@ NowPlaying :: onUpdateTime(void) throw ()
}
setRemainsTimeColor(remainsTimeState);
Ptr<Playable>::Ref innerPlayable = playable;
Ptr<time_duration>::Ref innerElapsed = elapsed;
Ptr<time_duration>::Ref innerRemains = remains;
Glib::ustring playlistInfo;
bool isFirst = true;
while (innerPlayable->getType() == Playable::PlaylistType) {
if (isFirst) {
isFirst = false;
} else {
playlistInfo += " >>> ";
}
playlistInfo += *innerPlayable->getTitle();
playlistInfo += " [";
playlistInfo += *TimeConversion::timeDurationToHhMmSsString(
innerRemains);
playlistInfo += "/";
playlistInfo += *TimeConversion::timeDurationToHhMmSsString(
innerPlayable->getPlaylength());
playlistInfo += "]";
Ptr<PlaylistElement>::Ref element
= innerPlayable->getPlaylist()
->findAtOffset(elapsed);
if (!element) {
break;
}
innerPlayable = element->getPlayable();
*innerElapsed -= *element->getRelativeOffset();
*innerRemains = *TimeConversion::roundToNearestSecond(
innerPlayable->getPlaylength())
- *innerElapsed;
}
playlistLabel->set_text(playlistInfo);
titleLabel->set_text(*innerPlayable->getTitle());
Ptr<Glib::ustring>::Ref
creator = innerPlayable->getMetadata("dc:creator");
if (creator) {
creatorLabel->set_text(*creator);
} else {
creatorLabel->set_text("");
}
elapsedTime->set_text(*TimeConversion::timeDurationToHhMmSsString(
elapsed ));
innerElapsed ));
remainsTime->set_text(*TimeConversion::timeDurationToHhMmSsString(
remains ));
innerRemains ));
}

View File

@ -84,9 +84,9 @@ class NowPlaying : public Gtk::HBox,
bool isPaused;
/**
* The length of the item currently playing.
* The item which is currently playing.
*/
Ptr<time_duration>::Ref audioLength;
Ptr<Playable>::Ref playable;
/**
* The label holding the title of the now playing item.