Wed, 30 Oct 2013 02:58:57 +0530
Merged default branch
| libpurple/Makefile.am | file | annotate | diff | comparison | revisions | |
| libpurple/request.h | file | annotate | diff | comparison | revisions | |
| pidgin/gtkmain.c | file | annotate | diff | comparison | revisions | |
| pidgin/gtkrequest.c | file | annotate | diff | comparison | revisions |
--- a/libpurple/Makefile.am Mon Oct 28 20:58:24 2013 +0530 +++ b/libpurple/Makefile.am Wed Oct 30 02:58:57 2013 +0530 @@ -102,6 +102,7 @@ prpl.c \ purple-socket.c \ request.c \ + request-datasheet.c \ roomlist.c \ savedstatuses.c \ server.c \ @@ -174,6 +175,7 @@ prpl.h \ purple-socket.h \ request.h \ + request-datasheet.h \ roomlist.h \ savedstatuses.h \ server.h \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/request-datasheet.c Wed Oct 30 02:58:57 2013 +0530 @@ -0,0 +1,344 @@ +/** + * @file request-datasheet.c Request Datasheet API + * @ingroup core + */ + +/* purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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 02111-1301 USA + */ + +#include "request-datasheet.h" + +#include "debug.h" +#include "signals.h" + +struct _PurpleRequestDatasheet +{ + guint col_count; + GArray *col_types; + GArray *col_titles; + + GList *record_list; + GHashTable *record_li_by_key; +}; + +struct _PurpleRequestDatasheetRecord +{ + PurpleRequestDatasheet *sheet; + gpointer key; + gchar **data; /* at this point, there is only string data possible */ +}; + +static void +purple_request_datasheet_record_free(PurpleRequestDatasheetRecord *rec); + +/***** Datasheet API **********************************************************/ + +PurpleRequestDatasheet * +purple_request_datasheet_new(void) +{ + PurpleRequestDatasheet *sheet; + + sheet = g_new0(PurpleRequestDatasheet, 1); + + sheet->col_types = g_array_new(FALSE, FALSE, + sizeof(PurpleRequestDatasheetColumnType)); + sheet->col_titles = g_array_new(FALSE, FALSE, sizeof(gchar *)); + /* XXX: use g_array_set_clear_func when we depend on Glib 2.32 */ + + sheet->record_li_by_key = g_hash_table_new(g_direct_hash, g_direct_equal); + + purple_signal_register(sheet, "record-changed", + purple_marshal_VOID__POINTER_POINTER, NULL, 2, + purple_value_new(PURPLE_TYPE_BOXED, + "PurpleRequestDatasheet *"), + purple_value_new(PURPLE_TYPE_POINTER)); /* NULL for all */ + + purple_signal_register(sheet, "destroy", + purple_marshal_VOID__POINTER, NULL, 1, + purple_value_new(PURPLE_TYPE_BOXED, + "PurpleRequestDatasheet *")); + + return sheet; +} + +void +purple_request_datasheet_free(PurpleRequestDatasheet *sheet) +{ + guint i; + + g_return_if_fail(sheet != NULL); + + purple_signal_emit(sheet, "destroy", sheet); + purple_signals_unregister_by_instance(sheet); + + for (i = 0; i < sheet->col_titles->len; i++) + g_free(g_array_index(sheet->col_titles, gchar *, i)); + + g_array_free(sheet->col_titles, TRUE); + g_array_free(sheet->col_types, TRUE); + + g_hash_table_destroy(sheet->record_li_by_key); + g_list_free_full(sheet->record_list, + (GDestroyNotify)purple_request_datasheet_record_free); + + g_free(sheet); +} + +void +purple_request_datasheet_add_column(PurpleRequestDatasheet *sheet, + PurpleRequestDatasheetColumnType type, const gchar *title) +{ + gchar *title_clone; + + g_return_if_fail(sheet != NULL); + + if (sheet->record_list != NULL) { + purple_debug_error("request-datasheet", "Cannot modify model " + "when there is already some data"); + return; + } + + title_clone = g_strdup(title); + sheet->col_count++; + g_array_append_val(sheet->col_types, type); + g_array_append_val(sheet->col_titles, title_clone); +} + +guint +purple_request_datasheet_get_column_count(PurpleRequestDatasheet *sheet) +{ + g_return_val_if_fail(sheet != NULL, 0); + + return sheet->col_count; + /*return sheet->col_types->len;*/ +} + +PurpleRequestDatasheetColumnType +purple_request_datasheet_get_column_type(PurpleRequestDatasheet *sheet, + guint col_no) +{ + g_return_val_if_fail(sheet != NULL, 0); + + return g_array_index(sheet->col_types, + PurpleRequestDatasheetColumnType, col_no); +} + +const gchar * +purple_request_datasheet_get_column_title(PurpleRequestDatasheet *sheet, + guint col_no) +{ + g_return_val_if_fail(sheet != NULL, 0); + + return g_array_index(sheet->col_titles, gchar *, col_no); +} + +const GList * +purple_request_datasheet_get_records(PurpleRequestDatasheet *sheet) +{ + g_return_val_if_fail(sheet != NULL, NULL); + + return sheet->record_list; +} + +/***** Datasheet record API ***************************************************/ + +static PurpleRequestDatasheetRecord * +purple_request_datasheet_record_new(void) +{ + return g_new0(PurpleRequestDatasheetRecord, 1); +} + +static void +purple_request_datasheet_record_free(PurpleRequestDatasheetRecord *rec) +{ + g_strfreev(rec->data); + g_free(rec); +} + +gpointer +purple_request_datasheet_record_get_key(const PurpleRequestDatasheetRecord *rec) +{ + g_return_val_if_fail(rec != NULL, NULL); + + return rec->key; +} + +PurpleRequestDatasheet * +purple_request_datasheet_record_get_datasheet( + PurpleRequestDatasheetRecord *rec) +{ + g_return_val_if_fail(rec != NULL, NULL); + + return rec->sheet; +} + +PurpleRequestDatasheetRecord * +purple_request_datasheet_record_find(PurpleRequestDatasheet *sheet, + gpointer key) +{ + GList *it; + + g_return_val_if_fail(sheet != NULL, NULL); + + it = g_hash_table_lookup(sheet->record_li_by_key, key); + if (!it) + return NULL; + + return it->data; +} + +PurpleRequestDatasheetRecord * +purple_request_datasheet_record_add(PurpleRequestDatasheet *sheet, + gpointer key) +{ + PurpleRequestDatasheetRecord *rec; + + g_return_val_if_fail(sheet != NULL, NULL); + + rec = purple_request_datasheet_record_find(sheet, key); + if (rec != NULL) + return rec; + + rec = purple_request_datasheet_record_new(); + rec->sheet = sheet; + rec->key = key; + + /* we don't allow modifying collumn count when datasheet contains + * any records */ + rec->data = g_new0(gchar*, + purple_request_datasheet_get_column_count(sheet) + 1); + + sheet->record_list = g_list_append(sheet->record_list, rec); + g_hash_table_insert(sheet->record_li_by_key, key, + g_list_find(sheet->record_list, rec)); + + purple_signal_emit(sheet, "record-changed", sheet, key); + + return rec; +} + +void +purple_request_datasheet_record_remove(PurpleRequestDatasheet *sheet, + gpointer key) +{ + GList *it; + + g_return_if_fail(sheet != NULL); + + it = g_hash_table_lookup(sheet->record_li_by_key, key); + if (it == NULL) + return; + + purple_request_datasheet_record_free(it->data); + sheet->record_list = g_list_delete_link(sheet->record_list, it); + g_hash_table_remove(sheet->record_li_by_key, key); + + purple_signal_emit(sheet, "record-changed", sheet, key); +} + +void +purple_request_datasheet_record_remove_all(PurpleRequestDatasheet *sheet) +{ + g_return_if_fail(sheet != NULL); + + g_list_free_full(sheet->record_list, + (GDestroyNotify)purple_request_datasheet_record_free); + sheet->record_list = NULL; + g_hash_table_remove_all(sheet->record_li_by_key); + + purple_signal_emit(sheet, "record-changed", sheet, NULL); +} + +static void +purple_request_datasheet_record_set_common_data( + PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *data) +{ + g_return_if_fail(rec != NULL); + g_return_if_fail( + purple_request_datasheet_get_column_count(rec->sheet) > col_no); + + if (g_strcmp0(rec->data[col_no], data) == 0) + return; + + /* we assume, model hasn't changed */ + g_free(rec->data[col_no]); + rec->data[col_no] = g_strdup(data); + + purple_signal_emit(rec->sheet, "record-changed", rec->sheet, rec->key); +} + +void +purple_request_datasheet_record_set_string_data( + PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *data) +{ + g_return_if_fail(rec != NULL); + g_return_if_fail(purple_request_datasheet_get_column_type(rec->sheet, + col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_STRING); + + purple_request_datasheet_record_set_common_data(rec, col_no, data); +} + +void +purple_request_datasheet_record_set_image_data( + PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *stock_id) +{ + g_return_if_fail(rec != NULL); + g_return_if_fail(purple_request_datasheet_get_column_type(rec->sheet, + col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE); + + purple_request_datasheet_record_set_common_data(rec, col_no, stock_id); +} + +const gchar * +purple_request_datasheet_record_get_common_data( + const PurpleRequestDatasheetRecord *rec, guint col_no) +{ + g_return_val_if_fail(rec != NULL, NULL); + g_return_val_if_fail( + purple_request_datasheet_get_column_count(rec->sheet) > col_no, + NULL); + + return rec->data[col_no]; +} + +const gchar * +purple_request_datasheet_record_get_string_data( + const PurpleRequestDatasheetRecord *rec, guint col_no) +{ + g_return_val_if_fail(rec != NULL, NULL); + g_return_val_if_fail(purple_request_datasheet_get_column_type( + rec->sheet, col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_STRING, + NULL); + + return purple_request_datasheet_record_get_common_data(rec, col_no); +} + +const gchar * +purple_request_datasheet_record_get_image_data( + const PurpleRequestDatasheetRecord *rec, guint col_no) +{ + g_return_val_if_fail(rec != NULL, NULL); + g_return_val_if_fail(purple_request_datasheet_get_column_type( + rec->sheet, col_no) == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE, + NULL); + + return purple_request_datasheet_record_get_common_data(rec, col_no); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/request-datasheet.h Wed Oct 30 02:58:57 2013 +0530 @@ -0,0 +1,246 @@ +/** + * @file request-datasheet.h Request Datasheet API + * @ingroup core + */ + +/* purple + * + * Purple is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * source distribution. + * + * 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 02111-1301 USA + */ +#ifndef _PURPLE_REQUEST_DATA_H_ +#define _PURPLE_REQUEST_DATA_H_ + +typedef struct _PurpleRequestDatasheet PurpleRequestDatasheet; +typedef struct _PurpleRequestDatasheetRecord PurpleRequestDatasheetRecord; + +typedef enum +{ + PURPLE_REQUEST_DATASHEET_COLUMN_STRING, + PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE +} PurpleRequestDatasheetColumnType; + +#include <glib.h> + +G_BEGIN_DECLS + +/**************************************************************************/ +/** @name Datasheet API */ +/**************************************************************************/ +/*@{*/ + +/** + * Creates new Datasheet. + * + * @return The new datasheet. + */ +PurpleRequestDatasheet * +purple_request_datasheet_new(void); + +/** + * Destroys datasheet with all its contents. + * + * @param sheet The datasheet. + */ +void +purple_request_datasheet_free(PurpleRequestDatasheet *sheet); + +/** + * Adds a column to the datasheet. + * + * You cannot add a column if datasheet contains any data. + * + * @param sheet The datasheet. + * @param type The column type. + * @param title The column title (may be @c NULL). + */ +void +purple_request_datasheet_add_column(PurpleRequestDatasheet *sheet, + PurpleRequestDatasheetColumnType type, const gchar *title); + +/** + * Returns the column count of datasheet. + * + * @param sheet The datasheet. + * + * @return The column count. + */ +guint +purple_request_datasheet_get_column_count(PurpleRequestDatasheet *sheet); + +/** + * Returns the column type for a datasheet. + * + * @param sheet The datasheet. + * @param col_no The column number (0 is the first one). + * + * @return The column type. + */ +PurpleRequestDatasheetColumnType +purple_request_datasheet_get_column_type(PurpleRequestDatasheet *sheet, + guint col_no); + +/** + * Returns the column title for a datasheet. + * + * @param sheet The datasheet. + * @param col_no The column number (0 is the first one). + * + * @return The column title. + */ +const gchar * +purple_request_datasheet_get_column_title(PurpleRequestDatasheet *sheet, + guint col_no); + +/** + * Returns the list of records in a datasheet. + * + * You shouldn't modify datasheet's data while iterating through it. + * + * @param sheet The datasheet. + * + * @constreturn The list of records. + */ +const GList * +purple_request_datasheet_get_records(PurpleRequestDatasheet *sheet); + +/*@}*/ + + +/**************************************************************************/ +/** @name Datasheet record API */ +/**************************************************************************/ +/*@{*/ + +/** + * Returns the key of a record. + * + * @param rec The record. + * + * @return The key. + */ +gpointer +purple_request_datasheet_record_get_key( + const PurpleRequestDatasheetRecord *rec); + +/** + * Returns the datasheet of a record. + * + * @param rec The record. + * + * @return The datasheet. + */ +PurpleRequestDatasheet * +purple_request_datasheet_record_get_datasheet( + PurpleRequestDatasheetRecord *rec); + +/** + * Looks up for a record in datasheet. + * + * @param sheet The datasheet. + * @param key The key. + * + * @return The record if found, @c NULL otherwise. + */ +PurpleRequestDatasheetRecord * +purple_request_datasheet_record_find(PurpleRequestDatasheet *sheet, + gpointer key); + +/** + * Adds a record to the datasheet. + * + * If the specified key already exists in datasheet, old record is returned. + * + * @param sheet The datasheet. + * @param key The key. + * + * @return The record. + */ +PurpleRequestDatasheetRecord * +purple_request_datasheet_record_add(PurpleRequestDatasheet *sheet, + gpointer key); + +/** + * Removes a record from a datasheet. + * + * @param sheet The datasheet. + * @param key The key. + */ +void +purple_request_datasheet_record_remove(PurpleRequestDatasheet *sheet, + gpointer key); + +/** + * Removes all records from a datasheet. + * + * @param sheet The datasheet. + */ +void +purple_request_datasheet_record_remove_all(PurpleRequestDatasheet *sheet); + +/** + * Sets data for a string column of specified record. + * + * @param rec The record. + * @param col_no The column. + * @param data The data. + */ +void +purple_request_datasheet_record_set_string_data( + PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *data); + +/** + * Sets data for a image column of specified record. + * + * @param rec The record. + * @param col_no The column. + * @param data The stock identifier of a image. + */ +void +purple_request_datasheet_record_set_image_data( + PurpleRequestDatasheetRecord *rec, guint col_no, const gchar *stock_id); + +/** + * Returns data for a string column of specified record. + * + * @param rec The record. + * @param col_no The column. + * + * @return The data. + */ +const gchar * +purple_request_datasheet_record_get_string_data( + const PurpleRequestDatasheetRecord *rec, guint col_no); + +/** + * Returns data for an image column of specified record. + * + * @param rec The record. + * @param col_no The column. + * + * @return The stock id of an image. + */ +const gchar * +purple_request_datasheet_record_get_image_data( + const PurpleRequestDatasheetRecord *rec, guint col_no); + +/*@}*/ + +G_END_DECLS + +#endif /* _PURPLE_REQUEST_DATA_H_ */
--- a/libpurple/request.c Mon Oct 28 20:58:24 2013 +0530 +++ b/libpurple/request.c Wed Oct 30 02:58:57 2013 +0530 @@ -132,6 +132,10 @@ PurpleCertificate *cert; } certificate; + struct + { + PurpleRequestDatasheet *sheet; + } datasheet; } u; void *ui_data; @@ -985,6 +989,10 @@ g_hash_table_destroy(field->u.list.item_data); g_hash_table_destroy(field->u.list.selected_table); } + else if (field->type == PURPLE_REQUEST_FIELD_DATASHEET) + { + purple_request_datasheet_free(field->u.datasheet.sheet); + } g_free(field); } @@ -1972,6 +1980,31 @@ return field->u.certificate.cert; } +PurpleRequestField * +purple_request_field_datasheet_new(const char *id, + const gchar *text, PurpleRequestDatasheet *sheet) +{ + PurpleRequestField *field; + + g_return_val_if_fail(id != NULL, NULL); + g_return_val_if_fail(sheet != NULL, NULL); + + field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_DATASHEET); + + field->u.datasheet.sheet = sheet; + + return field; +} + +PurpleRequestDatasheet * +purple_request_field_datasheet_get_sheet(PurpleRequestField *field) +{ + g_return_val_if_fail(field != NULL, NULL); + g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_DATASHEET, NULL); + + return field->u.datasheet.sheet; +} + /* -- */ gboolean
--- a/libpurple/request.h Mon Oct 28 20:58:24 2013 +0530 +++ b/libpurple/request.h Wed Oct 30 02:58:57 2013 +0530 @@ -31,6 +31,7 @@ #include <glib.h> #include "certificate.h" +#include "request-datasheet.h" /** * A request field. @@ -85,7 +86,8 @@ PURPLE_REQUEST_FIELD_LABEL, PURPLE_REQUEST_FIELD_IMAGE, PURPLE_REQUEST_FIELD_ACCOUNT, - PURPLE_REQUEST_FIELD_CERTIFICATE + PURPLE_REQUEST_FIELD_CERTIFICATE, + PURPLE_REQUEST_FIELD_DATASHEET } PurpleRequestFieldType; @@ -1670,6 +1672,35 @@ /*@}*/ /**************************************************************************/ +/** @name Datasheet Field API */ +/**************************************************************************/ +/*@{*/ + +/** + * Creates a datasheet item field. + * + * @param id The field ID. + * @param text The label of the field, may be @c NULL. + * @param sheet The datasheet. + * + * @return The new field. + */ +PurpleRequestField *purple_request_field_datasheet_new(const char *id, + const gchar *text, PurpleRequestDatasheet *sheet); + +/** + * Returns a datasheet for a field. + * + * @param field The field. + * + * @constreturn The datasheet object. + */ +PurpleRequestDatasheet *purple_request_field_datasheet_get_sheet( + PurpleRequestField *field); + +/*@}*/ + +/**************************************************************************/ /** @name Validators for request fields. */ /**************************************************************************/ /*@{*/
--- a/pidgin/gtkmain.c Mon Oct 28 20:58:24 2013 +0530 +++ b/pidgin/gtkmain.c Wed Oct 30 02:58:57 2013 +0530 @@ -275,6 +275,7 @@ pidgin_accounts_init(); pidgin_connection_init(); + pidgin_request_init(); pidgin_blist_init(); pidgin_status_init(); pidgin_conversations_init(); @@ -308,6 +309,7 @@ pidgin_status_uninit(); pidgin_docklet_uninit(); pidgin_blist_uninit(); + pidgin_request_uninit(); pidgin_connection_uninit(); pidgin_accounts_uninit(); pidgin_xfers_uninit();
--- a/pidgin/gtkrequest.c Mon Oct 28 20:58:24 2013 +0530 +++ b/pidgin/gtkrequest.c Wed Oct 30 02:58:57 2013 +0530 @@ -35,6 +35,7 @@ #include "gtkutils.h" #include "pidginstock.h" #include "gtkblist.h" +#include "gtkinternal.h" #include <gdk/gdkkeysyms.h> @@ -48,8 +49,6 @@ #include "gtk3compat.h" -static GtkWidget * create_account_field(PurpleRequestField *field); - typedef struct { PurpleRequestType type; @@ -95,6 +94,10 @@ } PidginRequestData; +static GHashTable *datasheet_stock = NULL; + +static GtkWidget * create_account_field(PurpleRequestField *field); + static void pidgin_widget_decorate_account(GtkWidget *cont, PurpleAccount *account) { @@ -1569,6 +1572,266 @@ #endif } +static GdkPixbuf* +_pidgin_datasheet_stock_icon_get(const gchar *stock_name) +{ + GdkPixbuf *image = NULL; + gchar *domain, *id; + + if (stock_name == NULL) + return NULL; + + /* core is quitting */ + if (datasheet_stock == NULL) + return NULL; + + if (g_hash_table_lookup_extended(datasheet_stock, stock_name, + NULL, (gpointer*)&image)) + { + return image; + } + + domain = g_strdup(stock_name); + id = strchr(domain, '/'); + if (!id) { + g_free(domain); + return NULL; + } + id[0] = '\0'; + id++; + + if (g_strcmp0(domain, "prpl") == 0) { + PurpleAccount *account; + gchar *prpl, *accountname; + + prpl = id; + accountname = strchr(id, ':'); + + if (!accountname) { + g_free(domain); + return NULL; + } + + accountname[0] = '\0'; + accountname++; + + account = purple_accounts_find(accountname, prpl); + if (account) { + image = pidgin_create_prpl_icon(account, + PIDGIN_PRPL_ICON_SMALL); + } + } else if (g_strcmp0(domain, "e2ee") == 0) { + image = pidgin_pixbuf_from_imgstore( + _pidgin_e2ee_stock_icon_get(id)); + } else { + purple_debug_error("gtkrequest", "Unknown domain: %s", domain); + g_free(domain); + return NULL; + } + + g_hash_table_insert(datasheet_stock, g_strdup(stock_name), image); + return image; +} + +static void +datasheet_update_rec(PurpleRequestDatasheetRecord *rec, GtkListStore *model, + GtkTreeIter *iter) +{ + guint i, col_count; + PurpleRequestDatasheet *sheet; + + g_return_if_fail(rec != NULL); + g_return_if_fail(model != NULL); + g_return_if_fail(iter != NULL); + + sheet = purple_request_datasheet_record_get_datasheet(rec); + + g_return_if_fail(sheet != NULL); + + col_count = purple_request_datasheet_get_column_count(sheet); + + for (i = 0; i < col_count; i++) { + PurpleRequestDatasheetColumnType type; + + type = purple_request_datasheet_get_column_type( + sheet, i); + if (type == PURPLE_REQUEST_DATASHEET_COLUMN_STRING) { + GValue val; + + val.g_type = 0; + g_value_init(&val, G_TYPE_STRING); + g_value_set_string(&val, + purple_request_datasheet_record_get_string_data( + rec, i)); + gtk_list_store_set_value(model, iter, + i + 1, &val); + } else if (type == + PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE) + { + GdkPixbuf *pixbuf; + + pixbuf = _pidgin_datasheet_stock_icon_get( + purple_request_datasheet_record_get_image_data( + rec, i)); + gtk_list_store_set(model, iter, i + 1, + pixbuf, -1); + } else + g_warn_if_reached(); + } +} + +static void +datasheet_fill(PurpleRequestDatasheet *sheet, GtkListStore *model) +{ + const GList *it; + + gtk_list_store_clear(model); + + it = purple_request_datasheet_get_records(sheet); + for (; it != NULL; it = g_list_next(it)) { + PurpleRequestDatasheetRecord *rec = it->data; + GtkTreeIter iter; + + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, 0, + purple_request_datasheet_record_get_key(rec), -1); + + datasheet_update_rec(rec, model, &iter); + } +} + +static void +datasheet_update(PurpleRequestDatasheet *sheet, gpointer key, + GtkListStore *model) +{ + PurpleRequestDatasheetRecord *rec; + GtkTreeIter iter; + GtkTreeModel *tmodel = GTK_TREE_MODEL(model); + gboolean found = FALSE; + + g_return_if_fail(tmodel != NULL); + + if (key == NULL) { + datasheet_fill(sheet, model); + return; + } + + rec = purple_request_datasheet_record_find(sheet, key); + + if (gtk_tree_model_get_iter_first(tmodel, &iter)) { + do { + gpointer ikey; + + gtk_tree_model_get(tmodel, &iter, 0, &ikey, -1); + + if (key == ikey) { + found = TRUE; + break; + } + } while (gtk_tree_model_iter_next(tmodel, &iter)); + } + + if (rec == NULL && !found) { + return; + } + + if (rec == NULL) { + gtk_list_store_remove(model, &iter); + return; + } + + if (!found) { + gtk_list_store_append(model, &iter); + gtk_list_store_set(model, &iter, 0, key, -1); + } + + datasheet_update_rec(rec, model, &iter); +} + +static GtkWidget * +create_datasheet_field(PurpleRequestField *field) +{ + PurpleRequestDatasheet *sheet; + guint i, col_count; + GType *col_types; + GtkListStore *model; + GtkTreeView *view; + GtkWidget *scrollable; + GtkCellRenderer *renderer_image = NULL, *renderer_text = NULL; + GtkTreeViewColumn *id_column; + + sheet = purple_request_field_datasheet_get_sheet(field); + + col_count = purple_request_datasheet_get_column_count(sheet); + + col_types = g_new0(GType, col_count + 1); + col_types[0] = G_TYPE_POINTER; + for (i = 0; i < col_count; i++) { + PurpleRequestDatasheetColumnType type; + type = purple_request_datasheet_get_column_type(sheet, i); + if (type == PURPLE_REQUEST_DATASHEET_COLUMN_STRING) + col_types[i + 1] = G_TYPE_STRING; + else if (type == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE) + col_types[i + 1] = GDK_TYPE_PIXBUF; + else + g_warn_if_reached(); + } + model = gtk_list_store_newv(col_count + 1, col_types); + g_free(col_types); + + view = GTK_TREE_VIEW(gtk_tree_view_new_with_model( + GTK_TREE_MODEL(model))); + g_object_unref(G_OBJECT(model)); + + id_column = gtk_tree_view_column_new(); + gtk_tree_view_column_set_visible(id_column, FALSE); + gtk_tree_view_append_column(view, id_column); + + for (i = 0; i < col_count; i++) { + PurpleRequestDatasheetColumnType type; + const gchar *title; + GtkCellRenderer *renderer; + const gchar *type_str = ""; + + type = purple_request_datasheet_get_column_type(sheet, i); + title = purple_request_datasheet_get_column_title(sheet, i); + + if (type == PURPLE_REQUEST_DATASHEET_COLUMN_STRING) { + type_str = "text"; + if (!renderer_text) + renderer_text = gtk_cell_renderer_text_new(); + renderer = renderer_text; + } + else if (type == PURPLE_REQUEST_DATASHEET_COLUMN_IMAGE) { + type_str = "pixbuf"; + if (!renderer_image) + renderer_image = gtk_cell_renderer_pixbuf_new(); + renderer = renderer_image; + } else + g_warn_if_reached(); + + if (title == NULL) + title = ""; + gtk_tree_view_insert_column_with_attributes( + view, -1, title, renderer, type_str, + i + 1, NULL); + } + + gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(view), TRUE); + + datasheet_fill(sheet, model); + purple_signal_connect(sheet, "record-changed", + pidgin_request_get_handle(), + PURPLE_CALLBACK(datasheet_update), model); + + gtk_widget_set_size_request(GTK_WIDGET(view), 400, 250); + + scrollable = pidgin_make_scrollable(GTK_WIDGET(view), + GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS, GTK_SHADOW_IN, -1, -1); + gtk_widget_show(GTK_WIDGET(view)); + return scrollable; +} + static void * pidgin_request_fields(const char *title, const char *primary, const char *secondary, PurpleRequestFields *fields, const char *ok_text, @@ -1779,6 +2042,7 @@ size_t col_num; size_t row_num = 0; guint tab_no; + gboolean contains_resizable = FALSE, frame_fill; group = gl->data; field_list = purple_request_field_group_get_fields(group); @@ -1818,6 +2082,9 @@ type = purple_request_field_get_type(field); + if (type == PURPLE_REQUEST_FIELD_DATASHEET) + contains_resizable = TRUE; + if (type == PURPLE_REQUEST_FIELD_LABEL) { if (col_num > 0) @@ -1849,8 +2116,8 @@ gtk_table_set_row_spacings(GTK_TABLE(table), PIDGIN_HIG_BOX_SPACE); gtk_table_set_col_spacings(GTK_TABLE(table), PIDGIN_HIG_BOX_SPACE); - gtk_box_pack_start(GTK_BOX(frame), table, - (notebook == NULL), (notebook == NULL), 0); + frame_fill = (notebook == NULL || contains_resizable); + gtk_box_pack_start(GTK_BOX(frame), table, frame_fill, frame_fill, 0); gtk_widget_show(table); for (row_num = 0, fl = field_list; @@ -1942,6 +2209,8 @@ widget = create_account_field(field); else if (type == PURPLE_REQUEST_FIELD_CERTIFICATE) widget = create_certificate_field(field); + else if (type == PURPLE_REQUEST_FIELD_DATASHEET) + widget = create_datasheet_field(field); else continue; } @@ -2274,3 +2543,26 @@ { return &ops; } + +void * +pidgin_request_get_handle(void) +{ + static int handle; + + return &handle; +} + +void +pidgin_request_init(void) +{ + datasheet_stock = g_hash_table_new_full(g_str_hash, g_str_equal, + g_free, g_object_unref); +} + +void +pidgin_request_uninit(void) +{ + purple_signals_disconnect_by_handle(pidgin_request_get_handle()); + g_hash_table_destroy(datasheet_stock); + datasheet_stock = NULL; +}
--- a/pidgin/gtkrequest.h Mon Oct 28 20:58:24 2013 +0530 +++ b/pidgin/gtkrequest.h Wed Oct 30 02:58:57 2013 +0530 @@ -47,6 +47,30 @@ GtkWindow * pidgin_request_get_dialog_window(void *ui_handle); +/**************************************************************************/ +/** @name GTK+ Requests Subsystem */ +/**************************************************************************/ +/*@{*/ + +/** + * Returns the gtk requests subsystem handle. + * + * @return The requests subsystem handle. + */ +void *pidgin_request_get_handle(void); + +/** + * Initializes the GTK+ requests subsystem. + */ +void pidgin_request_init(void); + +/** + * Uninitializes the GTK+ requests subsystem. + */ +void pidgin_request_uninit(void); + +/*@}*/ + G_END_DECLS #endif /* _PIDGINREQUEST_H_ */