END_TEST START_TEST (test_rhythmdb_deserialisation3) { RhythmDBQueryModel *model; /* two entries of different types db */ g_object_set (G_OBJECT (db), "name", "deserialization-test3.xml", NULL); set_waiting_signal (G_OBJECT (db), "load-complete"); rhythmdb_load (db); wait_for_signal (); model = rhythmdb_query_model_new_empty (db); g_object_set (G_OBJECT (model), "show-hidden", TRUE, NULL); set_waiting_signal (G_OBJECT (model), "complete"); rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (model), NULL, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE, RHYTHMDB_QUERY_END); wait_for_signal (); /* FIXME: this fails for some reason fail_unless (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 1, "deserialisation incorrect");*/ g_object_unref (model); /* TODO: check values */ }
static void start_media_browse (RBGriloSource *source, GrlMedia *container, GtkTreeIter *container_iter, guint limit) { rb_debug ("starting media browse for %s", grl_source_get_name (source->priv->grilo_source)); /* cancel existing operation? */ if (source->priv->media_browse_op != 0) { grl_operation_cancel (source->priv->media_browse_op); } if (source->priv->media_browse_container != NULL) { g_object_unref (source->priv->media_browse_container); } source->priv->media_browse_container = container; if (container_iter != NULL) { /* hrm, probably have to use row references here.. */ source->priv->media_browse_container_iter = *container_iter; } source->priv->media_browse_position = 0; source->priv->media_browse_limit = limit; source->priv->media_browse_got_containers = FALSE; if (source->priv->query_model != NULL) { g_object_unref (source->priv->query_model); } source->priv->query_model = rhythmdb_query_model_new_empty (source->priv->db); rb_entry_view_set_model (RB_ENTRY_VIEW (source->priv->entry_view), source->priv->query_model); g_object_set (source, "query-model", source->priv->query_model, NULL); media_browse_next (source); }
int main (int argc, char **argv) { GtkWidget *main_window; GtkTreeModel *main_model; GtkTreeIter iter; RBEntryView *view; RhythmDB *db; RhythmDBEntry *entry; gtk_init (&argc, &argv); gdk_threads_init (); rb_thread_helpers_init (); rb_file_helpers_init (TRUE); rb_stock_icons_init (); rb_debug_init (TRUE); GDK_THREADS_ENTER (); db = rhythmdb_tree_new ("test"); rhythmdb_write_lock (db); entry = create_entry (db, "file:///sin.mp3", "Sin", "Pretty Hate Machine", "Nine Inch Nails", "Rock"); rhythmdb_write_unlock (db); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE, RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL); view = rb_entry_view_new (db, rb_file ("rb-entry-view-library.xml")); rb_entry_view_set_query_model (view, RHYTHMDB_QUERY_MODEL (main_model)); gtk_container_add (GTK_CONTAINER (main_window), GTK_WIDGET (view)); g_signal_connect (G_OBJECT (main_window), "destroy", G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show_all (GTK_WIDGET (main_window)); gtk_main (); rhythmdb_shutdown (db); g_object_unref (G_OBJECT (db)); GDK_THREADS_LEAVE (); exit (0); }
/** * rb_transfer_target_check_duplicate: * @target: an #RBTransferTarget * @entry: a #RhythmDBEntry to check * * This checks for an existing entry in the target that matches * the title, album, artist, and track number of the entry being * considered. This can be used to implement @should_transfer. * * Return value: %TRUE if the entry already exists on the target. */ gboolean rb_transfer_target_check_duplicate (RBTransferTarget *target, RhythmDBEntry *entry) { RhythmDBEntryType *entry_type; RhythmDB *db; RBShell *shell; const char *title; const char *album; const char *artist; gulong track_number; GtkTreeModel *query_model; GtkTreeIter iter; gboolean is_dup; g_object_get (target, "shell", &shell, "entry-type", &entry_type, NULL); g_object_get (shell, "db", &db, NULL); g_object_unref (shell); query_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); title = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_TITLE); album = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM); artist = rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ARTIST); track_number = rhythmdb_entry_get_ulong (entry, RHYTHMDB_PROP_TRACK_NUMBER); rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (query_model), RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ARTIST, artist, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ALBUM, album, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, title, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TRACK_NUMBER, track_number, RHYTHMDB_QUERY_END); is_dup = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (query_model), &iter); g_object_unref (entry_type); g_object_unref (query_model); g_object_unref (db); if (is_dup) { rb_debug ("not transferring %lu - %s - %s - %s as already present", track_number, title, album, artist); } return is_dup; }
static void test_query_eval (RhythmDB *db, RhythmDBQuery *query, RhythmDBEntry *entry, gboolean expected, const char *what) { RhythmDBQueryModel *model; RhythmDBQuery *processed; GtkTreeIter iter = {0,}; /* direct evaluation - need to preprocess it first */ processed = rhythmdb_query_copy (query); rhythmdb_query_preprocess (db, processed); fail_unless (rhythmdb_evaluate_query (db, processed, entry) == expected, what); rhythmdb_query_free (processed); /* query evaluation - query is preprocessed by rhythmdb */ model = rhythmdb_query_model_new_empty (db); rhythmdb_do_full_query_parsed (db, RHYTHMDB_QUERY_RESULTS (model), query); fail_unless (rhythmdb_query_model_entry_to_iter (model, entry, &iter) == expected, what); g_object_unref (model); }
static void rb_static_playlist_source_do_query (RBStaticPlaylistSource *source) { RBStaticPlaylistSourcePrivate *priv = RB_STATIC_PLAYLIST_SOURCE_GET_PRIVATE (source); RBPlaylistSource *psource = RB_PLAYLIST_SOURCE (source); RhythmDB *db = rb_playlist_source_get_db (psource); GPtrArray *query; if (priv->filter_model != NULL) { g_object_unref (priv->filter_model); } priv->filter_model = rhythmdb_query_model_new_empty (db); g_object_set (priv->filter_model, "base-model", priv->base_model, NULL); query = construct_query_from_selection (source); g_object_set (priv->filter_model, "query", query, NULL); rhythmdb_query_free (query); rhythmdb_query_model_reapply_query (priv->filter_model, TRUE); rb_library_browser_set_model (priv->browser, priv->filter_model, FALSE); }
END_TEST START_TEST (test_rhythmdb_deserialisation1) { RhythmDBQueryModel *model; /* empty db */ g_object_set (G_OBJECT (db), "name", "deserialization-test1.xml", NULL); set_waiting_signal (G_OBJECT (db), "load-complete"); rhythmdb_load (db); wait_for_signal (); model = rhythmdb_query_model_new_empty (db); g_object_set (G_OBJECT (model), "show-hidden", TRUE, NULL); set_waiting_signal (G_OBJECT (model), "complete"); rhythmdb_do_full_query (db, RHYTHMDB_QUERY_RESULTS (model), NULL, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE, RHYTHMDB_QUERY_END); wait_for_signal (); fail_unless (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL) == 0, "deserialisation incorrect"); g_object_unref (model); }
static void rebuild_child_model (RBLibraryBrowser *widget, gint property_index, gboolean query_pending) { RBLibraryBrowserPrivate *priv = RB_LIBRARY_BROWSER_GET_PRIVATE (widget); RhythmDBPropertyModel *prop_model; RhythmDBQueryModel *base_model, *child_model; RBPropertyView *view; RhythmDBQuery *query; GList *selections; g_assert (property_index >= 0); g_assert (property_index < num_browser_properties); /* get the query model for the previous property view */ view = g_hash_table_lookup (priv->property_views, (gpointer)browser_properties[property_index].type); prop_model = rb_property_view_get_model (view); g_object_get (prop_model, "query-model", &base_model, NULL); selections = g_hash_table_lookup (priv->selections, (gpointer)browser_properties[property_index].type); if (selections != NULL) { /* create a new query model based on it, filtered by * the selections of the previous property view. * we need the entry type query criteria to allow the * backend to optimise the query. */ query = rhythmdb_query_parse (priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, priv->entry_type, RHYTHMDB_QUERY_END); rhythmdb_query_append_prop_multiple (priv->db, query, browser_properties[property_index].type, selections); child_model = rhythmdb_query_model_new_empty (priv->db); if (query_pending) { rb_debug ("rebuilding child model for browser %d; query is pending", property_index); g_object_set (child_model, "query", query, "base-model", base_model, NULL); } else { rb_debug ("rebuilding child model for browser %d; running new query", property_index); rhythmdb_query_model_chain (child_model, base_model, FALSE); rhythmdb_do_full_query_parsed (priv->db, RHYTHMDB_QUERY_RESULTS (child_model), query); } rhythmdb_query_free (query); } else { rb_debug ("no selection for browser %d - reusing parent model", property_index); child_model = g_object_ref (base_model); } /* If this is the last property, use the child model as the output model * for the browser. Otherwise, use it as the input for the next property * view. */ if (property_index == num_browser_properties-1) { if (priv->output_model != NULL) { g_object_unref (priv->output_model); } priv->output_model = child_model; g_object_notify (G_OBJECT (widget), "output-model"); } else { view = g_hash_table_lookup (priv->property_views, (gpointer)browser_properties[property_index+1].type); ignore_selection_changes (widget, view, TRUE); prop_model = rb_property_view_get_model (view); g_object_set (prop_model, "query-model", child_model, NULL); g_object_unref (child_model); rebuild_child_model (widget, property_index + 1, query_pending); restore_selection (widget, property_index + 1, query_pending); } g_object_unref (base_model); }
static void rb_import_errors_source_constructed (GObject *object) { GObject *shell_player; RBImportErrorsSource *source; RBShell *shell; GPtrArray *query; RhythmDBQueryModel *model; RhythmDBEntryType *entry_type; GtkWidget *box; GtkWidget *label; RB_CHAIN_GOBJECT_METHOD (rb_import_errors_source_parent_class, constructed, object); source = RB_IMPORT_ERRORS_SOURCE (object); g_object_get (source, "shell", &shell, "entry-type", &entry_type, NULL); g_object_get (shell, "db", &source->priv->db, NULL); shell_player = rb_shell_get_player (shell); g_object_unref (shell); /* construct real query */ query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type, RHYTHMDB_QUERY_END); model = rhythmdb_query_model_new (source->priv->db, query, (GCompareDataFunc) rhythmdb_query_model_string_sort_func, GUINT_TO_POINTER (RHYTHMDB_PROP_LOCATION), NULL, FALSE); rhythmdb_query_free (query); /* set up entry view */ source->priv->view = rb_entry_view_new (source->priv->db, shell_player, NULL, FALSE, FALSE); rb_entry_view_set_model (source->priv->view, model); rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_LOCATION, TRUE); rb_entry_view_append_column (source->priv->view, RB_ENTRY_VIEW_COL_ERROR, TRUE); g_signal_connect_object (source->priv->view, "show_popup", G_CALLBACK (rb_import_errors_source_songs_show_popup_cb), source, 0); g_object_set (source, "query-model", model, NULL); g_object_unref (model); /* set up query model for tracking missing plugin information */ query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type, RHYTHMDB_QUERY_PROP_NOT_EQUAL, RHYTHMDB_PROP_COMMENT, "", RHYTHMDB_QUERY_END); source->priv->missing_plugin_model = rhythmdb_query_model_new_empty (source->priv->db); rhythmdb_do_full_query_async_parsed (source->priv->db, RHYTHMDB_QUERY_RESULTS (source->priv->missing_plugin_model), query); rhythmdb_query_free (query); /* set up info bar for triggering codec installation */ source->priv->infobar = gtk_info_bar_new_with_buttons (_("Install Plugins"), GTK_RESPONSE_OK, NULL); g_signal_connect_object (source->priv->infobar, "response", G_CALLBACK (infobar_response_cb), source, 0); label = gtk_label_new (_("Additional GStreamer plugins are required to play some of these files.")); gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (source->priv->infobar))), label); g_object_unref (entry_type); box = gtk_vbox_new (FALSE, 6); gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (source->priv->view), TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (box), source->priv->infobar, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (source), box); gtk_widget_show_all (GTK_WIDGET (source)); gtk_widget_hide (source->priv->infobar); /* show the info bar when there are missing plugin entries */ g_signal_connect_object (source->priv->missing_plugin_model, "row-inserted", G_CALLBACK (missing_plugin_row_inserted_cb), source, 0); g_signal_connect_object (source->priv->missing_plugin_model, "row-deleted", G_CALLBACK (missing_plugin_row_deleted_cb), source, 0); }
END_TEST /* this tests that chained query models, where the base shows hidden entries * forwards visibility changes correctly. This is basically what static playlists do */ START_TEST (test_hidden_chain_filter) { RhythmDBQueryModel *base_model; RhythmDBQueryModel *filter_model; RhythmDBQuery *query; RhythmDBEntry *entry; GtkTreeIter iter; GValue val = {0,}; start_test_case (); /* setup */ base_model = rhythmdb_query_model_new_empty (db); g_object_set (base_model, "show-hidden", TRUE, NULL); filter_model = rhythmdb_query_model_new_empty (db); g_object_set (filter_model, "base-model", base_model, NULL); query = g_ptr_array_new (); g_object_set (filter_model, "query", query, NULL); rhythmdb_query_free (query); entry = rhythmdb_entry_new (db, RHYTHMDB_ENTRY_TYPE_IGNORE, "file:///whee.ogg"); rhythmdb_commit (db); g_value_init (&val, G_TYPE_BOOLEAN); /* add entry to base, should be in both */ rhythmdb_query_model_add_entry (base_model, entry, -1); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* hide entry, should be in base and not filtered */ g_value_set_boolean (&val, TRUE); set_waiting_signal (G_OBJECT (db), "entry-changed"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val); rhythmdb_commit (db); wait_for_signal (); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_if (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* show entry again, should be in both */ g_value_set_boolean (&val, FALSE); set_waiting_signal (G_OBJECT (db), "entry-changed"); rhythmdb_entry_set (db, entry, RHYTHMDB_PROP_HIDDEN, &val); rhythmdb_commit (db); wait_for_signal (); fail_unless (rhythmdb_query_model_entry_to_iter (base_model, entry, &iter)); fail_unless (rhythmdb_query_model_entry_to_iter (filter_model, entry, &iter)); end_step (); /* tidy up */ rhythmdb_entry_delete (db, entry); g_object_unref (base_model); g_object_unref (filter_model); g_value_unset (&val); end_test_case (); }
static void impl_constructed (GObject *object) { RBPodcastAddDialog *dialog; GtkBuilder *builder; GtkWidget *widget; GtkWidget *paned; GtkTreeViewColumn *column; GtkCellRenderer *renderer; RBEntryView *episodes; RBShellPlayer *shell_player; RhythmDBQuery *query; RhythmDBQueryModel *query_model; const char *episode_strings[3]; RB_CHAIN_GOBJECT_METHOD (rb_podcast_add_dialog_parent_class, constructed, object); dialog = RB_PODCAST_ADD_DIALOG (object); g_object_get (dialog->priv->podcast_mgr, "db", &dialog->priv->db, NULL); builder = rb_builder_load ("podcast-add-dialog.ui", NULL); dialog->priv->info_bar_message = gtk_label_new (""); dialog->priv->info_bar = gtk_info_bar_new (); g_object_set (dialog->priv->info_bar, "spacing", 0, NULL); gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (dialog->priv->info_bar))), dialog->priv->info_bar_message); gtk_widget_set_no_show_all (dialog->priv->info_bar, TRUE); gtk_box_pack_start (GTK_BOX (dialog), dialog->priv->info_bar, FALSE, FALSE, 0); gtk_widget_show (dialog->priv->info_bar_message); dialog->priv->subscribe_button = GTK_WIDGET (gtk_builder_get_object (builder, "subscribe-button")); g_signal_connect_object (dialog->priv->subscribe_button, "clicked", G_CALLBACK (subscribe_clicked_cb), dialog, 0); gtk_widget_set_sensitive (dialog->priv->subscribe_button, FALSE); dialog->priv->feed_view = GTK_WIDGET (gtk_builder_get_object (builder, "feed-view")); g_signal_connect (dialog->priv->feed_view, "row-activated", G_CALLBACK (feed_activated_cb), dialog); g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->priv->feed_view)), "changed", G_CALLBACK (feed_selection_changed_cb), dialog); dialog->priv->search_entry = rb_search_entry_new (FALSE); gtk_widget_set_size_request (GTK_WIDGET (dialog->priv->search_entry), 400, -1); g_object_set (dialog->priv->search_entry,"explicit-mode", TRUE, NULL); g_signal_connect (dialog->priv->search_entry, "search", G_CALLBACK (search_cb), dialog); g_signal_connect (dialog->priv->search_entry, "activate", G_CALLBACK (search_cb), dialog); gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (builder, "search-entry-box")), GTK_WIDGET (dialog->priv->search_entry)); g_signal_connect (gtk_builder_get_object (builder, "close-button"), "clicked", G_CALLBACK (close_clicked_cb), dialog); dialog->priv->feed_model = gtk_list_store_new (7, G_TYPE_STRING, /* name */ G_TYPE_STRING, /* author */ GDK_TYPE_PIXBUF, /* image */ G_TYPE_FILE, /* image file */ G_TYPE_INT, /* episode count */ G_TYPE_POINTER, /* RBPodcastChannel */ G_TYPE_ULONG); /* date */ gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->priv->feed_view), GTK_TREE_MODEL (dialog->priv->feed_model)); column = gtk_tree_view_column_new_with_attributes (_("Title"), gtk_cell_renderer_pixbuf_new (), "pixbuf", FEED_COLUMN_IMAGE, NULL); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_attributes (column, renderer, "text", FEED_COLUMN_TITLE, NULL); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->feed_view), column); renderer = gtk_cell_renderer_text_new (); g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL); column = gtk_tree_view_column_new_with_attributes (_("Author"), renderer, "text", FEED_COLUMN_AUTHOR, NULL); gtk_tree_view_column_set_expand (column, TRUE); gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->feed_view), column); renderer = gtk_cell_renderer_text_new (); column = gtk_tree_view_column_new_with_attributes (_("Episodes"), renderer, NULL); gtk_tree_view_column_set_cell_data_func (column, renderer, episode_count_column_cell_data_func, NULL, NULL); episode_strings[0] = "0000"; episode_strings[1] = _("Episodes"); episode_strings[2] = NULL; rb_set_tree_view_column_fixed_width (dialog->priv->feed_view, column, renderer, episode_strings, 6); gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->priv->feed_view), column); widget = GTK_WIDGET (gtk_builder_get_object (builder, "podcast-add-dialog")); gtk_box_pack_start (GTK_BOX (dialog), widget, TRUE, TRUE, 0); /* set up episode view */ g_object_get (dialog->priv->shell, "shell-player", &shell_player, NULL); episodes = rb_entry_view_new (dialog->priv->db, G_OBJECT (shell_player), TRUE, FALSE); g_object_unref (shell_player); g_signal_connect (episodes, "entry-activated", G_CALLBACK (episode_entry_activated_cb), dialog); /* date column */ column = gtk_tree_view_column_new (); renderer = gtk_cell_renderer_text_new(); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_clickable (column, TRUE); gtk_tree_view_column_set_resizable (column, TRUE); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); { const char *sample_strings[3]; sample_strings[0] = _("Date"); sample_strings[1] = rb_entry_view_get_time_date_column_sample (); sample_strings[2] = NULL; rb_entry_view_set_fixed_column_width (episodes, column, renderer, sample_strings); } gtk_tree_view_column_set_cell_data_func (column, renderer, (GtkTreeCellDataFunc) podcast_post_date_cell_data_func, dialog, NULL); rb_entry_view_append_column_custom (episodes, column, _("Date"), "Date", (GCompareDataFunc) podcast_post_date_sort_func, 0, NULL); rb_entry_view_append_column (episodes, RB_ENTRY_VIEW_COL_TITLE, TRUE); rb_entry_view_append_column (episodes, RB_ENTRY_VIEW_COL_DURATION, TRUE); rb_entry_view_set_sorting_order (RB_ENTRY_VIEW (episodes), "Date", GTK_SORT_DESCENDING); g_signal_connect (episodes, "notify::sort-order", G_CALLBACK (episodes_sort_changed_cb), dialog); query = rhythmdb_query_parse (dialog->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_PODCAST_SEARCH, RHYTHMDB_QUERY_END); query_model = rhythmdb_query_model_new_empty (dialog->priv->db); rb_entry_view_set_model (episodes, query_model); rhythmdb_do_full_query_async_parsed (dialog->priv->db, RHYTHMDB_QUERY_RESULTS (query_model), query); rhythmdb_query_free (query); g_object_unref (query_model); paned = GTK_WIDGET (gtk_builder_get_object (builder, "paned")); g_signal_connect (paned, "size-allocate", G_CALLBACK (paned_size_allocate_cb), dialog); gtk_paned_pack2 (GTK_PANED (paned), GTK_WIDGET (episodes), TRUE, FALSE); gtk_widget_show_all (GTK_WIDGET (dialog)); g_object_unref (builder); }
static void impl_constructed (GObject *object) { RBImportDialog *dialog; RhythmDBQuery *query; GtkBuilder *builder; GSettings *settings; char **locations; RB_CHAIN_GOBJECT_METHOD (rb_import_dialog_parent_class, constructed, object); dialog = RB_IMPORT_DIALOG (object); g_object_get (dialog->priv->shell, "db", &dialog->priv->db, "shell-player", &dialog->priv->shell_player, NULL); /* create entry types */ dialog->priv->entry_type = g_object_new (rb_import_dialog_entry_type_get_type (), "db", dialog->priv->db, "name", "import-dialog", NULL); dialog->priv->ignore_type = g_object_new (rb_import_dialog_ignore_type_get_type (), "db", dialog->priv->db, "name", "import-dialog-ignore", NULL); rhythmdb_register_entry_type (dialog->priv->db, dialog->priv->entry_type); rhythmdb_register_entry_type (dialog->priv->db, dialog->priv->ignore_type); builder = rb_builder_load ("import-dialog.ui", NULL); dialog->priv->import_button = GTK_WIDGET (gtk_builder_get_object (builder, "import-button")); g_signal_connect_object (dialog->priv->import_button, "clicked", G_CALLBACK (import_clicked_cb), dialog, 0); gtk_widget_set_sensitive (dialog->priv->import_button, FALSE); dialog->priv->copy_check = GTK_WIDGET (gtk_builder_get_object (builder, "copy-check")); g_signal_connect (gtk_builder_get_object (builder, "close-button"), "clicked", G_CALLBACK (close_clicked_cb), dialog); dialog->priv->file_chooser = GTK_WIDGET (gtk_builder_get_object (builder, "file-chooser-button")); /* select the first library location, since the default may be * the user's home dir or / or something that will take forever to scan. */ settings = g_settings_new ("org.gnome.rhythmbox.rhythmdb"); locations = g_settings_get_strv (settings, "locations"); if (locations[0] != NULL) { dialog->priv->current_uri = g_strdup (locations[0]); } else { dialog->priv->current_uri = g_filename_to_uri (rb_music_dir (), NULL, NULL); } gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dialog->priv->file_chooser), dialog->priv->current_uri); g_strfreev (locations); g_object_unref (settings); g_signal_connect_object (dialog->priv->file_chooser, "selection-changed", G_CALLBACK (current_folder_changed_cb), dialog, 0); /* not sure why we have to set this, it should be the default */ gtk_widget_set_vexpand (gtk_widget_get_parent (dialog->priv->file_chooser), FALSE); dialog->priv->info_bar_container = GTK_WIDGET (gtk_builder_get_object (builder, "info-bar-container")); /* set up entry view */ dialog->priv->entry_view = rb_entry_view_new (dialog->priv->db, G_OBJECT (dialog->priv->shell_player), TRUE, FALSE); g_signal_connect (dialog->priv->entry_view, "entry-activated", G_CALLBACK (entry_activated_cb), dialog); g_signal_connect (dialog->priv->entry_view, "selection-changed", G_CALLBACK (selection_changed_cb), dialog); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_TRACK_NUMBER, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_TITLE, TRUE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_GENRE, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_ARTIST, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_ALBUM, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_YEAR, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_DURATION, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_QUALITY, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_PLAY_COUNT, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_BPM, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_COMMENT, FALSE); rb_entry_view_append_column (dialog->priv->entry_view, RB_ENTRY_VIEW_COL_LOCATION, FALSE); settings = g_settings_new ("org.gnome.rhythmbox.sources"); g_settings_bind (settings, "visible-columns", dialog->priv->entry_view, "visible-columns", G_SETTINGS_BIND_DEFAULT); g_object_unref (settings); g_signal_connect (dialog->priv->entry_view, "notify::sort-order", G_CALLBACK (sort_changed_cb), dialog); rb_entry_view_set_sorting_order (dialog->priv->entry_view, "Album", GTK_SORT_ASCENDING); gtk_container_add (GTK_CONTAINER (gtk_builder_get_object (builder, "entry-view-container")), GTK_WIDGET (dialog->priv->entry_view)); dialog->priv->query_model = rhythmdb_query_model_new_empty (dialog->priv->db); rb_entry_view_set_model (dialog->priv->entry_view, dialog->priv->query_model); query = rhythmdb_query_parse (dialog->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, dialog->priv->entry_type, RHYTHMDB_QUERY_END); rhythmdb_do_full_query_async_parsed (dialog->priv->db, RHYTHMDB_QUERY_RESULTS (dialog->priv->query_model), query); rhythmdb_query_free (query); g_signal_connect (dialog->priv->query_model, "post-entry-delete", G_CALLBACK (entry_deleted_cb), dialog); g_signal_connect (dialog->priv->query_model, "row-inserted", G_CALLBACK (entry_inserted_cb), dialog); gtk_container_add (GTK_CONTAINER (dialog), GTK_WIDGET (gtk_builder_get_object (builder, "import-dialog"))); gtk_widget_show_all (GTK_WIDGET (dialog)); g_object_unref (builder); }
static void rb_playlist_source_constructed (GObject *object) { GObject *shell_player; RBPlaylistSource *source; RBShell *shell; RhythmDB *db; RhythmDBQueryModel *query_model; GtkBuilder *builder; GSettings *settings; RB_CHAIN_GOBJECT_METHOD (rb_playlist_source_parent_class, constructed, object); source = RB_PLAYLIST_SOURCE (object); g_object_get (source, "shell", &shell, NULL); g_object_get (shell, "db", &db, "shell-player", &shell_player, NULL); rb_playlist_source_set_db (source, db); g_object_unref (db); g_object_unref (shell); /* store playlist settings using the memory backend * this means the settings path doesn't have to be consistent, * it just has to be unique, so the address of the source object works. * for local playlists, we write the settings into the playlist file on disk * to make them persistent. */ g_object_get (source, "settings", &settings, NULL); if (settings == NULL) { char *path; path = g_strdup_printf ("/org/gnome/rhythmbox/playlist/%p/", source); settings = g_settings_new_with_backend_and_path ("org.gnome.rhythmbox.source", playlist_settings_backend, path); g_free (path); g_object_set (source, "settings", settings, NULL); } g_signal_connect (settings, "changed", G_CALLBACK (playlist_settings_changed_cb), source); g_object_unref (settings); builder = rb_builder_load ("playlist-popup.ui", NULL); source->priv->popup = G_MENU (gtk_builder_get_object (builder, "playlist-popup")); rb_application_link_shared_menus (RB_APPLICATION (g_application_get_default ()), source->priv->popup); g_object_ref (source->priv->popup); g_object_unref (builder); source->priv->entries = g_hash_table_new_full (rb_refstring_hash, rb_refstring_equal, (GDestroyNotify)rb_refstring_unref, NULL); source->priv->songs = rb_entry_view_new (source->priv->db, shell_player, TRUE, TRUE); g_object_unref (shell_player); g_signal_connect_object (source->priv->songs, "notify::sort-order", G_CALLBACK (rb_playlist_source_songs_sort_order_changed_cb), source, 0); query_model = rhythmdb_query_model_new_empty (source->priv->db); rb_playlist_source_set_query_model (source, query_model); g_object_unref (query_model); { const char *title = ""; const char *strings[3] = {0}; GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); g_object_set(renderer, "style", PANGO_STYLE_OBLIQUE, "weight", PANGO_WEIGHT_LIGHT, "xalign", 1.0, NULL); gtk_tree_view_column_pack_start (column, renderer, TRUE); gtk_tree_view_column_set_resizable (column, TRUE); gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_FIXED); strings[0] = title; strings[1] = "9999"; rb_entry_view_set_fixed_column_width (source->priv->songs, column, renderer, strings); gtk_tree_view_column_set_cell_data_func (column, renderer, (GtkTreeCellDataFunc) rb_playlist_source_track_cell_data_func, source, NULL); rb_entry_view_insert_column_custom (source->priv->songs, column, title, "PlaylistTrack", NULL, 0, NULL, 0); } rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TRACK_NUMBER, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_TITLE, TRUE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_GENRE, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ARTIST, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMPOSER, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_ALBUM, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_YEAR, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_DURATION, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_QUALITY, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_RATING, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_PLAY_COUNT, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_COMMENT, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_LOCATION, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_LAST_PLAYED, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_FIRST_SEEN, FALSE); rb_entry_view_append_column (source->priv->songs, RB_ENTRY_VIEW_COL_BPM, FALSE); rb_entry_view_set_columns_clickable (source->priv->songs, FALSE); rb_playlist_source_setup_entry_view (source, source->priv->songs); gtk_container_add (GTK_CONTAINER (source), GTK_WIDGET (source->priv->songs)); gtk_widget_show_all (GTK_WIDGET (source)); }
int main (int argc, char **argv) { RhythmDB *db; RhythmDBEntry *entry, *entry2, *entry3, *entry4; GtkTreeModel *main_model; GtkTreeIter iter; guint testnum = 1; query_func qfunc; gtk_init (&argc, &argv); gdk_threads_init (); rb_thread_helpers_init (); rb_debug_init (TRUE); GDK_THREADS_ENTER (); qfunc = rhythmdb_do_full_query; begin: db = rhythmdb_tree_new ("test"); /* * TEST 1: Entry creation with album */ g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); entry = create_entry (db, "file:///sin.mp3", "Sin", "Pretty Hate Machine", "Nine Inch Nails", "Rock"); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 2: Do a query for all songs, verify our single song is in it */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); qfunc (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, RHYTHMDB_ENTRY_TYPE_IGNORE, RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 3: Do a query for songs named "Sin" */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 4: Do a query for songs named "Cow", should be empty */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Cow", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (!gtk_tree_model_get_iter_first (main_model, &iter)); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 5 * Do a query for songs named "Cow" and "Sin", should be empty. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Cow", RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (!gtk_tree_model_get_iter_first (main_model, &iter)); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 6 * Do a query for songs named "Cow" or "Sin", should have our song. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Cow", RHYTHMDB_QUERY_DISJUNCTION, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 7 * Do a query for songs with Genre "Rock", should have our song. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, "Rock", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 8 * Do a query for songs with Genre "Nine Inch Nails", * should be empty. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, "Nine Inch Nails", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (!gtk_tree_model_get_iter_first (main_model, &iter)); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 9 * Do a query for songs with album "Pretty Hate Machine", * should have our song. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ALBUM, "Pretty Hate Machine", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; /* * TEST 10 * Do a query for songs with artist "Nine Inch Nails", * should have our song. */ g_print ("Test %d\n", testnum); rhythmdb_read_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ARTIST, "Nine Inch Nails", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); /* We should only have one entry. */ g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); DESTROY_MODELS (); rhythmdb_read_unlock (db); g_print ("Test %d\n", testnum); testnum++; g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); entry2 = create_entry (db, "file:///head like a hole.mp3", "Head Like A Hole", "Pretty Hate Machine", "Nine Inch Nails", "Rock"); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ARTIST, "Nine Inch Nails", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); VERIFY_MAIN_MODEL (entry2); DESTROY_MODELS (); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); testnum++; g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_ALBUM, "Pretty Hate Machine", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); VERIFY_MAIN_MODEL (entry2); DESTROY_MODELS (); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); testnum++; g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, "Rock", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); VERIFY_MAIN_MODEL (entry2); DESTROY_MODELS (); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); entry3 = create_entry (db, "file:///angel.ogg", "Angel", "Mezzanine", "Massive Attack", "Electronica"); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, "Electronica", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Mezzanine", "Massive Attack", "Electronica"); VERIFY_MAIN_MODEL (entry3); DESTROY_MODELS (); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); testnum++; g_print ("Test %d\n", testnum); rhythmdb_write_lock (db); entry4 = create_entry (db, "file:///killa bees.ogg", "Killa Bees", "Armageddon", "Usual Suspects", "Drum N' Bass"); main_model = GTK_TREE_MODEL (rhythmdb_query_model_new_empty (db)); rhythmdb_do_full_query (db, main_model, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Angel", RHYTHMDB_QUERY_DISJUNCTION, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Sin", RHYTHMDB_QUERY_DISJUNCTION, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Head Like A Hole", RHYTHMDB_QUERY_DISJUNCTION, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TITLE, "Killa Bees", RHYTHMDB_QUERY_END); wait_for_model_completion (RHYTHMDB_QUERY_MODEL (main_model)); g_assert (gtk_tree_model_get_iter_first (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (gtk_tree_model_iter_next (main_model, &iter)); g_assert (!gtk_tree_model_iter_next (main_model, &iter)); VERIFY_META_MODELS ("Mezzanine", "Massive Attack", "Electronica"); VERIFY_META_MODELS ("Armageddon", "Usual Suspects", "Drum N' Bass"); VERIFY_META_MODELS ("Pretty Hate Machine", "Nine Inch Nails", "Rock"); VERIFY_MAIN_MODEL (entry); VERIFY_MAIN_MODEL (entry2); VERIFY_MAIN_MODEL (entry3); VERIFY_MAIN_MODEL (entry4); DESTROY_MODELS (); rhythmdb_write_unlock (db); g_print ("Test %d\n", testnum); testnum++; if (qfunc == rhythmdb_do_full_query) { rhythmdb_shutdown (db); g_object_unref (G_OBJECT (db)); qfunc = rhythmdb_do_full_query_async; goto begin; } /* * THE END */ rhythmdb_shutdown (db); g_object_unref (G_OBJECT (db)); GDK_THREADS_LEAVE (); exit (0); }
static void rb_iradio_source_do_query (RBIRadioSource *source) { RhythmDBQueryModel *genre_query_model = NULL; RhythmDBQueryModel *station_query_model = NULL; RhythmDBPropertyModel *genre_model; GPtrArray *query; RhythmDBEntryType *entry_type; /* don't update the selection while we're rebuilding the query */ source->priv->setting_new_query = TRUE; /* construct and run the query for the search box. * this is used as the model for the genre view. */ g_object_get (source, "entry-type", &entry_type, NULL); query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_TYPE, entry_type, RHYTHMDB_QUERY_END); g_object_unref (entry_type); if (source->priv->search_query != NULL) { rhythmdb_query_append (source->priv->db, query, RHYTHMDB_QUERY_SUBQUERY, source->priv->search_query, RHYTHMDB_QUERY_END); } genre_model = rb_property_view_get_model (source->priv->genres); genre_query_model = rhythmdb_query_model_new_empty (source->priv->db); g_object_set (genre_model, "query-model", genre_query_model, NULL); rhythmdb_do_full_query_parsed (source->priv->db, RHYTHMDB_QUERY_RESULTS (genre_query_model), query); rhythmdb_query_free (query); query = NULL; /* check the selected genre is still available, and if not, select 'all' */ if (source->priv->selected_genre != NULL) { GList *sel = NULL; if (!rhythmdb_property_model_iter_from_string (genre_model, source->priv->selected_genre, NULL)) { g_free (source->priv->selected_genre); source->priv->selected_genre = NULL; } sel = g_list_prepend (sel, source->priv->selected_genre); rb_property_view_set_selection (source->priv->genres, sel); g_list_free (sel); } /* if a genre is selected, construct a new query for it, and create * a new model based on the search box query model. otherwise, just * reuse the search box query model. */ if (source->priv->selected_genre != NULL) { rb_debug ("matching on genre \"%s\"", source->priv->selected_genre); station_query_model = rhythmdb_query_model_new_empty (source->priv->db); query = rhythmdb_query_parse (source->priv->db, RHYTHMDB_QUERY_PROP_EQUALS, RHYTHMDB_PROP_GENRE, source->priv->selected_genre, RHYTHMDB_QUERY_END); g_object_set (station_query_model, "query", query, "base-model", genre_query_model, NULL); rhythmdb_query_free (query); query = NULL; } else { station_query_model = g_object_ref (genre_query_model); } rb_entry_view_set_model (source->priv->stations, station_query_model); g_object_set (source, "query-model", station_query_model, NULL); g_object_unref (genre_query_model); g_object_unref (station_query_model); source->priv->setting_new_query = FALSE; }