Add the translators

Tue, 15 Aug 2017 23:46:46 -0500

author
Gary Kramlich <grim@reaperworld.com>
date
Tue, 15 Aug 2017 23:46:46 -0500
changeset 38662
808d7958b434
parent 38661
cf4073d0d648
child 38663
a463d40cb9ec

Add the translators

pidgin/about.ui file | annotate | diff | comparison | revisions
pidgin/contributors.json file | annotate | diff | comparison | revisions
pidgin/developers.json file | annotate | diff | comparison | revisions
pidgin/pidgin.gresource.xml file | annotate | diff | comparison | revisions
pidgin/pidginabout.c file | annotate | diff | comparison | revisions
pidgin/translators.json file | annotate | diff | comparison | revisions
--- a/pidgin/about.ui	Sat Aug 12 16:44:50 2017 -0500
+++ b/pidgin/about.ui	Tue Aug 15 23:46:46 2017 -0500
@@ -10,7 +10,15 @@
       <column type="gchararray"/>
     </columns>
   </object>
-  <object class="GtkTreeStore" id="credits_store">
+  <object class="GtkTreeStore" id="developers_store">
+    <columns>
+      <!-- column-name markup -->
+      <column type="gchararray"/>
+      <!-- column-name align -->
+      <column type="gfloat"/>
+    </columns>
+  </object>
+  <object class="GtkTreeStore" id="translators_store">
     <columns>
       <!-- column-name markup -->
       <column type="gchararray"/>
@@ -34,8 +42,21 @@
             <property name="can_focus">False</property>
             <property name="layout_style">spread</property>
             <child>
-              <object class="GtkToggleButton" id="credits_button">
-                <property name="label" translatable="yes">Credits</property>
+              <object class="GtkToggleButton" id="developers_button">
+                <property name="label" translatable="yes">Developers</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToggleButton" id="translators_button">
+                <property name="label" translatable="yes">Translators</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
@@ -185,28 +206,28 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkScrolledWindow" id="credits_page">
+                  <object class="GtkScrolledWindow" id="developers_page">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="hscrollbar_policy">never</property>
                     <property name="shadow_type">in</property>
                     <child>
-                      <object class="GtkTreeView" id="credits_treeview">
+                      <object class="GtkTreeView" id="developers_treeview">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="model">credits_store</property>
+                        <property name="model">developers_store</property>
                         <property name="headers_visible">False</property>
                         <property name="show_expanders">False</property>
                         <child internal-child="selection">
                           <object class="GtkTreeSelection"/>
                         </child>
                         <child>
-                          <object class="GtkTreeViewColumn" id="credits_column">
+                          <object class="GtkTreeViewColumn" id="developers_column">
                             <property name="resizable">True</property>
                             <property name="sizing">autosize</property>
                             <property name="title" translatable="yes">Contributor</property>
                             <child>
-                              <object class="GtkCellRendererText" id="credits_cell_renderer"/>
+                              <object class="GtkCellRendererText" id="developers_cell_renderer"/>
                               <attributes>
                                 <attribute name="xalign">1</attribute>
                                 <attribute name="markup">0</attribute>
@@ -218,12 +239,48 @@
                     </child>
                   </object>
                   <packing>
-                    <property name="name">credits</property>
-                    <property name="title" translatable="yes">credits</property>
+                    <property name="name">developers</property>
+                    <property name="title" translatable="yes">developers</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkScrolledWindow" id="translators_page">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="shadow_type">in</property>
+                    <child>
+                      <object class="GtkTreeView" id="translators_treeview">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="model">translators_store</property>
+                        <property name="headers_visible">False</property>
+                        <property name="show_expanders">False</property>
+                        <child internal-child="selection">
+                          <object class="GtkTreeSelection"/>
+                        </child>
+                        <child>
+                          <object class="GtkTreeViewColumn" id="translators_column">
+                            <property name="title" translatable="yes">Markup</property>
+                            <child>
+                              <object class="GtkCellRendererText" id="translators_cell_renderer"/>
+                              <attributes>
+                                <attribute name="xalign">1</attribute>
+                                <attribute name="markup">0</attribute>
+                              </attributes>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="name">translators</property>
+                    <property name="title" translatable="yes">translators</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkScrolledWindow" id="build_info_page">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
@@ -268,7 +325,7 @@
                   <packing>
                     <property name="name">build-info</property>
                     <property name="title" translatable="yes">build-info</property>
-                    <property name="position">2</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
               </object>
--- a/pidgin/contributors.json	Sat Aug 12 16:44:50 2017 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-{
-	"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"
-		]
-	}]
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/developers.json	Tue Aug 15 23:46:46 2017 -0500
@@ -0,0 +1,164 @@
+{
+	"developers": [{
+		"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"
+		]
+	}]
+}
--- a/pidgin/pidgin.gresource.xml	Sat Aug 12 16:44:50 2017 -0500
+++ b/pidgin/pidgin.gresource.xml	Tue Aug 15 23:46:46 2017 -0500
@@ -8,6 +8,7 @@
   </gresource>
   <gresource prefix="/im/pidgin/Pidgin/About">
     <file compressed="true">about.ui</file>
-    <file compressed="true">contributors.json</file>
+    <file compressed="true">developers.json</file>
+    <file compressed="true">translators.json</file>
   </gresource>
 </gresources>
--- a/pidgin/pidginabout.c	Sat Aug 12 16:44:50 2017 -0500
+++ b/pidgin/pidginabout.c	Tue Aug 15 23:46:46 2017 -0500
@@ -17,10 +17,15 @@
 struct _PidginAboutDialogPrivate {
 	GtkWidget *stack;
 
-	GtkWidget *credits_button;
-	GtkWidget *credits_page;
-	GtkWidget *credits_treeview;
-	GtkTreeStore *credits_store;
+	GtkWidget *developers_button;
+	GtkWidget *developers_page;
+	GtkWidget *developers_treeview;
+	GtkTreeStore *developers_store;
+
+	GtkWidget *translators_button;
+	GtkWidget *translators_page;
+	GtkWidget *translators_treeview;
+	GtkTreeStore *translators_store;
 
 	GtkWidget *build_info_button;
 	GtkWidget *build_info_page;
@@ -39,10 +44,16 @@
 
 	gtk_stack_set_visible_child_name(GTK_STACK(about->priv->stack), name);
 
-	/* now figure out if credits button is active */
+	/* now figure out if developers button is active */
 	gtk_toggle_button_set_active(
-		GTK_TOGGLE_BUTTON(about->priv->credits_button),
-		g_str_equal("credits", name)
+		GTK_TOGGLE_BUTTON(about->priv->developers_button),
+		g_str_equal("developers", name)
+	);
+
+	/* is the translators button active? */
+	gtk_toggle_button_set_active(
+		GTK_TOGGLE_BUTTON(about->priv->translators_button),
+		g_str_equal("translators", name)
 	);
 
 	/* is the build info button active? */
@@ -55,19 +66,19 @@
 }
 
 static void
-_pidgin_about_dialog_load_contributors(PidginAboutDialog *about) {
+_pidgin_about_dialog_load_developers(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;
+	JsonArray *developers = NULL;
 
-	/* get a stream to the credits resource */
+	/* get a stream to the developers resource */
 	istream = g_resource_open_stream(
 		pidgin_get_resource(),
-		"/im/pidgin/Pidgin/About/contributors.json",
+		"/im/pidgin/Pidgin/About/developers.json",
 		G_RESOURCE_LOOKUP_FLAGS_NONE,
 		NULL
 	);
@@ -82,8 +93,8 @@
 	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);
+	developers = json_object_get_array_member(root_object, "developers");
+	sections = json_array_get_elements(developers);
 
 	for(l = sections; l; l = l->next) {
 		GtkTreeIter section_iter;
@@ -97,9 +108,9 @@
 			json_object_get_string_member(section, "title")
 		);
 
-		gtk_tree_store_append(about->priv->credits_store, &section_iter, NULL);
+		gtk_tree_store_append(about->priv->developers_store, &section_iter, NULL);
 		gtk_tree_store_set(
-			about->priv->credits_store,
+			about->priv->developers_store,
 			&section_iter,
 			0, markup,
 			1, 0.5f,
@@ -115,9 +126,93 @@
 			GtkTreeIter person_iter;
 			gchar *markup = g_strdup(json_node_get_string(ll->data));
 
-			gtk_tree_store_append(about->priv->credits_store, &person_iter, &section_iter);
+			gtk_tree_store_append(about->priv->developers_store, &person_iter, &section_iter);
 			gtk_tree_store_set(
-				about->priv->credits_store,
+				about->priv->developers_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);
+}
+
+static void
+_pidgin_about_dialog_load_translators(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 *languages = NULL;
+
+	/* get a stream to the developers resource */
+	istream = g_resource_open_stream(
+		pidgin_get_resource(),
+		"/im/pidgin/Pidgin/About/translators.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("%s", error->message);
+	}
+
+	root_node = json_parser_get_root(parser);
+	root_object = json_node_get_object(root_node);
+
+	languages = json_object_get_array_member(root_object, "languages");
+	sections = json_array_get_elements(languages);
+
+	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(
+			"<span font_weight=\"bold\" font_size=\"large\">%s</span>",
+			json_object_get_string_member(section, "title")
+		);
+
+		gtk_tree_store_append(about->priv->translators_store, &section_iter, NULL);
+		gtk_tree_store_set(
+			about->priv->translators_store,
+			&section_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->translators_store, &person_iter, &section_iter);
+			gtk_tree_store_set(
+				about->priv->translators_store,
 				&person_iter,
 				0, markup,
 				1, 0.5f,
@@ -318,7 +413,7 @@
  * Callbacks
  *****************************************************************************/
 static void
-_pidgin_about_dialog_toggle_credits(GtkToggleButton *b, gpointer d) {
+_pidgin_about_dialog_toggle_developers(GtkToggleButton *b, gpointer d) {
 	PidginAboutDialog *about = d;
 	gboolean show = FALSE;
 
@@ -327,7 +422,20 @@
 
 	show = gtk_toggle_button_get_active(b);
 
-	_pidgin_about_dialog_switch_page(d, show ? "credits" : "main");
+	_pidgin_about_dialog_switch_page(d, show ? "developers" : "main");
+}
+
+static void
+_pidgin_about_dialog_toggle_translators(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 ? "translators" : "main");
 }
 
 static void
@@ -359,10 +467,15 @@
 
 	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);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, developers_button);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, developers_page);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, developers_store);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, developers_treeview);
+
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, translators_button);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, translators_page);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, translators_store);
+	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, translators_treeview);
 
 	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, build_info_button);
 	gtk_widget_class_bind_template_child_private(widget_class, PidginAboutDialog, build_info_page);
@@ -378,16 +491,27 @@
 
 	gtk_widget_init_template(GTK_WIDGET(about));
 
-	/* setup the credits stuff */
+	/* setup the developers stuff */
 	g_signal_connect(
-		about->priv->credits_button,
+		about->priv->developers_button,
 		"toggled",
-		G_CALLBACK(_pidgin_about_dialog_toggle_credits),
+		G_CALLBACK(_pidgin_about_dialog_toggle_developers),
 		about
 	);
 
-	_pidgin_about_dialog_load_contributors(about);
-	gtk_tree_view_expand_all(GTK_TREE_VIEW(about->priv->credits_treeview));
+	_pidgin_about_dialog_load_developers(about);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(about->priv->developers_treeview));
+
+	/* setup the translators stuff */
+	g_signal_connect(
+		about->priv->translators_button,
+		"toggled",
+		G_CALLBACK(_pidgin_about_dialog_toggle_translators),
+		about
+	);
+
+	_pidgin_about_dialog_load_translators(about);
+	gtk_tree_view_expand_all(GTK_TREE_VIEW(about->priv->translators_treeview));
 
 	/* setup the build info page */
 	g_signal_connect(
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/translators.json	Tue Aug 15 23:46:46 2017 -0500
@@ -0,0 +1,475 @@
+{
+	"languages": [{
+		"title": "Afrikaans (af)",
+		"people": [
+			"Samuel Murray",
+			"Friedel Wolff"
+		]
+	}, {
+		"title": "Arabic (ar)",
+		"people": [
+			"Khaled Hosny"
+		]
+	}, {
+		"title": "Assamese (as)",
+		"people": [
+			"Amitakhya Phukan"
+		]
+	}, {
+		"title": "Asturian (ast)",
+		"people": [
+			"Llumex03"
+		]
+	}, {
+		"title": "Belarusian Latin (be@latin)",
+		"people": [
+			"Ihar Hrachyshka"
+		]
+	}, {
+		"title": "Bulgarian (bg)",
+		"people": [
+			"Vladimira Girginova",
+			"Vladimir (Kaladan) Petkov"
+		]
+	}, {
+		"title": "Bengali (bn)",
+		"people": [
+			"Jamil Ahmed",
+			"Israt Jahan",
+			"Samia Nimatullah"
+		]
+	}, {
+		"title": "Bengali-India (bn_IN)",
+		"people": [
+			"Runa Bhattacharjee"
+		]
+	}, {
+		"title": "Breton (br)",
+		"people": [
+			"Gwenn Meynier"
+		]
+	}, {
+		"title": "Bodo (brx)",
+		"people": [
+			"Chandrakant Dhutadmal"
+		]
+	}, {
+		"title": "Bosnian (bs)",
+		"people": [
+			"Lejla Hadzialic"
+		]
+	}, {
+		"title": "Catalan (ca)",
+		"people": [
+			"Josep Puigdemont"
+		]
+	}, {
+		"title": "Valencian-Catalan (ca@valencia)",
+		"people": [
+			"Toni Hermoso",
+			"Josep Puigdemont"
+		]
+	}, {
+		"title": "Czech (cs)",
+		"people": [
+			"David Vachulka"
+		]
+	}, {
+		"title": "Danish (da)",
+		"people": [
+			"Nicky Thomassen"
+		]
+	}, {
+		"title": "German (de)",
+		"people": [
+			"Björn Voigt"
+		]
+	}, {
+		"title": "Dzongkha (dz)",
+		"people": [
+			"Norbu",
+			"Jurmey Rabgay",
+			"Wangmo Sherpa"
+		]
+	}, {
+		"title": "Greek (el)",
+		"people": [
+			"Katsaloulis Panayotis",
+			"Panos Bouklis"
+		]
+	}, {
+		"title": "Australian English (en_AU)",
+		"people": [
+			"Michael Findlay"
+		]
+	}, {
+		"title": "British English (en_GB)",
+		"people": [
+			"Phil Hannent"
+		]
+	}, {
+		"title": "Canadian English (en_CA)",
+		"people": [
+			"Adam Weinberger"
+		]
+	}, {
+		"title": "Esperanto (eo)",
+		"people": [
+			"Stéphane Fillod"
+		]
+	}, {
+		"title": "Spanish (es)",
+		"people": [
+			"Javier Fernández-Sanguino Peña"
+		]
+	}, {
+		"title": "Argentine Spanish (es_AR)",
+		"people": [
+			"KNTRO"
+		]
+	}, {
+		"title": "Estonian (et)",
+		"people": [
+			"Ivar Smolin"
+		]
+	}, {
+		"title": "Basque (eu)",
+		"people": [
+			"Mikel Pascual Aldabaldetreku"
+		]
+	}, {
+		"title": "Persian (fa)",
+		"people": [
+			"Elnaz Sarbar",
+			"Roozbeh Pournader",
+			"Meelad Zakaria"
+		]
+	}, {
+		"title": "Finnish (fi)",
+		"people": [
+			"Timo Jyrinki"
+		]
+	}, {
+		"title": "Irish (ga)",
+		"people": [
+			"Aaron Kearns",
+			"Kevin Scannell"
+		]
+	}, {
+		"title": "Galician (gl)",
+		"people": [
+			"Mar Castro",
+			"Frco. Javier Rial"
+		]
+	}, {
+		"title": "Gujarati (gu)",
+		"people": [
+			"Ankit Patel",
+			"Gujarati Language Team"
+		]
+	}, {
+		"title": "Hebrew (he)",
+		"people": [
+			"Shalom Craimer"
+		]
+	}, {
+		"title": "Hindi (hi)",
+		"people": [
+			"Sangeeta Kumari",
+			"Rajesh Ranjan"
+		]
+	}, {
+		"title": "Croatian (hr)",
+		"people": [
+			"Sabina Drempetić"
+		]
+	}, {
+		"title": "Hungarian (hu)",
+		"people": [
+			"Kelemen Gábor"
+		]
+	}, {
+		"title": "Indonesian (id)",
+		"people": [
+			"Rai S. Regawa"
+		]
+	}, {
+		"title": "Italian (it)",
+		"people": [
+			"Claudio Satriano"
+		]
+	}, {
+		"title": "Japanese (ja)",
+		"people": [
+			"Takayuki Kusano"
+		]
+	}, {
+		"title": "Georgian (ka)",
+		"people": [
+			"Ubuntu Georgian Translators"
+		]
+	}, {
+		"title": "Kazakh (kk)",
+		"people": [
+			"Baurzhan Muftakhidinov"
+		]
+	}, {
+		"title": "Khmer (km)",
+		"people": [
+			"Khoem Sokhem"
+		]
+	}, {
+		"title": "Kannada (kn)",
+		"people": [
+			"Kannada Translation team"
+		]
+	}, {
+		"title": "Korean (ko)",
+		"people": [
+			"Sushizang"
+		]
+	}, {
+		"title": "Kashmiri (kas)",
+		"people": [
+			"Chandrakant Dhutadmal"
+		]
+	}, {
+		"title": "Kurdish (ku)",
+		"people": [
+			"Amed Ç. Jiyan",
+			"Erdal Ronahi",
+			"Rizoyê Xerzî"
+		]
+	}, {
+		"title": "Kurdish (Sorani) (ku_IQ)",
+		"people": [
+			"Haval A. Ahmed"
+		]
+	}, {
+		"title": "Lithuanian (lt)",
+		"people": [
+			"Algimantas Margevičius"
+		]
+	}, {
+		"title": "Latvian (lv)",
+		"people": [
+			"Rudolfs Mazurs",
+			"Ingmārs Dīriņš"
+		]
+	}, {
+		"title": "Maithili (mai)",
+		"people": [
+			"Sangeeta Kumari",
+			"Rajesh Ranjan"
+		]
+	}, {
+		"title": "Meadow Mari (mhr)",
+		"people": [
+			"David Preece"
+		]
+	}, {
+		"title": "Macedonian (mk)",
+		"people": [
+			"Arangel Angov",
+			"Ivana Kirkovska",
+			"Jovan Naumovski"
+		]
+	}, {
+		"title": "Malayalam (ml)",
+		"people": [
+			"Ani Peter"
+		]
+	}, {
+		"title": "Mongolian (mn)",
+		"people": [
+			"gooyo"
+		]
+	}, {
+		"title": "Marathi (mr)",
+		"people": [
+			"Sandeep Shedmake"
+		]
+	}, {
+		"title": "Malay (ms_MY)",
+		"people": [
+			"abuyop"
+		]
+	}, {
+		"title": "Burmese (my_MM)",
+		"people": [
+			"Thura Hlaing"
+		]
+	}, {
+		"title": "Bokmål Norwegian (nb)",
+		"people": [
+			"Allan Nordhøy"
+		]
+	}, {
+		"title": "Nepali (ne)",
+		"people": [
+			"Saroj Dhakal"
+		]
+	}, {
+		"title": "Dutch, Flemish (nl)",
+		"people": [
+			"Gideon van Melle"
+		]
+	}, {
+		"title": "Norwegian Nynorsk (nn)",
+		"people": [
+			"Yngve Spjeld Landro"
+		]
+	}, {
+		"title": "Occitan (oc)",
+		"people": [
+			"Cédric Valmary"
+		]
+	}, {
+		"title": "Oriya (or)",
+		"people": [
+			"Manoj Kumar Giri"
+		]
+	}, {
+		"title": "Punjabi (pa)",
+		"people": [
+			"Amanpreet Singh Alam"
+		]
+	}, {
+		"title": "Polish (pl)",
+		"people": [
+			"Piotr Drąg"
+		]
+	}, {
+		"title": "Portuguese (pt)",
+		"people": [
+			"Paulo Ribeiro"
+		]
+	}, {
+		"title": "Portuguese-Brazil (pt_BR)",
+		"people": [
+			"Renato Silva"
+		]
+	}, {
+		"title": "Pashto (ps)",
+		"people": [
+			"Kashif Masood"
+		]
+	}, {
+		"title": "Romanian (ro)",
+		"people": [
+			"Mișu Moldovan",
+			"Andrei Popescu"
+		]
+	}, {
+		"title": "Russian (ru)",
+		"people": [
+			"Антон Самохвалов"
+		]
+	}, {
+		"title": "Sindhi (sd)",
+		"people": [
+			"Chandrakant Dhutadmal"
+		]
+	}, {
+		"title": "Slovak (sk)",
+		"people": [
+			"Jozef Káčer",
+			"loptosko"
+		]
+	}, {
+		"title": "Slovenian (sl)",
+		"people": [
+			"Martin Srebotnjak"
+		]
+	}, {
+		"title": "Albanian (sq)",
+		"people": [
+			"Besnik Bleta"
+		]
+	}, {
+		"title": "Serbian (sr)",
+		"people": [
+			"Miloš Popović"
+		]
+	}, {
+		"title": "Serbian Latin (sr@latin)",
+		"people": [
+			"Miloš Popović"
+		]
+	}, {
+		"title": "Sinhala (si)",
+		"people": [
+			"Yajith Ajantha Dayarathna",
+			"Danishka Navin"
+		]
+	}, {
+		"title": "Swedish (sv)",
+		"people": [
+			"Josef Andersson"
+		]
+	}, {
+		"title": "Swahili (sw)",
+		"people": [
+			"Paul Msegeya"
+		]
+	}, {
+		"title": "Tamil (ta)",
+		"people": [
+			"I. Felix",
+			"Viveka Nathan K"
+		]
+	}, {
+		"title": "Telugu (te)",
+		"people": [
+			"Krishnababu Krottapalli"
+		]
+	}, {
+		"title": "Thai (th)",
+		"people": [
+			"Isriya Paireepairit"
+		]
+	}, {
+		"title": "Tatar (tt)",
+		"people": [
+			"ILDAR Valeev"
+		]
+	}, {
+		"title": "Ukranian (uk)",
+		"people": [
+			"Oleksandr Kovalenko"
+		]
+	}, {
+		"title": "Urdu (ur)",
+		"people": [
+			"RKVS Raman"
+		]
+	}, {
+		"title": "Uzbek (uz)",
+		"people": [
+			"Akmal Khushvakov"
+		]
+	}, {
+		"title": "Vietnamese (vi)",
+		"people": [
+			"Nguyễn Vũ Hưng"
+		]
+	}, {
+		"title": "Simplified Chinese (zh_CN)",
+		"people": [
+			"Aron Xu"
+		]
+	}, {
+		"title": "Hong Kong Chinese (zh_HK)",
+		"people": [
+			"Abel Cheung",
+			"Ambrose C. Li",
+			"Paladin R. Liu"
+		]
+	}, {
+		"title": "Traditional Chinese (zh_TW)",
+		"people": [
+			"Ambrose C. Li",
+			"Paladin R. Liu"
+		]
+	}]
+}

mercurial