From 42726a229e4e77b196490148145ddbb0ded61f60 Mon Sep 17 00:00:00 2001 From: LarsDW223 Date: Sun, 11 Jun 2017 16:04:35 +0200 Subject: [PATCH 1/2] pretty-printer: added saving and loading of preferences in/from a file. Fixes #494. --- pretty-printer/src/ConfigUI.c | 206 ++++++++++++++++++++++++++++- pretty-printer/src/ConfigUI.h | 4 +- pretty-printer/src/PluginEntry.c | 76 ++++++++++- pretty-printer/src/PrettyPrinter.c | 2 +- 4 files changed, 280 insertions(+), 8 deletions(-) diff --git a/pretty-printer/src/ConfigUI.c b/pretty-printer/src/ConfigUI.c index c9121bd5e..b4172d661 100644 --- a/pretty-printer/src/ConfigUI.c +++ b/pretty-printer/src/ConfigUI.c @@ -93,11 +93,12 @@ GtkWidget* createPrettyPrinterConfigUI(GtkDialog * dialog) return container; } -void saveSettings(void) +static void +fetchSettingsFromConfigUI(PrettyPrintingOptions* ppo) { int breakStyle; - PrettyPrintingOptions* ppo = prettyPrintingOptions; + if (ppo == NULL) return; ppo->oneLineComment = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(commentOneLine)); ppo->inlineComment = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(commentInline)); ppo->alignComment = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(commentAlign)); @@ -118,9 +119,204 @@ void saveSettings(void) ppo->indentChar = gtk_combo_box_get_active(GTK_COMBO_BOX(indentationChar))==0 ? '\t' : ' '; breakStyle = gtk_combo_box_get_active(GTK_COMBO_BOX(lineBreak)); - if (breakStyle == 0) ppo->newLineChars = "\r"; - else if (breakStyle == 1) ppo->newLineChars = "\n"; - else ppo->newLineChars = "\r\n"; + if (ppo->newLineChars != NULL) + { + g_free ((gpointer)ppo->newLineChars); + } + if (breakStyle == 0) ppo->newLineChars = g_strdup("\r"); + else if (breakStyle == 1) ppo->newLineChars = g_strdup("\n"); + else ppo->newLineChars = g_strdup("\r\n"); +} + +static gchar * +prefsToData (PrettyPrintingOptions* ppo, + gsize* size, + GError** error) +{ + GKeyFile *kf; + gchar *contents; + + kf = g_key_file_new (); + + g_key_file_set_string (kf, "pretty-printer", "newLineChars", ppo->newLineChars); + g_key_file_set_integer (kf, "pretty-printer", "indentChar", (int)ppo->indentChar); + g_key_file_set_integer (kf, "pretty-printer", "indentLength", ppo->indentLength); + g_key_file_set_boolean (kf, "pretty-printer", "oneLineText", ppo->oneLineText); + g_key_file_set_boolean (kf, "pretty-printer", "inlineText", ppo->inlineText); + g_key_file_set_boolean (kf, "pretty-printer", "oneLineComment", ppo->oneLineComment); + g_key_file_set_boolean (kf, "pretty-printer", "inlineComment", ppo->inlineComment); + g_key_file_set_boolean (kf, "pretty-printer", "oneLineCdata", ppo->oneLineCdata); + g_key_file_set_boolean (kf, "pretty-printer", "inlineCdata", ppo->inlineCdata); + g_key_file_set_boolean (kf, "pretty-printer", "emptyNodeStripping", ppo->emptyNodeStripping); + g_key_file_set_boolean (kf, "pretty-printer", "emptyNodeStrippingSpace", ppo->emptyNodeStrippingSpace); + g_key_file_set_boolean (kf, "pretty-printer", "forceEmptyNodeSplit", ppo->forceEmptyNodeSplit); + g_key_file_set_boolean (kf, "pretty-printer", "trimLeadingWhites", ppo->trimLeadingWhites); + g_key_file_set_boolean (kf, "pretty-printer", "trimTrailingWhites", ppo->trimTrailingWhites); + g_key_file_set_boolean (kf, "pretty-printer", "alignComment", ppo->alignComment); + g_key_file_set_boolean (kf, "pretty-printer", "alignText", ppo->alignText); + g_key_file_set_boolean (kf, "pretty-printer", "alignCdata", ppo->alignCdata); + + contents = g_key_file_to_data (kf, size, error); + g_key_file_free (kf); + return contents; +} + +static gboolean +prefsFromData (PrettyPrintingOptions* ppo, + const gchar* contents, + gssize size, + GError** error) +{ + GKeyFile *kf; + + g_return_val_if_fail (contents != NULL, FALSE); + + kf = g_key_file_new (); + + if (!g_key_file_load_from_data (kf, contents, size, + G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, + error)) + { + g_key_file_free (kf); + return FALSE; + } + + if (g_key_file_has_key (kf, "pretty-printer", "newLineChars", NULL)) + { + if (ppo->newLineChars != NULL ) + { + g_free ((gpointer)ppo->newLineChars); + } + ppo->newLineChars = g_key_file_get_string (kf, "pretty-printer", "newLineChars", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "indentChar", NULL)) + { + ppo->indentChar = (char)g_key_file_get_integer (kf, "pretty-printer", "indentChar", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "indentLength", NULL)) + { + ppo->indentLength = g_key_file_get_integer (kf, "pretty-printer", "indentLength", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "oneLineText", NULL)) + { + ppo->oneLineText = g_key_file_get_boolean (kf, "pretty-printer", "oneLineText", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "inlineText", NULL)) + { + ppo->inlineText = g_key_file_get_boolean (kf, "pretty-printer", "inlineText", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "oneLineComment", NULL)) + { + ppo->oneLineComment = g_key_file_get_boolean (kf, "pretty-printer", "oneLineComment", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "inlineComment", NULL)) + { + ppo->inlineComment = g_key_file_get_boolean (kf, "pretty-printer", "inlineComment", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "oneLineCdata", NULL)) + { + ppo->oneLineCdata = g_key_file_get_boolean (kf, "pretty-printer", "oneLineCdata", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "inlineCdata", NULL)) + { + ppo->inlineCdata = g_key_file_get_boolean (kf, "pretty-printer", "inlineCdata", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "emptyNodeStripping", NULL)) + { + ppo->emptyNodeStripping = g_key_file_get_boolean (kf, "pretty-printer", "emptyNodeStripping", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "emptyNodeStrippingSpace", NULL)) + { + ppo->emptyNodeStrippingSpace = g_key_file_get_boolean (kf, "pretty-printer", "emptyNodeStrippingSpace", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "forceEmptyNodeSplit", NULL)) + { + ppo->forceEmptyNodeSplit = g_key_file_get_boolean (kf, "pretty-printer", "forceEmptyNodeSplit", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "trimLeadingWhites", NULL)) + { + ppo->trimLeadingWhites = g_key_file_get_boolean (kf, "pretty-printer", "trimLeadingWhites", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "trimTrailingWhites", NULL)) + { + ppo->trimTrailingWhites = g_key_file_get_boolean (kf, "pretty-printer", "trimTrailingWhites", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "alignComment", NULL)) + { + ppo->alignComment = g_key_file_get_boolean (kf, "pretty-printer", "alignComment", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "alignText", NULL)) + { + ppo->alignText = g_key_file_get_boolean (kf, "pretty-printer", "alignText", error); + } + if (g_key_file_has_key (kf, "pretty-printer", "alignCdata", NULL)) + { + ppo->alignCdata = g_key_file_get_boolean (kf, "pretty-printer", "alignCdata", error); + } + + g_key_file_free (kf); + return TRUE; +} + +gboolean +prefsLoad (const gchar* filename, + GError** error) +{ + PrettyPrintingOptions* ppo; + gchar *contents = NULL; + gsize size = 0; + + g_return_val_if_fail (filename != NULL, FALSE); + + /* default printing options */ + if (prettyPrintingOptions == NULL) { prettyPrintingOptions = createDefaultPrettyPrintingOptions(); } + ppo = prettyPrintingOptions; + + if (!g_file_get_contents (filename, &contents, &size, error)) + return FALSE; + if (!prefsFromData (ppo, contents, size, error)) + { + g_free (contents); + return FALSE; + } + g_free (contents); + return TRUE; +} + +gboolean +prefsSave (const gchar* filename, + GError** error) +{ + PrettyPrintingOptions* ppo; + gchar *contents = NULL; + gsize size = 0; + + g_return_val_if_fail (filename != NULL, FALSE); + ppo = prettyPrintingOptions; + fetchSettingsFromConfigUI (ppo); + contents = prefsToData (ppo, &size, error); + if (contents == NULL) + return FALSE; + if (! g_file_set_contents (filename, contents, size, error)) + { + g_free (contents); + return FALSE; + } + g_free (contents); + return TRUE; +} + +gchar * +getDefaultPrefs (GError** error) +{ + gchar *contents = NULL; + gsize size = 0; + PrettyPrintingOptions* ppo; + + ppo = createDefaultPrettyPrintingOptions(); + g_return_val_if_fail (ppo != NULL, NULL); + contents = prefsToData (ppo, &size, error); + return contents; } /*============================================= PRIVATE FUNCTIONS =======================================*/ diff --git a/pretty-printer/src/ConfigUI.h b/pretty-printer/src/ConfigUI.h index 9927f23cb..30f724347 100644 --- a/pretty-printer/src/ConfigUI.h +++ b/pretty-printer/src/ConfigUI.h @@ -37,6 +37,8 @@ extern PrettyPrintingOptions* prettyPrintingOptions; /*========================================== FUNCTIONS ========================================================*/ GtkWidget* createPrettyPrinterConfigUI(GtkDialog* dialog); -void saveSettings(void); +gboolean prefsLoad (const gchar* filename, GError** error); +gboolean prefsSave (const gchar* filename, GError** error); +gchar *getDefaultPrefs (GError** error); #endif diff --git a/pretty-printer/src/PluginEntry.c b/pretty-printer/src/PluginEntry.c index 886d9dd20..13fa7a4fa 100644 --- a/pretty-printer/src/PluginEntry.c +++ b/pretty-printer/src/PluginEntry.c @@ -21,7 +21,12 @@ * http://www.geany.org/manual/reference/howto.html */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "PluginEntry.h" +#include GeanyPlugin* geany_plugin; @@ -49,10 +54,70 @@ static void config_closed(GtkWidget* configWidget, gint response, gpointer data) /*========================================== FUNCTIONS ===================================================================*/ +static gchar * +get_config_file (void) +{ + gchar *dir; + gchar *fn; + + dir = g_build_filename (geany_data->app->configdir, "plugins", "pretty-printer", NULL); + fn = g_build_filename (dir, "prefs.conf", NULL); + + if (! g_file_test (fn, G_FILE_TEST_IS_DIR)) + { + if (g_mkdir_with_parents (dir, 0755) != 0) + { + g_critical ("failed to create config dir '%s': %s", dir, g_strerror (errno)); + g_free (dir); + g_free (fn); + return NULL; + } + } + + g_free (dir); + + if (! g_file_test (fn, G_FILE_TEST_EXISTS)) + { + GError *error = NULL; + const gchar *def_config; + + def_config = getDefaultPrefs(&error); + if (def_config == NULL) + { + g_critical ("failed to fetch default config data (%s)", + error->message); + g_error_free (error); + g_free (fn); + return NULL; + } + if (!g_file_set_contents (fn, def_config, -1, &error)) + { + g_critical ("failed to save default config to file '%s': %s", + fn, error->message); + g_error_free (error); + g_free (fn); + return NULL; + } + } + + return fn; +} + void plugin_init(GeanyData *data) { + gchar *conf_file; + GError *error = NULL; GeanyKeyGroup *key_group; + /* load preferences */ + conf_file = get_config_file (); + if (!prefsLoad (conf_file, &error)) + { + g_critical ("failed to load preferences file '%s': %s", conf_file, error->message); + g_error_free (error); + } + g_free (conf_file); + /* initializes the libxml2 */ LIBXML_TEST_VERSION @@ -95,7 +160,16 @@ void config_closed(GtkWidget* configWidget, gint response, gpointer gdata) if (response == GTK_RESPONSE_OK || response == GTK_RESPONSE_APPLY) { - saveSettings(); + gchar* conf_file; + GError* error = NULL; + + conf_file = get_config_file (); + if (! prefsSave (conf_file, &error)) + { + g_critical ("failed to save preferences to file '%s': %s", conf_file, error->message); + g_error_free (error); + } + g_free (conf_file); } } diff --git a/pretty-printer/src/PrettyPrinter.c b/pretty-printer/src/PrettyPrinter.c index b952860ca..3a57d15f3 100644 --- a/pretty-printer/src/PrettyPrinter.c +++ b/pretty-printer/src/PrettyPrinter.c @@ -172,7 +172,7 @@ PrettyPrintingOptions* createDefaultPrettyPrintingOptions(void) return NULL; } - defaultOptions->newLineChars = "\r\n"; + defaultOptions->newLineChars = g_strdup ("\r\n"); defaultOptions->indentChar = ' '; defaultOptions->indentLength = 2; defaultOptions->oneLineText = FALSE; From 2149e3fb4fd9dc43b28747a25c8ad0ff4e60196c Mon Sep 17 00:00:00 2001 From: LarsDW223 Date: Sun, 18 Jun 2017 11:24:04 +0200 Subject: [PATCH 2/2] Fixed unnecessary NULL pointer checks on call to 'g_free()'. --- pretty-printer/src/ConfigUI.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/pretty-printer/src/ConfigUI.c b/pretty-printer/src/ConfigUI.c index b4172d661..f02d3208c 100644 --- a/pretty-printer/src/ConfigUI.c +++ b/pretty-printer/src/ConfigUI.c @@ -119,10 +119,7 @@ fetchSettingsFromConfigUI(PrettyPrintingOptions* ppo) ppo->indentChar = gtk_combo_box_get_active(GTK_COMBO_BOX(indentationChar))==0 ? '\t' : ' '; breakStyle = gtk_combo_box_get_active(GTK_COMBO_BOX(lineBreak)); - if (ppo->newLineChars != NULL) - { - g_free ((gpointer)ppo->newLineChars); - } + g_free ((gpointer)ppo->newLineChars); if (breakStyle == 0) ppo->newLineChars = g_strdup("\r"); else if (breakStyle == 1) ppo->newLineChars = g_strdup("\n"); else ppo->newLineChars = g_strdup("\r\n"); @@ -183,10 +180,7 @@ prefsFromData (PrettyPrintingOptions* ppo, if (g_key_file_has_key (kf, "pretty-printer", "newLineChars", NULL)) { - if (ppo->newLineChars != NULL ) - { - g_free ((gpointer)ppo->newLineChars); - } + g_free ((gpointer)ppo->newLineChars); ppo->newLineChars = g_key_file_get_string (kf, "pretty-printer", "newLineChars", error); } if (g_key_file_has_key (kf, "pretty-printer", "indentChar", NULL))