lists.geany.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
List overview
Plugins-Commits
February 2015
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
plugins-commits@lists.geany.org
1 participants
61 discussions
Start a n
N
ew thread
[geany/geany-plugins] 332639: git-changebar: Fix support for libgit2 0.19.0
by Colomban Wendling
17 Feb '15
17 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 17 Feb 2015 15:17:00 UTC Commit: 332639f8585f0dbbbcd57d1c3d17865303b538cd
https://github.com/geany/geany-plugins/commit/332639f8585f0dbbbcd57d1c3d178…
Log Message: ----------- git-changebar: Fix support for libgit2 0.19.0 libgit2 < 0.20 had incompatible API for diff callbacks, so it requires some wrapping. Modified Paths: -------------- git-changebar/src/gcb-plugin.c Modified: git-changebar/src/gcb-plugin.c 27 lines changed, 27 insertions(+), 0 deletions(-) =================================================================== @@ -36,6 +36,9 @@ # define git_libgit2_init git_threads_init # define git_libgit2_shutdown git_threads_shutdown #endif +#if LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR < 20 +# define git_diff_hunk git_diff_range +#endif GeanyPlugin *geany_plugin; @@ -569,6 +572,18 @@ diff_hunk_cb (const git_diff_delta *delta, return 0; } +#if LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR < 20 +static int +diff_hunk_cb_wrapper (const git_diff_delta *delta, + const git_diff_hunk *hunk, + const char *header, + size_t header_len, + void *data) +{ + return diff_hunk_cb (delta, hunk, data); +} +# define diff_hunk_cb diff_hunk_cb_wrapper +#endif static GtkWidget * get_widget_for_blob_range (GeanyDocument *doc, @@ -663,6 +678,18 @@ tooltip_diff_hunk_cb (const git_diff_delta *delta, return thd->found; } +#if LIBGIT2_VER_MAJOR == 0 && LIBGIT2_VER_MINOR < 20 +static int +tooltip_diff_hunk_cb_wrapper (const git_diff_delta *delta, + const git_diff_hunk *hunk, + const char *header, + size_t header_len, + void *data) +{ + return tooltip_diff_hunk_cb (delta, hunk, data); +} +# define tooltip_diff_hunk_cb tooltip_diff_hunk_cb_wrapper +#endif static gboolean on_sci_query_tooltip (GtkWidget *widget, -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] 249320: pohelper: Only make leaf menu items insensitive
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 17:29:48 UTC Commit: 24932064310c0c5d6f6308f613f2ddf1334ffb4a
https://github.com/geany/geany-plugins/commit/24932064310c0c5d6f6308f613f2d…
Log Message: ----------- pohelper: Only make leaf menu items insensitive Don't make items with children insensitive, as this makes it impossible to open them, lowering the discoverability of the items. So, only make leaf items insensitive. Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 41 lines changed, 31 insertions(+), 10 deletions(-) =================================================================== @@ -69,12 +69,14 @@ static struct Plugin { GdkColor color_fuzzy; GdkColor color_untranslated; + GeanyKeyGroup *key_group; GtkWidget *menu_item; } plugin = { TRUE, { 0, 0x7373, 0xd2d2, 0x1616 }, /* tango mid green */ { 0, 0xeded, 0xd4d4, 0x0000 }, /* tango mid yellow */ { 0, 0xcccc, 0x0000, 0x0000 }, /* tango mid red */ + NULL, NULL }; @@ -533,10 +535,20 @@ on_document_save (GObject *obj, } static void -update_menus (GeanyDocument *doc) +update_menu_items_sensitivity (GeanyDocument *doc) { - if (plugin.menu_item) { - gtk_widget_set_sensitive (plugin.menu_item, doc_is_po (doc)); + gboolean sensitive = doc_is_po (doc); + guint i; + + /* since all the document-sensitive items have keybindings and all + * keybinginds that have a widget are document-sensitive, just walk + * the keybindings list to fetch the widgets */ + for (i = 0; i < GPH_KB_COUNT; i++) { + GeanyKeyBinding *kb = keybindings_get_item (plugin.key_group, i); + + if (kb->menu_item) { + gtk_widget_set_sensitive (kb->menu_item, sensitive); + } } } @@ -545,7 +557,7 @@ on_document_activate (GObject *obj, GeanyDocument *doc, gpointer user_data) { - update_menus (doc); + update_menu_items_sensitivity (doc); } static void @@ -554,7 +566,7 @@ on_document_filetype_set (GObject *obj, GeanyFiletype *old_ft, gpointer user_data) { - update_menus (doc); + update_menu_items_sensitivity (doc); } static void @@ -562,7 +574,13 @@ on_document_close (GObject *obj, GeanyDocument *doc, gpointer user_data) { - update_menus (NULL); + GtkNotebook *nb = GTK_NOTEBOOK (geany_data->main_widgets->notebook); + + /* the :document-close signal is emitted before a document gets closed, + * so there always still is the current document open (hence the < 2) */ + if (gtk_notebook_get_n_pages (nb) < 2) { + update_menu_items_sensitivity (NULL); + } } static void @@ -1675,7 +1693,6 @@ save_config (void) void plugin_init (GeanyData *data) { - GeanyKeyGroup *group; GtkBuilder *builder; GError *error = NULL; guint i; @@ -1717,7 +1734,8 @@ plugin_init (GeanyData *data) G_CALLBACK (on_document_save), NULL); /* add keybindings */ - group = plugin_set_key_group (geany_plugin, "pohelper", GPH_KB_COUNT, NULL); + plugin.key_group = plugin_set_key_group (geany_plugin, "pohelper", + GPH_KB_COUNT, NULL); for (i = 0; i < G_N_ELEMENTS (G_actions); i++) { GtkWidget *widget = NULL; @@ -1736,9 +1754,12 @@ plugin_init (GeanyData *data) } } - keybindings_set_item (group, G_actions[i].id, G_actions[i].callback, 0, 0, - G_actions[i].name, _(G_actions[i].label), widget); + keybindings_set_item (plugin.key_group, G_actions[i].id, + G_actions[i].callback, 0, 0, G_actions[i].name, + _(G_actions[i].label), widget); } + /* initial items sensitivity update */ + update_menu_items_sensitivity (document_get_current ()); if (builder) { g_object_unref (builder); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] 58aae2: Merge branch 'pohelper/stats-dialog' into pohelper/wip
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:20:45 UTC Commit: 58aae2b22b3cb4d96cfded1ccbbf3f283d81a7a1
https://github.com/geany/geany-plugins/commit/58aae2b22b3cb4d96cfded1ccbbf3…
Log Message: ----------- Merge branch 'pohelper/stats-dialog' into pohelper/wip Modified Paths: -------------- po/POTFILES.in pohelper/data/Makefile.am pohelper/data/menus.ui pohelper/data/stats.ui pohelper/src/gph-plugin.c Modified: po/POTFILES.in 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -220,11 +220,12 @@ gproject/src/gproject-sidebar.c markdown/src/conf.c markdown/src/plugin.c - # Pairtaghighlighter pairtaghighlighter/src/pair_tag_highlighter.c + # PoHelper [type: gettext/glade]pohelper/data/menus.ui +[type: gettext/glade]pohelper/data/stats.ui pohelper/src/gph-plugin.c # Pretty-printer Modified: pohelper/data/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1,4 +1,4 @@ include $(top_srcdir)/build/vars.docs.mk plugin = pohelper -dist_plugindata_DATA = menus.ui +dist_plugindata_DATA = menus.ui stats.ui Modified: pohelper/data/menus.ui 16 lines changed, 16 insertions(+), 0 deletions(-) =================================================================== @@ -224,6 +224,22 @@ </object> </child> <child> + <object class="GtkMenuItem" id="show_stats"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Show statistics of the current document</property> + <property name="label" translatable="yes">_Show stats</property> + <property name="use_underline">True</property> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem" id="separator6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + <child> <object class="GtkCheckMenuItem" id="update_headers_upon_save"> <property name="use_action_appearance">False</property> <property name="visible">True</property> Modified: pohelper/data/stats.ui 231 lines changed, 231 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="2.16"/> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkDialog" id="dialog"> + <property name="can_focus">False</property> + <property name="border_width">5</property> + <property name="title" translatable="yes">Translation statistics</property> + <property name="modal">True</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button1"> + <property name="label">gtk-close</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="spacing">5</property> + <child> + <object class="GtkDrawingArea" id="drawing_area"> + <property name="height_request">24</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">3</property> + <property name="n_columns">3</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkColorButton" id="color_translated"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for translated strings</property> + <property name="color">#7373d2d21616</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="color_fuzzy"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for fuzzily translated strings</property> + <property name="color">#ededd4d40000</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="color_untranslated"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for untranslated strings</property> + <property name="color">#cccc00000000</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Translated:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Fuzzy:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Untranslated:</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_translated"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_fuzzy"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_untranslated"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-7">button1</action-widget> + </action-widgets> + </object> +</interface> Modified: pohelper/src/gph-plugin.c 551 lines changed, 506 insertions(+), 45 deletions(-) =================================================================== @@ -57,16 +57,24 @@ enum { GPH_KB_PASTE_UNTRANSLATED, GPH_KB_REFLOW, GPH_KB_TOGGLE_FUZZY, + GPH_KB_SHOW_STATS, GPH_KB_COUNT }; static struct Plugin { gboolean update_headers; + /* stats dialog colors */ + GdkColor color_translated; + GdkColor color_fuzzy; + GdkColor color_untranslated; GtkWidget *menu_item; } plugin = { TRUE, + { 0, 0x7373, 0xd2d2, 0x1616 }, /* tango mid green */ + { 0, 0xeded, 0xd4d4, 0x0000 }, /* tango mid yellow */ + { 0, 0xcccc, 0x0000, 0x0000 }, /* tango mid red */ NULL }; @@ -747,6 +755,7 @@ get_msgstr_text_at (GeanyDocument *doc, if (pos >= 0) { ScintillaObject *sci = doc->editor->sci; GString *msgstr = g_string_new (NULL); + gint length = sci_get_length (sci); while (sci_get_style_at (sci, pos) == SCE_PO_MSGSTR_TEXT) { pos++; /* skip opening quote */ @@ -757,7 +766,7 @@ get_msgstr_text_at (GeanyDocument *doc, pos++; /* skip closing quote */ /* skip until next non-default style */ - while (sci_get_style_at (sci, pos) == SCE_PO_DEFAULT) { + while (pos < length && sci_get_style_at (sci, pos) == SCE_PO_DEFAULT) { pos++; } } @@ -768,6 +777,70 @@ get_msgstr_text_at (GeanyDocument *doc, return NULL; } +/* finds the start of the msgid text at @pos. the returned position is the + * start of the msgid text style, so it's on the first opening quote. Returns + * -1 if none found */ +static gint +find_msgid_start_at (GeanyDocument *doc, + gint pos) +{ + if (doc_is_po (doc)) { + ScintillaObject *sci = doc->editor->sci; + gint style = sci_get_style_at (sci, pos); + + /* find the previous non-default style */ + while (pos > 0 && style == SCE_PO_DEFAULT) { + style = sci_get_style_at (sci, --pos); + } + + /* if a msgid or msgstr, go to the msgstr keyword */ + if (style == SCE_PO_MSGID_TEXT || + style == SCE_PO_MSGSTR || + style == SCE_PO_MSGSTR_TEXT) { + pos = find_style (sci, SCE_PO_MSGID, pos, 0); + if (pos >= 0) + style = SCE_PO_MSGID; + } + + if (style == SCE_PO_MSGID) { + return find_style (sci, SCE_PO_MSGID_TEXT, pos, sci_get_length (sci)); + } + } + + return -1; +} + +static GString * +get_msgid_text_at (GeanyDocument *doc, + gint pos) +{ + pos = find_msgid_start_at (doc, pos); + + if (pos >= 0) { + ScintillaObject *sci = doc->editor->sci; + GString *msgid = g_string_new (NULL); + gint length = sci_get_length (sci); + + while (sci_get_style_at (sci, pos) == SCE_PO_MSGID_TEXT) { + pos++; /* skip opening quote */ + while (sci_get_style_at (sci, pos + 1) == SCE_PO_MSGID_TEXT) { + g_string_append_c (msgid, sci_get_char_at (sci, pos)); + pos++; + } + pos++; /* skip closing quote */ + + /* skip until next non-default style */ + while (pos < length && sci_get_style_at (sci, pos) == SCE_PO_DEFAULT) { + pos++; + } + } + + return msgid; + } + + return NULL; +} + /* cuts @str in human-readable chunks for max @len. * cuts first at \n, then at spaces and punctuation */ static gchar ** @@ -940,6 +1013,76 @@ parse_flags_line (ScintillaObject *sci, } } +static gint +find_msgid_line_at (GeanyDocument *doc, + gint pos) +{ + ScintillaObject *sci = doc->editor->sci; + gint line = sci_get_line_from_position (sci, pos); + gint style = find_first_non_default_style_on_line (sci, line); + + while (line > 0 && + (style == SCE_PO_DEFAULT || + (style == SCE_PO_MSGID && ! line_is_primary_msgid (sci, line)) || + style == SCE_PO_MSGID_TEXT || + style == SCE_PO_MSGSTR || + style == SCE_PO_MSGSTR_TEXT)) { + line--; + style = find_first_non_default_style_on_line (sci, line); + } + while (line < sci_get_line_count (sci) && + (style == SCE_PO_COMMENT || + style == SCE_PO_PROGRAMMER_COMMENT || + style == SCE_PO_REFERENCE || + style == SCE_PO_FLAGS || + style == SCE_PO_FUZZY)) { + line++; + style = find_first_non_default_style_on_line (sci, line); + } + + return (style == SCE_PO_MSGID) ? line : -1; +} + +static gint +find_flags_line_at (GeanyDocument *doc, + gint pos) +{ + gint line = find_msgid_line_at (doc, pos); + + if (line > 0) { + gint style; + + do { + line--; + style = find_first_non_default_style_on_line (doc->editor->sci, line); + } while (line > 0 && + (style == SCE_PO_COMMENT || + style == SCE_PO_PROGRAMMER_COMMENT || + style == SCE_PO_REFERENCE)); + + if (style != SCE_PO_FLAGS && style != SCE_PO_FUZZY) { + line = -1; + } + } + + return line; +} + +static GPtrArray * +get_flags_at (GeanyDocument *doc, + gint pos) +{ + GPtrArray *flags = NULL; + gint line = find_flags_line_at (doc, pos); + + if (line >= 0) { + flags = g_ptr_array_new (); + parse_flags_line (doc->editor->sci, line, flags); + } + + return flags; +} + /* adds or remove @flag from @flags. returns whether the flag was added */ static gboolean toggle_flag (GPtrArray *flags, @@ -1007,57 +1150,23 @@ on_kb_toggle_fuzziness (guint key_id) if (doc_is_po (doc)) { ScintillaObject *sci = doc->editor->sci; gint pos = sci_get_current_position (sci); - gint line = sci_get_line_from_position (sci, pos); - gint style = find_first_non_default_style_on_line (sci, line); - - /* find the msgid for the current line */ - while (line > 0 && - (style == SCE_PO_DEFAULT || - (style == SCE_PO_MSGID && ! line_is_primary_msgid (sci, line)) || - style == SCE_PO_MSGID_TEXT || - style == SCE_PO_MSGSTR || - style == SCE_PO_MSGSTR_TEXT)) { - line--; - style = find_first_non_default_style_on_line (sci, line); - } - while (line < sci_get_line_count (sci) && - (style == SCE_PO_COMMENT || - style == SCE_PO_PROGRAMMER_COMMENT || - style == SCE_PO_REFERENCE || - style == SCE_PO_FLAGS || - style == SCE_PO_FUZZY)) { - line++; - style = find_first_non_default_style_on_line (sci, line); - } + gint msgid_line = find_msgid_line_at (doc, pos); + gint flags_line = find_flags_line_at (doc, pos); - if (style == SCE_PO_MSGID) { - gint msgid_line = line; + if (flags_line >= 0 || msgid_line >= 0) { GPtrArray *flags = g_ptr_array_new_with_free_func (g_free); sci_start_undo_action (sci); - if (line > 0) { - /* search for an existing flags line */ - do { - line--; - style = find_first_non_default_style_on_line (sci, line); - } while (line > 0 && - (style == SCE_PO_COMMENT || - style == SCE_PO_PROGRAMMER_COMMENT || - style == SCE_PO_REFERENCE)); - - if (style == SCE_PO_FLAGS || style == SCE_PO_FUZZY) { - /* ok we got a line with flags, parse them and remove them */ - parse_flags_line (sci, line, flags); - delete_line (sci, line); - } else { - /* no flags, add the line */ - line = msgid_line; - } + if (flags_line >= 0) { + parse_flags_line (sci, flags_line, flags); + delete_line (sci, flags_line); + } else { + flags_line = msgid_line; } toggle_flag (flags, "fuzzy"); - write_flags (sci, sci_get_position_from_line (sci, line), flags); + write_flags (sci, sci_get_position_from_line (sci, flags_line), flags); sci_end_undo_action (sci); @@ -1066,6 +1175,308 @@ on_kb_toggle_fuzziness (guint key_id) } } +typedef struct { + gdouble translated; + gdouble fuzzy; + gdouble untranslated; +} StatsGraphData; + +/* + * rounded_rectangle: + * @cr: a Cairo context + * @x: X coordinate of the top-left corner of the rectangle + * @y: Y coordinate of the top-left corner of the rectangle + * @width: width of the rectangle + * @height: height of the rectangle + * @r1: radius of the top-left corner + * @r2: radius of the top-right corner + * @r3: radius of the bottom-right corner + * @r4: radius of the bottom-left corner + * + * Creates a rectangle path with rounded corners. + * + * Warning: The rectangle should be big enough to include the corners, + * otherwise the result will be weird. For example, if all corners + * radius are set to 5, the rectangle should be at least 10x10. + */ +static void +rounded_rectangle (cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble r1, + gdouble r2, + gdouble r3, + gdouble r4) +{ + cairo_move_to (cr, x + r1, y); + cairo_arc (cr, x + width - r2, y + r2, r2, -G_PI/2.0, 0); + cairo_arc (cr, x + width - r3, y + height - r3, r3, 0, G_PI/2.0); + cairo_arc (cr, x + r4, y + height - r4, r4, G_PI/2.0, -G_PI); + cairo_arc (cr, x + r1, y + r1, r1, -G_PI, -G_PI/2.0); + cairo_close_path (cr); +} + +#if ! GTK_CHECK_VERSION (3, 0, 0) && ! defined (gtk_widget_get_allocated_width) +# define gtk_widget_get_allocated_width(w) (GTK_WIDGET (w)->allocation.width) +#endif +#if ! GTK_CHECK_VERSION (3, 0, 0) && ! defined (gtk_widget_get_allocated_height) +# define gtk_widget_get_allocated_height(w) (GTK_WIDGET (w)->allocation.height) +#endif + +static gboolean +stats_graph_draw (GtkWidget *widget, + cairo_t *cr, + gpointer user_data) +{ + const StatsGraphData *data = user_data; + const gint width = gtk_widget_get_allocated_width (widget); + const gint height = gtk_widget_get_allocated_height (widget); + const gdouble translated = width * data->translated; + const gdouble fuzzy = width * data->fuzzy; + const gdouble untranslated = width * data->untranslated; + const gdouble r = MIN (width / 4, height / 4); + cairo_pattern_t *pat; + + rounded_rectangle (cr, 0, 0, width, height, r, r, r, r); + cairo_clip (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_translated); + cairo_rectangle (cr, 0, 0, translated, height); + cairo_fill (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_fuzzy); + cairo_rectangle (cr, translated, 0, fuzzy, height); + cairo_fill (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_untranslated); + cairo_rectangle (cr, translated + fuzzy, 0, untranslated, height); + cairo_fill (cr); + + /* draw a nice thin border */ + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgba (cr, 0, 0, 0, 0.2); + rounded_rectangle (cr, 0.5, 0.5, width - 1, height - 1, r, r, r, r); + cairo_stroke (cr); + + /* draw a gradient to give the graph a little depth */ + pat = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 0.2); + cairo_pattern_add_color_stop_rgba (pat, height, 0, 0, 0, 0.2); + cairo_set_source (cr, pat); + cairo_pattern_destroy (pat); + cairo_rectangle (cr, 0, 0, width, height); + cairo_paint (cr); + + return TRUE; +} + +static gboolean +stats_graph_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip, + gpointer user_data) +{ + const StatsGraphData *data = user_data; + gchar *markup = NULL; + + if (keyboard_mode) { + gchar *translated_str = g_strdup_printf (_("<b>Translated:</b> %.3g%%"), + data->translated * 100); + gchar *fuzzy_str = g_strdup_printf (_("<b>Fuzzy:</b> %.3g%%"), + data->fuzzy * 100); + gchar *untranslated_str = g_strdup_printf (_("<b>Untranslated:</b> %.3g%%"), + data->untranslated * 100); + + markup = g_strconcat (translated_str, "\n", + fuzzy_str, "\n", + untranslated_str, NULL); + g_free (translated_str); + g_free (fuzzy_str); + g_free (untranslated_str); + } else { + const gint width = gtk_widget_get_allocated_width (widget); + + if (x <= width * data->translated) { + markup = g_strdup_printf (_("<b>Translated:</b> %.3g%%"), + data->translated * 100); + } else if (x <= width * (data->translated + data->fuzzy)) { + markup = g_strdup_printf (_("<b>Fuzzy:</b> %.3g%%"), data->fuzzy * 100); + } else { + markup = g_strdup_printf (_("<b>Untranslated:</b> %.3g%%"), + data->untranslated * 100); + } + } + + gtk_tooltip_set_markup (tooltip, markup); + g_free (markup); + + return TRUE; +} + +#if ! GTK_CHECK_VERSION (3, 0, 0) +static gboolean +on_stats_graph_expose_event (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + cairo_t *cr = gdk_cairo_create (GDK_DRAWABLE (widget->window)); + gboolean ret = stats_graph_draw (widget, cr, data); + + cairo_destroy (cr); + + return ret; +} +#endif + +static void +on_color_button_color_notify (GtkWidget *widget, + GParamSpec *pspec, + gpointer user_data) +{ + gtk_color_button_get_color (GTK_COLOR_BUTTON (widget), user_data); +} + +static void +show_stats_dialog (guint all, + guint translated, + guint untranslated, + guint fuzzy) +{ + GError *error = NULL; + GtkBuilder *builder = gtk_builder_new (); + + gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); + if (! gtk_builder_add_from_file (builder, PKGDATADIR"/pohelper/stats.ui", + &error)) { + g_critical (_("Failed to load UI definition, please check your " + "installation. The error was: %s"), error->message); + g_error_free (error); + } else { + StatsGraphData data; + GObject *dialog; + GObject *drawing_area; + + data.translated = all ? (translated * 1.0 / all) : 0; + data.fuzzy = all ? (fuzzy * 1.0 / all) : 0; + data.untranslated = all ? (untranslated * 1.0 / all) : 0; + + drawing_area = gtk_builder_get_object (builder, "drawing_area"); +#if ! GTK_CHECK_VERSION (3, 0, 0) + g_signal_connect (drawing_area, + "expose-event", G_CALLBACK (on_stats_graph_expose_event), + &data); +#else + g_signal_connect (drawing_area, + "draw", G_CALLBACK (stats_graph_draw), + &data); +#endif + g_signal_connect (drawing_area, + "query-tooltip", G_CALLBACK (stats_graph_query_tooltip), + &data); + gtk_widget_set_has_tooltip (GTK_WIDGET (drawing_area), TRUE); + + #define SET_LABEL_N(id, value) \ + do { \ + GObject *obj__ = gtk_builder_get_object (builder, (id)); \ + \ + if (! obj__) { \ + g_warning ("Object \"%s\" is missing from the UI definition", (id)); \ + } else { \ + gchar *text__ = g_strdup_printf (_("%u (%.3g%%)"), \ + (value), \ + all ? ((value) * 100.0 / all) : 0); \ + \ + gtk_label_set_text (GTK_LABEL (obj__), text__); \ + g_free (text__); \ + } \ + } while (0) + + SET_LABEL_N ("n_translated", translated); + SET_LABEL_N ("n_fuzzy", fuzzy); + SET_LABEL_N ("n_untranslated", untranslated); + + #undef SET_LABEL_N + + #define BIND_COLOR_BTN(id, color) \ + do { \ + GObject *obj__ = gtk_builder_get_object (builder, (id)); \ + \ + if (! obj__) { \ + g_warning ("Object \"%s\" is missing from the UI definition", (id)); \ + } else { \ + gtk_color_button_set_color (GTK_COLOR_BUTTON (obj__), (color)); \ + g_signal_connect (obj__, "notify::color", \ + G_CALLBACK (on_color_button_color_notify), \ + (color)); \ + /* queue a redraw on the drawing area so it uses the new color */ \ + g_signal_connect_swapped (obj__, "notify::color", \ + G_CALLBACK (gtk_widget_queue_draw), \ + drawing_area); \ + } \ + } while (0) + + BIND_COLOR_BTN ("color_translated", &plugin.color_translated); + BIND_COLOR_BTN ("color_fuzzy", &plugin.color_fuzzy); + BIND_COLOR_BTN ("color_untranslated", &plugin.color_untranslated); + + #undef BIND_COLOR_BTN + + dialog = gtk_builder_get_object (builder, "dialog"); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (geany_data->main_widgets->window)); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + g_object_unref (builder); +} + +static void +on_kb_show_stats (guint key_id) +{ + GeanyDocument *doc = document_get_current (); + + if (doc_is_po (doc)) { + ScintillaObject *sci = doc->editor->sci; + const gint len = sci_get_length (sci); + gint pos = 0; + guint all = 0; + guint untranslated = 0; + guint fuzzy = 0; + + /* don't use find_message() because we want only match one block, not each + * msgstr as there might be plural forms */ + while ((pos = find_style (sci, SCE_PO_MSGID, pos, len)) >= 0 && + (pos = find_style (sci, SCE_PO_MSGSTR, pos, len)) >= 0) { + GString *msgid = get_msgid_text_at (doc, pos); + GString *msgstr = get_msgstr_text_at (doc, pos); + + if (msgid->len > 0) { + all++; + if (msgstr->len < 1) { + untranslated++; + } else { + GPtrArray *flags = get_flags_at (doc, pos); + + if (flags) { + fuzzy += ! toggle_flag (flags, "fuzzy"); + + g_ptr_array_foreach (flags, (GFunc) g_free, NULL); + g_ptr_array_free (flags, TRUE); + } + } + } + g_string_free (msgstr, TRUE); + g_string_free (msgid, TRUE); + } + + show_stats_dialog (all, all - untranslated - fuzzy, fuzzy, untranslated); + } +} + static const struct Action { guint id; const gchar *name; @@ -1108,7 +1519,10 @@ static const struct Action { N_("Reflow the current translation string"), "reflow_translation" }, { GPH_KB_TOGGLE_FUZZY, "toggle-fuzziness", on_kb_toggle_fuzziness, - N_("Toggle current translation fuzziness"), "toggle_fuzziness" } + N_("Toggle current translation fuzziness"), "toggle_fuzziness" }, + { GPH_KB_SHOW_STATS, "show-stats", + on_kb_show_stats, + N_("Show statistics of the current document"), "show_stats" } }; static void @@ -1182,6 +1596,47 @@ write_keyfile (GKeyFile *kf, return success; } +/* + * get_setting_color: + * @kf: a #GKeyFile from which load the color + * @group: the key file group + * @key: the key file key + * @color: (out): the color to fill with the read value. If the key is not + * found, the color isn't updated + * + * Loads a color from a key file entry. + * + * Returns: %TRUE if the color was loaded, %FALSE otherwise. + */ +static gboolean +get_setting_color (GKeyFile *kf, + const gchar *group, + const gchar *key, + GdkColor *color) +{ + gboolean success = FALSE; + gchar *value = g_key_file_get_value (kf, group, key, NULL); + + if (value) { + success = gdk_color_parse (value, color); + g_free (value); + } + + return success; +} + +static void +set_setting_color (GKeyFile *kf, + const gchar *group, + const gchar *key, + const GdkColor *color) +{ + gchar *value = gdk_color_to_string (color); + + g_key_file_set_value (kf, group, key, value); + g_free (value); +} + static void load_config (void) { @@ -1192,6 +1647,9 @@ load_config (void) plugin.update_headers = utils_get_setting_boolean (kf, "general", "update-headers", plugin.update_headers); + get_setting_color (kf, "colors", "translated", &plugin.color_translated); + get_setting_color (kf, "colors", "fuzzy", &plugin.color_fuzzy); + get_setting_color (kf, "colors", "untranslated", &plugin.color_untranslated); } g_key_file_free (kf); g_free (filename); @@ -1206,6 +1664,9 @@ save_config (void) load_keyfile (kf, filename, G_KEY_FILE_KEEP_COMMENTS); g_key_file_set_boolean (kf, "general", "update-headers", plugin.update_headers); + set_setting_color (kf, "colors", "translated", &plugin.color_translated); + set_setting_color (kf, "colors", "fuzzy", &plugin.color_fuzzy); + set_setting_color (kf, "colors", "untranslated", &plugin.color_untranslated); write_keyfile (kf, filename); g_key_file_free (kf); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] fa7e9f: pohelper: Fix leaks retrieving file stats
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:22:13 UTC Commit: fa7e9f69a33cc5e4a9ad3de3256e7eee252ea472
https://github.com/geany/geany-plugins/commit/fa7e9f69a33cc5e4a9ad3de3256e7…
Log Message: ----------- pohelper: Fix leaks retrieving file stats Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 3 lines changed, 1 insertions(+), 2 deletions(-) =================================================================== @@ -1076,7 +1076,7 @@ get_flags_at (GeanyDocument *doc, gint line = find_flags_line_at (doc, pos); if (line >= 0) { - flags = g_ptr_array_new (); + flags = g_ptr_array_new_with_free_func (g_free); parse_flags_line (doc->editor->sci, line, flags); } @@ -1464,7 +1464,6 @@ on_kb_show_stats (guint key_id) if (flags) { fuzzy += ! toggle_flag (flags, "fuzzy"); - g_ptr_array_foreach (flags, (GFunc) g_free, NULL); g_ptr_array_free (flags, TRUE); } } -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] a3a416: pohelper: Fix stats when file contains plural forms
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:16:27 UTC Commit: a3a416200c4158e3e2bb4e150d267845c625c413
https://github.com/geany/geany-plugins/commit/a3a416200c4158e3e2bb4e150d267…
Log Message: ----------- pohelper: Fix stats when file contains plural forms Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 16 lines changed, 10 insertions(+), 6 deletions(-) =================================================================== @@ -1344,13 +1344,17 @@ on_kb_show_stats (guint key_id) GeanyDocument *doc = document_get_current (); if (doc_is_po (doc)) { - const gint len = sci_get_length (doc->editor->sci); - gint pos = 0; - guint all = 0; - guint untranslated = 0; - guint fuzzy = 0; + ScintillaObject *sci = doc->editor->sci; + const gint len = sci_get_length (sci); + gint pos = 0; + guint all = 0; + guint untranslated = 0; + guint fuzzy = 0; - while ((pos = find_message (doc, pos, len)) >= 0) { + /* don't use find_message() because we want only match one block, not each + * msgstr as there might be plural forms */ + while ((pos = find_style (sci, SCE_PO_MSGID, pos, len)) >= 0 && + (pos = find_style (sci, SCE_PO_MSGSTR, pos, len)) >= 0) { GString *msgid = get_msgid_text_at (doc, pos); GString *msgstr = get_msgstr_text_at (doc, pos); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] 2780d1: pohelper: Add tooltip to stats graph
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:16:33 UTC Commit: 2780d126ae03fa9cd1be42b0d69ba09b24a355e1
https://github.com/geany/geany-plugins/commit/2780d126ae03fa9cd1be42b0d69ba…
Log Message: ----------- pohelper: Add tooltip to stats graph Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 49 lines changed, 49 insertions(+), 0 deletions(-) =================================================================== @@ -1225,6 +1225,51 @@ stats_graph_draw (GtkWidget *widget, return TRUE; } +static gboolean +stats_graph_query_tooltip (GtkWidget *widget, + gint x, + gint y, + gboolean keyboard_mode, + GtkTooltip *tooltip, + gpointer user_data) +{ + const StatsGraphData *data = user_data; + gchar *markup = NULL; + + if (keyboard_mode) { + gchar *translated_str = g_strdup_printf (_("<b>Translated:</b> %.3g%%"), + data->translated * 100); + gchar *fuzzy_str = g_strdup_printf (_("<b>Fuzzy:</b> %.3g%%"), + data->fuzzy * 100); + gchar *untranslated_str = g_strdup_printf (_("<b>Untranslated:</b> %.3g%%"), + data->untranslated * 100); + + markup = g_strconcat (translated_str, "\n", + fuzzy_str, "\n", + untranslated_str, NULL); + g_free (translated_str); + g_free (fuzzy_str); + g_free (untranslated_str); + } else { + const gint width = gtk_widget_get_allocated_width (widget); + + if (x <= width * data->translated) { + markup = g_strdup_printf (_("<b>Translated:</b> %.3g%%"), + data->translated * 100); + } else if (x <= width * (data->translated + data->fuzzy)) { + markup = g_strdup_printf (_("<b>Fuzzy:</b> %.3g%%"), data->fuzzy * 100); + } else { + markup = g_strdup_printf (_("<b>Untranslated:</b> %.3g%%"), + data->untranslated * 100); + } + } + + gtk_tooltip_set_markup (tooltip, markup); + g_free (markup); + + return TRUE; +} + #if ! GTK_CHECK_VERSION (3, 0, 0) static gboolean on_stats_graph_expose_event (GtkWidget *widget, @@ -1282,6 +1327,10 @@ show_stats_dialog (guint all, "draw", G_CALLBACK (stats_graph_draw), &data); #endif + g_signal_connect (drawing_area, + "query-tooltip", G_CALLBACK (stats_graph_query_tooltip), + &data); + gtk_widget_set_has_tooltip (GTK_WIDGET (drawing_area), TRUE); #define SET_LABEL_N(id, value) \ do { \ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] fcacc7: pohelper: Improve display of stats percentage
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:16:15 UTC Commit: fcacc7e7db6ed8cf8aa1391e0cf0ca709933585b
https://github.com/geany/geany-plugins/commit/fcacc7e7db6ed8cf8aa1391e0cf0c…
Log Message: ----------- pohelper: Improve display of stats percentage Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1290,7 +1290,7 @@ show_stats_dialog (guint all, if (! obj__) { \ g_warning ("Object \"%s\" is missing from the UI definition", (id)); \ } else { \ - gchar *text__ = g_strdup_printf (_("%u (%.1f%%)"), \ + gchar *text__ = g_strdup_printf (_("%u (%.3g%%)"), \ (value), \ all ? ((value) * 100.0 / all) : 0); \ \ -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] 34d7af: pohelper: Fix finding previous msgstr when it has plural forms
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:08:37 UTC Commit: 34d7af8fdfdd8ec26da0f6656eb5c4328a9bb808
https://github.com/geany/geany-plugins/commit/34d7af8fdfdd8ec26da0f6656eb5c…
Log Message: ----------- pohelper: Fix finding previous msgstr when it has plural forms Modified Paths: -------------- pohelper/src/gph-plugin.c Modified: pohelper/src/gph-plugin.c 67 lines changed, 56 insertions(+), 11 deletions(-) =================================================================== @@ -126,6 +126,36 @@ find_style (ScintillaObject *sci, return pos; } +/* like find_style(), but searches for the first style change from @start to + * @end. Returns the first position in the search direction with a style + * different from the one at @start, or -1 */ +static gint +find_style_boundary (ScintillaObject *sci, + gint start, + gint end) +{ + gint style = sci_get_style_at (sci, start); + gint pos; + + if (start > end) { /* search backwards */ + for (pos = start; pos >= end; pos--) { + if (sci_get_style_at (sci, pos) != style) + break; + } + if (pos < end) + return -1; + } else { + for (pos = start; pos < end; pos++) { + if (sci_get_style_at (sci, pos) != style) + break; + } + if (pos >= end) + return -1; + } + + return pos; +} + /* * find_message: * @doc: A #GeanyDocument @@ -147,6 +177,29 @@ find_message (GeanyDocument *doc, ScintillaObject *sci = doc->editor->sci; gint pos = find_style (sci, SCE_PO_MSGSTR, start, end); + /* if searching backwards and already in a msgstr style, search previous + * again not to go to current's start */ + if (pos >= 0 && start > end) { + gint style = sci_get_style_at (sci, start); + + /* don't take default style into account, so find previous non-default */ + if (style == SCE_PO_DEFAULT) { + gint style_pos = find_style_boundary (sci, start, end); + if (style_pos >= 0) { + style = sci_get_style_at (sci, style_pos); + } + } + + if (style == SCE_PO_MSGSTR || + style == SCE_PO_MSGSTR_TEXT || + style == SCE_PO_MSGSTR_TEXT_EOL) { + pos = find_style_boundary (sci, pos, end); + if (pos >= 0) { + pos = find_style (sci, SCE_PO_MSGSTR, pos, end); + } + } + } + if (pos >= 0) { pos = find_style (sci, SCE_PO_MSGSTR_TEXT, pos, sci_get_length (sci)); if (pos >= 0) { @@ -177,15 +230,10 @@ find_untranslated (GeanyDocument *doc, { if (doc_is_po (doc)) { ScintillaObject *sci = doc->editor->sci; - gboolean backwards = start > end; while (start >= 0) { gint pos; - if (backwards) { - start = find_style (sci, SCE_PO_MSGID, start, end); - } - pos = find_message (doc, start, end); if (pos < 0) { return -1; @@ -298,14 +346,11 @@ static void goto_prev (GeanyDocument *doc) { if (doc_is_po (doc)) { - gint pos = sci_get_current_position (doc->editor->sci); + gint pos = find_message (doc, sci_get_current_position (doc->editor->sci), + 0); - pos = find_style (doc->editor->sci, SCE_PO_MSGID, pos, 0); if (pos >= 0) { - pos = find_message (doc, pos, 0); - if (pos >= 0) { - editor_goto_pos (doc->editor, pos, FALSE); - } + editor_goto_pos (doc->editor, pos, FALSE); } } } -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] 6ebce8: pohelper: Fix a memory leak when removing fuzzy flag
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Tue, 22 Apr 2014 16:14:10 UTC Commit: 6ebce810274c2be48ba5dafa3c1df5697c9c07ca
https://github.com/geany/geany-plugins/commit/6ebce810274c2be48ba5dafa3c1df…
Log Message: ----------- pohelper: Fix a memory leak when removing fuzzy flag Modified Paths: -------------- build/pohelper.m4 pohelper/src/gph-plugin.c Modified: build/pohelper.m4 5 lines changed, 4 insertions(+), 1 deletions(-) =================================================================== @@ -1,6 +1,9 @@ AC_DEFUN([GP_CHECK_POHELPER], [ - GP_ARG_DISABLE([PoHelper], [yes]) + GP_ARG_DISABLE([PoHelper], [auto]) + + dnl We require GLib >= 2.22, and Geany only depends on 2.20 + GP_CHECK_PLUGIN_DEPS([PoHelper], [GLIB], [glib-2.0 >= 2.22]) GP_COMMIT_PLUGIN_STATUS([PoHelper]) Modified: pohelper/src/gph-plugin.c 3 lines changed, 1 insertions(+), 2 deletions(-) =================================================================== @@ -1032,7 +1032,7 @@ on_kb_toggle_fuzziness (guint key_id) if (style == SCE_PO_MSGID) { gint msgid_line = line; - GPtrArray *flags = g_ptr_array_new (); + GPtrArray *flags = g_ptr_array_new_with_free_func (g_free); sci_start_undo_action (sci); @@ -1061,7 +1061,6 @@ on_kb_toggle_fuzziness (guint key_id) sci_end_undo_action (sci); - g_ptr_array_foreach (flags, (GFunc) g_free, NULL); g_ptr_array_free (flags, TRUE); } } -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
[geany/geany-plugins] c4a2dc: pohelper: Add a stats dialog
by Colomban Wendling
16 Feb '15
16 Feb '15
Branch: refs/heads/master Author: Colomban Wendling <ban(a)herbesfolles.org> Committer: Colomban Wendling <ban(a)herbesfolles.org> Date: Mon, 17 Jun 2013 15:06:36 UTC Commit: c4a2dc18d85fb694a5b21bec54781b5cfaec265b
https://github.com/geany/geany-plugins/commit/c4a2dc18d85fb694a5b21bec54781…
Log Message: ----------- pohelper: Add a stats dialog Modified Paths: -------------- po/POTFILES.in pohelper/data/Makefile.am pohelper/data/menus.ui pohelper/data/stats.ui pohelper/src/gph-plugin.c Modified: po/POTFILES.in 3 lines changed, 2 insertions(+), 1 deletions(-) =================================================================== @@ -211,11 +211,12 @@ gproject/src/gproject-sidebar.c markdown/src/conf.c markdown/src/plugin.c - # Pairtaghighlighter pairtaghighlighter/src/pair_tag_highlighter.c + # PoHelper [type: gettext/glade]pohelper/data/menus.ui +[type: gettext/glade]pohelper/data/stats.ui pohelper/src/gph-plugin.c # Pretty-printer Modified: pohelper/data/Makefile.am 2 lines changed, 1 insertions(+), 1 deletions(-) =================================================================== @@ -1,4 +1,4 @@ include $(top_srcdir)/build/vars.docs.mk plugin = pohelper -dist_plugindata_DATA = menus.ui +dist_plugindata_DATA = menus.ui stats.ui Modified: pohelper/data/menus.ui 16 lines changed, 16 insertions(+), 0 deletions(-) =================================================================== @@ -224,6 +224,22 @@ </object> </child> <child> + <object class="GtkMenuItem" id="show_stats"> + <property name="use_action_appearance">False</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="tooltip_text" translatable="yes">Show statistics of the current document</property> + <property name="label" translatable="yes">_Show stats</property> + <property name="use_underline">True</property> + </object> + </child> + <child> + <object class="GtkSeparatorMenuItem" id="separator6"> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + </child> + <child> <object class="GtkCheckMenuItem" id="update_headers_upon_save"> <property name="use_action_appearance">False</property> <property name="visible">True</property> Modified: pohelper/data/stats.ui 222 lines changed, 222 insertions(+), 0 deletions(-) =================================================================== @@ -0,0 +1,222 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <requires lib="gtk+" version="2.16"/> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkDialog" id="dialog"> + <property name="can_focus">False</property> + <property name="border_width">5</property> + <property name="title" translatable="yes">Translation statistics</property> + <property name="modal">True</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button1"> + <property name="label">gtk-close</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="has_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="border_width">6</property> + <property name="spacing">5</property> + <child> + <object class="GtkDrawingArea" id="drawing_area"> + <property name="height_request">24</property> + <property name="visible">True</property> + <property name="can_focus">False</property> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkTable" id="table1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="n_rows">3</property> + <property name="n_columns">3</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkColorButton" id="color_translated"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for translated strings</property> + <property name="color">#7373d2d21616</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="color_fuzzy"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for fuzzily translated strings</property> + <property name="color">#ededd4d40000</property> + </object> + <packing> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkColorButton" id="color_untranslated"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="relief">none</property> + <property name="title" translatable="yes">Choose a color for untranslated strings</property> + <property name="color">#cccc00000000</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Translated:</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label2"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Fuzzy:</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label3"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Untranslated:</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_translated"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_fuzzy"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="n_untranslated"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="xalign">0</property> + <property name="label">0</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-7">button1</action-widget> + </action-widgets> + </object> +</interface> Modified: pohelper/src/gph-plugin.c 388 lines changed, 387 insertions(+), 1 deletions(-) =================================================================== @@ -57,16 +57,24 @@ enum { GPH_KB_PASTE_UNTRANSLATED, GPH_KB_REFLOW, GPH_KB_TOGGLE_FUZZY, + GPH_KB_SHOW_STATS, GPH_KB_COUNT }; static struct Plugin { gboolean update_headers; + /* stats dialog colors */ + GdkColor color_translated; + GdkColor color_fuzzy; + GdkColor color_untranslated; GtkWidget *menu_item; } plugin = { TRUE, + { 0, 0x7373, 0xd2d2, 0x1616 }, /* tango mid green */ + { 0, 0xeded, 0xd4d4, 0x0000 }, /* tango mid yellow */ + { 0, 0xcccc, 0x0000, 0x0000 }, /* tango mid red */ NULL }; @@ -724,6 +732,70 @@ get_msgstr_text_at (GeanyDocument *doc, return NULL; } +/* finds the start of the msgid text at @pos. the returned position is the + * start of the msgid text style, so it's on the first opening quote. Returns + * -1 if none found */ +static gint +find_msgid_start_at (GeanyDocument *doc, + gint pos) +{ + if (doc_is_po (doc)) { + ScintillaObject *sci = doc->editor->sci; + gint style = sci_get_style_at (sci, pos); + + /* find the previous non-default style */ + while (pos > 0 && style == SCE_PO_DEFAULT) { + style = sci_get_style_at (sci, --pos); + } + + /* if a msgid or msgstr, go to the msgstr keyword */ + if (style == SCE_PO_MSGID_TEXT || + style == SCE_PO_MSGSTR || + style == SCE_PO_MSGSTR_TEXT) { + pos = find_style (sci, SCE_PO_MSGID, pos, 0); + if (pos >= 0) + style = SCE_PO_MSGID; + } + + if (style == SCE_PO_MSGID) { + return find_style (sci, SCE_PO_MSGID_TEXT, pos, sci_get_length (sci)); + } + } + + return -1; +} + +static GString * +get_msgid_text_at (GeanyDocument *doc, + gint pos) +{ + pos = find_msgid_start_at (doc, pos); + + if (pos >= 0) { + ScintillaObject *sci = doc->editor->sci; + GString *msgid = g_string_new (NULL); + gint length = sci_get_length (sci); + + while (sci_get_style_at (sci, pos) == SCE_PO_MSGID_TEXT) { + pos++; /* skip opening quote */ + while (sci_get_style_at (sci, pos + 1) == SCE_PO_MSGID_TEXT) { + g_string_append_c (msgid, sci_get_char_at (sci, pos)); + pos++; + } + pos++; /* skip closing quote */ + + /* skip until next non-default style */ + while (pos < length && sci_get_style_at (sci, pos) == SCE_PO_DEFAULT) { + pos++; + } + } + + return msgid; + } + + return NULL; +} + /* cuts @str in human-readable chunks for max @len. * cuts first at \n, then at spaces and punctuation */ static gchar ** @@ -948,6 +1020,21 @@ find_flags_line_at (GeanyDocument *doc, return line; } +static GPtrArray * +get_flags_at (GeanyDocument *doc, + gint pos) +{ + GPtrArray *flags = NULL; + gint line = find_flags_line_at (doc, pos); + + if (line >= 0) { + flags = g_ptr_array_new (); + parse_flags_line (doc->editor->sci, line, flags); + } + + return flags; +} + /* adds or remove @flag from @flags. returns whether the flag was added */ static gboolean toggle_flag (GPtrArray *flags, @@ -1041,6 +1128,255 @@ on_kb_toggle_fuzziness (guint key_id) } } +typedef struct { + gdouble translated; + gdouble fuzzy; + gdouble untranslated; +} StatsGraphData; + +/* + * rounded_rectangle: + * @cr: a Cairo context + * @x: X coordinate of the top-left corner of the rectangle + * @y: Y coordinate of the top-left corner of the rectangle + * @width: width of the rectangle + * @height: height of the rectangle + * @r1: radius of the top-left corner + * @r2: radius of the top-right corner + * @r3: radius of the bottom-right corner + * @r4: radius of the bottom-left corner + * + * Creates a rectangle path with rounded corners. + * + * Warning: The rectangle should be big enough to include the corners, + * otherwise the result will be weird. For example, if all corners + * radius are set to 5, the rectangle should be at least 10x10. + */ +static void +rounded_rectangle (cairo_t *cr, + gdouble x, + gdouble y, + gdouble width, + gdouble height, + gdouble r1, + gdouble r2, + gdouble r3, + gdouble r4) +{ + cairo_move_to (cr, x + r1, y); + cairo_arc (cr, x + width - r2, y + r2, r2, -G_PI/2.0, 0); + cairo_arc (cr, x + width - r3, y + height - r3, r3, 0, G_PI/2.0); + cairo_arc (cr, x + r4, y + height - r4, r4, G_PI/2.0, -G_PI); + cairo_arc (cr, x + r1, y + r1, r1, -G_PI, -G_PI/2.0); + cairo_close_path (cr); +} + +#if ! GTK_CHECK_VERSION (3, 0, 0) && ! defined (gtk_widget_get_allocated_width) +# define gtk_widget_get_allocated_width(w) (GTK_WIDGET (w)->allocation.width) +#endif +#if ! GTK_CHECK_VERSION (3, 0, 0) && ! defined (gtk_widget_get_allocated_height) +# define gtk_widget_get_allocated_height(w) (GTK_WIDGET (w)->allocation.height) +#endif + +static gboolean +stats_graph_draw (GtkWidget *widget, + cairo_t *cr, + gpointer user_data) +{ + const StatsGraphData *data = user_data; + const gint width = gtk_widget_get_allocated_width (widget); + const gint height = gtk_widget_get_allocated_height (widget); + const gdouble translated = width * data->translated; + const gdouble fuzzy = width * data->fuzzy; + const gdouble untranslated = width * data->untranslated; + const gdouble r = MIN (width / 4, height / 4); + cairo_pattern_t *pat; + + rounded_rectangle (cr, 0, 0, width, height, r, r, r, r); + cairo_clip (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_translated); + cairo_rectangle (cr, 0, 0, translated, height); + cairo_fill (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_fuzzy); + cairo_rectangle (cr, translated, 0, fuzzy, height); + cairo_fill (cr); + + gdk_cairo_set_source_color (cr, &plugin.color_untranslated); + cairo_rectangle (cr, translated + fuzzy, 0, untranslated, height); + cairo_fill (cr); + + /* draw a nice thin border */ + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgba (cr, 0, 0, 0, 0.2); + rounded_rectangle (cr, 0.5, 0.5, width - 1, height - 1, r, r, r, r); + cairo_stroke (cr); + + /* draw a gradient to give the graph a little depth */ + pat = cairo_pattern_create_linear (0, 0, 0, height); + cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 0.2); + cairo_pattern_add_color_stop_rgba (pat, height, 0, 0, 0, 0.2); + cairo_set_source (cr, pat); + cairo_pattern_destroy (pat); + cairo_rectangle (cr, 0, 0, width, height); + cairo_paint (cr); + + return TRUE; +} + +#if ! GTK_CHECK_VERSION (3, 0, 0) +static gboolean +on_stats_graph_expose_event (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + cairo_t *cr = gdk_cairo_create (GDK_DRAWABLE (widget->window)); + gboolean ret = stats_graph_draw (widget, cr, data); + + cairo_destroy (cr); + + return ret; +} +#endif + +static void +on_color_button_color_notify (GtkWidget *widget, + GParamSpec *pspec, + gpointer user_data) +{ + gtk_color_button_get_color (GTK_COLOR_BUTTON (widget), user_data); +} + +static void +show_stats_dialog (guint all, + guint translated, + guint untranslated, + guint fuzzy) +{ + GError *error = NULL; + GtkBuilder *builder = gtk_builder_new (); + + gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); + if (! gtk_builder_add_from_file (builder, PKGDATADIR"/pohelper/stats.ui", + &error)) { + g_critical (_("Failed to load UI definition, please check your " + "installation. The error was: %s"), error->message); + g_error_free (error); + } else { + StatsGraphData data; + GObject *dialog; + GObject *drawing_area; + + data.translated = all ? (translated * 1.0 / all) : 0; + data.fuzzy = all ? (fuzzy * 1.0 / all) : 0; + data.untranslated = all ? (untranslated * 1.0 / all) : 0; + + drawing_area = gtk_builder_get_object (builder, "drawing_area"); +#if ! GTK_CHECK_VERSION (3, 0, 0) + g_signal_connect (drawing_area, + "expose-event", G_CALLBACK (on_stats_graph_expose_event), + &data); +#else + g_signal_connect (drawing_area, + "draw", G_CALLBACK (stats_graph_draw), + &data); +#endif + + #define SET_LABEL_N(id, value) \ + do { \ + GObject *obj__ = gtk_builder_get_object (builder, (id)); \ + \ + if (! obj__) { \ + g_warning ("Object \"%s\" is missing from the UI definition", (id)); \ + } else { \ + gchar *text__ = g_strdup_printf (_("%u (%.1f%%)"), \ + (value), \ + all ? ((value) * 100.0 / all) : 0); \ + \ + gtk_label_set_text (GTK_LABEL (obj__), text__); \ + g_free (text__); \ + } \ + } while (0) + + SET_LABEL_N ("n_translated", translated); + SET_LABEL_N ("n_fuzzy", fuzzy); + SET_LABEL_N ("n_untranslated", untranslated); + + #undef SET_LABEL_N + + #define BIND_COLOR_BTN(id, color) \ + do { \ + GObject *obj__ = gtk_builder_get_object (builder, (id)); \ + \ + if (! obj__) { \ + g_warning ("Object \"%s\" is missing from the UI definition", (id)); \ + } else { \ + gtk_color_button_set_color (GTK_COLOR_BUTTON (obj__), (color)); \ + g_signal_connect (obj__, "notify::color", \ + G_CALLBACK (on_color_button_color_notify), \ + (color)); \ + /* queue a redraw on the drawing area so it uses the new color */ \ + g_signal_connect_swapped (obj__, "notify::color", \ + G_CALLBACK (gtk_widget_queue_draw), \ + drawing_area); \ + } \ + } while (0) + + BIND_COLOR_BTN ("color_translated", &plugin.color_translated); + BIND_COLOR_BTN ("color_fuzzy", &plugin.color_fuzzy); + BIND_COLOR_BTN ("color_untranslated", &plugin.color_untranslated); + + #undef BIND_COLOR_BTN + + dialog = gtk_builder_get_object (builder, "dialog"); + gtk_window_set_transient_for (GTK_WINDOW (dialog), + GTK_WINDOW (geany_data->main_widgets->window)); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (GTK_WIDGET (dialog)); + } + g_object_unref (builder); +} + +static void +on_kb_show_stats (guint key_id) +{ + GeanyDocument *doc = document_get_current (); + + if (doc_is_po (doc)) { + const gint len = sci_get_length (doc->editor->sci); + gint pos = 0; + guint all = 0; + guint untranslated = 0; + guint fuzzy = 0; + + while ((pos = find_message (doc, pos, len)) >= 0) { + GString *msgid = get_msgid_text_at (doc, pos); + GString *msgstr = get_msgstr_text_at (doc, pos); + + if (msgid->len > 0) { + all++; + if (msgstr->len < 1) { + untranslated++; + } else { + GPtrArray *flags = get_flags_at (doc, pos); + + if (flags) { + fuzzy += ! toggle_flag (flags, "fuzzy"); + + g_ptr_array_foreach (flags, (GFunc) g_free, NULL); + g_ptr_array_free (flags, TRUE); + } + } + } + g_string_free (msgstr, TRUE); + g_string_free (msgid, TRUE); + } + + show_stats_dialog (all, all - untranslated - fuzzy, fuzzy, untranslated); + } +} + static const struct Action { guint id; const gchar *name; @@ -1083,7 +1419,10 @@ static const struct Action { N_("Reflow the current translation string"), "reflow_translation" }, { GPH_KB_TOGGLE_FUZZY, "toggle-fuzziness", on_kb_toggle_fuzziness, - N_("Toggle current translation fuzziness"), "toggle_fuzziness" } + N_("Toggle current translation fuzziness"), "toggle_fuzziness" }, + { GPH_KB_SHOW_STATS, "show-stats", + on_kb_show_stats, + N_("Show statistics of the current document"), "show_stats" } }; static void @@ -1157,6 +1496,47 @@ write_keyfile (GKeyFile *kf, return success; } +/* + * get_setting_color: + * @kf: a #GKeyFile from which load the color + * @group: the key file group + * @key: the key file key + * @color: (out): the color to fill with the read value. If the key is not + * found, the color isn't updated + * + * Loads a color from a key file entry. + * + * Returns: %TRUE if the color was loaded, %FALSE otherwise. + */ +static gboolean +get_setting_color (GKeyFile *kf, + const gchar *group, + const gchar *key, + GdkColor *color) +{ + gboolean success = FALSE; + gchar *value = g_key_file_get_value (kf, group, key, NULL); + + if (value) { + success = gdk_color_parse (value, color); + g_free (value); + } + + return success; +} + +static void +set_setting_color (GKeyFile *kf, + const gchar *group, + const gchar *key, + const GdkColor *color) +{ + gchar *value = gdk_color_to_string (color); + + g_key_file_set_value (kf, group, key, value); + g_free (value); +} + static void load_config (void) { @@ -1167,6 +1547,9 @@ load_config (void) plugin.update_headers = utils_get_setting_boolean (kf, "general", "update-headers", plugin.update_headers); + get_setting_color (kf, "colors", "translated", &plugin.color_translated); + get_setting_color (kf, "colors", "fuzzy", &plugin.color_fuzzy); + get_setting_color (kf, "colors", "untranslated", &plugin.color_untranslated); } g_key_file_free (kf); g_free (filename); @@ -1181,6 +1564,9 @@ save_config (void) load_keyfile (kf, filename, G_KEY_FILE_KEEP_COMMENTS); g_key_file_set_boolean (kf, "general", "update-headers", plugin.update_headers); + set_setting_color (kf, "colors", "translated", &plugin.color_translated); + set_setting_color (kf, "colors", "fuzzy", &plugin.color_fuzzy); + set_setting_color (kf, "colors", "untranslated", &plugin.color_untranslated); write_keyfile (kf, filename); g_key_file_free (kf); -------------- This E-Mail was brought to you by github_commit_mail.py (Source:
https://github.com/geany/infrastructure
).
1
0
0
0
← Newer
1
2
3
4
5
6
7
Older →
Jump to page:
1
2
3
4
5
6
7
Results per page:
10
25
50
100
200