summaryrefslogtreecommitdiff
path: root/src/glade-registration.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/glade-registration.c')
-rw-r--r--src/glade-registration.c1100
1 files changed, 0 insertions, 1100 deletions
diff --git a/src/glade-registration.c b/src/glade-registration.c
deleted file mode 100644
index ec8d5de0..00000000
--- a/src/glade-registration.c
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
- * Copyright (C) 2014, 2020 Juan Pablo Ugarte.
- *
- * 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.
- *
- * Authors:
- * Juan Pablo Ugarte <juanpablougarte@gmail.com>
- */
-
-#include "config.h"
-#include "glade-registration.h"
-#include "glade-window.h"
-#include "glade-http.h"
-#include "glade-logo.h"
-#include <gladeui/glade.h>
-#include <glib/gi18n.h>
-
-#define USER_SURVEY_CONFIG_GROUP "User & Survey"
-#define SURVEY_DATA_CONFIG_GROUP "Survey Data"
-
-struct _GladeRegistrationPrivate
-{
- GKeyFile *config;
- gchar *user_agent;
-
- GtkWidget *infobar;
- GtkWidget *statusbar;
- GtkWidget *net_spinner;
- GtkLabel *infobar_label;
- GtkLabel *status_label;
- GtkWidget *submit_button;
- GtkContainer *user_survey_box;
-
- GladeHTTP *http;
- GladeHTTP *sub_http;
- GCancellable *cancellable;
- GCancellable *sub_cancellable;
-
- /* HTML Form parsing */
- GHashTable *hidden_inputs;
- gboolean form_loaded;
- GHashTable *sub_hidden_inputs;
- gboolean sub_form_loaded;
-
- /* Form widgets */
-
- GtkWidget *name;
- GtkWidget *email;
- GtkWidget *country_id;
- GtkWidget *city;
- GtkWidget *contact_type;
- GtkWidget *contact_name;
- GtkWidget *contact_website;
- GtkWidget *subscribe;
-
- GtkWidget *experience;
- GtkWidget *experience_unit;
- GtkWidget *experience_not_programmer;
- GtkWidget *lang_c;
- GtkWidget *lang_cpp;
- GtkWidget *lang_csharp;
- GtkWidget *lang_java;
- GtkWidget *lang_python;
- GtkWidget *lang_javascript;
- GtkWidget *lang_vala;
- GtkWidget *lang_perl;
- GtkWidget *lang_rust;
- GtkWidget *lang_other;
- GtkWidget *start_using;
- GtkWidget *start_using_unit;
- GtkWidget *version;
- GtkWidget *version_other;
- GtkWidget *os;
- GtkWidget *os_linux;
- GtkWidget *os_bsd;
- GtkWidget *os_windows;
- GtkWidget *os_osx;
- GtkWidget *os_solaris;
- GtkWidget *os_other;
- GtkWidget *freq;
- GtkWidget *user_level;
- GtkWidget *soft_free;
- GtkWidget *soft_open;
- GtkWidget *soft_commercial;
- GtkWidget *soft_none;
- GtkWidget *field_academic;
- GtkWidget *field_accounting;
- GtkWidget *field_desktop;
- GtkWidget *field_educational;
- GtkWidget *field_embedded;
- GtkWidget *field_medical;
- GtkWidget *field_industrial;
- GtkWidget *field_scientific;
- GtkWidget *field_other;
- GtkWidget *improvement;
- GtkWidget *problem;
- GtkWidget *problem_other;
- GtkWidget *bug;
- GtkWidget *bugzilla;
- GtkWidget *contributing;
- GtkWidget *contributing_whynot;
- GtkWidget *comments;
-};
-
-G_DEFINE_TYPE_WITH_PRIVATE (GladeRegistration, glade_registration, GTK_TYPE_DIALOG)
-
-enum
-{
- PROP_0,
- PROP_COMPLETED,
- PROP_SKIP_REMINDER
-};
-
-static void
-glade_registration_parse_response_form (GladeRegistration *registration,
- const gchar *response,
- const gchar *form_action,
- GHashTable *data);
-
-static void
-string_append_input_key_value_tuple (GString *string,
- const gchar *name,
- GtkWidget *input)
-{
- if (string->len)
- g_string_append_c (string, '&');
-
- g_string_append (string, name);
- g_string_append_c (string, '=');
-
- if (GTK_IS_ENTRY (input))
- g_string_append_uri_escaped (string, gtk_entry_get_text (GTK_ENTRY (input)), NULL, FALSE);
- else if (GTK_IS_TEXT_VIEW (input))
- {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (input));
- GtkTextIter start, end;
- gchar *text;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
- text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- g_string_append_uri_escaped (string, text ? text : "", NULL, FALSE);
- g_free (text);
- }
- else if (GTK_IS_COMBO_BOX (input))
- g_string_append_uri_escaped (string, gtk_combo_box_get_active_id (GTK_COMBO_BOX (input)), NULL, FALSE);
- else if (GTK_IS_RADIO_BUTTON (input))
- {
- GSList *group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (input));
-
- for (; group; group = g_slist_next (group))
- {
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (group->data)))
- g_string_append (string, gtk_widget_get_name (group->data));
- }
- }
- else if (GTK_IS_TOGGLE_BUTTON (input) &&
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (input)))
- g_string_append_c (string, 'Y');
-}
-
-static void
-append_hidden_inputs (gpointer key, gpointer value, gpointer user_data)
-{
- GString *str = user_data;
- g_string_append_printf (str, "&%s=%s", (gchar *)key, (gchar *)value);
-}
-
-static void
-glade_registration_show_message (GladeRegistration *registration,
- GtkMessageType type,
- const gchar *format,
- ...) G_GNUC_PRINTF (3, 4);
-
-static void
-glade_registration_show_message (GladeRegistration *registration,
- GtkMessageType type,
- const gchar *format,
- ...)
-{
- GladeRegistrationPrivate *priv = registration->priv;
-
- gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar), type);
-
- if (format)
- {
- g_autofree gchar *string = NULL;
- va_list args;
-
- va_start (args, format);
- string = g_strdup_vprintf (format, args);
- va_end (args);
-
- gtk_label_set_markup (priv->infobar_label, string);
- }
- else
- gtk_label_set_markup (priv->infobar_label, "");
-
- /* Only show the infobar if the dialog is visible */
- if (gtk_widget_is_visible (GTK_WIDGET (registration)))
- gtk_widget_show (priv->infobar);
-}
-
-static void
-glade_registration_http_post (GladeRegistration *registration,
- GladeHTTP *http,
- GCancellable *cancellable,
- const gchar *url,
- GString *content)
-{
- const gchar *lang = pango_language_to_string (pango_language_get_default ());
- g_autofree gchar *cookies = glade_http_get_cookies (http);
-
- glade_http_request_send_async (http, cancellable,
- "POST %s HTTP/1.1\r\n"
- "Host: %s\r\n"
- "User-Agent: %s\r\n"
- "Connection: close\r\n"
- "Accept: text/html\r\n"
- "Accept-Language: %s\r\n"
- "Cookie: %s\r\n"
- "Origin: https://%s\r\n"
- "Referer: https://%s%s\r\n"
- "Content-Type: application/x-www-form-urlencoded\r\n"
- "Content-Length: %"G_GSIZE_FORMAT"\r\n"
- "\r\n%s",
- url, /* POST url */
- glade_http_get_host (http), /* Host */
- registration->priv->user_agent, /* User-Agent */
- lang, /* Accept-Language */
- cookies, /* Cookie */
- glade_http_get_host (http), /* Origin */
- glade_http_get_host (http), /* Referer */
- url, /* Referer */
- content->len, /* Content-length */
- content->str); /* content */
-}
-
-static void
-glade_registration_http_get (GladeRegistration *registration,
- GladeHTTP *http,
- GCancellable *cancellable,
- const gchar *url)
-{
- glade_http_request_send_async (http, cancellable,
- "GET %s HTTP/1.1\r\n"
- "Host: %s\r\n"
- "User-Agent: %s\r\n"
- "Connection: close\r\n"
- "Accept: text/html\r\n"
- "Content-Length: 0\r\n"
- "\r\n",
- url, /* POST url */
- glade_http_get_host (http), /* Host */
- registration->priv->user_agent); /* User-Agent */
-}
-
-static void
-on_http_status (GladeHTTP *http,
- GladeHTTPStatus status,
- GError *error,
- GladeRegistration *registration)
-{
- g_autofree gchar *text = NULL;
-
- switch (status)
- {
- case GLADE_HTTP_READY:
- break;
- case GLADE_HTTP_CONNECTING:
- text = g_strdup_printf (_("Connecting to %s"), glade_http_get_host (http));
- break;
- case GLADE_HTTP_SENDING:
- text = g_strdup_printf (_("Sending data to %s"), glade_http_get_host (http));
- break;
- case GLADE_HTTP_WAITING:
- text = g_strdup_printf (_("Waiting for %s"), glade_http_get_host (http));
- break;
- case GLADE_HTTP_RECEIVING:
- text = g_strdup_printf (_("Receiving data from %s"), glade_http_get_host (http));
- break;
- case GLADE_HTTP_ERROR:
- glade_registration_show_message (registration, GTK_MESSAGE_WARNING,
- "%s", error->message);
- break;
- }
-
- gtk_label_set_text (registration->priv->status_label, text ? text : "");
- gtk_widget_set_visible (registration->priv->net_spinner, text != NULL);
- gtk_widget_set_visible (registration->priv->statusbar, text != NULL);
-}
-
-static void
-glade_registration_subscribe_email (GladeRegistration *registration)
-{
- GladeRegistrationPrivate *priv = registration->priv;
- g_autoptr(GString) post = g_string_new ("");
-
- string_append_input_key_value_tuple (post, "email", priv->email);
- string_append_input_key_value_tuple (post, "fullname", priv->name);
-
- /* Append magic token */
- g_hash_table_foreach (priv->sub_hidden_inputs, append_hidden_inputs, post);
-
- glade_registration_http_post (registration, priv->sub_http, NULL,
- "/mailman/subscribe/glade-users-list",
- post);
-}
-
-static void
-on_subscribe_http_request_done (GladeHTTP *http,
- gint code,
- const gchar *response,
- GladeRegistration *registration)
-{
- GladeRegistrationPrivate *priv = registration->priv;
-
- switch (code)
- {
- case 100:
- /* Ignore Continue HTTP response */
- break;
- case 200:
- {
- if (!priv->sub_form_loaded)
- {
- /* Get magic token from html form */
- glade_registration_parse_response_form (registration,
- response,
- "subscribe/glade-users-list",
- priv->sub_hidden_inputs);
- priv->sub_form_loaded = TRUE;
-
- /* Now that we have the magic token we can make the actual POST */
- glade_registration_subscribe_email (registration);
- }
- else
- glade_registration_show_message (registration, GTK_MESSAGE_INFO, "%s",
- _("Your subscription to the users list has been received!\nCheck your email!"));
- }
- break;
- default:
- {
-#define SUBSCRIPTION_FAILED "Sorry, automatic subscription to Glade Users mailing list failed.\n\
-<a href=\"https://mail.gnome.org/mailman/listinfo/glade-users-list\">Open Glade Users Website</a>"
-
- glade_registration_show_message (registration, GTK_MESSAGE_WARNING,
- "%s\nHTTP response %d",
- _(SUBSCRIPTION_FAILED),
- code);
- }
- break;
- }
-}
-
-static void
-glade_registration_clear (GladeRegistrationPrivate *priv)
-{
- g_clear_object (&priv->cancellable);
- g_clear_object (&priv->sub_cancellable);
-
- priv->cancellable = g_cancellable_new ();
- priv->sub_cancellable = g_cancellable_new ();
-
- gtk_widget_hide (priv->infobar);
- g_hash_table_remove_all (priv->hidden_inputs);
- g_hash_table_remove_all (priv->sub_hidden_inputs);
- priv->form_loaded = FALSE;
- priv->sub_form_loaded = FALSE;
-}
-
-#define ADD_USER_INPUT(p,q,i) string_append_input_key_value_tuple (p, "311811X51X"q, priv->i)
-#define ADD_SURVEY_INPUT(p,q,i) string_append_input_key_value_tuple (p, "311811X57X"q, priv->i)
-
-static void
-glade_registration_submit_survey (GladeRegistration *registration)
-{
- GladeRegistrationPrivate *priv = registration->priv;
- g_autoptr(GString) post;
-
- post = g_string_new ("move=movesubmit&ajax=off&311811X51X843=");
-
- /* User Agent */
- g_string_append_uri_escaped (post, priv->user_agent, NULL, FALSE);
-
- /* User info */
- ADD_USER_INPUT (post, "849", name);
- ADD_USER_INPUT (post, "852", email);
- ADD_USER_INPUT (post, "1074", country_id);
- ADD_USER_INPUT (post, "858", city);
- ADD_USER_INPUT (post, "861", contact_type);
- ADD_USER_INPUT (post, "864", contact_name);
- ADD_USER_INPUT (post, "867", contact_website);
-
- /* Survey data */
- ADD_SURVEY_INPUT (post, "873", experience);
- ADD_SURVEY_INPUT (post, "879", experience_unit);
- ADD_SURVEY_INPUT (post, "882", experience_not_programmer);
- ADD_SURVEY_INPUT (post, "885c", lang_c);
- ADD_SURVEY_INPUT (post, "885cpp", lang_cpp);
- ADD_SURVEY_INPUT (post, "885csharp", lang_csharp);
- ADD_SURVEY_INPUT (post, "885java", lang_java);
- ADD_SURVEY_INPUT (post, "885python", lang_python);
- ADD_SURVEY_INPUT (post, "885javascript", lang_javascript);
- ADD_SURVEY_INPUT (post, "885vala", lang_vala);
- ADD_SURVEY_INPUT (post, "885perl", lang_perl);
- ADD_SURVEY_INPUT (post, "885rust", lang_rust);
- ADD_SURVEY_INPUT (post, "885other", lang_other);
- ADD_SURVEY_INPUT (post, "915", start_using);
- ADD_SURVEY_INPUT (post, "918", start_using_unit);
- ADD_SURVEY_INPUT (post, "921", version);
- ADD_SURVEY_INPUT (post, "924", version_other);
- ADD_SURVEY_INPUT (post, "927", os);
-
- ADD_SURVEY_INPUT (post, "930", os_linux);
- ADD_SURVEY_INPUT (post, "933", os_bsd);
- ADD_SURVEY_INPUT (post, "936", os_windows);
- ADD_SURVEY_INPUT (post, "939", os_osx);
- ADD_SURVEY_INPUT (post, "942", os_solaris);
-
- ADD_SURVEY_INPUT (post, "945", os_other);
-
- ADD_SURVEY_INPUT (post, "948", freq);
- ADD_SURVEY_INPUT (post, "951", user_level);
-
- ADD_SURVEY_INPUT (post, "954free", soft_free);
- ADD_SURVEY_INPUT (post, "954open", soft_open);
- ADD_SURVEY_INPUT (post, "954commercial", soft_commercial);
- ADD_SURVEY_INPUT (post, "954none", soft_none);
-
- ADD_SURVEY_INPUT (post, "969academic", field_academic);
- ADD_SURVEY_INPUT (post, "969accounting", field_accounting);
- ADD_SURVEY_INPUT (post, "969desktop", field_desktop);
- ADD_SURVEY_INPUT (post, "969educational", field_educational);
- ADD_SURVEY_INPUT (post, "969embedded", field_embedded);
- ADD_SURVEY_INPUT (post, "969medical", field_medical);
- ADD_SURVEY_INPUT (post, "969industrial", field_industrial);
- ADD_SURVEY_INPUT (post, "969scientific", field_scientific);
-
- ADD_SURVEY_INPUT (post, "1134", field_other);
-
- ADD_SURVEY_INPUT (post, "999", improvement);
- ADD_SURVEY_INPUT (post, "1002", problem);
- ADD_SURVEY_INPUT (post, "1140", problem_other);
- ADD_SURVEY_INPUT (post, "1005", bug);
-
- ADD_SURVEY_INPUT (post, "1008", bugzilla);
- ADD_SURVEY_INPUT (post, "1011", contributing);
- ADD_SURVEY_INPUT (post, "1014", contributing_whynot);
- ADD_SURVEY_INPUT (post, "1017", comments);
-
- /* Append hidden inputs */
- g_hash_table_foreach (priv->hidden_inputs, append_hidden_inputs, post);
-
- glade_registration_http_post (GLADE_REGISTRATION (registration),
- priv->http,
- priv->cancellable,
- "/index.php/311811",
- post);
-}
-
-static void
-on_http_request_done (GladeHTTP *http,
- gint code,
- const gchar *response,
- GladeRegistration *registration)
-{
- switch (code)
- {
- case 100:
- /* Ignore Continue HTTP response */
- break;
- case 200:
- {
- GladeRegistrationPrivate *priv = registration->priv;
-
- if (!priv->form_loaded)
- {
- glade_registration_parse_response_form (registration,
- response,
- "311811",
- priv->hidden_inputs);
- priv->form_loaded = TRUE;
-
- /* Now that we have the magic token we can make the actual POST */
- glade_registration_submit_survey (registration);
- return;
- }
-
- if (g_strstr_len (response, -1, "GLADE_USER_REGISTRATION_SURVEY_OK") != NULL)
- {
- gtk_label_set_text (priv->status_label, "");
- gtk_widget_hide (priv->statusbar);
-
- g_object_set (registration, "completed", TRUE, NULL);
- glade_app_config_save ();
-
- glade_util_ui_message (GTK_WIDGET (registration), GLADE_UI_INFO, NULL,
- "<big>%s</big>", _("Thank you for taking the time to complete the survey, we appreciate it!"));
- gtk_widget_hide (GTK_WIDGET (registration));
- }
- else
- glade_registration_show_message (registration, GTK_MESSAGE_WARNING,
- "Internal server error");
- }
- break;
- default:
- glade_registration_show_message (registration, GTK_MESSAGE_WARNING,
- "Got HTTP response %d", code);
- break;
- }
-}
-
-static inline void
-survey_data_set_string (GKeyFile *config, const gchar *id, const gchar *value)
-{
- if (value)
- g_key_file_set_string (config, SURVEY_DATA_CONFIG_GROUP, id, value);
-}
-
-void
-glade_registration_save_state_foreach (GtkWidget *widget, gpointer data)
-{
- GladeRegistration *registration = GLADE_REGISTRATION (data);
- const gchar *id = gtk_buildable_get_name (GTK_BUILDABLE (widget));
-
- if (id)
- {
- GKeyFile *config = registration->priv->config;
-
- if (GTK_IS_ENTRY (widget))
- survey_data_set_string (config, id, gtk_entry_get_text (GTK_ENTRY (widget)));
- else if (GTK_IS_TEXT_VIEW (widget))
- {
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
- GtkTextIter start, end;
- g_autofree gchar *text = NULL;
-
- gtk_text_buffer_get_bounds (buffer, &start, &end);
- text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- survey_data_set_string (config, id, text);
- }
- else if (GTK_IS_COMBO_BOX (widget))
- survey_data_set_string (config, id, gtk_combo_box_get_active_id (GTK_COMBO_BOX (widget)));
- else if (GTK_IS_TOGGLE_BUTTON (widget))
- g_key_file_set_boolean (config, SURVEY_DATA_CONFIG_GROUP, id,
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
- }
-
- /* Recurse all containers */
- if (GTK_IS_CONTAINER (widget))
- gtk_container_foreach (GTK_CONTAINER (widget),
- glade_registration_save_state_foreach,
- data);
-}
-
-void
-glade_registration_load_state_foreach (GtkWidget *widget, gpointer data)
-{
- GladeRegistration *registration = GLADE_REGISTRATION (data);
- const gchar *id = gtk_buildable_get_name (GTK_BUILDABLE (widget));
-
- if (id)
- {
- GKeyFile *config = registration->priv->config;
-
- if (GTK_IS_SPIN_BUTTON (widget))
- {
- gint val = g_key_file_get_integer (config, SURVEY_DATA_CONFIG_GROUP, id, NULL);
- gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), val);
- }
- else if (GTK_IS_ENTRY (widget))
- {
- g_autofree gchar *val = NULL;
- val = g_key_file_get_string (config, SURVEY_DATA_CONFIG_GROUP, id, NULL);
- gtk_entry_set_text (GTK_ENTRY (widget), val ? val : "");
- }
- else if (GTK_IS_TEXT_VIEW (widget))
- {
- g_autofree gchar *val = NULL;
-
- val = g_key_file_get_string (config, SURVEY_DATA_CONFIG_GROUP, id, NULL);
- GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
-
- gtk_text_buffer_set_text (buffer, val ? val : "", -1);
- }
- else if (GTK_IS_COMBO_BOX (widget)){
- g_autofree gchar *val = NULL;
-
- val = g_key_file_get_string (config, SURVEY_DATA_CONFIG_GROUP, id, NULL);
- gtk_combo_box_set_active_id (GTK_COMBO_BOX (widget), val ? val : "");
- }
- else if (GTK_IS_TOGGLE_BUTTON (widget)){
- gboolean val = g_key_file_get_boolean (config, SURVEY_DATA_CONFIG_GROUP, id, NULL);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), val);
- }
- }
-
- /* Recurse all containers */
- if (GTK_IS_CONTAINER (widget))
- gtk_container_foreach (GTK_CONTAINER (widget),
- glade_registration_load_state_foreach,
- data);
-}
-
-static gboolean
-entry_is_empty (GtkWidget *entry)
-{
- const gchar *text = gtk_entry_get_text (GTK_ENTRY (entry));
- g_autofree gchar *str = NULL;
-
- if (!text || *text == '\0')
- return TRUE;
-
- str = g_strstrip (g_strdup (text));
-
- return (!str || *str == '\0');
-}
-
-static gboolean
-glade_registration_verify (GtkWidget *entry)
-{
- GtkStyleContext *ctx = gtk_widget_get_style_context (entry);
-
- gtk_style_context_remove_class (ctx, "error");
-
- if (entry_is_empty (entry))
- {
- gtk_style_context_add_class (ctx, "error");
- gtk_widget_grab_focus (entry);
- return TRUE;
- }
-
- if (gtk_entry_get_input_purpose (GTK_ENTRY (entry)) == GTK_INPUT_PURPOSE_EMAIL)
- {
- const char *text = gtk_entry_get_text (GTK_ENTRY (entry));
- g_auto(GStrv) email = NULL;
-
- /* Check if this looks like an email */
- if (g_strstr_len (text, -1, " ") ||
- g_strstr_len (text, -1, "\t") ||
- g_strstr_len (text, -1, "\n") ||
- !(email = g_strsplit (text, "@", 2)) ||
- g_strv_length (email) != 2 ||
- *email[0] == '\0'|| *email[1] == '\0')
- {
- gtk_style_context_add_class (ctx, "error");
- gtk_widget_grab_focus (entry);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static void
-glade_registration_verify_entry (GtkEntry *entry, GladeRegistration *registration)
-{
- glade_registration_verify (GTK_WIDGET (entry));
-}
-
-static void
-on_registration_dialog_response (GtkDialog *dialog, gint response_id)
-{
- GladeRegistration *registration = GLADE_REGISTRATION (dialog);
- GladeRegistrationPrivate *priv = registration->priv;
-
- gtk_widget_hide (priv->infobar);
-
- /* Save state */
- gtk_container_foreach (priv->user_survey_box,
- glade_registration_save_state_foreach,
- registration);
- glade_app_config_save ();
-
- if (response_id != GTK_RESPONSE_OK)
- {
- gtk_widget_hide (GTK_WIDGET (dialog));
- glade_registration_clear (priv);
- return;
- }
-
- if (glade_registration_verify (priv->name) ||
- glade_registration_verify (priv->email) ||
- g_key_file_get_boolean (priv->config, USER_SURVEY_CONFIG_GROUP, "completed", NULL))
- return;
-
- /* Init state */
- glade_registration_clear (priv);
-
-
- /* Get survey form */
- glade_registration_http_get (registration,
- priv->http,
- priv->cancellable,
- "/index.php/311811");
-
- /* Get mailman form */
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->subscribe)))
- glade_registration_http_get (registration,
- priv->sub_http,
- priv->sub_cancellable,
- "/mailman/listinfo/glade-users-list");
-}
-
-static void
-toggle_button_set_visible_on_toggle (GtkToggleButton *button, GtkWidget *widget)
-{
- gtk_widget_set_visible (widget, gtk_toggle_button_get_active (button));
-}
-
-static void
-toggle_button_set_sensitive_on_toggle (GtkToggleButton *button, GtkWidget *widget)
-{
- gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (button));
-}
-
-static gboolean
-on_viewport_draw (GtkWidget *viewport, cairo_t *cr, GladeRegistration *widget)
-{
- GtkStyleContext *context = gtk_widget_get_style_context (viewport);
- GtkAllocation alloc;
- gdouble scale;
- GdkRGBA c;
-
- gtk_style_context_get_color (context, gtk_style_context_get_state (context), &c);
-
- gtk_widget_get_allocation (viewport, &alloc);
-
- scale = MIN (alloc.width/GLADE_LOGO_WIDTH, alloc.height/GLADE_LOGO_HEIGHT) - .1;
-
- cairo_save (cr);
-
- cairo_set_source_rgba (cr, c.red, c.green, c.blue, .04);
- cairo_scale (cr, scale, scale);
- cairo_translate (cr, (alloc.width / scale) - GLADE_LOGO_WIDTH*.95,
- (alloc.height / scale) - GLADE_LOGO_HEIGHT);
- cairo_append_path (cr, &glade_logo_path);
- cairo_fill (cr);
-
- cairo_restore (cr);
-
- return FALSE;
-}
-
-static void
-glade_registration_update_state (GladeRegistration *registration)
-{
- GladeRegistrationPrivate *priv = glade_registration_get_instance_private (registration);
-
- if (g_key_file_get_boolean (priv->config, USER_SURVEY_CONFIG_GROUP, "completed", NULL))
- {
- GtkWidget *headerbar = gtk_dialog_get_header_bar (GTK_DIALOG (registration));
-
- gtk_widget_set_sensitive (GTK_WIDGET (priv->user_survey_box), FALSE);
- gtk_widget_set_sensitive (GTK_WIDGET (priv->submit_button), FALSE);
-
- if (headerbar)
- gtk_header_bar_set_subtitle(GTK_HEADER_BAR (headerbar),
- _("Completed and submitted!"));
- }
-}
-
-static void
-glade_registration_init (GladeRegistration *registration)
-{
- GladeRegistrationPrivate *priv = glade_registration_get_instance_private (registration);
-
- registration->priv = priv;
-
- priv->config = glade_app_get_config ();
-
- /* Create user agent */
- priv->user_agent =
- g_strdup_printf ("Glade/"PACKAGE_VERSION" (%s; Gtk+ %d.%d.%d; glib %d.%d.%d; %s)",
- glade_window_get_gdk_backend (), /* Gdk backend */
- GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION, /* Gtk version */
- glib_major_version, glib_minor_version, glib_micro_version,/* Glib version */
- pango_language_to_string (pango_language_get_default ()));
-
- priv->hidden_inputs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
- priv->sub_hidden_inputs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
- /* HTTPS default port is 443 */
- priv->http = glade_http_new ("surveys.gnome.org", 443, TRUE);
-
- g_signal_connect_object (priv->http, "request-done",
- G_CALLBACK (on_http_request_done),
- registration, 0);
- g_signal_connect_object (priv->http, "status",
- G_CALLBACK (on_http_status),
- registration, 0);
-
- priv->sub_http = glade_http_new ("mail.gnome.org", 443, TRUE);
- g_signal_connect_object (priv->sub_http, "request-done",
- G_CALLBACK (on_subscribe_http_request_done),
- registration, 0);
-
- gtk_widget_init_template (GTK_WIDGET (registration));
-
- /* Generate Glade versions */
- if (GTK_IS_COMBO_BOX_TEXT (priv->version_other))
- {
- GtkComboBoxText *combo = GTK_COMBO_BOX_TEXT (priv->version_other);
- gchar id[16], text[18];
- gint minor;
-
- for (minor = 0; minor <= GLADE_MINOR_VERSION; minor+=2)
- {
- g_snprintf (id, 16, "%d", minor);
- g_snprintf (text, 18, "3.%d", minor);
- gtk_combo_box_text_prepend (combo, id, text);
-
- /* Skip non released version 24-34 */
- if (minor == 22)
- minor = 34;
- }
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
- }
-
- /* Load survey state */
- gtk_container_foreach (priv->user_survey_box,
- glade_registration_load_state_foreach,
- registration);
-
- gtk_dialog_set_default_response (GTK_DIALOG (registration), GTK_RESPONSE_OK);
-
- glade_registration_update_state (registration);
-}
-
-static void
-glade_registration_finalize (GObject *object)
-{
- GladeRegistrationPrivate *priv = GLADE_REGISTRATION (object)->priv;
-
- g_clear_pointer (&priv->user_agent, g_free);
- g_clear_object (&priv->http);
- g_clear_object (&priv->sub_http);
- g_clear_object (&priv->cancellable);
- g_clear_object (&priv->sub_cancellable);
- g_hash_table_destroy (priv->hidden_inputs);
- g_hash_table_destroy (priv->sub_hidden_inputs);
-
- G_OBJECT_CLASS (glade_registration_parent_class)->finalize (object);
-}
-
-static void
-glade_registration_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
-{
- GladeRegistrationPrivate *priv;
-
- g_return_if_fail (GLADE_IS_REGISTRATION (object));
-
- priv = GLADE_REGISTRATION (object)->priv;
-
- switch (prop_id)
- {
- case PROP_SKIP_REMINDER:
- g_key_file_set_boolean (priv->config, USER_SURVEY_CONFIG_GROUP,
- pspec->name, g_value_get_boolean (value));
- break;
- case PROP_COMPLETED:
- g_key_file_set_boolean (priv->config, USER_SURVEY_CONFIG_GROUP,
- pspec->name, g_value_get_boolean (value));
- glade_registration_update_state (GLADE_REGISTRATION (object));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-glade_registration_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
-{
- GladeRegistrationPrivate *priv;
-
- g_return_if_fail (GLADE_IS_REGISTRATION (object));
-
- priv = GLADE_REGISTRATION (object)->priv;
-
- switch (prop_id)
- {
- case PROP_SKIP_REMINDER:
- case PROP_COMPLETED:
- g_value_set_boolean (value, g_key_file_get_boolean (priv->config, USER_SURVEY_CONFIG_GROUP, pspec->name, NULL));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-glade_registration_class_init (GladeRegistrationClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- GtkCssProvider *css_provider;
-
- gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/glade/glade-registration.glade");
-
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, infobar);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, statusbar);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, net_spinner);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, infobar_label);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, status_label);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, submit_button);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, user_survey_box);
-
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, name);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, email);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, country_id);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, city);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, contact_type);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, contact_name);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, contact_website);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, subscribe);
-
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, experience);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, experience_unit);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, experience_not_programmer);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_c);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_cpp);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_csharp);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_java);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_python);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_javascript);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_vala);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_perl);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_rust);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, lang_other);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, start_using);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, start_using_unit);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, version);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, version_other);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_linux);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_bsd);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_windows);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_osx);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_solaris);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, os_other);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, freq);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, user_level);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, soft_free);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, soft_open);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, soft_commercial);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, soft_none);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_academic);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_accounting);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_desktop);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_educational);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_embedded);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_medical);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_industrial);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_scientific);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, field_other);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, improvement);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, problem);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, problem_other);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, bug);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, bugzilla);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, contributing);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, contributing_whynot);
- gtk_widget_class_bind_template_child_private (widget_class, GladeRegistration, comments);
-
- gtk_widget_class_bind_template_callback (widget_class, glade_registration_verify_entry);
- gtk_widget_class_bind_template_callback (widget_class, on_registration_dialog_response);
- gtk_widget_class_bind_template_callback (widget_class, toggle_button_set_visible_on_toggle);
- gtk_widget_class_bind_template_callback (widget_class, toggle_button_set_sensitive_on_toggle);
- gtk_widget_class_bind_template_callback (widget_class, on_viewport_draw);
-
- object_class->finalize = glade_registration_finalize;
- object_class->set_property = glade_registration_set_property;
- object_class->get_property = glade_registration_get_property;
-
- g_object_class_install_property (object_class,
- PROP_COMPLETED,
- g_param_spec_boolean ("completed",
- "Completed",
- "Registration was completed successfully",
- FALSE,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (object_class,
- PROP_SKIP_REMINDER,
- g_param_spec_boolean ("skip-reminder",
- "Skip reminder",
- "Skip registration reminder dialog",
- FALSE,
- G_PARAM_READWRITE));
-
- /* Setup Custom CSS */
- css_provider = gtk_css_provider_new ();
- gtk_css_provider_load_from_resource (css_provider, "/org/gnome/glade/glade-registration.css");
-
- gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
- GTK_STYLE_PROVIDER (css_provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
- g_object_unref (css_provider);
-}
-
-GtkWidget*
-glade_registration_new (void)
-{
- return GTK_WIDGET (g_object_new (GLADE_TYPE_REGISTRATION,
- "use-header-bar", TRUE,
- NULL));
-}
-
-/* HTML Form parsing utils */
-#include <libxml/HTMLparser.h>
-
-typedef struct {
- const gchar *form_action;
- GHashTable *inputs;
-
- gboolean in_form;
-} ParseData;
-
-static void
-start_element (ParseData *data, const gchar *name, const gchar **atts)
-{
- gboolean is_hidden = FALSE;
- const gchar *input_name = NULL, *input_value = NULL;
- gint i;
-
- if (g_strcmp0 (name, "form") == 0)
- {
- for (i = 0; atts[i]; i++)
- if (g_strcmp0 (atts[i], "action") == 0 &&
- g_strstr_len (atts[i+1], -1, data->form_action))
- data->in_form = TRUE;
-
- return;
- }
-
- /* Ignore elements outside of the form */
- if (!data->in_form)
- return;
-
- if (g_strcmp0 (name, "input"))
- return;
-
- for (i = 0; atts[i]; i += 2)
- {
- gint val = i + 1;
-
- if (!g_strcmp0 (atts[i], "type") && !g_strcmp0 (atts[val], "hidden"))
- is_hidden = TRUE;
-
- if (!g_strcmp0 (atts[i], "name"))
- input_name = atts[val];
-
- if (!g_strcmp0 (atts[i], "value"))
- input_value = atts[val];
- }
-
- if (is_hidden && input_name && input_value)
- g_hash_table_insert (data->inputs,
- g_uri_escape_string (input_name, NULL, FALSE),
- g_uri_escape_string (input_value, NULL, FALSE));
-}
-
-static void
-end_element (ParseData *data, const gchar *name)
-{
- if (g_strcmp0 (name, "form") == 0)
- data->in_form = FALSE;
-}
-
-static void
-glade_registration_parse_response_form (GladeRegistration *registration,
- const gchar *response,
- const gchar *form_action,
- GHashTable *inputs)
-{
- ParseData data = { .form_action = form_action, .inputs = inputs };
- htmlSAXHandler sax = { NULL, };
-
- sax.startElement = (startElementSAXFunc) start_element;
- sax.endElement = (endElementSAXFunc) end_element;
-
- /* Parse response and collect hidden inputs in the hash table */
- xmlFreeDoc (htmlSAXParseDoc ((guchar *)response, NULL, &sax, &data));
-}
-