void metadb_handle_list_helper::sort_by_relative_path_get_order(metadb_handle_list_cref p_list,t_size* order) { const t_size count = p_list.get_count(); t_size n; pfc::array_t<custom_sort_data> data; data.set_size(count); static_api_ptr_t<library_manager> api; pfc::string8_fastalloc temp; temp.prealloc(512); for(n=0;n<count;n++) { metadb_handle_ptr item; p_list.get_item_ex(item,n); if (!api->get_relative_path(item,temp)) temp = ""; data[n].index = n; data[n].text = makeSortString(temp); //data[n].subsong = item->get_subsong_index(); } pfc::sort_t(data,custom_sort_compare<1>,count); //qsort(data.get_ptr(),count,sizeof(custom_sort_data),(int (__cdecl *)(const void *elem1, const void *elem2 ))custom_sort_compare); for(n=0;n<count;n++) { order[n]=data[n].index; delete[] data[n].text; } }
virtual void context_command(unsigned int p_index, metadb_handle_list_cref p_data, const GUID& p_caller) { if(p_index == 0 && p_data.get_count() == 1) AlsongLyricLinkDialog::OpenLyricLinkDialog(core_api::get_main_window(), p_data.get_item(0)); else if(p_index == 1 && p_data.get_count() == 1) LyricSyncDialog::Open(p_data.get_item(0), core_api::get_main_window()); }
virtual void context_command( unsigned int index, metadb_handle_list_cref tracks, const GUID& /*caller*/ ) { switch(index) { case Items::GetArtistTopTracks: { generateArtistPlaylist(tracks); break; } case Items::GetSimilarTracks: { if(tracks.get_count() > 0) { generateSimilarTracksPlaylist(tracks.get_item(0)); } break; } default: { uBugCheck(); } } }
double metadb_handle_list_helper::calc_total_duration(metadb_handle_list_cref p_list) { double ret = 0; t_size n, m = p_list.get_count(); for(n=0;n<m;n++) { double temp = p_list.get_item(n)->get_length(); if (temp > 0) ret += temp; } return ret; }
bool playlist_manager::playlist_update_content(t_size playlist, metadb_handle_list_cref content, bool bUndoBackup) { metadb_handle_list old; playlist_get_all_items(playlist, old); if (old.get_size() == 0) { if (content.get_size() == 0) return false; if (bUndoBackup) playlist_undo_backup(playlist); playlist_add_items(playlist, content, bit_array_false()); return true; } pfc::avltree_t<metadb_handle::nnptr> itemsOld, itemsNew; for(t_size walk = 0; walk < old.get_size(); ++walk) itemsOld += old[walk]; for(t_size walk = 0; walk < content.get_size(); ++walk) itemsNew += content[walk]; bit_array_bittable removeMask(old.get_size()); bit_array_bittable filterMask(content.get_size()); bool gotNew = false, filterNew = false, gotRemove = false; for(t_size walk = 0; walk < content.get_size(); ++walk) { const bool state = !itemsOld.have_item(content[walk]); if (state) gotNew = true; else filterNew = true; filterMask.set(walk, state); } for(t_size walk = 0; walk < old.get_size(); ++walk) { const bool state = !itemsNew.have_item(old[walk]); if (state) gotRemove = true; removeMask.set(walk, state); } if (!gotNew && !gotRemove) return false; if (bUndoBackup) playlist_undo_backup(playlist); if (gotRemove) { playlist_remove_items(playlist, removeMask); } if (gotNew) { if (filterNew) { metadb_handle_list temp(content); temp.filter_mask(filterMask); playlist_add_items(playlist, temp, bit_array_false()); } else { playlist_add_items(playlist, content, bit_array_false()); } } { playlist_get_all_items(playlist, old); pfc::array_t<t_size> order; if (pfc::guess_reorder_pattern<pfc::list_base_const_t<metadb_handle_ptr> >(order, old, content)) { playlist_reorder_items(playlist, order.get_ptr(), order.get_size()); } } return true; }
virtual bool context_get_display(unsigned int p_index, metadb_handle_list_cref p_data, pfc::string_base & p_out, unsigned & p_displayflags, const GUID & p_caller) { if(p_index == 0) { p_out = EncodingFunc::ToUTF8(TEXT("알송 가사 추가/변경")).c_str(); return p_data.get_count() == 1; } else if(p_index == 1) { p_out = EncodingFunc::ToUTF8(TEXT("가사 싱크 수정")).c_str(); return p_data.get_count() == 1; } return false; }
virtual bool context_get_display( unsigned int index, metadb_handle_list_cref tracks, pfc::string_base& out, unsigned int& /*displayflags*/, const GUID& /*caller*/ ) { switch(index) { case Items::ReplaceWithBestVersion: { out = "Replace with best version of track"; if(tracks.get_count() > 1) { out.add_string("s"); } return true; } default: { // Nothing wants to customise the display of the item; let the regular name be displayed. get_item_name(index, out); return true; } } }
void metadb_handle_list_helper::sort_by_format_get_order(metadb_handle_list_cref p_list,t_size* order,const service_ptr_t<titleformat_object> & p_script,titleformat_hook * p_hook,int p_direction) { // pfc::hires_timer timer; timer.start(); const t_size count = p_list.get_count(); pfc::array_t<custom_sort_data> data; data.set_size(count); { pfc::counter counter(0); pfc::array_t<pfc::rcptr_t<tfthread> > threads; threads.set_size(pfc::getOptimalWorkerThreadCountEx(p_list.get_count() / 128)); PFC_ASSERT( threads.get_size() > 0 ); for(t_size walk = 0; walk < threads.get_size(); ++walk) { threads[walk].new_t(&counter,p_list,data.get_ptr(),p_script,p_hook); } for(t_size walk = 1; walk < threads.get_size(); ++walk) threads[walk]->start(); threads[0]->threadProc(); for(t_size walk = 1; walk < threads.get_size(); ++walk) threads[walk]->waitTillDone(); } // console::formatter() << "metadb_handle sort: prepared in " << pfc::format_time_ex(timer.query(),6); pfc::sort_t(data, p_direction > 0 ? custom_sort_compare<1> : custom_sort_compare<-1>,count); //qsort(data.get_ptr(),count,sizeof(custom_sort_data),p_direction > 0 ? _custom_sort_compare<1> : _custom_sort_compare<-1>); // console::formatter() << "metadb_handle sort: sorted in " << pfc::format_time_ex(timer.query(),6); for(t_size n=0;n<count;n++) { order[n]=data[n].index; delete[] data[n].text; } // console::formatter() << "metadb_handle sort: finished in " << pfc::format_time_ex(timer.query(),6); }
t_size file_list_from_metadb_handle_list::g_get_count(metadb_handle_list_cref data, t_size max) { pfc::avltree_t<const char*, metadb::path_comparator> content; const t_size inCount = data.get_size(); for(t_size walk = 0; walk < inCount && content.get_count() < max; ++walk) { content += data[walk]->get_path(); } return content.get_count(); }
void playlist_manager::on_file_rechaptered(const char * path, metadb_handle_list_cref newItems) { if (newItems.get_size() == 0) return; const size_t numPlaylists = this->get_playlist_count(); for( size_t walkPlaylist = 0; walkPlaylist < numPlaylists; ++ walkPlaylist ) { if (!playlist_lock_is_present(walkPlaylist)) { auto itemCount = [=] () -> unsigned { return this->playlist_get_item_count( walkPlaylist ); }; auto itemHandle = [=] ( unsigned item ) -> metadb_handle_ptr { return this->playlist_get_item_handle( walkPlaylist, item ); }; auto itemMatch = [=] ( unsigned item ) -> bool { return metadb::path_compare(path, itemHandle(item)->get_path()) == 0; }; auto itemMatch2 = [=] ( metadb_handle_ptr item ) -> bool { return metadb::path_compare(path, item->get_path() ) == 0; }; for( size_t walkItem = 0; walkItem < itemCount(); ) { if (itemMatch( walkItem )) { pfc::avltree_t<uint32_t> subsongs; unsigned base = walkItem; bool bSel = false; for( ++walkItem ; walkItem < itemCount() ; ++ walkItem ) { auto handle = itemHandle( walkItem ); if (! itemMatch2( handle ) ) break; if (! subsongs.add_item_check(handle->get_subsong_index())) break; bSel = bSel || this->playlist_is_item_selected(walkPlaylist, walkItem); } // REMOVE base ... walkItem range and insert newHandles at base this->playlist_remove_items( walkPlaylist, pfc::bit_array_range(base, walkItem-base) ); this->playlist_insert_items( walkPlaylist, base, newItems, pfc::bit_array_val( bSel ) ); walkItem = base + newItems.get_size(); } else { ++walkItem; } } } } }
bool metadb_handle_list_helper::extract_single_path(metadb_handle_list_cref list, const char * &pathOut) { const t_size total = list.get_count(); if (total == 0) return false; const char * path = list[0]->get_path(); for(t_size walk = 1; walk < total; ++walk) { if (metadb::path_compare(path, list[walk]->get_path()) != 0) return false; } pathOut = path; return true; }
void playlist_manager::on_files_rechaptered( metadb_handle_list_cref newHandles ) { pfc::map_t< const char*, metadb_handle_list, metadb::path_comparator > byPath; const size_t total = newHandles.get_count(); for( size_t w = 0; w < total; ++w ) { auto handle = newHandles[w]; byPath[ handle->get_path() ] += handle; } for( auto iter = byPath.first(); iter.is_valid(); ++ iter ) { this->on_file_rechaptered( iter->m_key, iter->m_value ); } }
void RunCalculatePeak(metadb_handle_list_cref data) { try { if (data.get_count() == 0) throw pfc::exception_invalid_params(); service_ptr_t<threaded_process_callback> cb = new service_impl_t<calculate_hash>(data); static_api_ptr_t<threaded_process>()->run_modeless( cb, threaded_process::flag_show_progress_dual | threaded_process::flag_show_item | threaded_process::flag_show_abort, core_api::get_main_window(), "Calculating audio data hashes..."); } catch(std::exception const & e) { popup_message::g_complain("Could not start audio hashing process", e); } }
t_filesize metadb_handle_list_helper::calc_total_size(metadb_handle_list_cref p_list, bool skipUnknown) { pfc::avltree_t< const char*, metadb::path_comparator > beenHere; // metadb_handle_list list(p_list); // list.sort_t(metadb::path_compare_metadb_handle); t_filesize ret = 0; t_size n, m = p_list.get_count(); for(n=0;n<m;n++) { bool isNew; metadb_handle_ptr h; p_list.get_item_ex(h, n); beenHere.add_ex( h->get_path(), isNew); if (isNew) { t_filesize t = h->get_filesize(); if (t == filesize_invalid) { if (!skipUnknown) return filesize_invalid; } else { ret += t; } } } return ret; }
void nonautoregister_callbacks::on_selection_changed(metadb_handle_list_cref p_selection) { if (p_selection.get_count() > 0) { simple_callback_data<metadb_handle_ptr>* on_selection_changed_data = new simple_callback_data<metadb_handle_ptr>(p_selection[0]); panel_manager::instance().post_msg_to_all_pointer(CALLBACK_UWM_ON_SELECTION_CHANGED, on_selection_changed_data); } else { panel_manager::instance().post_msg_to_all(CALLBACK_UWM_ON_SELECTION_CHANGED); } }
void selection_properties_t::on_changed_sorted(metadb_handle_list_cref p_items_sorted, bool p_fromhook) { if (!p_fromhook) { bool b_refresh = false; t_size i, count = m_handles.get_count(); for (i=0; i<count && !b_refresh; i++) { t_size index = pfc_infinite; if (p_items_sorted.bsearch_t(pfc::compare_t<metadb_handle_ptr, metadb_handle_ptr>, m_handles[i], index)) b_refresh = true; } if (b_refresh) { refresh_contents(); } } }
std::string getMainArtist(metadb_handle_list_cref tracks) { // Don't look at too many tracks - this method should be quick but won't be if we don't limit ourselves. static const t_size maxNumberOfTracksToConsider = 100; // Keep track of the number of each artist name we encounter. std::map<const char*, t_size> artists; // For each track, increment the number of occurrences of its artist. for(t_size i = 0; i < tracks.get_count() && i < maxNumberOfTracksToConsider; i++) { service_ptr_t<metadb_info_container> outInfo; if(tracks[i]->get_async_info_ref(outInfo)) { const file_info& fileInfo = outInfo->info(); const bool has_artist_tag = fileInfo.meta_exists("artist"); const bool has_album_artist_tag = fileInfo.meta_exists("album artist"); if(has_artist_tag || has_album_artist_tag) { const char * artist = has_artist_tag ? fileInfo.meta_get("artist", 0) : fileInfo.meta_get("album artist", 0); ++artists[artist]; } } } // Find the artist that occurred the most. t_size maxCount = 0; const char* maxArtist = ""; for(auto iter = artists.begin(); iter != artists.end(); iter++) { if((iter->second) > maxCount) { maxCount = iter->second; maxArtist = iter->first; } } // We've kept the database locked this whole time because we're just storing char* in the map, not copying the strings. return maxArtist; }
virtual bool context_get_display( unsigned int index, metadb_handle_list_cref tracks, pfc::string_base& out, unsigned int& displayflags, const GUID& /*caller*/ ) { switch(index) { case Items::GetArtistTopTracks: { const auto& mainArtist = getMainArtist(tracks); const t_size stringLength = mainArtist.length(); if(stringLength > 0) { // We have found a main artist; set the display of the item to be of the form: // "Artist's top tracks". out = mainArtist.c_str(); // Grammar alert! Artists ending with "s" get just a "'" rather than "'s". if(out[stringLength - 1] == 's') { out.add_string("' top tracks"); } else { out.add_string("'s top tracks"); } } else { // Failed to find a main artist; return the normal, non-custom name for the item. get_item_name(index, out); } return true; } case Items::GetSimilarTracks: { if(tracks.get_count() == 0) { displayflags = FLAG_DISABLED_GRAYED; get_item_name(index, out); } else { out = "Get tracks similar to "; out.add_string(getTitle(tracks.get_item(0)).c_str()); } return true; } default: { // Nothing wants to customise the display of the item; let the regular name be displayed. get_item_name(index, out); return true; } } }
t_size metadb_handle_list_helper::bsearch_by_pointer(metadb_handle_list_cref p_list,const metadb_handle_ptr & val) { t_size blah; if (p_list.bsearch_t(pfc::compare_t<metadb_handle_ptr,metadb_handle_ptr>,val,blah)) return blah; else return ~0; }