/*--------------------------------------------------------------------------------*/ bool XMLADMData::SetChna(const uint8_t *data, uint64_t len) { const CHNA_CHUNK& chna = *(const CHNA_CHUNK *)data; uint_t maxuids = (uint_t)((len - sizeof(CHNA_CHUNK)) / sizeof(chna.UIDs[0])); // calculate maximum number of UIDs given chunk length std::string terminator; bool success = true; // create string with a single 0 byte in it to detect terminators terminator.push_back(0); if (maxuids < chna.UIDCount) BBCERROR("Warning: chna specifies %u UIDs but chunk has only length for %u", (uint_t)chna.UIDCount, maxuids); uint16_t i; for (i = 0; (i < chna.UIDCount) && (i < maxuids); i++) { // only handle non-zero track numbers if (chna.UIDs[i].TrackNum) { ADMAudioTrack *track; std::string id; id.assign(chna.UIDs[i].UID, sizeof(chna.UIDs[i].UID)); id = id.substr(0, id.find(terminator)); // delete any existing ADMAudioTracks of the same ID if ((track = dynamic_cast<ADMAudioTrack *>(Create(ADMAudioTrack::Type, id, "", true))) != NULL) { XMLValue tvalue, pvalue; track->SetTrackNum(chna.UIDs[i].TrackNum - 1); tvalue.name = ADMAudioTrackFormat::Reference; tvalue.value.assign(chna.UIDs[i].TrackRef, sizeof(chna.UIDs[i].TrackRef)); // trim any zero bytes off the end of the string tvalue.value = tvalue.value.substr(0, tvalue.value.find(terminator)); track->AddValue(tvalue); pvalue.name = ADMAudioPackFormat::Reference; pvalue.value.assign(chna.UIDs[i].PackRef, sizeof(chna.UIDs[i].PackRef)); // trim any zero bytes off the end of the string pvalue.value = pvalue.value.substr(0, pvalue.value.find(terminator)); track->AddValue(pvalue); track->SetValues(); BBCDEBUG2(("Track %u/%u: Index %u UID '%s' TrackFormatRef '%s' PackFormatRef '%s'", i, (uint_t)tracklist.size(), track->GetTrackNum() + 1, track->GetID().c_str(), tvalue.value.c_str(), pvalue.value.c_str())); } else BBCERROR("Failed to create AudioTrack for UID %u", i); } } SortTracks(); return success; }
void TrackWindow::MessageReceived( BMessage * msg ) { switch (msg->what) { case VolumeQuery::BEGIN_FETCH: { m_fetching++; } break; case VolumeQuery::END_FETCH: { m_fetching--; if ( !m_fetching ) { // no more fetches underway, add to list //printf("sorting tracks..\n"); // m_fetched_items.SortItems( compare_track_items ); //printf("adding tracks..\n"); m_list->SupressUpdates(true); for ( int i=0; i<m_fetched_items.CountItems(); i++ ) { // add items to list TrackItem * item = (TrackItem*)m_fetched_items.ItemAt(i); if ( !item ) { //printf("Something fishy..\n"); continue; } AddTrack( item, false ); } SortTracks(); m_list->SupressUpdates(false); } } break; case LIST_INVOKE: { TrackItem * item = dynamic_cast<TrackItem*>(m_list->CurrentSelection()); if ( item ) { // send message to playlist window! // DON'T -- be_roster->Launch( item->GetTrack()->GetEntry() ); BMessage playmsg( PlayList::PLAY_FILE ); playmsg.AddRef( "file", item->GetTrack()->GetEntry() ); m_playlist_messenger.SendMessage( &playmsg ); } else { BetterListItem * i = m_list->CurrentSelection(); if ( i->IsExpanded() ) m_list->Collapse( i ); else m_list->Expand( i ); } } break; case B_QUERY_UPDATE: { int32 op = 0; int64 node = 0; msg->FindInt32("opcode",&op); msg->FindInt64("node",&node); switch ( op ) { case B_ENTRY_CREATED: { const char * name; dev_t device; ino_t directory; ino_t node; msg->FindString("name", &name ); msg->FindInt64("directory", &directory); msg->FindInt32("device", &device); msg->FindInt64("node", &node); bool found = false; for ( int c=0; m_list->ItemAt(c); c++ ) { TrackItem * item = dynamic_cast<TrackItem*>(m_list->ItemAt(c)); if ( item && item->IsNode(node) ) { found = true; break; } } if ( !found ) { // a new file is added entry_ref ref( device, directory, name ); TrackItem * item = new TrackItem( new Track(&ref), false ); m_info->TrackAdded( item->GetTrack() ); if ( m_fetching ) { m_fetched_items.AddItem( item ); } else { AddTrack( item ); SortTracks(); } } } break; case B_ENTRY_REMOVED: { for ( int c=0; m_list->ItemAt(c); c++ ) { TrackItem * item = dynamic_cast<TrackItem*>(m_list->ItemAt(c)); if ( item && item->IsNode(node) ) { m_info->TrackRemoved( item->GetTrack() ); BetterListItem * album = m_list->Superitem(item); m_list->RemoveItem( item ); delete item; // remove album if empty if ( m_list->CountItemsUnder(album,true) == 0 ) { BetterListItem * artist = m_list->Superitem(album); m_list->RemoveItem( album ); delete album; // remove artist if empty if ( m_list->CountItemsUnder(artist,true) == 0 ) { m_list->RemoveItem( artist ); delete artist; } } // if last track in album and/or last album in artist // delete these as well break; } } } break; default: break; } } break; default: BWindow::MessageReceived(msg); } }