# HG changeset patch # User Gary Kramlich # Date 1502418968 18000 # Node ID 7772f66662f0dd78f7a3394ee3eb8b4870f3ca8a # Parent f3db8eafde9e73ce7bf07da590faac456dfd19cd Lots of tweaking/wiring diff -r f3db8eafde9e -r 7772f66662f0 pidgin/about.ui --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/about.ui Thu Aug 10 21:36:08 2017 -0500 @@ -0,0 +1,279 @@ + + + + + + + + + + + + + + diff -r f3db8eafde9e -r 7772f66662f0 pidgin/contributors.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/contributors.json Thu Aug 10 21:36:08 2017 -0500 @@ -0,0 +1,164 @@ +{ + "credits": [{ + "title": "Developers", + "people": [ + "Daniel 'datallah' Atallah", + "Ethan 'Paco-Paco' Blanton", + "Gary 'grim' Kramlich", + "Richard 'rlaager' Laager", + "Etan 'deryni' Reisner", + "Michael 'Maiku' Ruprecht", + "Elliott 'QuLogic' Sales de Andrade", + "Kevin 'SimGuy' Stange", + "Jorge 'Masca' VillaseƱor", + "Tomasz Wasilczyk" + ] + }, { + "title": "Retired Developers", + "people": [ + "Paul 'darkrain42' Aurich", + "John 'rekkanoryo' Bailey", + "Herman Bloggs", + "Thomas Butter", + "Ka-Hing Cheung", + "Sadrul Habib Chowdhury", + "Mark 'KingAnt' Doliner", + "Jim Duchek", + "Sean Egan", + "Rob Flynn", + "Adam Fritzler", + "Christian 'ChipX86' Hammond", + "Casey Harkins", + "Ivan Komarov", + "Syd Logan", + "Marcus 'malu' Lundblad", + "Sulabh 'sulabh_m' Mahajan", + "Richard 'wabs' Nelson", + "Christopher 'siege' O'Brien", + "Bartosz Oler", + "Tim 'marv' Rigenbach", + "Luke 'LSchiere' Schierer", + "Megan 'Cae' Schneider", + "Evan Schoenberg", + "Jim Seymour", + "Mark Spencer", + "Will 'resiak' Thompson", + "Stu 'nosnilmot' Tomlinson", + "Nathan 'faceprint' Walp", + "Eric Warmenhoven" + ] + }, { + "title": "Crazy Patch Writers", + "people": [ + "Jakub 'haakon' Adam", + "Eion Robb" + ] + }, { + "title": "Retired Crazy Patch Writers", + "people": [ + "Felipe 'shx' Contreras", + "Decklin Foster", + "Krzysztof Klinikowski", + "Peter 'Bleeter' Lawler", + "Robert 'Robot101' McQueen", + "Benjamin Miller", + "Dennis 'EvilDennisR' Ristuccia", + "Peter 'Fmoo' Ruibal", + "Gabriel 'Nix' Schulhof", + "Ankit Vani" + ] + }, { + "title": "Artists", + "people": [ + "Hylke Bons" + ] + }, { + "title": "Google Summer of Code 2015", + "people": [ + "Abel Serrano Juste", + "Igor Gajowiak", + "James Geboski", + "Koosha Khajehmoogahi", + "Michael McConville", + "Nakul Gulati" + ] + }, { + "title": "Google Summer of Code 2013", + "people": [ + "Ashish Gupta", + "Bhaskar Kandiyal", + "Phil Hannent", + "Ankit Vani" + ] + }, { + "title": "Google Summer of Code 2012", + "people": [ + "Michael Zangl", + "Nikhil Bafna", + "Sanket Agarwal", + "Tomasz Wasilczyk" + ] + }, { + "title": "Google Summer of Code 2010", + "people": [ + "Ivan Komarov", + "Adam Fowler", + "Gilles Bedel", + "Jorge VillaseƱor Salinas" + ] + }, { + "title": "Google Summer of Code 2009", + "people": [ + "Felix Kerekes", + "Wade Fagen", + "Sulabh Mahajan", + "Eric Polino", + "Gregor Dick", + "Jan Kaluza", + "Arnold Noronha" + ] + }, { + "title": "Google Summer of Code 2008", + "people": [ + "Mark Schneider", + "Justin Rodriguez", + "Vivien Bernet-Rollande", + "Sulabh Mahajan", + "Mike Ruprecht", + "Tobias Markmann" + ] + }, { + "title": "Google Summer of Code 2007", + "people": [ + "Eion Coffey", + "Jeffery Connelly", + "Michael Shkutkov", + "William Ehlhardt", + "Eric Polino", + "Prekshu Ajmera", + "Carlos Silva", + "Will Thompson" + ] + }, { + "title": "Google Summer of Code 2006", + "people": [ + "Sadrul Habib Chowdhury", + "Ma Yuan", + "Geoffrey Foster", + "Brian Chu", + "Mark Huetsch", + "Aaron Sheldon" + ] + }, { + "title": "Google Summer of Code 2005", + "people": [ + "Adam Warrington", + "Bartosz Oler", + "Christian Muise", + "Jonathan Clark", + "Juanjo Molinero Horno", + "Piotr Zielinski", + "Thomas Butter" + ] + }] +} diff -r f3db8eafde9e -r 7772f66662f0 pidgin/gtkblist.c --- a/pidgin/gtkblist.c Thu Aug 10 21:01:21 2017 -0500 +++ b/pidgin/gtkblist.c Thu Aug 10 21:36:08 2017 -0500 @@ -59,6 +59,7 @@ #include "gtkblist-theme-loader.h" #include "gtkutils.h" #include "pidgin/minidialog.h" +#include "pidgin/pidginabout.h" #include "pidgin/pidgintooltip.h" #include @@ -3604,6 +3605,12 @@ /*************************************************** * Crap * ***************************************************/ +static void +_pidgin_about_cb(void) { + GtkWidget *about = pidgin_about_dialog_new(); + gtk_widget_show_all(about); +} + /* TODO: fill out tooltips... */ static const GtkActionEntry blist_menu_entries[] = { /* NOTE: Do not set any accelerator to Control+O. It is mapped by @@ -3647,6 +3654,7 @@ { "PluginInformation", NULL, N_("_Plugin Information"), NULL, NULL, pidgin_dialogs_plugins_info }, { "TranslatorInformation", NULL, N_("_Translator Information"), NULL, NULL, pidgin_dialogs_translators }, { "About", GTK_STOCK_ABOUT, N_("_About"), NULL, NULL, pidgin_dialogs_about }, + { "About2", GTK_STOCK_ABOUT, N_("_About (*)"), NULL, NULL, _pidgin_about_cb }, }; /* Toggle items */ @@ -3715,6 +3723,7 @@ "" "" "" + "" "" "" ""; diff -r f3db8eafde9e -r 7772f66662f0 pidgin/gtkdebug.c --- a/pidgin/gtkdebug.c Thu Aug 10 21:01:21 2017 -0500 +++ b/pidgin/gtkdebug.c Thu Aug 10 21:36:08 2017 -0500 @@ -40,7 +40,7 @@ #include "gtk3compat.h" -#include "pidgin.gresource.h" +#include "pidginresources.h" typedef struct { diff -r f3db8eafde9e -r 7772f66662f0 pidgin/logo.png Binary file pidgin/logo.png has changed diff -r f3db8eafde9e -r 7772f66662f0 pidgin/meson.build --- a/pidgin/meson.build Thu Aug 10 21:01:21 2017 -0500 +++ b/pidgin/meson.build Thu Aug 10 21:36:08 2017 -0500 @@ -42,7 +42,8 @@ 'gtkxfer.c', 'libpidgin.c', 'minidialog.c', - 'pidgintooltip.c' + 'pidginabout.c', + 'pidgintooltip.c', ] libpidgin_headers = [ @@ -90,15 +91,16 @@ 'gtkwhiteboard.h', 'gtkxfer.h', 'minidialog.h', + 'pidginabout.h', 'pidgintooltip.h', - 'pidgin.h' + 'pidgin.h', ] pidgin_SOURCES = [ 'pidgin.c' ] -pidgin_resource = gnome.compile_resources('pidgin.gresource', 'pidgin.gresource.xml', +pidgin_resource = gnome.compile_resources('pidginresources', 'pidgin.gresource.xml', c_name : 'pidgin') libpidgin_SOURCES += pidgin_resource @@ -149,7 +151,20 @@ libpidgin_SOURCES, include_directories : [toplevel_inc], version : PURPLE_LIB_VERSION, - dependencies : [gtk, gstreamer_video, webkit, enchant, dbus, x11, GCR, IOKIT, libpurple_dep, glib, math], + dependencies : [ + dbus, + enchant, + GCR, + glib, + gstreamer_video, + gtk, + IOKIT, + json, + math, + webkit, + x11, + libpurple_dep, + ], install : true) libpidgin_dep = declare_dependency( include_directories : [toplevel_inc, libpidgin_inc], diff -r f3db8eafde9e -r 7772f66662f0 pidgin/pidgin.gresource.xml --- a/pidgin/pidgin.gresource.xml Thu Aug 10 21:01:21 2017 -0500 +++ b/pidgin/pidgin.gresource.xml Thu Aug 10 21:36:08 2017 -0500 @@ -1,6 +1,13 @@ + + logo.png + gtkdebug.html + + about.ui + contributors.json + diff -r f3db8eafde9e -r 7772f66662f0 pidgin/pidginabout.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidginabout.c Thu Aug 10 21:36:08 2017 -0500 @@ -0,0 +1,193 @@ +#include +#include + +#include "pidginabout.h" +#include "pidginresources.h" + +struct _PidginAboutDialogPrivate { + GtkWidget *stack; + + GtkWidget *credits_button; + GtkWidget *credits_page; + GtkWidget *credits_treeview; + GtkTreeStore *credits_store; + + gboolean switching_pages; +}; + +/****************************************************************************** + * Helpers + *****************************************************************************/ +static void +_pidgin_about_dialog_switch_page(PidginAboutDialog *about, const gchar *name) { + about->priv->switching_pages = TRUE; + + gtk_stack_set_visible_child_name(GTK_STACK(about->priv->stack), name); + + /* now figure out if credits button is active */ + gtk_toggle_button_set_active( + GTK_TOGGLE_BUTTON(about->priv->credits_button), + g_str_equal("credits", name) + ); + + about->priv->switching_pages = FALSE; +} + +static void +_pidgin_about_dialog_load_contributors(PidginAboutDialog *about) { + GInputStream *istream = NULL; + GList *l = NULL, *sections = NULL; + GError *error = NULL; + JsonParser *parser = NULL; + JsonNode *root_node = NULL; + JsonObject *root_object = NULL; + JsonArray *credits = NULL; + + /* get a stream to the credits resource */ + istream = g_resource_open_stream( + pidgin_get_resource(), + "/im/pidgin/Pidgin/About/contributors.json", + G_RESOURCE_LOOKUP_FLAGS_NONE, + NULL + ); + + /* create our parser */ + parser = json_parser_new(); + + if(!json_parser_load_from_stream(parser, istream, NULL, &error)) { + g_critical(error->message); + } + + root_node = json_parser_get_root(parser); + root_object = json_node_get_object(root_node); + + credits = json_object_get_array_member(root_object, "credits"); + sections = json_array_get_elements(credits); + + for(l = sections; l; l = l->next) { + GtkTreeIter section_iter; + GList *ll = NULL, *people = NULL; + JsonObject *section = json_node_get_object(l->data); + JsonArray *people_array = NULL; + gchar *markup = NULL; + + markup = g_strdup_printf( + "%s", + json_object_get_string_member(section, "title") + ); + + gtk_tree_store_append(about->priv->credits_store, §ion_iter, NULL); + gtk_tree_store_set( + about->priv->credits_store, + §ion_iter, + 0, markup, + 1, 0.5f, + -1 + ); + + g_free(markup); + + people_array = json_object_get_array_member(section, "people"); + people = json_array_get_elements(people_array); + + for(ll = people; ll; ll = ll->next) { + GtkTreeIter person_iter; + gchar *markup = g_strdup(json_node_get_string(ll->data)); + + gtk_tree_store_append(about->priv->credits_store, &person_iter, §ion_iter); + gtk_tree_store_set( + about->priv->credits_store, + &person_iter, + 0, markup, + 1, 0.5f, + -1 + ); + + g_free(markup); + } + + g_list_free(people); + } + + g_list_free(sections); + + /* clean up */ + g_object_unref(G_OBJECT(parser)); + + g_input_stream_close(istream, NULL, NULL); +} + +/****************************************************************************** + * Callbacks + *****************************************************************************/ +static void +_pidgin_about_dialog_toggle_credits(GtkToggleButton *b, gpointer d) { + PidginAboutDialog *about = d; + gboolean show = FALSE; + + if(about->priv->switching_pages) + return; + + show = gtk_toggle_button_get_active(b); + + _pidgin_about_dialog_switch_page(d, show ? "credits" : "main"); +} + +/****************************************************************************** + * GObject Stuff + *****************************************************************************/ +G_DEFINE_TYPE_WITH_PRIVATE(PidginAboutDialog, pidgin_about_dialog, GTK_TYPE_DIALOG); + +static void +pidgin_about_dialog_class_init(PidginAboutDialogClass *klass) { + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + + gtk_widget_class_set_template_from_resource( + widget_class, + "/im/pidgin/Pidgin/About/about.ui" + ); + + gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, stack); + + gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, credits_button); + gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, credits_page); + gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, credits_store); + gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, credits_treeview); +} + +static void +pidgin_about_dialog_init(PidginAboutDialog *about) { + about->priv = pidgin_about_dialog_get_instance_private(about); + + about->priv->switching_pages = FALSE; + + gtk_widget_init_template(GTK_WIDGET(about)); + + g_signal_connect( + about->priv->credits_button, + "toggled", + G_CALLBACK(_pidgin_about_dialog_toggle_credits), + about + ); + + _pidgin_about_dialog_load_contributors(about); + + /* expand all the nodes in the credits treeview and tweak some other + * properties. + */ + gtk_tree_view_expand_all(GTK_TREE_VIEW(about->priv->credits_treeview)); +} + +GtkWidget * +pidgin_about_dialog_new(void) { + GtkWidget *about = NULL; + + about = g_object_new( + PIDGIN_TYPE_ABOUT_DIALOG, + "title", "About Pidgin", + NULL + ); + + return about; +} + diff -r f3db8eafde9e -r 7772f66662f0 pidgin/pidginabout.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pidgin/pidginabout.h Thu Aug 10 21:36:08 2017 -0500 @@ -0,0 +1,41 @@ +#ifndef PIDGIN_ABOUT_H +#define PIDGIN_ABOUT_H + +#include + +#define PIDGIN_TYPE_ABOUT_DIALOG (pidgin_about_dialog_get_type()) +#define PIDGIN_ABOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), PIDGIN_TYPE_ABOUT_DIALOG, PidginAboutDialog)) +#define PIDGIN_ABOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), PIDGIN_TYPE_ABOUT_DIALOG, PidginAboutDialogClass)) +#define PIDGIN_IS_ABOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), PIDGIN_TYPE_ABOUT_DIALOG)) +#define PIDGIN_IS_ABOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PIDGIN_TYPE_ABOUT_DIALOG)) +#define PIDGIN_ABOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), PIDGIN_TYPE_ABOUT_DIALOG, PidginAboutDialogClass)) + +typedef struct _PidginAboutDialog PidginAboutDialog; +typedef struct _PidginAboutDialogClass PidginAboutDialogClass; +typedef struct _PidginAboutDialogPrivate PidginAboutDialogPrivate; + +struct _PidginAboutDialog { + GtkDialog parent; + + /*< private >*/ + PidginAboutDialogPrivate *priv; +}; + +struct _PidginAboutDialogClass { + GtkDialogClass parent; + + void (*_pidgin_reserved1)(void); + void (*_pidgin_reserved2)(void); + void (*_pidgin_reserved3)(void); + void (*_pidgin_reserved4)(void); +}; + +G_BEGIN_DECLS + +GType pidgin_about_dialog_get_type(void); +GtkWidget *pidgin_about_dialog_new(void); + +G_END_DECLS + +#endif /* PIDGIN_ABOUT_H */ +