From adf06453574270bf467b5f37e632c04c153ee90a Mon Sep 17 00:00:00 2001 From: Alan F Date: Mon, 10 Feb 2014 18:53:52 +0000 Subject: RSS viewer now gets feed URLS from the config JSON, and displays the item titles in a treeview. --- src/Makefile.am | 3 +- src/trg-client.c | 34 +++++--- src/trg-client.h | 1 + src/trg-main-window.c | 8 +- src/trg-prefs.c | 6 ++ src/trg-prefs.h | 2 + src/trg-rss-model.c | 215 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/trg-rss-model.h | 63 +++++++++++++++ src/trg-rss-window.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++ src/trg-rss-window.h | 53 +++++++++++++ 10 files changed, 580 insertions(+), 17 deletions(-) create mode 100644 src/trg-rss-model.c create mode 100644 src/trg-rss-model.h create mode 100644 src/trg-rss-window.c create mode 100644 src/trg-rss-window.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 1feb5fb..f82a7f5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -105,7 +105,8 @@ transmission_remote_gtk_SOURCES = \ trg-client.c \ trg-main-window.c \ main.c \ - trg-rss-dialog.c \ + trg-rss-window.c \ + trg-rss-model.c \ $(NULL) transmission_remote_gtk_LDFLAGS = -lm $(jsonglib_LIBS) $(gtk_LIBS) $(gthread_LIBS) $(GEOIP_LIBS) $(gio_LIBS) $(notify_LIBS) $(libproxy_LIBS) $(libcurl_LIBS) $(libappindicator_LIBS) $(rssglib_LIBS) diff --git a/src/trg-client.c b/src/trg-client.c index 3ce5637..6f33b36 100644 --- a/src/trg-client.c +++ b/src/trg-client.c @@ -517,8 +517,6 @@ static CURL* get_curl(TrgClient *tc, guint http_class) TrgPrefs *prefs = trg_client_get_prefs(tc); trg_tls *tls = get_tls(tc); CURL *curl = tls->curl; - struct curl_slist *headers = NULL; - gchar *session_id = NULL; g_mutex_lock(priv->configMutex); @@ -530,6 +528,7 @@ static CURL* get_curl(TrgClient *tc, guint http_class) curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE_NAME); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &http_receive_callback); + //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); if (http_class == HTTP_CLASS_TRANSMISSION) { curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *) tc); @@ -561,12 +560,6 @@ static CURL* get_curl(TrgClient *tc, guint http_class) } if (http_class == HTTP_CLASS_TRANSMISSION) { - session_id = trg_client_get_session_id(tc); - if (session_id) { - headers = curl_slist_append(NULL, session_id); - curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); - } - curl_easy_setopt(curl, CURLOPT_URL, trg_client_get_url(tc)); } @@ -586,6 +579,8 @@ trg_http_perform_inner(TrgClient * tc, gchar * reqstr, { CURL* curl = get_curl(tc, HTTP_CLASS_TRANSMISSION); + struct curl_slist *headers = NULL; + gchar *session_id = NULL; long httpCode = 0; response->size = 0; @@ -594,10 +589,21 @@ trg_http_perform_inner(TrgClient * tc, gchar * reqstr, curl_easy_setopt(curl, CURLOPT_POSTFIELDS, reqstr); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response); + session_id = trg_client_get_session_id(tc); + if (session_id) { + headers = curl_slist_append(NULL, session_id); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + } + response->status = curl_easy_perform(curl); curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); + if (session_id) { + g_free(session_id); + curl_slist_free_all(headers); + } + if (response->status == CURLE_OK) { if (httpCode == HTTP_CONFLICT && recurse == TRUE) return trg_http_perform_inner(tc, reqstr, response, FALSE); @@ -626,7 +632,7 @@ trg_response *dispatch(TrgClient * tc, JsonNode * req) return dispatch_str(tc, serialized); } -trg_response *dispatch_public_http(TrgClient *tc, const gchar *url) { +trg_response *dispatch_public_http(TrgClient *tc, trg_request *req) { trg_response *response = g_new0(trg_response, 1); CURL* curl = get_curl(tc, HTTP_CLASS_PUBLIC); @@ -636,10 +642,14 @@ trg_response *dispatch_public_http(TrgClient *tc, const gchar *url) { response->size = 0; response->raw = NULL; - curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_URL, req->url); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) response); response->status = curl_easy_perform(curl); + g_free(req->url); + req->url = NULL; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &httpCode); if (response->status == CURLE_OK && httpCode != HTTP_OK) { @@ -690,7 +700,7 @@ static void dispatch_async_threadfunc(trg_request * req, TrgClient * tc) if (req->str) rsp = dispatch_str(tc, req->str); else if (req->url) - rsp = dispatch_public_http(tc, req->url); + rsp = dispatch_public_http(tc, req); else rsp = dispatch(tc, req->node); @@ -749,7 +759,7 @@ dispatch_async_str(TrgClient * tc, gchar * req, gboolean async_http_request(TrgClient *tc, gchar *url, GSourceFunc callback, gpointer data) { trg_request *trg_req = g_new0(trg_request, 1); - trg_req->url = url; + trg_req->url = g_strdup(url); return dispatch_async_common(tc, trg_req, callback, data); } diff --git a/src/trg-client.h b/src/trg-client.h index 21833fc..ce98a4e 100644 --- a/src/trg-client.h +++ b/src/trg-client.h @@ -126,6 +126,7 @@ int trg_http_perform(TrgClient * client, gchar * reqstr, /* stuff that used to be in dispatch.c */ trg_response *dispatch(TrgClient * client, JsonNode * req); trg_response *dispatch_str(TrgClient * client, gchar * req); +trg_response *dispatch_public_http(TrgClient *tc, trg_request *req); gboolean dispatch_async(TrgClient * client, JsonNode * req, GSourceFunc callback, gpointer data); gboolean async_http_request(TrgClient *tc, gchar *url, GSourceFunc callback, gpointer data); diff --git a/src/trg-main-window.c b/src/trg-main-window.c index cc72527..f4e479c 100644 --- a/src/trg-main-window.c +++ b/src/trg-main-window.c @@ -73,7 +73,7 @@ #include "trg-menu-bar.h" #include "trg-status-bar.h" #include "trg-stats-dialog.h" -#include "trg-rss-dialog.h" +#include "trg-rss-window.h" #include "trg-remote-prefs-dialog.h" #include "trg-preferences-dialog.h" @@ -931,10 +931,10 @@ static void view_rss_toggled_cb(GtkWidget * w, gpointer data) TrgMainWindowPrivate *priv = win->priv; if (trg_client_is_connected(priv->client)) { - TrgRssDialog *dlg = - trg_rss_dialog_get_instance(TRG_MAIN_WINDOW(data)); + TrgRssWindow *rss = + trg_rss_window_get_instance(TRG_MAIN_WINDOW(data), priv->client); - gtk_widget_show_all(GTK_WIDGET(dlg)); + gtk_widget_show_all(GTK_WIDGET(rss)); } } diff --git a/src/trg-prefs.c b/src/trg-prefs.c index b559479..811c575 100644 --- a/src/trg-prefs.c +++ b/src/trg-prefs.c @@ -421,6 +421,12 @@ JsonArray *trg_prefs_get_profiles(TrgPrefs * p) TRG_PREFS_KEY_PROFILES); } +JsonArray *trg_prefs_get_rss(TrgPrefs *p) { + TrgPrefsPrivate *priv = p->priv; + return json_object_get_array_member(priv->userObj, + TRG_PREFS_KEY_RSS); +} + void trg_prefs_set_double(TrgPrefs * p, const gchar * key, gdouble value, int flags) diff --git a/src/trg-prefs.h b/src/trg-prefs.h index 9dda148..d8afe8f 100644 --- a/src/trg-prefs.h +++ b/src/trg-prefs.h @@ -33,6 +33,7 @@ #define TRG_PREFS_KEY_RPC_URL_PATH "rpc-url-path" #define TRG_PREFS_KEY_PROFILE_ID "profile-id" #define TRG_PREFS_KEY_PROFILES "profiles" +#define TRG_PREFS_KEY_RSS "rss" #define TRG_PREFS_KEY_PROFILE_NAME "profile-name" #define TRG_PREFS_KEY_HOSTNAME "hostname" #define TRG_PREFS_KEY_PORT "port" @@ -139,6 +140,7 @@ gboolean trg_prefs_get_bool(TrgPrefs * p, const gchar * key, int flags); JsonObject *trg_prefs_get_profile(TrgPrefs * p); JsonObject *trg_prefs_get_connection(TrgPrefs * p); JsonArray *trg_prefs_get_profiles(TrgPrefs * p); +JsonArray *trg_prefs_get_rss(TrgPrefs *p); void trg_prefs_set_connection(TrgPrefs * p, JsonObject * profile); gint trg_prefs_get_profile_id(TrgPrefs * p); void trg_prefs_del_profile(TrgPrefs * p, JsonObject * profile); diff --git a/src/trg-rss-model.c b/src/trg-rss-model.c new file mode 100644 index 0000000..bc43ef7 --- /dev/null +++ b/src/trg-rss-model.c @@ -0,0 +1,215 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011-2013 Alan Fitton + + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "config.h" +#include "torrent.h" +#include "trg-client.h" +#include "trg-model.h" +#include "trg-rss-model.h" + +enum { + PROP_0, PROP_CLIENT +}; + +G_DEFINE_TYPE(TrgRssModel, trg_rss_model, GTK_TYPE_LIST_STORE) +#define TRG_RSS_MODEL_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_RSS_MODEL, TrgRssModelPrivate)) +typedef struct _TrgRssModelPrivate TrgRssModelPrivate; + +struct _TrgRssModelPrivate { + TrgClient *client; + GHashTable *table; +}; + +typedef struct { + TrgRssModel *model; + gchar *feed_id; + gchar *feed_url; + gint status; + RssParser *parser; + gboolean success; + GError *error; +} feed_update; + +static void feed_update_free(feed_update *update) { + if (update->error) + g_error_free(update->error); + + g_free(update->feed_id); + g_free(update->feed_url); + + if (update->parser) + g_object_unref(update->parser); + + g_free(update); +} + +static gboolean on_rss_receive_idle(gpointer data) { + feed_update *update = (feed_update*) data; + TrgRssModel *model = update->model; + TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(model); + + if (update->success) { + RssDocument *doc = rss_parser_get_document(update->parser); + GtkTreeIter iter; + GList *list, *tmp; + gchar *title; + + list = rss_document_get_items(doc); + + for (tmp = list; tmp != NULL; tmp = tmp->next) { + RssItem *item = (RssItem*) tmp->data; + const gchar *guid = rss_item_get_guid(item); + if (g_hash_table_lookup(priv->table, guid) != (void*) 1) { + gtk_list_store_append(GTK_LIST_STORE(model), &iter); + gtk_list_store_set(GTK_LIST_STORE(model), &iter, RSSCOL_ID, + guid, RSSCOL_TITLE, rss_item_get_title(item), + RSSCOL_LINK, rss_item_get_link(item), -1); + g_hash_table_insert(priv->table, g_strdup(guid), (void*) 1); + } + } + + g_list_free(list); + g_object_unref(doc); + } + + feed_update_free(update); + + return FALSE; +} + +static gboolean on_rss_receive(gpointer data) { + trg_response *response = (trg_response *) data; + feed_update *update = (feed_update*) response->cb_data; + + update->status = response->status; + + if (response->status == CURLE_OK) { + update->parser = rss_parser_new(); + update->success = rss_parser_load_from_data(update->parser, + response->raw, response->size, &(update->error)); + } + + g_idle_add(on_rss_receive_idle, update); + + trg_response_free(response); + + return FALSE; +} + +void trg_rss_model_update(TrgRssModel * model) { + TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(model); + TrgPrefs *prefs = trg_client_get_prefs(priv->client); + JsonArray *feeds = trg_prefs_get_rss(prefs); + GList *li; + + if (!feeds) + return; + + for (li = json_array_get_elements(feeds); li != NULL; li = g_list_next(li)) { + JsonObject *feed = json_node_get_object((JsonNode *) li->data); + const gchar *url = json_object_get_string_member(feed, "url"); + const gchar *id = json_object_get_string_member(feed, "id"); + + if (!url || !id) + continue; + + feed_update *update = g_new0(feed_update, 1); + update->feed_url = g_strdup(url); + update->feed_id = g_strdup(id); + update->model = model; + + async_http_request(priv->client, update->feed_url, on_rss_receive, + update); + } + + /*trg_model_remove_removed(GTK_LIST_STORE(model), + RSSCOL_UPDATESERIAL, updateSerial);*/ +} + +static void trg_rss_model_set_property(GObject * object, guint prop_id, + const GValue * value, GParamSpec * pspec G_GNUC_UNUSED) { + TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(object); + + switch (prop_id) { + case PROP_CLIENT: + priv->client = g_value_get_pointer(value); + break; + } +} + +static void trg_rss_model_get_property(GObject * object, guint prop_id, + GValue * value, GParamSpec * pspec G_GNUC_UNUSED) { +} + +static GObject *trg_rss_model_constructor(GType type, + guint n_construct_properties, GObjectConstructParam * construct_params) { + GObject *obj = G_OBJECT_CLASS + (trg_rss_model_parent_class)->constructor(type, + n_construct_properties, construct_params); + TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(obj); + + priv->table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + + return obj; +} + +static void trg_rss_model_dispose(GObject * object) +{ + TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(object); + g_hash_table_destroy(priv->table); + G_OBJECT_CLASS(trg_rss_model_parent_class)->dispose(object); +} + +static void trg_rss_model_class_init(TrgRssModelClass * klass) { + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(TrgRssModelPrivate)); + + object_class->set_property = trg_rss_model_set_property; + object_class->get_property = trg_rss_model_get_property; + object_class->constructor = trg_rss_model_constructor; + object_class->dispose = trg_rss_model_dispose; + + g_object_class_install_property(object_class, PROP_CLIENT, + g_param_spec_pointer("client", "client", "client", + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY + | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK + | G_PARAM_STATIC_BLURB)); +} + +static void trg_rss_model_init(TrgRssModel * self) { + //TrgRssModelPrivate *priv = TRG_RSS_MODEL_GET_PRIVATE(self); + GType column_types[RSSCOL_COLUMNS]; + + column_types[RSSCOL_ID] = G_TYPE_STRING; + column_types[RSSCOL_TITLE] = G_TYPE_STRING; + column_types[RSSCOL_LINK] = G_TYPE_STRING; + + gtk_list_store_set_column_types(GTK_LIST_STORE(self), RSSCOL_COLUMNS, + column_types); +} + +TrgRssModel *trg_rss_model_new(TrgClient *client) { + return g_object_new(TRG_TYPE_RSS_MODEL, "client", client, NULL); +} diff --git a/src/trg-rss-model.h b/src/trg-rss-model.h new file mode 100644 index 0000000..9befa48 --- /dev/null +++ b/src/trg-rss-model.h @@ -0,0 +1,63 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011-2013 Alan Fitton + + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TRG_RSS_MODEL_H_ +#define TRG_RSS_MODEL_H_ + +#include +#include + +#include "trg-client.h" +#include "trg-model.h" + +G_BEGIN_DECLS +#define TRG_TYPE_RSS_MODEL trg_rss_model_get_type() +#define TRG_RSS_MODEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_RSS_MODEL, TrgRssModel)) +#define TRG_RSS_MODEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_RSS_MODEL, TrgRssModelClass)) +#define TRG_IS_RSS_MODEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_RSS_MODEL)) +#define TRG_IS_RSS_MODEL_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_RSS_MODEL)) +#define TRG_RSS_MODEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_RSS_MODEL, TrgRssModelClass)) + typedef struct { + GtkListStore parent; +} TrgRssModel; + +typedef struct { + GtkListStoreClass parent_class; +} TrgRssModelClass; + +GType trg_rss_model_get_type(void); + +TrgRssModel *trg_rss_model_new(TrgClient *client); + +G_END_DECLS +void trg_rss_model_update(TrgRssModel * model); + +enum { + RSSCOL_ID, + RSSCOL_TITLE, + RSSCOL_LINK, + RSSCOL_COLUMNS +}; + +#endif /* TRG_RSS_MODEL_H_ */ diff --git a/src/trg-rss-window.c b/src/trg-rss-window.c new file mode 100644 index 0000000..52a096f --- /dev/null +++ b/src/trg-rss-window.c @@ -0,0 +1,212 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011-2013 Alan Fitton + + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include + +#include "trg-rss-window.h" +#include "trg-rss-model.h" +#include "trg-client.h" +#include "util.h" + +G_DEFINE_TYPE(TrgRssWindow, trg_rss_window, + GTK_TYPE_WINDOW) +#define TRG_RSS_WINDOW_GET_PRIVATE(o) \ +(G_TYPE_INSTANCE_GET_PRIVATE ((o), TRG_TYPE_RSS_WINDOW, TrgRssWindowPrivate)) +enum { + PROP_0, PROP_PARENT, PROP_CLIENT +}; + +typedef struct _TrgRssWindowPrivate TrgRssWindowPrivate; + +struct _TrgRssWindowPrivate { + TrgMainWindow *parent; + TrgClient *client; +}; + +static GObject *instance = NULL; + +static void +trg_rss_window_get_property(GObject * object, + guint property_id, + GValue * value, GParamSpec * pspec) +{ + TrgRssWindowPrivate *priv = + TRG_RSS_WINDOW_GET_PRIVATE(object); + switch (property_id) { + case PROP_CLIENT: + g_value_set_pointer(value, priv->client); + break; + case PROP_PARENT: + g_value_set_object(value, priv->parent); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +trg_rss_window_set_property(GObject * object, + guint property_id, + const GValue * value, + GParamSpec * pspec) +{ + TrgRssWindowPrivate *priv = + TRG_RSS_WINDOW_GET_PRIVATE(object); + switch (property_id) { + case PROP_PARENT: + priv->parent = g_value_get_object(value); + break; + case PROP_CLIENT: + priv->client = g_value_get_pointer(value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); + break; + } +} + +static void +trg_rss_window_response_cb(GtkDialog * dlg, gint res_id, + gpointer data G_GNUC_UNUSED) +{ + TrgRssWindowPrivate *priv = + TRG_RSS_WINDOW_GET_PRIVATE(dlg); + + gtk_widget_destroy(GTK_WIDGET(dlg)); + instance = NULL; +} + +static GObject *trg_rss_window_constructor(GType type, + guint + n_construct_properties, + GObjectConstructParam * + construct_params) +{ + GObject *object; + TrgRssWindowPrivate *priv; + TrgRssModel *model; + GtkTreeView *view; + GtkWidget *vbox, *toolbar, *contentbox; + GtkToolItem *item; + + object = G_OBJECT_CLASS + (trg_rss_window_parent_class)->constructor(type, + n_construct_properties, + construct_params); + priv = TRG_RSS_WINDOW_GET_PRIVATE(object); + + model = trg_rss_model_new(priv->client); + trg_rss_model_update(model); + + view = GTK_TREE_VIEW(gtk_tree_view_new()); + gtk_tree_view_set_model(view, GTK_TREE_MODEL(model)); + gtk_tree_view_insert_column_with_attributes(view, -1, "Title", gtk_cell_renderer_text_new(), "text", RSSCOL_TITLE, NULL); + + gtk_window_set_title(GTK_WINDOW(object), _("RSS Viewer")); + + //contentbox = gtk_dialog_get_content_area(GTK_DIALOG(object)); + + toolbar = gtk_toolbar_new(); + + item = gtk_tool_button_new_from_stock(GTK_STOCK_PREFERENCES); + gtk_widget_set_sensitive(GTK_WIDGET(item), TRUE); + gtk_tool_item_set_tooltip_text(item, "Configure"); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), item, 0); + + vbox = trg_vbox_new(FALSE, 0); + + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(toolbar), + FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(view), + TRUE, TRUE, 0); + + gtk_container_add(GTK_CONTAINER(object), vbox); + + /*g_signal_connect(object, "response", + G_CALLBACK(trg_rss_window_response_cb), NULL);*/ + + return object; +} + +static void trg_rss_window_dispose(GObject * object) +{ + instance = NULL; + G_OBJECT_CLASS(trg_rss_window_parent_class)->dispose(object); +} + +static void +trg_rss_window_class_init(TrgRssWindowClass * klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + g_type_class_add_private(klass, sizeof(TrgRssWindowPrivate)); + + object_class->constructor = trg_rss_window_constructor; + object_class->get_property = trg_rss_window_get_property; + object_class->set_property = trg_rss_window_set_property; + object_class->dispose = trg_rss_window_dispose; + + g_object_class_install_property(object_class, + PROP_CLIENT, + g_param_spec_pointer("trg-client", + "TClient", + "Client", + G_PARAM_READWRITE + | + G_PARAM_CONSTRUCT_ONLY + | + G_PARAM_STATIC_NAME + | + G_PARAM_STATIC_NICK + | + G_PARAM_STATIC_BLURB)); + + g_object_class_install_property(object_class, + PROP_PARENT, + g_param_spec_object("parent-window", + "Parent window", + "Parent window", + TRG_TYPE_MAIN_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY + | + G_PARAM_STATIC_NAME + | + G_PARAM_STATIC_NICK + | + G_PARAM_STATIC_BLURB)); +} + +static void +trg_rss_window_init(TrgRssWindow * self G_GNUC_UNUSED) +{ +} + +TrgRssWindow *trg_rss_window_get_instance(TrgMainWindow *parent, TrgClient *client) +{ + if (instance == NULL) { + instance = + g_object_new(TRG_TYPE_RSS_WINDOW, "parent-window", parent, "trg-client", client, NULL); + } + + return TRG_RSS_WINDOW(instance); +} diff --git a/src/trg-rss-window.h b/src/trg-rss-window.h new file mode 100644 index 0000000..c628a6b --- /dev/null +++ b/src/trg-rss-window.h @@ -0,0 +1,53 @@ +/* + * transmission-remote-gtk - A GTK RPC client to Transmission + * Copyright (C) 2011-2013 Alan Fitton + + * 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 2 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, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef TRG_RSS_WINDOW_H_ +#define TRG_RSS_WINDOW_H_ + +#include +#include + +#include "trg-main-window.h" + +G_BEGIN_DECLS +#define TRG_TYPE_RSS_WINDOW trg_rss_window_get_type() +#define TRG_RSS_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRG_TYPE_RSS_WINDOW, TrgRssWindow)) +#define TRG_RSS_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), TRG_TYPE_RSS_WINDOW, TrgRssWindowClass)) +#define TRG_IS_RSS_WINDOW(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRG_TYPE_RSS_WINDOW)) +#define TRG_IS_RSS_WINDOW_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), TRG_TYPE_RSS_WINDOW)) +#define TRG_RSS_WINDOW_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS ((obj), TRG_TYPE_RSS_WINDOW, TrgRssWindowClass)) + typedef struct { + GtkWindow parent; +} TrgRssWindow; + +typedef struct { + GtkWindowClass parent_class; +} TrgRssWindowClass; + +GType trg_rss_window_get_type(void); + +TrgRssWindow *trg_rss_window_get_instance(TrgMainWindow *parent, TrgClient *client); + +G_END_DECLS +#endif /* TRG_RSS_WINDOW_H_ */ -- cgit v1.2.3