示例#1
0
/*--------------------------------------------------------------------------------*/
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);
	}
}