diff --git a/src/gtr-header.c b/src/gtr-header.c index 02f53776a5c4dab987bd10e4147457fa4d588242..9a6f408281860cc408cb74119d8dee63551fc186 100644 --- a/src/gtr-header.c +++ b/src/gtr-header.c @@ -72,7 +72,7 @@ gtr_header_set_field (GtrHeader * header, static void parse_nplurals (GtrHeader * header) { - gchar *pointer, *plural_forms; + gchar *plural_forms; gboolean use_profile_values; GtrHeaderPrivate *priv = gtr_header_get_instance_private (header); @@ -111,30 +111,7 @@ parse_nplurals (GtrHeader * header) return; } - pointer = g_strrstr (plural_forms, "nplurals"); - - if (pointer != NULL) - { - while (*pointer != '\0' && *pointer != '=') - pointer++; - - if (*pointer != '\0') - { - pointer++; - while (*pointer != '\0' && *pointer == ' ') - pointer++; - - if (*pointer == '\0') - return; - } - else - return; - - priv->nplurals = g_ascii_digit_value (*pointer); - } - - /*g_message ("nplurals: %d", priv->nplurals); */ - + priv->nplurals = parse_nplurals_header (plural_forms); g_free (plural_forms); } diff --git a/src/gtr-po.c b/src/gtr-po.c index 506d2d7694e6bcb063fe5a47e5510718ab83109e..a894189d4d5c4a444e885760dd9e28e5982647f0 100644 --- a/src/gtr-po.c +++ b/src/gtr-po.c @@ -38,6 +38,7 @@ #include "gtr-msg.h" #include "gtr-enum-types.h" #include "gtr-profile.h" +#include "gtr-profile-manager.h" #include "gtr-utils.h" #include "gtr-message-container.h" #include "gtr-preferences-dialog.h" @@ -129,6 +130,14 @@ enum PROP_STATE }; +enum +{ + FILE_INCONSISTENT_WITH_PROFILE, + NO_OF_SIGNALS +}; + +guint signals[NO_OF_SIGNALS]; + static gchar *message_error = NULL; static void @@ -331,6 +340,14 @@ gtr_po_class_init (GtrPoClass * klass) GTR_TYPE_PO_STATE, GTR_PO_STATE_SAVED, G_PARAM_READABLE)); + /* Signals */ + signals[FILE_INCONSISTENT_WITH_PROFILE] = + g_signal_new ("file-is-inconsistent-with-profile", + G_OBJECT_CLASS_TYPE (klass), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); } /* @@ -1401,6 +1418,35 @@ gtr_po_check_po_file (GtrPo * po) return message_error; } +/** + * gtr_po_consistent_with_profile + * @po: a #GtrPo + * + * Tests whether the po file is consistent or not with profile values + * Returns: If the po file is not consistent with profile then it returns 0 . + **/ +gboolean +gtr_po_consistent_with_profile (GtrPo * po) +{ + GtrProfileManager *prof_manager; + GtrProfile *profile; + gint po_header_nplurals; + gint profile_nplurals = -1; + + GtrHeader *header = gtr_po_get_header (po); + po_header_nplurals = gtr_header_get_nplurals (header); + + prof_manager = gtr_profile_manager_get_default (); + profile = gtr_profile_manager_get_active_profile (prof_manager); + profile_nplurals = parse_nplurals_header ( + gtr_profile_get_plural_forms (profile) + ); + + g_object_unref (prof_manager); + + return profile_nplurals == po_header_nplurals; +} + const gchar * gtr_po_get_dl_team (GtrPo *po) { @@ -1442,3 +1488,9 @@ gtr_po_can_dl_upload (GtrPo *po) GtrPoPrivate *priv = gtr_po_get_instance_private (po); return g_strcmp0 (priv->dl_state, "Translating") == 0; } + +void +gtr_po_emit_file_not_consistent (GtrPo *po) +{ + g_signal_emit (G_OBJECT(po), signals[FILE_INCONSISTENT_WITH_PROFILE], 0); +} diff --git a/src/gtr-po.h b/src/gtr-po.h index 6d3089e19ab97b101258b2c1bf595a040dabfac6..520c54e82873b12f9cba737399e86a5f640a491b 100644 --- a/src/gtr-po.h +++ b/src/gtr-po.h @@ -152,7 +152,11 @@ gtr_po_get_message_position (GtrPo * po); gchar *gtr_po_check_po_file (GtrPo * po); +void +gtr_po_emit_file_not_consistent (GtrPo * po); +gboolean +gtr_po_consistent_with_profile (GtrPo * po); /* Unexported funcs */ void _gtr_po_increase_decrease_translated (GtrPo * po, gboolean increase); diff --git a/src/gtr-profile-manager.c b/src/gtr-profile-manager.c index 81eb12864b2c8b7b20708e2f89caefbdf9845aba..7c7b83990e262f6fb272c8ac4802bcc571a435b7 100644 --- a/src/gtr-profile-manager.c +++ b/src/gtr-profile-manager.c @@ -382,7 +382,6 @@ gtr_profile_manager_set_active_profile (GtrProfileManager *manager, priv->active_profile = profile; g_signal_emit (G_OBJECT (manager), signals[ACTIVE_PROFILE_CHANGED], 0, profile); - save_profiles (manager); } diff --git a/src/gtr-tab.c b/src/gtr-tab.c index 93b9059b76fa8d29139b01dffe82cc080f1c8210..1547300c3efb37fd1e3ccb2a108263b451534cb2 100644 --- a/src/gtr-tab.c +++ b/src/gtr-tab.c @@ -28,6 +28,7 @@ * Thomas Ziehmer */ +#include "gtr-profile.h" #ifdef HAVE_CONFIG_H #include #endif @@ -48,6 +49,7 @@ #include "gtr-progress.h" #include "gtr-actions.h" #include "gtr-utils.h" +#include "gtr-profile-manager.h" #include #include @@ -261,6 +263,67 @@ show_hide_revealer (GtkWidget *widget, GdkEvent *ev, GtrTab *tab) return TRUE; } +static void +handle_file_is_inconsistent (GtrPo *po, GtrTab *tab) +{ + GtrTabPrivate *priv = gtr_tab_get_instance_private (tab); + GtrProfileManager *manager = gtr_profile_manager_get_default (); + GtrProfile *active_profile = gtr_profile_manager_get_active_profile (manager); + const char *profile_name = gtr_profile_get_name (active_profile); + int profile_nplurals = -1; + int po_nplurals = -1; + + g_autofree char *info_msg_primary = NULL; + g_autofree char *info_msg_secondary = NULL; + g_autofree char *filename = NULL; + g_autoptr (GFile) po_file = gtr_po_get_location (po); + + filename = g_file_get_path (po_file); + po_nplurals = gtr_header_get_nplurals (gtr_po_get_header (po)); + profile_nplurals = parse_nplurals_header (gtr_profile_get_plural_forms (active_profile)); + + info_msg_primary = g_strdup_printf ("File is not consistent with profile %s", profile_name); + info_msg_secondary = g_strdup_printf ( + "File nplurals: %d, is different from profile nplurals %d.\n" + "Kindly go to preferences and select a profile with consistent nplurals " + "values as this file %s.", + po_nplurals, profile_nplurals, filename + ); + gtr_tab_set_info (tab, info_msg_primary, info_msg_secondary); + + GtkWidget *nb = priv->trans_notebook; + gtk_widget_set_sensitive (nb, FALSE); + + g_object_unref (manager); +} + +static void +on_active_profile_changed (GtrProfileManager *manager, GtrProfile *profile, GtrTab *tab) +{ + GtrTabPrivate *priv = gtr_tab_get_instance_private (tab); + GtkWidget *nb = priv->trans_notebook; + + GtrPo *po = priv->po; + if (!gtr_po_consistent_with_profile (po)) + { + gtr_po_emit_file_not_consistent (po); + } + else + { + gtk_widget_set_sensitive (nb, TRUE); + } +} + +static void +on_profile_modified (GtrProfileManager *manager, + GtrProfile *old_profile, + GtrProfile *new_profile, + GtrTab *tab) +{ + on_active_profile_changed (manager, new_profile, tab); +} + + static void install_autosave_timeout (GtrTab * tab) { @@ -688,7 +751,7 @@ update_status (GtrTab * tab, GtrMsg * msg, gpointer useless) else gtk_label_set_text (GTK_LABEL (priv->msgid_tags), ""); - /* We need to update the tab state too if is neccessary */ + /* We need to update the tab state too if is necessary */ if (po_state != GTR_PO_STATE_MODIFIED) gtr_po_set_state (priv->po, GTR_PO_STATE_MODIFIED); } @@ -1033,9 +1096,12 @@ gtr_tab_new (GtrPo * po, { GtrTab *tab; GtrTabPrivate *priv; + GtrProfileManager *manager; g_return_val_if_fail (po != NULL, NULL); + manager = gtr_profile_manager_get_default(); + tab = g_object_new (GTR_TYPE_TAB, NULL); priv = gtr_tab_get_instance_private (tab); @@ -1052,6 +1118,15 @@ gtr_tab_new (GtrPo * po, g_signal_connect (po, "notify::state", G_CALLBACK (on_state_notify), tab); + g_signal_connect (po, "file-is-inconsistent-with-profile", + G_CALLBACK (handle_file_is_inconsistent), tab); + + g_signal_connect (manager, "active-profile-changed", + G_CALLBACK (on_active_profile_changed), tab); + + g_signal_connect (manager, "profile-modified", + G_CALLBACK (on_profile_modified), tab); + install_autosave_timeout_if_needed (tab); /* Now we have to initialize the number of msgstr tabs */ @@ -1060,6 +1135,11 @@ gtr_tab_new (GtrPo * po, gtr_message_table_populate (GTR_MESSAGE_TABLE (priv->message_table), GTR_MESSAGE_CONTAINER (priv->po)); + if (!gtr_po_consistent_with_profile (po)) + { + gtr_po_emit_file_not_consistent (po); + } + gtk_widget_show (GTK_WIDGET (tab)); return tab; } diff --git a/src/gtr-utils.c b/src/gtr-utils.c index c89d15147adb0b524cb72ae1bcacb456825bc0ed..756550193d898405124fb3591a198cef875b42b3 100644 --- a/src/gtr-utils.c +++ b/src/gtr-utils.c @@ -818,3 +818,31 @@ gtk_list_box_remove (GtkListBox *box, GtkWidget *child) { gtk_container_remove (GTK_CONTAINER (box), child); } + +// TODO: Improve this parser, this string parsing is weak +// It could be better to use GRegex: https://docs.gtk.org/glib/method.Regex.match.html +int +parse_nplurals_header (const gchar * plurals_header) +{ + gchar * pointer = g_strrstr (plurals_header, "nplurals"); + + if (!pointer) + return -1; + + while (*pointer != '\0' && *pointer != '=') + pointer++; + + if (*pointer != '\0') + { + pointer++; + while (*pointer != '\0' && *pointer == ' ') + pointer++; + + if (*pointer == '\0') + return -1; + } + else + return -1; + + return g_ascii_digit_value (*pointer); +} diff --git a/src/gtr-utils.h b/src/gtr-utils.h index 10aea1913c309775d54feeb56a616d8473c188ef..78362d6e767b26ec1ac3c9af156c424fe2b99b43 100644 --- a/src/gtr-utils.h +++ b/src/gtr-utils.h @@ -86,4 +86,6 @@ void gtr_utils_menu_position_under_tree_view (GtkMenu * menu, void gtk_list_box_append (GtkListBox *box, GtkWidget *child); void gtk_list_box_remove (GtkListBox *box, GtkWidget *child); + + int parse_nplurals_header (const gchar * plurals_header); #endif