+
+std::string
+SoundFileBrowser::freesound_get_audio_file(Gtk::TreeIter iter)
+{
+
+ Mootcher *mootcher = new Mootcher;
+ std::string file;
+
+ string id = (*iter)[freesound_list_columns.id];
+ string uri = (*iter)[freesound_list_columns.uri];
+ string ofn = (*iter)[freesound_list_columns.filename];
+
+ if (mootcher->checkAudioFile(ofn, id)) {
+ // file already exists, no need to download it again
+ file = mootcher->audioFileName;
+ delete mootcher;
+ (*iter)[freesound_list_columns.started] = false;
+ return file;
+ }
+ if (!(*iter)[freesound_list_columns.started]) {
+ // start downloading the sound file
+ (*iter)[freesound_list_columns.started] = true;
+ mootcher->fetchAudioFile(ofn, id, uri, this);
+ }
+ return "";
+}
+
+void
+SoundFileBrowser::freesound_list_view_selected ()
+{
+
+ if (!reset_options ()) {
+ set_action_sensitive (false);
+ } else {
+ std::string file;
+ ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
+ for (ListPath::iterator i = rows.begin() ; i != rows.end(); ++i) {
+ file = freesound_get_audio_file (freesound_list->get_iter(*i));
+ }
+
+ switch (rows.size()) {
+ case 0:
+ // nothing selected
+ freesound_similar_btn.set_sensitive(false);
+ set_action_sensitive (false);
+ break;
+ case 1:
+ // exactly one item selected
+ if (file != "") {
+ // file exists on disk already
+ chooser.set_filename (file);
+ preview.setup_labels (file);
+ set_action_sensitive (true);
+ }
+ freesound_similar_btn.set_sensitive(true);
+ break;
+ default:
+ // multiple items selected
+ preview.setup_labels ("");
+ freesound_similar_btn.set_sensitive(false);
+ break;
+ }
+
+ }
+}
+
+void
+SoundFileBrowser::refresh_display(std::string ID, std::string file)
+{
+ // called when the mootcher has finished downloading a file
+ ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
+ if (rows.size() == 1) {
+ // there's a single item selected in the freesound list
+ //XXX make a function to be used to construct the actual file name both here and in the mootcher
+ Gtk::TreeIter row = freesound_list->get_iter(*rows.begin());
+ std::string selected_ID = (*row)[freesound_list_columns.id];
+ if (ID == selected_ID) {
+ // the selected item in the freesound list is the item that has just finished downloading
+ chooser.set_filename(file);
+ preview.setup_labels (file);
+ set_action_sensitive (true);
+ }
+ }
+}
+
+void
+SoundFileBrowser::freesound_search_clicked ()
+{
+ freesound_page = 1;
+ freesound_list->clear();
+ matches = 0;
+ freesound_search();
+}
+
+void
+SoundFileBrowser::freesound_more_clicked ()
+{
+ char row_path[21];
+ freesound_page++;
+ freesound_search();
+ snprintf(row_path, 21, "%d", (freesound_page - 1) * 100);
+ freesound_list_view.scroll_to_row(Gtk::TreePath(row_path), 0);
+}
+
+void
+SoundFileBrowser::freesound_similar_clicked ()
+{
+ ListPath rows = freesound_list_view.get_selection()->get_selected_rows ();
+ if (rows.size() == 1) {
+ Mootcher mootcher;
+ string id;
+ Gtk::TreeIter iter = freesound_list->get_iter(*rows.begin());
+ id = (*iter)[freesound_list_columns.id];
+ freesound_list->clear();
+
+ GdkCursor *prev_cursor;
+ prev_cursor = gdk_window_get_cursor (get_window()->gobj());
+ gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
+ gdk_flush();
+
+ std::string theString = mootcher.searchSimilar(id);
+
+ gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
+ handle_freesound_results(theString);
+ }
+}
+
+void
+SoundFileBrowser::freesound_search()
+{
+ Mootcher mootcher;
+
+ string search_string = freesound_entry.get_text ();
+ enum sortMethod sort_method = (enum sortMethod) freesound_sort.get_active_row_number();
+
+ GdkCursor *prev_cursor;
+ prev_cursor = gdk_window_get_cursor (get_window()->gobj());
+ gdk_window_set_cursor (get_window()->gobj(), gdk_cursor_new(GDK_WATCH));
+ gdk_flush();
+
+ std::string theString = mootcher.searchText(
+ search_string,
+ freesound_page,
+#ifdef GTKOSX
+ "", // OSX eats anything incl mp3
+#else
+ "type:wav OR type:aiff OR type:flac OR type:aif OR type:ogg OR type:oga",
+#endif
+ sort_method
+ );
+
+ gdk_window_set_cursor (get_window()->gobj(), prev_cursor);
+ handle_freesound_results(theString);
+}
+
+void
+SoundFileBrowser::handle_freesound_results(std::string theString) {
+ XMLTree doc;
+ doc.read_buffer( theString );
+ XMLNode *root = doc.root();
+
+ if (!root) {
+ error << "no root XML node!" << endmsg;
+ return;
+ }
+
+ if ( strcmp(root->name().c_str(), "response") != 0) {
+ error << string_compose ("root node name == %1 != \"response\"", root->name()) << endmsg;
+ return;
+ }
+
+ // find out how many pages are available to search
+ int freesound_n_pages = 1;
+ XMLNode *res = root->child("num_pages");
+ if (res) {
+ string result = res->child("text")->content();
+ freesound_n_pages = atoi(result);
+ }
+
+ int more_pages = freesound_n_pages - freesound_page;
+
+ if (more_pages > 0) {
+ freesound_more_btn.set_sensitive(true);
+ freesound_more_btn.set_tooltip_text(string_compose(P_(
+ "%1 more page of 100 results available",
+ "%1 more pages of 100 results available",
+ more_pages), more_pages));
+ } else {
+ freesound_more_btn.set_sensitive(false);
+ freesound_more_btn.set_tooltip_text(_("No more results available"));
+ }
+
+ XMLNode *sounds_root = root->child("sounds");
+ if (!sounds_root) {
+ error << "no child node \"sounds\" found!" << endmsg;
+ return;
+ }
+
+ XMLNodeList sounds = sounds_root->children();
+ if (sounds.size() == 0) {
+ /* nothing found */
+ return;
+ }
+
+ XMLNodeConstIterator niter;
+ XMLNode *node;
+ for (niter = sounds.begin(); niter != sounds.end(); ++niter) {
+ node = *niter;
+ if( strcmp( node->name().c_str(), "resource") != 0 ) {
+ error << string_compose ("node->name()=%1 != \"resource\"", node->name()) << endmsg;
+ break;
+ }
+
+ // node->dump(cerr, "node:");
+
+
+ XMLNode *id_node = node->child ("id");
+ XMLNode *uri_node = node->child ("serve");
+ XMLNode *ofn_node = node->child ("original_filename");
+ XMLNode *dur_node = node->child ("duration");
+ XMLNode *siz_node = node->child ("filesize");
+ XMLNode *srt_node = node->child ("samplerate");
+ XMLNode *lic_node = node->child ("license");
+
+ if (id_node && uri_node && ofn_node && dur_node && siz_node && srt_node) {
+
+ std::string id = id_node->child("text")->content();
+ std::string uri = uri_node->child("text")->content();
+ std::string ofn = ofn_node->child("text")->content();
+ std::string dur = dur_node->child("text")->content();
+ std::string siz = siz_node->child("text")->content();
+ std::string srt = srt_node->child("text")->content();
+ std::string lic = lic_node->child("text")->content();
+
+ std::string r;
+ // cerr << "id=" << id << ",uri=" << uri << ",ofn=" << ofn << ",dur=" << dur << endl;
+
+ double duration_seconds = atof(dur);
+ double h, m, s;
+ char duration_hhmmss[16];
+ if (duration_seconds >= 99 * 60 * 60) {
+ strcpy(duration_hhmmss, ">99h");
+ } else {
+ s = modf(duration_seconds/60, &m) * 60;
+ m = modf(m/60, &h) * 60;
+ sprintf(duration_hhmmss, "%02.fh:%02.fm:%04.1fs",
+ h, m, s
+ );
+ }
+
+ double size_bytes = atof(siz);
+ char bsize[32];
+ if (size_bytes < 1000) {
+ sprintf(bsize, "%.0f %s", size_bytes, _("B"));
+ } else if (size_bytes < 1000000 ) {
+ sprintf(bsize, "%.1f %s", size_bytes / 1000.0, _("kB"));
+ } else if (size_bytes < 10000000) {
+ sprintf(bsize, "%.1f %s", size_bytes / 1000000.0, _("MB"));
+ } else if (size_bytes < 1000000000) {
+ sprintf(bsize, "%.2f %s", size_bytes / 1000000.0, _("MB"));
+ } else {
+ sprintf(bsize, "%.2f %s", size_bytes / 1000000000.0, _("GB"));
+ }
+
+ /* see http://www.freesound.org/help/faq/#licenses */
+ char shortlicense[64];
+ if(!lic.compare(0, 42, "http://creativecommons.org/licenses/by-nc/")){
+ sprintf(shortlicense, "CC-BY-NC");
+ } else if(!lic.compare(0, 39, "http://creativecommons.org/licenses/by/")) {
+ sprintf(shortlicense, "CC-BY");
+ } else if(!lic.compare("http://creativecommons.org/licenses/sampling+/1.0/")) {
+ sprintf(shortlicense, "sampling+");
+ } else if(!lic.compare(0, 40, "http://creativecommons.org/publicdomain/")) {
+ sprintf(shortlicense, "PD");
+ } else {
+ snprintf(shortlicense, 64, "%s", lic.c_str());
+ shortlicense[63]= '\0';
+ }
+
+ TreeModel::iterator new_row = freesound_list->append();
+ TreeModel::Row row = *new_row;
+
+ row[freesound_list_columns.id ] = id;
+ row[freesound_list_columns.uri ] = uri;
+ row[freesound_list_columns.filename] = ofn;
+ row[freesound_list_columns.duration] = duration_hhmmss;
+ row[freesound_list_columns.filesize] = bsize;
+ row[freesound_list_columns.smplrate] = srt;
+ row[freesound_list_columns.license ] = shortlicense;
+ matches++;
+ }
+ }
+}
+
+vector<string>