gpe-expenses 0.1.9
gpe-expenses.c
00001 /******************************************************************
00002  *            gpe-expenses.c
00003  *
00004  *  Sun Nov 13 14:54:18 2005
00005  *  Copyright  2005  Neil Williams
00006  *  linux@codehelp.co.uk
00007  ******************************************************************/
00008 /*
00009     This package is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 3 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00021  */
00022 
00023 #define _GNU_SOURCE
00024 #include "config.h"
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 #include <glib.h>
00028 #include <glib/gi18n.h>
00029 #include <glib/gprintf.h>
00030 #include <glib/gstdio.h>
00031 #include <qof.h>
00032 #include <gtk/gtk.h>
00033 #include <gpe/init.h>
00034 #include <gtk/gtkmain.h>
00035 #include <gpe/pixmaps.h>
00036 #include <gpe/pim-categories.h>
00037 #include <gpe/errorbox.h>
00038 #include <regex.h>
00039 #include <popt.h>
00040 #include <locale.h>
00041 #include "qof-main.h"
00042 #include "gpe-expenses.h"
00043 #include "expenses-gtk.h"
00044 
00045 /* used to print debug logs. */
00046 static QofLogModule log_module = GPE_MOD_CLI;
00047 #define EXPENSE_ICON PREFIX "/share/pixmaps/gpe-expenses.xpm"
00048 #define GPE_EXPENSE_LOG "/tmp/gpe-expense.trace"
00049 #define ARGUMENT_BAD_OPTION 17227
00050 #define QOF_MOD_SQLITE "qof-sqlite-module"
00051 #define SQLITE_DIR ".gpe/"
00052 #define DEFAULT_FILE "expenses"
00053 #define ACCESS_METHOD "sqlite"
00054 
00055 #define ENUM_LIST_Q(_)  \
00056         _(qof_op_noop, = 0) \
00057         _(qof_op_list,)     \
00058         _(qof_op_category,) \
00059         _(qof_op_time,) \
00060         _(qof_op_sql,)      \
00061         _(qof_op_sql_file,) \
00062         _(qof_op_write, )   \
00063         _(qof_op_explain,)  \
00064         _(qof_op_vers,)     \
00065         _(qof_op_compress,) \
00066         _(qof_op_debug,)    \
00067         _(qof_op_input, ) \
00068         _(qof_op_gui, )
00069 
00070         DEFINE_ENUM(qof_op_type, ENUM_LIST_Q)
00071 
00072 GpeExpenseData*
00073 gpe_expense_init (void)
00074 {
00075         GpeExpenseData *context;
00076 
00077         qof_init();
00078         g_return_val_if_fail(ExpensesRegister (), NULL);
00079         context = g_new0(GpeExpenseData, 1);
00080         return context;
00081 }
00082 
00083 void
00084 gpe_expense_close(GpeExpenseData *context)
00085 {
00086         qof_main_free(&context->qof);
00087         qof_close();
00088         g_free(context);
00089 }
00090 
00091 void
00092 gpe_expense_error (QofSession * session)
00093 {
00094         if (qof_error_check (session))
00095                 gpe_error_box (qof_error_get_message (session));
00096 }
00097 
00098 static struct gpe_icon my_icons[] = {
00099         { "icon", EXPENSE_ICON, 0 },
00100   { NULL, NULL, NULL }
00101 };
00102 
00103 static void
00104 gpe_gui_start(int argc, char *argv[], GpeExpenseData *context)
00105 {
00106         g_return_if_fail(context);
00107         g_return_if_fail(gpe_application_init (&argc, &argv));
00108         g_return_if_fail(gpe_load_icons (my_icons));
00109         ENTER (" file=%s", context->qof.write_file);
00110         if(!context->qof.write_file)
00111         {
00112                 gint test;
00113                 gboolean gpe_home_exists;
00114 
00115                 /* use a fixed file location. */
00116                 test = 0;
00117                 context->qof.write_file = g_strconcat (g_get_home_dir(), 
00118                         "/", SQLITE_DIR, NULL);
00119                 gpe_home_exists = g_file_test (context->qof.write_file, G_FILE_TEST_IS_DIR);
00120                 if (!gpe_home_exists)
00121                         test = g_mkdir (context->qof.write_file, 0700);
00122                 g_free (context->qof.write_file);
00123                 context->qof.write_file = g_strconcat (ACCESS_METHOD, 
00124                         ":", g_get_home_dir(), "/", SQLITE_DIR, DEFAULT_FILE, NULL);
00125                 if (test)
00126                         context->qof.write_file = g_strconcat (ACCESS_METHOD,
00127                         ":", g_get_tmp_dir(), "/", DEFAULT_FILE, NULL);
00128         }
00129         qof_session_begin(context->qof.input_session, 
00130                 context->qof.write_file, TRUE, FALSE);
00131         gpe_expense_error (context->qof.input_session);
00132         qof_session_load(context->qof.input_session, NULL);
00133         context->book = qof_session_get_book(context->qof.input_session);
00134         gtk_set_locale ();
00135         gtk_init (&argc, &argv);
00136 
00137         open_expenses_window (context);
00138 
00139         gtk_main ();
00140         qof_session_save(context->qof.input_session, NULL);
00141         LEAVE (" ");
00142 }
00143 
00144 int
00145 main (int argc, char *argv[])
00146 {
00147         QOF_OP_VARS
00148         const gchar *help_header_text;
00149         GpeExpenseData *gpe_expense_context;
00150         gboolean debug_on;
00151         poptContext pc;
00152         gint optc;
00153         qof_op_type exp_command;
00154 
00155         struct poptOption options[] = {
00156                 { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptionsI18N,
00157                         0, _("Help options:"), NULL },
00158                 {"list", 'l', POPT_ARG_NONE, NULL, qof_op_list,
00159                  _("List all databases supported by the current QOF framework and exit."), NULL},
00160                 {"explain", 0, POPT_ARG_NONE, NULL, qof_op_explain,
00161                  _("List the fields within the specified database and exit, requires -d."), NULL},
00162                 {"input-file", 'i', POPT_ARG_STRING, &filename, qof_op_input,
00163                  _("Query the QSF XML data in <filename>"), _("filename")},
00164                 {"date", 't', POPT_ARG_STRING, &date_time, qof_op_time,
00165                  _("Shorthand to only query objects that contain the specified date."), _("string")},
00166                 {"sql", 's', POPT_ARG_STRING, &sql_query, qof_op_sql,
00167                  _("Specify a SQL query on the command line."), _("string")},
00168                 {"sql-file", 'f', POPT_ARG_STRING, &sql_file, qof_op_sql_file,
00169                  _("Specify one or more SQL queries contained in a file."), _("filename")},
00170                 {"write", 'w', POPT_ARG_STRING, &write_file, qof_op_write,
00171                  _("Write the results of any query to the file"), _("filename")},
00172                 {"gui", 0, POPT_ARG_NONE, NULL, qof_op_gui,
00173                  _("Use the Gtk graphic interface"), NULL},
00174                 {"debug", 0, POPT_ARG_NONE, NULL, qof_op_debug,
00175                  _("Print debugging information to a temporary file."), NULL},
00176                 {"version", 0, POPT_ARG_NONE, NULL, qof_op_vers,
00177                  _("Display version information"), NULL},
00178                 {"category", 'c', POPT_ARG_STRING, &category, qof_op_category,
00179                  _("Shorthand to only query objects that are set to the specified category."),
00180                  _("string")},
00181                 POPT_TABLEEND
00182         };
00183         exp_command = qof_op_noop;
00184         debug_on = FALSE;
00185         QOF_OP_INIT
00186         database = g_strdup("gpe_expenses");
00187 
00188 #ifdef ENABLE_NLS
00189         setlocale (LC_ALL, "");
00190         bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
00191         bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
00192         textdomain (GETTEXT_PACKAGE);
00193 #endif
00194         help_header_text = _(
00195         /* Translators: please retain the line endings
00196         and punctuation. -i -l --gui or --explain are commands,
00197         options are as specified. Please retain 'or' in all cases,
00198         options and commands can only be combined in specific ways.
00199         */
00200                 "\n"
00201                 "   Expenses applet for GPE using QOF - \n"
00202                 "   the Query Object Framework.\n"
00203                 "   Supports writing iPAQ data to SQLite.\n"
00204                 "   SQL-type queries on the live data or SQLite file.\n"
00205                 "   SQLite data can be imported into other QOF applications.\n\n"
00206                 "   Use exactly one of -i -l --gui or --explain;\n"
00207                 "   options are -c -t -w, -s or -f.\n\n");
00208 
00209         pc = poptGetContext (PACKAGE, argc, (const char **)argv, options, 0);
00210 
00211         poptSetOtherOptionHelp (pc, help_header_text);
00212 
00213         if (argc < 2)
00214         {
00215                 poptPrintUsage (pc, stderr, 0);
00216                 return EXIT_FAILURE;
00217         }
00218         gpe_expense_context = gpe_expense_init();
00219         g_return_val_if_fail (gpe_expense_context, 1);
00220         while ((optc = poptGetNextOpt (pc)) >= 0)
00221         {
00222                 switch (optc)
00223                 {
00224                         /* commands - mutually exclusive */
00225                         case qof_op_input:
00226                         case qof_op_list:
00227                         case qof_op_explain:
00228                         case qof_op_gui:
00229                         {
00230                                 if (qof_op_noop != exp_command)
00231                                 {
00232                                         fprintf (stderr, _("%s: ERROR: specify only one of"
00233                                                 "-i, -l, --gui or --explain.\n"), PACKAGE);
00234                                         return 1;
00235                                 }
00236                                 exp_command = optc;
00237                                 break;
00238                         }
00239                         case qof_op_vers :
00240                         {
00241                                 fprintf (stdout, "\n Copyright (c) 2005-2007 Neil Williams <linux@codehelp.co.uk>\n");
00242                                 fprintf (stdout, _(" For gpe-expenses support, join the QOF-devel mailing list at\n"));
00243                                 fprintf (stdout, " http://lists.sourceforge.net/mailman/listinfo/qof-devel\n");
00244                                 fprintf (stdout, _("\n This is gpe-expenses v%s\n"), VERSION);
00245                                 fprintf (stdout, _(" Expenses applet for GPE on iPAQ .\n"));
00246                                 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00247                                 fprintf (stdout, _(" Build target.........: %s\n"), HOST_OS);
00248                                 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00249                                 fprintf (stdout, _(" Build date...........: %s %s\n"), __DATE__, __TIME__);
00250                                 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00251                                 fprintf (stdout, _(" --debug logs to......: %s\n\n"), GPE_EXPENSE_LOG);
00252                                 /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
00253                                 fprintf (stdout, _(" Please use --help for more detailed options.\n\n"));
00254                                 return EXIT_SUCCESS;
00255                         }
00256                         /* optional modifiers - store to act on later. */
00257                         case qof_op_category:
00258                         {
00259                                 qof_mod_category (category, &gpe_expense_context->qof);
00260                                 break;
00261                         }
00262                         case qof_op_time:
00263                         {
00264                                 qof_mod_time (date_time, &gpe_expense_context->qof);
00265                                 break;
00266                         }
00267                         case qof_op_sql:
00268                         {
00269                                 qof_mod_sql (sql_query, &gpe_expense_context->qof);
00270                                 break;
00271                         }
00272                         case qof_op_sql_file:
00273                         {
00274                                 qof_mod_sql_file (sql_file, &gpe_expense_context->qof);
00275                                 break;
00276                         }
00277                         case qof_op_write:
00278                         {
00279                                 qof_mod_write (write_file, &gpe_expense_context->qof);
00280                                 break;
00281                         }
00282                         case qof_op_debug:
00283                         {
00284                                 qof_log_init_filename(GPE_EXPENSE_LOG);
00285                                 qof_log_set_default(QOF_LOG_DETAIL);
00286                                 qof_log_set_level (GPE_MOD_CLI, QOF_LOG_DETAIL);
00287                                 qof_log_set_level (QOF_MAIN_CLI, QOF_LOG_DETAIL);
00288                                 qof_log_set_level (QOF_MOD_SQLITE, QOF_LOG_DETAIL);
00289                                 qof_log_set_level (GPE_MOD_GUI, QOF_LOG_DETAIL);
00290                                 debug_on = TRUE;
00291                                 break;
00292                         }
00293                         default:
00294                         {
00295                                 fprintf (stderr, _("%s: ERROR: got option %d, arg %s\n"), PACKAGE,
00296                                          optc, poptGetOptArg (pc));
00297                                 return EXIT_FAILURE;
00298                         }
00299                 }
00300         }
00301         if (optc < -1)
00302         {
00303                 fprintf(stderr, "%s: %s %s\n\n", PACKAGE,
00304                 poptBadOption(pc, POPT_BADOPTION_NOALIAS),
00305                 poptStrerror(optc));
00306                 poptPrintUsage(pc, stderr, 0);
00307                 return EXIT_FAILURE;
00308         }
00309         if (gpe_expense_context->qof.error)
00310                 return EXIT_FAILURE;
00311         /* If we get this far, we should have sensible options: start the work. */
00312         gpe_expense_context->qof.input_session = qof_session_new();
00313         switch (exp_command)
00314         {
00315                 case qof_op_input:
00316                 {
00317                         gpe_expense_context->qof.filename = g_strdup(filename);
00318                         /* despite the name, this is for any supported file */
00319                         qof_cmd_xmlfile (&gpe_expense_context->qof);
00320                         break;
00321                 }
00322                 case qof_op_list:
00323                 {
00324                         qof_cmd_list ();
00325                         break;
00326                 }
00327                 case qof_op_gui :
00328                 {
00329                         gpe_gui_start(argc, argv, gpe_expense_context);
00330                         break;
00331                 }
00332                 case qof_op_explain:
00333                 {
00334                         qof_mod_database (database, &gpe_expense_context->qof);
00335                         if(!gpe_expense_context->qof.database) 
00336                         { 
00337                                 /* Translators: capitalise only the initial letter of error. */
00338                                 fprintf (stderr, _("%s: Error: please specify which "
00339                                         "database you would like explained.\n\n"), PACKAGE);
00340                                 break;
00341                         }
00342                         qof_cmd_explain(&gpe_expense_context->qof);
00343                         break;
00344                 }
00345                 default:
00346                 {
00347                         /* should be impossible */
00348                         break;
00349                 }
00350         }
00351         poptFreeContext(pc);
00352         if(debug_on) { qof_log_shutdown(); }
00353         gpe_expense_close(gpe_expense_context);
00354         return EXIT_SUCCESS;
00355 }