From 317f32de0b17a9513a392beb4777eb11edc80e4d Mon Sep 17 00:00:00 2001 From: Geert Janssens Date: Sat, 23 May 2020 17:21:13 +0200 Subject: [PATCH] Only offer gtk options for gnucash, not for gnucash-cli * As the gtk command line options are only relevant for gnucash and not gnucash-cli, remove the bit that adds them from Gnucash::CoreApp. * As the gtk command line options are parsed out by gtk_init_check it's sufficient to run that before parsing our own command line options to have gtk handle them for us. * That just leaves us with the loss of a help message for the gtk command line options. To handle that we derive a class Gnucash::Gnucash from Gnucash::CoreApp which will generate an option context for the gtk options purely to extract the help message. This will then be used if the users pass option --help-gtk. This is a bit clumsy to do with GOptionContext as it requires to store a few gnucash only parameters in Gnucash::CoreApp. The plan is to improve this in a future commit. Note however we will still be stuck with the dummy option context generation for the gtk option help message. There's just no other way to extract this message otherwise. --- gnucash/gnucash-core-app.cpp | 26 +++++++++++++--- gnucash/gnucash-core-app.hpp | 5 ++++ gnucash/gnucash.cpp | 58 +++++++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 15 deletions(-) diff --git a/gnucash/gnucash-core-app.cpp b/gnucash/gnucash-core-app.cpp index 019884bfaf..576f9dfb3e 100644 --- a/gnucash/gnucash-core-app.cpp +++ b/gnucash/gnucash-core-app.cpp @@ -62,6 +62,7 @@ static QofLogModule log_module = GNC_MOD_GUI; #include #include +#include #ifdef MAC_INTEGRATION # include @@ -541,6 +542,9 @@ Gnucash::CoreApp::CoreApp () textdomain(PROJECT_NAME); bind_textdomain_codeset(PROJECT_NAME, "UTF-8"); g_free(localedir); + + // Now that gettext is properly initialized, set our help tagline. + tagline = bl::translate("- GnuCash, accounting for personal and small business finance").str(gnc_get_locale()); } /* Parse command line options, using GOption interface. @@ -611,15 +615,29 @@ Gnucash::CoreApp::parse_command_line (int *argc, char ***argv) N_("REGEXP") }, { - G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, N_("[datafile]") }, - { NULL } + G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, N_("[datafile]") + + }, + { NULL } }; GError *error = NULL; - GOptionContext *context = g_option_context_new (_("- GnuCash, accounting for personal and small business finance")); + GOptionContext *context = g_option_context_new (tagline.c_str()); g_option_context_add_main_entries (context, options, PROJECT_NAME); - g_option_context_add_group (context, gtk_get_option_group(FALSE)); + if (!gtk_help_msg.empty()) + { + GOptionEntry gtk_help_options[] = + { + { + "help-gtk", 'v', 0, G_OPTION_ARG_NONE, >k_show_help, + N_("Show GTK+ Options"), NULL + }, + { NULL } + }; + g_option_group_add_entries (g_option_context_get_main_group (context), gtk_help_options); + } + if (!g_option_context_parse (context, argc, argv, &error)) { std::cerr << error->message << "\n" diff --git a/gnucash/gnucash-core-app.hpp b/gnucash/gnucash-core-app.hpp index 1e58af6b5d..449257e8ff 100644 --- a/gnucash/gnucash-core-app.hpp +++ b/gnucash/gnucash-core-app.hpp @@ -40,6 +40,11 @@ public: int get_no_file (void); const char *get_quotes_file (void); +protected: + std::string gtk_help_msg; + int gtk_show_help = 0; + std::string tagline; + private: /* Command-line option variables */ diff --git a/gnucash/gnucash.cpp b/gnucash/gnucash.cpp index d816fdf49a..0f7dfb0e09 100644 --- a/gnucash/gnucash.cpp +++ b/gnucash/gnucash.cpp @@ -351,10 +351,56 @@ inner_main (void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **argv) return; } +namespace Gnucash { + + class Gnucash : public CoreApp + { + public: + void parse_command_line (int *argc, char ***argv); + }; + +} + +void +Gnucash::Gnucash::parse_command_line (int *argc, char ***argv) +{ + // The g_option context dance below is done to be able to show a help message + // for gtk's options. The options themselves are already parsed out by + // gtk_init_check by the time this function is called though. So it really only + // serves to be able to display a help message. + GError *error = NULL; + auto context = g_option_context_new (tagline.c_str()); + auto gtk_options = gtk_get_option_group(FALSE); + g_option_context_add_group (context, gtk_options); + gtk_help_msg = std::string (g_option_context_get_help (context, FALSE, gtk_options)); + g_option_context_free (context); + + // Pass remaining command line bits to our base class for further parsing + // This will include a --help-gtk option to display gtk's option help + // extracted above + Gnucash::CoreApp::parse_command_line (argc, argv); + + if (gtk_show_help) + { + std::cout << gtk_help_msg; + exit(0); + } +} + int main(int argc, char ** argv) { - Gnucash::CoreApp application; + Gnucash::Gnucash application; + + /* We need to initialize gtk before looking up all modules */ + if(!gtk_init_check (&argc, &argv)) + { + std::cerr << bl::format (bl::translate ("Run '{1} --help' to see a full list of available command line options.")) % *argv[0] + << "\n" + << bl::translate ("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n" + " Perhaps you need to set the $DISPLAY environment variable ?"); + return 1; + } application.parse_command_line (&argc, &argv); application.start(); @@ -367,16 +413,6 @@ main(int argc, char ** argv) exit (0); /* never reached */ } - /* We need to initialize gtk before looking up all modules */ - if(!gtk_init_check (&argc, &argv)) - { - std::cerr << bl::format (bl::translate ("Run '{1} --help' to see a full list of available command line options.")) % *argv[0] - << "\n" - << bl::translate ("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n" - " Perhaps you need to set the $DISPLAY environment variable ?"); - return 1; - } - /* Now the module files are looked up, which might cause some library initialization to be run, hence gtk must be initialized beforehand. */ gnc_module_system_init();