/* $Id$ */ /* * Cantus Tag Editor * Copyright © 2002-2004 by Samuel Abels * Copyright © 2007 by Tim Huetz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see **/ #ifdef HAVE_CONFIG_H # include #endif #include //#define _DEBUG_ /****************************************************************************** * Constructor/Destructor ******************************************************************************/ TagCopier::TagCopier(CantusHash *pplugindata) { plugindata = pplugindata; selected = NULL; // Connect all signals with Cantus. CantusAddListenerSigCFunc addlistener = (CantusAddListenerSigCFunc) cantushash_get_pointer(plugindata, "Cantus:AddListenerSigC"); g_return_if_fail(addlistener != NULL); listenerids.push_back( addlistener("Filelist:Read:Start", sigc::mem_fun(*this, &TagCopier::on_selection_changed_event))); listenerids.push_back( addlistener("File:Read:Finished", sigc::mem_fun(*this, &TagCopier::on_file_read_finished_event))); listenerids.push_back( addlistener("Filelist:Read:Finished", sigc::mem_fun(*this, &TagCopier::on_filelist_read_finished_event))); listenerids.push_back( addlistener("GUI:PluginWidget:Destroyed", sigc::mem_fun(*this, &TagCopier::on_uiwidget_destroyed_event))); hashmap["ID3V1:Artist"] = "ID3V2:Artist"; hashmap["ID3V1:Song"] = "ID3V2:Song"; hashmap["ID3V1:Album"] = "ID3V2:Album"; hashmap["ID3V1:Track"] = "ID3V2:Track"; hashmap["ID3V1:Year"] = "ID3V2:Year"; hashmap["ID3V1:Genre"] = "ID3V2:Genre"; hashmap["ID3V1:Comment"] = "ID3V2:Comment"; } TagCopier::~TagCopier(void) { #ifdef _DEBUG_ printf("id3copier(): TagCopier::~TagCopier(): Called.\n"); #endif // Disconnect all signals from Cantus. CantusRemoveListenerFunc removelistener = (CantusRemoveListenerFunc) cantushash_get_pointer(plugindata, "Cantus:RemoveListener"); g_return_if_fail(removelistener != NULL); std::list::iterator iter = listenerids.begin(); while (iter != listenerids.end()) { removelistener(*iter); iter++; } #ifdef _DEBUG_ printf("id3copier(): TagCopier::~TagCopier(): Finished.\n"); #endif } /****************************************************************************** * Public ******************************************************************************/ GtkWidget *TagCopier::editarea_build(gboolean vertical) { GtkWidget *editareawidget = editarea.build(vertical); editarea.signal_button_save_clicked.connect( sigc::mem_fun(*this, &TagCopier::on_editarea_button_save_clicked)); editarea.signal_direction_changed.connect( sigc::mem_fun(*this, &TagCopier::show_first_tag)); return editareawidget; } /****************************************************************************** * Private ******************************************************************************/ /* Called to update the GUI (fill a tag in). */ void TagCopier::show_first_tag(void) { if (!selected) return; // Get a pointer to all required functions. CantusFileInfoGetFunc get_info = (CantusFileInfoGetFunc) cantushash_get_pointer(plugindata, "Cantus:FileInfoGet"); CantusFileInfoUnlockFunc unlock_info = (CantusFileInfoUnlockFunc) cantushash_get_pointer(plugindata, "Cantus:FileInfoUnlock"); g_return_if_fail(get_info != NULL || unlock_info != NULL); const gchar *filename = (const gchar*)selected->data; CantusHash *info = get_info(filename); std::map::iterator iter = hashmap.begin(); while (iter != hashmap.end()) { gchar *fieldname = strchr(iter->first, ':') + 1; if (editarea.get_direction() == DIRECTION_V1TOV2) editarea.set_label_text(fieldname, cantushash_get_char(info, iter->first)); else editarea.set_label_text(fieldname, cantushash_get_char(info, iter->second)); iter++; } unlock_info(filename); } /* Called when the selection changed, but the selected files have not yet been * read. */ void TagCopier::on_selection_changed_event(void *pselected) { #ifdef _DEBUG_ printf("id3copier(): TagCopier::on_selection_changed_event(): Called.\n"); #endif if (pselected && ((GList*)pselected)->next) // Make the buttons inactive if at editarea.set_active(FALSE); // least two files are selected. isfirst = TRUE; if (selected) g_list_free(selected); selected = g_list_copy((GList*)pselected); } /* The selection has now been read. */ void TagCopier::on_file_read_finished_event(void *pinfo) { #ifdef _DEBUG_ printf("id3copier(): TagCopier::on_file_read_finished_event(): Called.\n"); #endif if (!isfirst) return; g_return_if_fail(pinfo != NULL); CantusHash *info = (CantusHash*)pinfo; isfirst = FALSE; std::map::iterator iter = hashmap.begin(); while (iter != hashmap.end()) { gchar *fieldname = strchr(iter->first, ':') + 1; if( editarea.get_direction() == DIRECTION_V1TOV2 ) { editarea.set_label_text(fieldname,cantushash_get_char(info, iter->first)); } else { editarea.set_label_text(fieldname, cantushash_get_char(info, iter->second)); } iter++; } } /* The files that have been selected have now all been read. */ void TagCopier::on_filelist_read_finished_event(void *trash) { #ifdef _DEBUG_ printf("id3copier(): TagCopier::on_filelist_read_finished_event() called.\n"); #endif editarea.set_active(TRUE); } void TagCopier::copy(CantusHash *info, int direction) { std::map::iterator iter = hashmap.begin(); while (iter != hashmap.end()) { gchar *fieldname = g_strconcat(strchr(iter->first, ':') + 1, ":Check",NULL); if (editarea.get_check_active(fieldname)) { if (direction == DIRECTION_V1TOV2) cantushash_set_char(info, iter->second, cantushash_get_char(info, iter->first)); else cantushash_set_char(info, iter->first, cantushash_get_char(info, iter->second)); } g_free(fieldname); iter++; } } void TagCopier::on_editarea_button_save_clicked(void) { // Get a pointer to all required functions. CantusEmitFunc emit = (CantusEmitFunc) cantushash_get_pointer(plugindata, "Cantus:Emit"); CantusFileInfoGetFunc get_info = (CantusFileInfoGetFunc) cantushash_get_pointer(plugindata, "Cantus:FileInfoGet"); CantusFileInfoUnlockFunc unlock_info = (CantusFileInfoUnlockFunc) cantushash_get_pointer(plugindata, "Cantus:FileInfoUnlock"); g_return_if_fail(emit != NULL || get_info != NULL || unlock_info != NULL); // Walk through all files, copying the tag fields. GList *item = selected; bool direction = editarea.get_direction(); while (item) { const gchar *filename = (const gchar*)item->data; g_assert(filename != NULL); CantusHash *info = get_info(filename); copy(info, direction); if (direction == DIRECTION_V1TOV2) cantushash_set_bool(info, "ID3V2:Changed", TRUE); else cantushash_set_bool(info, "ID3V1:Changed", TRUE); unlock_info(filename); item = item->next; } // Emit the write request in the eventbus. GValue arg = {0, }; g_value_init(&arg, G_TYPE_POINTER); g_value_set_pointer(&arg, (gpointer)selected); emit("Filelist:Save:Request", &arg); g_value_unset(&arg); } void TagCopier::on_uiwidget_destroyed_event(void *name) { #ifdef _DEBUG_ printf("id3copier(): TagCopier::on_uiwidget_destroyed_event(): Called.\n"); #endif if (strcmp((gchar*)name, cantushash_get_char(plugindata, "Plugin:Name")) == 0) delete this; }