Created
March 5, 2012 15:33
-
-
Save musically-ut/1978836 to your computer and use it in GitHub Desktop.
Rhythmbox patch for Ratings in notification.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 15b12ffc5b4b22ab104cf796e7173db4eeaefe90 Mon Sep 17 00:00:00 2001 | |
From: Utkarsh Upadhyay <musically.ut@gmail.com> | |
Date: Fri, 2 Mar 2012 11:56:32 +0530 | |
Subject: [PATCH] Notification rating plugin. | |
--- | |
data/org.gnome.rhythmbox.gschema.xml | 10 + | |
plugins/notification/Makefile.am | 6 + | |
plugins/notification/notification-preferences.ui | 28 +++ | |
plugins/notification/rb-notification-plugin.c | 243 ++++++++++++++++++++- | |
4 files changed, 275 insertions(+), 12 deletions(-) | |
create mode 100644 plugins/notification/notification-preferences.ui | |
diff --git a/data/org.gnome.rhythmbox.gschema.xml b/data/org.gnome.rhythmbox.gschema.xml | |
index 4d6458c..457daa5 100644 | |
--- a/data/org.gnome.rhythmbox.gschema.xml | |
+++ b/data/org.gnome.rhythmbox.gschema.xml | |
@@ -268,6 +268,16 @@ | |
<child name='source' schema='org.gnome.rhythmbox.source'/> | |
</schema> | |
+ <schema id="org.gnome.rhythmbox.plugins.notifications"> | |
+ <key name="ratings" type="b"> | |
+ <default>true</default> | |
+ <summary>Whether to show ratings button in notifications.</summary> | |
+ <description> | |
+ If true, the buttons to increase/decrease ratings will be displayed in the notifications. | |
+ </description> | |
+ </key> | |
+ </schema> | |
+ | |
<schema id="org.gnome.rhythmbox.plugins.audioscrobbler.service"> | |
<key name="enabled" type="b"> | |
<default>true</default> | |
diff --git a/plugins/notification/Makefile.am b/plugins/notification/Makefile.am | |
index f6c3db1..c027af5 100644 | |
--- a/plugins/notification/Makefile.am | |
+++ b/plugins/notification/Makefile.am | |
@@ -1,6 +1,7 @@ | |
NULL = | |
plugindir = $(PLUGINDIR)/notification | |
+plugindatadir = $(PLUGINDATADIR)/notification | |
plugin_LTLIBRARIES = libnotification.la | |
libnotification_la_SOURCES = \ | |
@@ -33,6 +34,10 @@ INCLUDES = \ | |
$(NOTIFY_CFLAGS) \ | |
-D_BSD_SOURCE | |
+gtkbuilderdir = $(plugindatadir) | |
+gtkbuilder_DATA = \ | |
+ notification-preferences.ui | |
+ | |
plugin_in_files = notification.plugin.in | |
%.plugin: %.plugin.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*po) ; $(INTLTOOL_MERGE) $(top_srcdir)/po $< $@ -d -u -c $(top_builddir)/po/.intltool-merge-cache | |
@@ -47,6 +52,7 @@ plugin_DATA = \ | |
EXTRA_DIST = \ | |
$(plugin_in_files) \ | |
+ $(gtkbuilder_DATA) \ | |
$(NULL) | |
CLEANFILES = \ | |
diff --git a/plugins/notification/notification-preferences.ui b/plugins/notification/notification-preferences.ui | |
new file mode 100644 | |
index 0000000..a0949c0 | |
--- /dev/null | |
+++ b/plugins/notification/notification-preferences.ui | |
@@ -0,0 +1,28 @@ | |
+<?xml version="1.0"?> | |
+<interface> | |
+ <requires lib="gtk+" version="2.16"/> | |
+ <!-- interface-naming-policy project-wide --> | |
+ <object class="GtkVBox" id="config"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">False</property> | |
+ <property name="valign">start</property> | |
+ <property name="orientation">vertical</property> | |
+ <child> | |
+ <object class="GtkCheckButton" id="rating_buttons_enabled_check"> | |
+ <property name="label" translatable="yes">Show rating buttons</property> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">True</property> | |
+ <property name="receives_default">False</property> | |
+ <property name="use_action_appearance">False</property> | |
+ <property name="xalign">0</property> | |
+ <property name="active">True</property> | |
+ <property name="draw_indicator">True</property> | |
+ </object> | |
+ <packing> | |
+ <property name="expand">False</property> | |
+ <property name="fill">True</property> | |
+ <property name="position">0</property> | |
+ </packing> | |
+ </child> | |
+ </object> | |
+</interface> | |
diff --git a/plugins/notification/rb-notification-plugin.c b/plugins/notification/rb-notification-plugin.c | |
index 0671b3d..ae8a14f 100644 | |
--- a/plugins/notification/rb-notification-plugin.c | |
+++ b/plugins/notification/rb-notification-plugin.c | |
@@ -28,6 +28,12 @@ | |
#include <config.h> | |
+#include <libpeas-gtk/peas-gtk.h> | |
+ | |
+#include <lib/rb-builder-helpers.h> | |
+#include <lib/rb-file-helpers.h> | |
+#include <plugins/rb-plugin-macros.h> | |
+ | |
#include <string.h> | |
#include <glib/gi18n-lib.h> | |
#include <gtk/gtk.h> | |
@@ -53,19 +59,30 @@ | |
#define RB_IS_NOTIFICATION_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), RB_TYPE_NOTIFICATION_PLUGIN)) | |
#define RB_NOTIFICATION_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), RB_TYPE_NOTIFICATION_PLUGIN, RBNotificationPluginClass)) | |
+#define NOTIFICATION_SETTINGS_SCHEMA "org.gnome.rhythmbox.plugins.notifications" | |
+#define NOTIFICATION_SETTINGS_PATH "/org/gnome/rhythmbox/plugins/notifications" | |
+#define NOTIFICATION_RATING_ENABLED_KEY "ratings" | |
+ | |
typedef struct | |
{ | |
PeasExtensionBase parent; | |
+ GtkWidget *config_dialog; | |
+ | |
/* current playing data */ | |
char *current_title; | |
- char *current_album_and_artist; /* from _album_ by _artist_ */ | |
+ char *current_album_artist_rating; /* from _album_ by _artist_ rated _rating_ */ | |
+ gdouble rating; | |
gchar *notify_art_path; | |
NotifyNotification *notification; | |
gboolean notify_supports_actions; | |
gboolean notify_supports_icon_buttons; | |
gboolean notify_supports_persistence; | |
+ gboolean rating_buttons_enabled; | |
+ | |
+ GtkWidget *rating_buttons_enabled_check; | |
+ GSettings *notification_settings; | |
RBShellPlayer *shell_player; | |
RhythmDB *db; | |
@@ -79,7 +96,14 @@ typedef struct | |
G_MODULE_EXPORT void peas_register_types (PeasObjectModule *module); | |
-RB_DEFINE_PLUGIN(RB_TYPE_NOTIFICATION_PLUGIN, RBNotificationPlugin, rb_notification_plugin,) | |
+static GtkWidget *impl_create_configure_widget (PeasGtkConfigurable *bplugin); | |
+static void peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface); | |
+ | |
+RB_DEFINE_PLUGIN(RB_TYPE_NOTIFICATION_PLUGIN, | |
+ RBNotificationPlugin, | |
+ rb_notification_plugin, | |
+ (G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_GTK_TYPE_CONFIGURABLE, | |
+ peas_gtk_configurable_iface_init))) | |
static gchar * | |
markup_escape (const char *text) | |
@@ -113,6 +137,90 @@ notification_playpause_cb (NotifyNotification *notification, | |
} | |
static void | |
+notification_ratedown_cb (NotifyNotification *notification, | |
+ const char *action, | |
+ RBNotificationPlugin *plugin) | |
+{ | |
+ rb_debug ("notification action: %s", action); | |
+ | |
+ RhythmDBEntry *playing; | |
+ | |
+ playing = rb_shell_player_get_playing_entry (plugin->shell_player); | |
+ if (playing == NULL) { | |
+ rb_debug ("no song is playing!"); | |
+ return; | |
+ } | |
+ | |
+ gdouble rating = rhythmdb_entry_get_double (playing, RHYTHMDB_PROP_RATING); | |
+ | |
+ /* To keep with the increase button, we'll start from rating = 2 */ | |
+ if (rating == 0) { | |
+ rating = 2; | |
+ } else { | |
+ rating--; | |
+ } | |
+ | |
+ if (rating < 1) { | |
+ rating = 1; | |
+ } | |
+ | |
+ rb_debug ("new rating: %lf", rating); | |
+ | |
+ GValue value = { 0, }; | |
+ | |
+ g_value_init (&value, G_TYPE_DOUBLE); | |
+ g_value_set_double (&value, rating); | |
+ rhythmdb_entry_set (plugin->db, playing, RHYTHMDB_PROP_RATING, &value); | |
+ g_value_unset (&value); | |
+ | |
+ rhythmdb_commit (plugin->db); | |
+ | |
+ rhythmdb_entry_unref (playing); | |
+} | |
+ | |
+static void | |
+notification_rateup_cb (NotifyNotification *notification, | |
+ const char *action, | |
+ RBNotificationPlugin *plugin) | |
+{ | |
+ rb_debug ("notification action: %s", action); | |
+ | |
+ RhythmDBEntry *playing; | |
+ | |
+ playing = rb_shell_player_get_playing_entry (plugin->shell_player); | |
+ if (playing == NULL) { | |
+ rb_debug ("no song is playing!"); | |
+ return; | |
+ } | |
+ | |
+ gdouble rating = rhythmdb_entry_get_double (playing, RHYTHMDB_PROP_RATING); | |
+ | |
+ /* pushing the increase button 5 times is un-cool, so we'll start from rating = 4 */ | |
+ if (rating == 0) { | |
+ rating = 4; | |
+ } else { | |
+ rating++; | |
+ } | |
+ | |
+ if (rating > 5) { | |
+ rating = 5; | |
+ } | |
+ | |
+ rb_debug ("new rating: %lf", rating); | |
+ | |
+ GValue value = { 0, }; | |
+ | |
+ g_value_init (&value, G_TYPE_DOUBLE); | |
+ g_value_set_double (&value, rating); | |
+ rhythmdb_entry_set (plugin->db, playing, RHYTHMDB_PROP_RATING, &value); | |
+ g_value_unset (&value); | |
+ | |
+ rhythmdb_commit (plugin->db); | |
+ | |
+ rhythmdb_entry_unref (playing); | |
+} | |
+ | |
+static void | |
notification_previous_cb (NotifyNotification *notification, | |
const char *action, | |
RBNotificationPlugin *plugin) | |
@@ -122,6 +230,57 @@ notification_previous_cb (NotifyNotification *notification, | |
} | |
static void | |
+notification_settings_changed_cb (GSettings *settings, | |
+ const char *key, | |
+ RBNotificationPlugin *plugin) { | |
+ | |
+ rb_debug ("notification setting changed for key: %s", key); | |
+ if (g_strcmp0 (key, NOTIFICATION_RATING_ENABLED_KEY) != 0) { | |
+ return; | |
+ } | |
+ | |
+ plugin->rating_buttons_enabled = g_settings_get_boolean (settings, key); | |
+ rb_debug ("ratings buttons are now: %s", | |
+ plugin->rating_buttons_enabled ? "enabled" : "disabled"); | |
+} | |
+ | |
+static GtkWidget * | |
+impl_create_configure_widget (PeasGtkConfigurable *bplugin) | |
+{ | |
+ RBNotificationPlugin *plugin; | |
+ char *builderfile; | |
+ GtkBuilder *builder; | |
+ GtkWidget *widget; | |
+ | |
+ rb_debug("initializing configuration widget"); | |
+ plugin = RB_NOTIFICATION_PLUGIN (bplugin); | |
+ | |
+ builderfile = rb_find_plugin_data_file (G_OBJECT (plugin), "notification-preferences.ui"); | |
+ if (builderfile == NULL) { | |
+ g_warning ("can't find notification-preferences.ui"); | |
+ return NULL; | |
+ } | |
+ | |
+ builder = rb_builder_load (builderfile, plugin); | |
+ g_free (builderfile); | |
+ | |
+ widget = GTK_WIDGET (gtk_builder_get_object (builder, "config")); | |
+ g_object_ref_sink (widget); | |
+ | |
+ plugin->rating_buttons_enabled_check = GTK_WIDGET (gtk_builder_get_object (builder, "rating_buttons_enabled_check")); | |
+ g_settings_bind (plugin->notification_settings, NOTIFICATION_RATING_ENABLED_KEY, plugin->rating_buttons_enabled_check, "active", G_SETTINGS_BIND_DEFAULT); | |
+ g_object_unref (builder); | |
+ return widget; | |
+} | |
+ | |
+static void | |
+peas_gtk_configurable_iface_init (PeasGtkConfigurableInterface *iface) | |
+{ | |
+ rb_debug("setting initializer function"); | |
+ iface->create_configure_widget = impl_create_configure_widget; | |
+} | |
+ | |
+static void | |
do_notify (RBNotificationPlugin *plugin, | |
guint timeout, | |
const char *primary, | |
@@ -217,6 +376,23 @@ do_notify (RBNotificationPlugin *plugin, | |
(NotifyActionCallback) notification_playpause_cb, | |
plugin, | |
NULL); | |
+ | |
+ if (plugin->rating_buttons_enabled) { | |
+ notify_notification_add_action (notification, | |
+ "go-down", | |
+ _("Rating Down"), | |
+ (NotifyActionCallback) notification_ratedown_cb, | |
+ plugin, | |
+ NULL); | |
+ notify_notification_add_action (notification, | |
+ "go-up", | |
+ _("Rating Up"), | |
+ (NotifyActionCallback) notification_rateup_cb, | |
+ plugin, | |
+ NULL); | |
+ | |
+ } | |
+ | |
notify_notification_set_hint (notification, "action-icons", g_variant_new_boolean (TRUE)); | |
} | |
@@ -251,7 +427,7 @@ notify_playing_entry (RBNotificationPlugin *plugin, gboolean requested) | |
do_notify (plugin, | |
PLAYING_ENTRY_NOTIFY_TIME * 1000, | |
plugin->current_title, | |
- plugin->current_album_and_artist, | |
+ plugin->current_album_artist_rating, | |
plugin->notify_art_path, | |
TRUE); | |
} | |
@@ -300,8 +476,10 @@ shell_notify_custom_cb (RBShell *shell, | |
static void | |
get_artist_album_templates (const char *artist, | |
const char *album, | |
+ const char *rating, | |
const char **artist_template, | |
- const char **album_template) | |
+ const char **album_template, | |
+ const char **rating_template) | |
{ | |
PangoDirection tag_dir; | |
PangoDirection template_dir; | |
@@ -310,6 +488,8 @@ get_artist_album_templates (const char *artist, | |
*artist_template = _("by <i>%s</i>"); | |
/* Translators: from Album */ | |
*album_template = _("from <i>%s</i>"); | |
+ /* Translators: rated Rating*/ | |
+ *rating_template = _("rated <i>%s</i>"); | |
/* find the direction (left-to-right or right-to-left) of the | |
* track's tags and the localized templates | |
@@ -320,6 +500,9 @@ get_artist_album_templates (const char *artist, | |
} else if (album != NULL && album[0] != '\0') { | |
tag_dir = pango_find_base_dir (album, -1); | |
template_dir = pango_find_base_dir (*album_template, -1); | |
+ } else if (rating != 0) { | |
+ tag_dir = pango_find_base_dir (rating, -1); | |
+ template_dir = pango_find_base_dir (*rating_template, -1); | |
} else { | |
return; | |
} | |
@@ -338,6 +521,7 @@ get_artist_album_templates (const char *artist, | |
*/ | |
*artist_template = "<i>%s</i>"; | |
*album_template = "/ <i>%s</i>"; | |
+ *rating_template = "/ (<i>%s</i>)"; | |
} | |
} | |
@@ -373,26 +557,30 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry) | |
char *artist = NULL; | |
char *album = NULL; | |
char *title = NULL; | |
+ char rating_str[10]; | |
+ gdouble rating; | |
GString *secondary; | |
RBExtDBKey *key; | |
const char *artist_template = NULL; | |
const char *album_template = NULL; | |
+ const char *rating_template = NULL; | |
g_free (plugin->current_title); | |
- g_free (plugin->current_album_and_artist); | |
+ g_free (plugin->current_album_artist_rating); | |
g_free (plugin->notify_art_path); | |
plugin->current_title = NULL; | |
- plugin->current_album_and_artist = NULL; | |
+ plugin->current_album_artist_rating = NULL; | |
+ plugin->rating = 0; | |
plugin->notify_art_path = NULL; | |
if (entry == NULL) { | |
plugin->current_title = g_strdup (_("Not Playing")); | |
- plugin->current_album_and_artist = g_strdup (""); | |
+ plugin->current_album_artist_rating = g_strdup (""); | |
return; | |
} | |
- secondary = g_string_sized_new (100); | |
+ secondary = g_string_sized_new (150); | |
/* request album art */ | |
key = rhythmdb_entry_create_ext_db_key (entry, RHYTHMDB_PROP_ALBUM); | |
@@ -427,7 +615,11 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry) | |
album = markup_escape (rhythmdb_entry_get_string (entry, RHYTHMDB_PROP_ALBUM)); | |
} | |
- get_artist_album_templates (artist, album, &artist_template, &album_template); | |
+ /* get ratings */ | |
+ rating = rhythmdb_entry_get_double (entry, RHYTHMDB_PROP_RATING); | |
+ sprintf (rating_str, "%d", (int) rating); | |
+ | |
+ get_artist_album_templates (artist, album, rating_str, &artist_template, &album_template, &rating_template); | |
if (artist != NULL && artist[0] != '\0') { | |
g_string_append_printf (secondary, artist_template, artist); | |
@@ -442,6 +634,14 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry) | |
} | |
g_free (album); | |
+ if (rating != 0) { | |
+ if (secondary->len != 0) | |
+ g_string_append_c (secondary, ' '); | |
+ | |
+ g_string_append_printf (secondary, rating_template, rating_str); | |
+ } | |
+ | |
+ | |
/* get title and possibly stream name. | |
* if we have a streaming song title, the entry's title | |
* property is the stream name. | |
@@ -475,8 +675,9 @@ update_current_playing_data (RBNotificationPlugin *plugin, RhythmDBEntry *entry) | |
title = g_strdup (_("Unknown")); | |
} | |
+ plugin->rating = rating; | |
plugin->current_title = title; | |
- plugin->current_album_and_artist = g_string_free (secondary, FALSE); | |
+ plugin->current_album_artist_rating = g_string_free (secondary, FALSE); | |
} | |
static void | |
@@ -547,6 +748,12 @@ impl_activate (PeasActivatable *bplugin) | |
G_CALLBACK (db_stream_metadata_cb), plugin, 0); | |
g_signal_connect_object (plugin->db, "entry_extra_metadata_notify::" RHYTHMDB_PROP_STREAM_SONG_ALBUM, | |
G_CALLBACK (db_stream_metadata_cb), plugin, 0); | |
+ g_signal_connect_object (plugin->notification_settings, | |
+ "changed", | |
+ G_CALLBACK (notification_settings_changed_cb), | |
+ plugin, 0); | |
+ | |
+ notification_settings_changed_cb (plugin->notification_settings, NOTIFICATION_RATING_ENABLED_KEY, plugin); | |
plugin->art_store = rb_ext_db_new ("album-art"); | |
@@ -563,6 +770,11 @@ impl_deactivate (PeasActivatable *bplugin) | |
plugin = RB_NOTIFICATION_PLUGIN (bplugin); | |
+ if (plugin->notification_settings != NULL) { | |
+ g_object_unref (plugin->notification_settings); | |
+ plugin->notification_settings = NULL; | |
+ } | |
+ | |
g_object_get (plugin, "object", &shell, NULL); | |
cleanup_notification (plugin); | |
@@ -590,10 +802,10 @@ impl_deactivate (PeasActivatable *bplugin) | |
/* forget what's playing */ | |
g_free (plugin->current_title); | |
- g_free (plugin->current_album_and_artist); | |
+ g_free (plugin->current_album_artist_rating); | |
g_free (plugin->notify_art_path); | |
plugin->current_title = NULL; | |
- plugin->current_album_and_artist = NULL; | |
+ plugin->current_album_artist_rating = NULL; | |
plugin->notify_art_path = NULL; | |
g_object_unref (shell); | |
@@ -602,6 +814,10 @@ impl_deactivate (PeasActivatable *bplugin) | |
static void | |
rb_notification_plugin_init (RBNotificationPlugin *plugin) | |
{ | |
+ rb_debug("RBNotificationPlugin initialising"); | |
+ | |
+ plugin->notification_settings = g_settings_new_with_path (NOTIFICATION_SETTINGS_SCHEMA, | |
+ NOTIFICATION_SETTINGS_PATH "/Ratings"); | |
} | |
G_MODULE_EXPORT void | |
@@ -611,4 +827,7 @@ peas_register_types (PeasObjectModule *module) | |
peas_object_module_register_extension_type (module, | |
PEAS_TYPE_ACTIVATABLE, | |
RB_TYPE_NOTIFICATION_PLUGIN); | |
+ peas_object_module_register_extension_type (module, | |
+ PEAS_GTK_TYPE_CONFIGURABLE, | |
+ RB_TYPE_NOTIFICATION_PLUGIN); | |
} | |
-- | |
1.7.7.6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment