Help - Search - Members - Calendar
Full Version: Modifying meta data in files
Hydrogenaudio Forums > Hosted Forums > foobar2000 > Development - (fb2k)
cwbowron
I'm working on a new component that allows you to add flickr, etc, style tagging to tracks.

This is basically how I am modifying the files, but I'm not positive this is the correct way to be doing it.

CODE

m_handle->metadb_lock();
file_info_impl info;
m_handle->get_info( info );
info.meta_remove_field( TAG_TAG );
for ( int n = 0; n < ListView_GetItemCount( get_list() ); n++ )
{
if ( BST_CHECKED == ListView_GetCheckState( get_list(), n ) )
{
pfc::string8 str;
listview_helper::get_item_text( get_list(), n, 0, str );
info.meta_add( TAG_TAG, str );
}
}
metadb_handle_list the_handle_list;
the_handle_list.add_item( m_handle );
pfc::list_t<const file_info*> the_info_list;
the_info_list.add_item( &info );

static_api_ptr_t<metadb_io_v2> io;
io->update_info_async_simple( the_handle_list, the_info_list, m_wnd, 0, NULL );
m_handle->metadb_unlock();


Am I using update_info_async_simple and the locks correctly?

Thanks.
bubbleguuum
QUOTE(cwbowron @ May 25 2007, 22:27) *

I'm working on a new component that allows you to add flickr, etc, style tagging to tracks.

This is basically how I am modifying the files, but I'm not positive this is the correct way to be doing it.

Thanks.



If you have a lot of files to update at once here's what i'd do:

CODE


class update_tags_task : public threaded_process_callback
{
public:
update_tags_task(const metadb_handle_list &items);
void start();
private:

file_info_update_helper finfo_helper;
void run(threaded_process_status & p_status, abort_callback & p_abort);
void on_done(HWND p_wnd, bool p_was_aborted);
};

update_tags_task::update_tags_task(const metadb_handle_list &items) : finfo_helper(items)
{
finfo_helper.read_infos(core_api::get_main_window(), true);
}

void update_tags_task::start()
{
threaded_process::g_run_modeless(
this,
threaded_process::flag_show_abort |
threaded_process::flag_show_delayed |
threaded_process::flag_show_minimize |
threaded_process::flag_show_progress |
threaded_process::flag_show_item,
core_api::get_main_window(),
"Updating tags..."
);
}


void update_tags_task::run(threaded_process_status & p_status, abort_callback & p_abort)
{
for(i = 0 ; i < finfo_helper.get_item_count() && !p_abort.is_aborting() ; i++)
{
file_info &finfo = finfo_helper.get_item(i);
finfo.meta_add(...)
// modify finfo here
}

// if(p_abort.is_aborting()) for( ; i < item_count ; i++) finfo_helper.invalidate_item(i);
// return ;
}

void update_tags_task::on_done(HWND p_wnd, bool p_was_aborted)
{
finfo_helper.write_infos(core_api::get_main_window(), true);
}





It uses the helper class file_info_helper to read/write a bunch of file_info at once. tags are effectively written to file in on_done(), which happens in main thread as it should. Using a threaded_process_callback is only useful if you have some action that take a long time per item in the for loop. Else you can combine the constructor, init() and on_done() sequentially.

You launch the whole thing with:

CODE

service_ptr_t<update_tags_task> task =
new service_impl_t<update_tags_task>(items);
task->start();
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Invision Power Board © 2001-2008 Invision Power Services, Inc.