static void mex_view_model_set_model (MexViewModel *self, MexModel *model) { MexViewModelPrivate *priv = self->priv; if (model == priv->model) return; if (model) { MexContent *content; GController *controller; gint i = 0; priv->model = g_object_ref_sink (model); controller = mex_model_get_controller (model); g_signal_connect (controller, "changed", G_CALLBACK (mex_view_model_controller_changed_cb), self); /* copy initial items across */ g_ptr_array_set_size (priv->internal_items, mex_model_get_length (priv->model)); while ((content = mex_model_get_content (priv->model, i))) priv->internal_items->pdata[i++] = content; } mex_view_model_refresh_external_items (self); }
void mex_aggregate_model_remove_model (MexAggregateModel *aggregate, MexModel *model) { GList *link; GController *controller; MexAggregateModelPrivate *priv; g_return_if_fail (MEX_IS_AGGREGATE_MODEL (aggregate)); g_return_if_fail (MEX_IS_MODEL (model)); priv = aggregate->priv; if (!(link = g_list_find (priv->models, model))) return; controller = mex_model_get_controller (model); /* Remove items */ mex_aggregate_model_clear_model (aggregate, model); /* Disconnect from signal */ g_signal_handlers_disconnect_by_func (controller, mex_aggregate_model_controller_changed_cb, aggregate); /* Remove model from list and remove custom data */ g_hash_table_remove (priv->controller_to_model, controller); priv->models = g_list_delete_link (priv->models, link); /* Emit removed signal */ g_signal_emit (aggregate, signals[MODEL_REMOVED], 0, model); /* Unref model */ g_object_unref (model); }
static void mex_view_model_dispose (GObject *object) { MexViewModelPrivate *priv = VIEW_MODEL_PRIVATE (object); if (priv->model) { g_signal_handlers_disconnect_by_func (mex_model_get_controller (priv->model), mex_view_model_controller_changed_cb, object); g_object_unref (priv->model); priv->model = NULL; } if (priv->start_content) { g_object_unref (priv->start_content); priv->start_content = NULL; } if (priv->controller) { g_object_unref (priv->controller); priv->controller = NULL; } G_OBJECT_CLASS (mex_view_model_parent_class)->dispose (object); }
/** * mex_column_set_model: * * Set the current model. */ void mex_column_set_model (MexColumn *column, MexModel *model) { MexColumnPrivate *priv; GController *controller; g_return_if_fail (MEX_IS_COLUMN (column)); g_return_if_fail (model == NULL || MEX_IS_MODEL (model)); priv = column->priv; if (priv->model) { /* remove the "changed" signal handler */ controller = mex_model_get_controller (priv->model); g_signal_handlers_disconnect_by_func (controller, mex_column_controller_changed, column); /* clear the column */ mex_column_clear (column); /* remove the model */ g_object_unref (priv->model); } if (model) { priv->model = g_object_ref (model); mex_column_populate (column); controller = mex_model_get_controller (priv->model); g_signal_connect (controller, "changed", G_CALLBACK (mex_column_controller_changed), column); } else priv->model = NULL; }
static void mex_proxy_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { MexProxy *proxy = MEX_PROXY (object); MexProxyPrivate *priv = proxy->priv; MexModel *new_model; switch (property_id) { case PROP_MODEL: new_model = g_value_get_object (value); if (priv->model) { GController *controller = mex_model_get_controller (priv->model); g_signal_handlers_disconnect_by_func (controller, mex_proxy_controller_changed_cb, proxy); g_object_unref (priv->model); } priv->model = new_model; if (new_model) g_object_ref (new_model); if (priv->started) { priv->started = FALSE; mex_proxy_start (proxy); } break; case PROP_TYPE: priv->object_type = g_value_get_gtype (value); break; case PROP_LIMIT: mex_proxy_set_limit (proxy, g_value_get_uint (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } }
static void mex_queue_model_init (MexQueueModel *self) { MexQueueModelPrivate *priv; self->priv = QUEUE_MODEL_PRIVATE (self); priv = self->priv; /* Load before setting up the controller otherwise .. BOOM! */ mex_queue_model_load (self); priv->controller = mex_model_get_controller (MEX_MODEL (self)); g_signal_connect (priv->controller, "changed", (GCallback)_controller_changed_cb, self); g_object_set (self, "title", _("Queue"), NULL); }
void mex_aggregate_model_add_model (MexAggregateModel *aggregate, MexModel *model) { gint i; MexContent *content; GController *controller; MexAggregateModelPrivate *priv; g_return_if_fail (MEX_IS_AGGREGATE_MODEL (aggregate)); g_return_if_fail (MEX_IS_MODEL (model)); priv = aggregate->priv; if (g_list_find (priv->models, model)) return; /* Add a link back to the model from the controller */ controller = mex_model_get_controller (model); g_hash_table_insert (priv->controller_to_model, controller, model); /* Add model to list */ priv->models = g_list_insert_sorted (priv->models, model, (GCompareFunc) mex_aggregate_model_sort_func); /* Add existing items */ i = 0; while ((content = mex_model_get_content (model, i))) { g_hash_table_insert (priv->content_to_model, content, model); mex_model_add_content (MEX_MODEL (aggregate), content); i++; } /* Connect to the controller changed signal */ g_signal_connect (controller, "changed", G_CALLBACK (mex_aggregate_model_controller_changed_cb), aggregate); /* Emit added signal */ g_signal_emit (aggregate, signals[MODEL_ADDED], 0, model); }
void mex_proxy_stop (MexProxy *proxy) { MexProxyPrivate *priv; GController *controller; g_return_if_fail (MEX_IS_PROXY (proxy)); priv = proxy->priv; /* There's nothing to do if there's no model set */ if (!priv->model) { priv->started = FALSE; return; } if (!priv->started) return; controller = mex_model_get_controller (priv->model); g_signal_handlers_disconnect_by_func (controller, mex_proxy_controller_changed_cb, proxy); if (priv->timer_timeout) { g_source_remove (priv->timer_timeout); priv->timer_timeout = 0; } g_queue_foreach (priv->to_add, (GFunc)g_object_unref, NULL); g_queue_clear (priv->to_add); priv->started = FALSE; }
static void mex_search_plugin_search (MexSearchPlugin *self, const gchar *search) { GList *s, *sources; MexSearchPluginPrivate *priv = self->priv; /* Kill the last search */ if (priv->search_model) { g_object_unref (priv->search_model); priv->search_model = NULL; } /* Create search model */ priv->search_model = mex_aggregate_model_new (); g_object_set (G_OBJECT (priv->search_model), "title", "Search results", NULL); /* Iterate over searchable Grilo sources */ sources = grl_plugin_registry_get_sources (grl_plugin_registry_get_default (), FALSE); /* find the local files source and place it first */ for (s = sources; s; s = s->next) { GrlMetadataSource *meta_src = s->data; const gchar *name = grl_metadata_source_get_name (meta_src); if (!GRL_IS_METADATA_SOURCE (meta_src)) continue; if (name && !strcmp (name, "Local files")) { sources = g_list_remove_link (sources, s); sources = g_list_concat (sources, s); break; } } for (s = sources; s; s = s->next) { const gchar *source_id; GrlSupportedOps supported; GrlMetadataSource *meta_src = s->data; if (!GRL_IS_METADATA_SOURCE (meta_src)) continue; /* only search upnp and tracker sources */ source_id = grl_media_plugin_get_id (GRL_MEDIA_PLUGIN (meta_src)); supported = grl_metadata_source_supported_operations (meta_src); if ((supported & GRL_OP_SEARCH) || (supported & GRL_OP_QUERY)) { MexFeed *feed; if (g_str_equal (source_id, "grl-tracker")) feed = mex_grilo_tracker_feed_new (GRL_MEDIA_SOURCE (meta_src), NULL, NULL, NULL, NULL); else feed = mex_grilo_feed_new (GRL_MEDIA_SOURCE (meta_src), NULL, NULL, NULL); g_object_set (G_OBJECT (feed), "placeholder-text", _("No videos found"), NULL); GController *controller = mex_model_get_controller (MEX_MODEL (feed)); /* Attach to the changed signal so that we can alter the * mime-type of content if necessary. */ g_signal_connect (controller, "changed", G_CALLBACK (mex_search_plugin_model_changed_cb), feed); mex_aggregate_model_add_model ( MEX_AGGREGATE_MODEL (priv->search_model), MEX_MODEL (feed)); /* FIXME: Arbitrary 50 item limit... */ mex_grilo_feed_search (MEX_GRILO_FEED (feed), search, 0, 50); } } g_list_free (sources); }
static void mex_search_plugin_search (MexSearchPlugin *self, const gchar *search) { GList *l, *list; MexSearchPluginPrivate *priv = self->priv; MexModelManager *manager = mex_model_manager_get_default (); gboolean have_tracker = FALSE; if (!priv->search_model) { /* Create search model */ priv->search_model = mex_aggregate_model_new (); g_object_set (G_OBJECT (priv->search_model), "title", _("Search results"), NULL); } /* Kill the last search */ list = (GList *) mex_aggregate_model_get_models ( MEX_AGGREGATE_MODEL (priv->search_model)); for (l = list; l; l = l->next) mex_model_manager_remove_model (manager, l->data); mex_aggregate_model_clear (MEX_AGGREGATE_MODEL (priv->search_model)); /* Iterate over searchable Grilo sources */ list = grl_plugin_registry_get_sources (grl_plugin_registry_get_default (), FALSE); /* find the local files source and place it first */ for (l = list; l; l = l->next) { GrlMetadataSource *meta_src = l->data; const gchar *name = grl_metadata_source_get_name (meta_src); const gchar *source_id; if (!GRL_IS_METADATA_SOURCE (meta_src)) continue; source_id = grl_media_plugin_get_id (GRL_MEDIA_PLUGIN (meta_src)); if (source_id && g_str_equal (source_id, "grl-tracker")) have_tracker = TRUE; if (name && !strcmp (name, "Local files")) { list = g_list_remove_link (list, l); list = g_list_concat (list, l); break; } } /* prefer tracker over the filesystem plugin by removing it from the list if * tracker is available */ if (have_tracker) { for (l = list; l; l = l->next) { GrlMetadataSource *meta_src = l->data; const gchar *source_id; if (!GRL_IS_METADATA_SOURCE (meta_src)) continue; source_id = grl_media_plugin_get_id (GRL_MEDIA_PLUGIN (meta_src)); if (source_id && g_str_equal (source_id, "grl-filesystem")) { list = g_list_delete_link (list, l); break; } } } for (l = list; l; l = l->next) { const gchar *source_id; GrlSupportedOps supported; GrlMetadataSource *meta_src = l->data; if (!GRL_IS_METADATA_SOURCE (meta_src)) continue; /* only search upnp and tracker sources */ source_id = grl_media_plugin_get_id (GRL_MEDIA_PLUGIN (meta_src)); supported = grl_metadata_source_supported_operations (meta_src); if ((supported & GRL_OP_SEARCH) || (supported & GRL_OP_QUERY)) { MexFeed *feed; GController *controller; if (g_str_equal (source_id, "grl-tracker")) feed = mex_grilo_tracker_feed_new (GRL_MEDIA_SOURCE (meta_src), NULL, NULL, NULL, NULL); else feed = mex_grilo_feed_new (GRL_MEDIA_SOURCE (meta_src), NULL, NULL, NULL); mex_model_set_sort_func (MEX_MODEL (feed), mex_model_sort_time_cb, GINT_TO_POINTER (TRUE)); g_object_set (G_OBJECT (feed), "category", "search-results", "placeholder-text", _("No videos found"), NULL); mex_model_manager_add_model (manager, MEX_MODEL (feed)); controller = mex_model_get_controller (MEX_MODEL (feed)); /* Attach to the changed signal so that we can alter the * mime-type of content if necessary. */ g_signal_connect (controller, "changed", G_CALLBACK (mex_search_plugin_model_changed_cb), feed); mex_aggregate_model_add_model ( MEX_AGGREGATE_MODEL (priv->search_model), MEX_MODEL (feed)); /* FIXME: Arbitrary 50 item limit... */ mex_grilo_feed_search (MEX_GRILO_FEED (feed), search, 0, 50); g_object_unref (G_OBJECT (feed)); } } g_list_free (list); }
/** * mex_proxy_start_at: * @proxy: Proxy to add content to * @start_at_content: First content item in the model to add to * the proxy * @loop: Whether to loop back to the beginning of the * associated #MexModel's content items once the last item is reached; * if %TRUE, content items before the @start_at_content will be * added once the last of the model's content items is reached; * if %FALSE, only content items from @start_at_content to the last of * the model's content items are added * * Add content from a model to a proxy. */ void mex_proxy_start_at (MexProxy *proxy, MexContent *start_at_content, gboolean loop) { gint i; MexContent *content; MexProxyPrivate *priv; GController *controller; g_return_if_fail (MEX_IS_PROXY (proxy)); priv = proxy->priv; if (priv->started) { g_warning (G_STRLOC ": Trying to start an already started proxy"); return; } mex_proxy_clear (proxy); priv->started = TRUE; if (!priv->model) return; if (!G_TYPE_IS_OBJECT (priv->object_type)) { g_warning (G_STRLOC ": Proxy type is not an object type"); return; } /* Iterate over existing objects */ if (!start_at_content) { i = 0; while ((content = mex_model_get_content (priv->model, i++))) mex_proxy_add_content (proxy, content); } else { gint start_at; gboolean looped = FALSE; start_at = mex_model_index (priv->model, start_at_content); if (start_at == -1) { g_critical (G_STRLOC ": Content %p not found in %p model", start_at_content, priv->model); return; } for (i = start_at; TRUE; i++) { /* break out if looped and back around to start_at */ if (loop && looped && i == start_at) break; if ((content = mex_model_get_content (priv->model, i))) { mex_proxy_add_content (proxy, content); } else { if (loop) { looped = TRUE; i = -1; } else break; } } } controller = mex_model_get_controller (priv->model); g_signal_connect_after (controller, "changed", G_CALLBACK (mex_proxy_controller_changed_cb), proxy); }