grim/guifications3

closing this since just about everything that can be is converted to cmake, and all newer changes will be maintenance
/*
* Guifications - The end-all, be-all notification framework
* Copyright (C) 2003-2009 Gary Kramlich <grim@reaperworld.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "gf_gtk_feeds.h"
#include <glib.h>
#include <gtk/gtk.h>
/******************************************************************************
* Structs
*****************************************************************************/
typedef struct {
GfClientConnection *connection;
GtkWidget *window;
GtkWidget *tree;
GtkTreeStore *store;
} GfGtkFeedsWindow;
/******************************************************************************
* Enums
*****************************************************************************/
enum {
COL_OBJECT,
COL_IMAGE,
COL_NAME,
COL_ENABLED,
COL_STICKY,
COLS
};
/******************************************************************************
* Globals
*****************************************************************************/
static GfGtkFeedsWindow *feeds_window = NULL;
/******************************************************************************
* Callbacks
*****************************************************************************/
static gboolean
gf_gtk_feeds_window_delete_cb(GtkWidget *w, GdkEvent *e, gpointer data) {
gtk_widget_hide(feeds_window->window);
return TRUE;
}
static void
gf_gtk_feeds_window_response_cb(GtkWidget *dialog, gpointer data) {
gtk_widget_hide(feeds_window->window);
}
/******************************************************************************
* Helpers
*****************************************************************************/
static void
feed_add(GfFeed *feed) {
GfEvent **events = NULL;
GfImage *image = NULL;
GdkPixbuf *pixbuf = NULL;
GtkTreeIter iter, child;
GString *str;
gchar *name = NULL;
const gchar *desc;
gint i = 0;
guint nevents = 0;
g_object_ref(feed);
name = gf_feed_get_name(feed);
str = g_string_new("");
g_string_append_printf(str, "<span weight=\"bold\">%s</span>", name);
desc = gf_feed_get_description(feed);
if(desc)
g_string_append_printf(str, "\n%s", desc);
image = gf_feed_get_image(feed);
if(GF_IS_IMAGE(image))
pixbuf = gf_gtk_image_to_pixbuf(image, NULL);
gtk_tree_store_append(feeds_window->store, &iter, NULL);
gtk_tree_store_set(feeds_window->store, &iter,
COL_OBJECT, feed,
COL_IMAGE, pixbuf,
COL_NAME, str->str,
-1);
g_string_free(str, TRUE);
if(GDK_IS_PIXBUF(pixbuf))
g_object_unref(pixbuf);
/* now add all of the events */
events = gf_feed_list_events(feed, &nevents);
if(!events) {
gf_log_info("GfGtkFeeds", "Feed %s does not have any events.\n", name);
return;
}
for(i = 0; events[i]; i++) {
str = g_string_new("");
g_string_append_printf(str, "<span weight=\"bold\">%s</span>",
gf_event_get_i18n(events[i]));
desc = gf_event_get_description(events[i]);
if(desc)
g_string_append_printf(str, "\n%s", desc);
gtk_tree_store_append(feeds_window->store, &child, &iter);
gtk_tree_store_set(feeds_window->store, &child,
COL_OBJECT, events[i],
COL_NAME, str->str,
-1);
g_string_free(str, TRUE);
}
gf_log_info("GfGtkFeeds", "Added feed %s with %d/%u events\n", name, i,
nevents);
}
static void
feeds_add_existing(void) {
GfFeedManager *manager = NULL;
GfFeed **feeds = NULL;
guint nfeeds = 0, i = 0;
const gchar *format = NULL;
manager =
gf_connection_get_feed_manager(GF_CONNECTION(feeds_window->connection));
if(!GF_IS_FEED_MANAGER(manager))
return;
feeds = gf_feed_manager_list_feeds(manager, &nfeeds);
switch(nfeeds) {
case 0:
format = "%d existing feeds were found.\n";
break;
case 1:
format = "Found %d existing feed, adding it...\n";
break;
default:
format = "Found %d existing feeds, adding them...\n";
break;
}
gf_log_info("Feeds", format, nfeeds);
for(i = 0; i < nfeeds && feeds[i]; i++)
feed_add(feeds[i]);
if(feeds)
gf_feed_freev(feeds);
}
static void
build_window() {
GtkWidget *sw, *vbox;
GtkTreeViewColumn *col;
GtkCellRenderer *rend;
/* create the window and connect signals */
feeds_window->window =
gtk_dialog_new_with_buttons(_("Feeds"), NULL, 0,
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
NULL);
gtk_window_set_role(GTK_WINDOW(feeds_window->window),
"GuificationsGtkFeeds");
gtk_window_set_default_size(GTK_WINDOW(feeds_window->window), 320, 240);
g_signal_connect(G_OBJECT(feeds_window->window), "delete-event",
G_CALLBACK(gf_gtk_feeds_window_delete_cb), NULL);
g_signal_connect(feeds_window->window, "response",
G_CALLBACK(gf_gtk_feeds_window_response_cb), NULL);
/* build our main vbox */
vbox = GTK_DIALOG(feeds_window->window)->vbox;
/* now the scrolled window */
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
GTK_SHADOW_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
gtk_widget_show(sw);
/* the tree */
feeds_window->store = gtk_tree_store_new(COLS, G_TYPE_OBJECT,
GDK_TYPE_PIXBUF, G_TYPE_STRING,
G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
feeds_window->tree =
gtk_tree_view_new_with_model(GTK_TREE_MODEL(feeds_window->store));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(feeds_window->tree), FALSE);
gtk_container_add(GTK_CONTAINER(sw), feeds_window->tree);
gtk_widget_show(feeds_window->tree);
/* name column, the image, name, and description */
col = gtk_tree_view_column_new();
rend = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(col, rend, FALSE);
gtk_tree_view_column_set_attributes(col, rend,
"pixbuf", COL_IMAGE,
NULL);
rend = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col, rend, TRUE);
gtk_tree_view_column_set_attributes(col, rend,
"markup", COL_NAME,
NULL);
gtk_tree_view_column_set_title(col, _("Name"));
gtk_tree_view_column_set_expand(col, TRUE);
gtk_tree_view_append_column(GTK_TREE_VIEW(feeds_window->tree), col);
feeds_add_existing();
}
static void
feed_registered(GfFeedManager *manager, GfFeed *feed) {
gf_log_info("GfGTK", "Feed '%s' was registered.\n",
gf_feed_get_name(feed));
feed_add(feed);
}
static void
feed_manager_set_cb(GfConnection *connection, GfFeedManager *manager, gpointer data) {
gtk_tree_store_clear(feeds_window->store);
g_signal_connect(G_OBJECT(manager), "registered-feed",
G_CALLBACK(feed_registered), NULL);
feeds_add_existing();
}
/******************************************************************************
* API
*****************************************************************************/
void
gf_gtk_feeds_init(GfClientConnection *connection) {
if(feeds_window)
return;
feeds_window = g_new0(GfGtkFeedsWindow, 1);
feeds_window->connection = g_object_ref(connection);
g_signal_connect(feeds_window->connection, "feed-manager-set",
G_CALLBACK(feed_manager_set_cb), NULL);
build_window();
}
void
gf_gtk_feeds_uninit(void) {
if(!feeds_window)
return;
if(GTK_IS_WIDGET(feeds_window->window))
gtk_widget_destroy(feeds_window->window);
g_free(feeds_window);
feeds_window = NULL;
}
void
gf_gtk_feeds_show(void) {
if(GTK_IS_WIDGET(feeds_window->window))
gtk_widget_show(feeds_window->window);
}