gpe-expenses  0.1.9
gpe-expenses.c
1 /******************************************************************
2  * gpe-expenses.c
3  *
4  * Sun Nov 13 14:54:18 2005
5  * Copyright 2005 Neil Williams
6  * linux@codehelp.co.uk
7  ******************************************************************/
8 /*
9  This package is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 3 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #define _GNU_SOURCE
24 #include "config.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <glib.h>
28 #include <glib/gi18n.h>
29 #include <glib/gprintf.h>
30 #include <glib/gstdio.h>
31 #include <qof.h>
32 #include <gtk/gtk.h>
33 #include <gpe/init.h>
34 #include <gtk/gtkmain.h>
35 #include <gpe/pixmaps.h>
36 #include <gpe/pim-categories.h>
37 #include <gpe/errorbox.h>
38 #include <regex.h>
39 #include <popt.h>
40 #include <locale.h>
41 #include "qof-main.h"
42 #include "gpe-expenses.h"
43 #include "expenses-gtk.h"
44 
45 /* used to print debug logs. */
46 static QofLogModule log_module = GPE_MOD_CLI;
47 #define EXPENSE_ICON PREFIX "/share/pixmaps/gpe-expenses.xpm"
48 #define GPE_EXPENSE_LOG "/tmp/gpe-expense.trace"
49 #define ARGUMENT_BAD_OPTION 17227
50 #define QOF_MOD_SQLITE "qof-sqlite-module"
51 #define SQLITE_DIR ".gpe/"
52 #define DEFAULT_FILE "expenses"
53 #define ACCESS_METHOD "sqlite"
54 
55 #define ENUM_LIST_Q(_) \
56  _(qof_op_noop, = 0) \
57  _(qof_op_list,) \
58  _(qof_op_category,) \
59  _(qof_op_time,) \
60  _(qof_op_sql,) \
61  _(qof_op_sql_file,) \
62  _(qof_op_write, ) \
63  _(qof_op_explain,) \
64  _(qof_op_vers,) \
65  _(qof_op_compress,) \
66  _(qof_op_debug,) \
67  _(qof_op_input, ) \
68  _(qof_op_gui, )
69 
70  DEFINE_ENUM(qof_op_type, ENUM_LIST_Q)
71 
73 gpe_expense_init (void)
74 {
75  GpeExpenseData *context;
76 
77  qof_init();
78  g_return_val_if_fail(ExpensesRegister (), NULL);
79  context = g_new0(GpeExpenseData, 1);
80  return context;
81 }
82 
83 void
85 {
86  qof_main_free(&context->qof);
87  qof_close();
88  g_free(context);
89 }
90 
91 void
92 gpe_expense_error (QofSession * session)
93 {
94  if (qof_error_check (session))
95  gpe_error_box (qof_error_get_message (session));
96 }
97 
98 static struct gpe_icon my_icons[] = {
99  { "icon", EXPENSE_ICON, 0 },
100  { NULL, NULL, NULL }
101 };
102 
103 static void
104 gpe_gui_start(int argc, char *argv[], GpeExpenseData *context)
105 {
106  g_return_if_fail(context);
107  g_return_if_fail(gpe_application_init (&argc, &argv));
108  g_return_if_fail(gpe_load_icons (my_icons));
109  ENTER (" file=%s", context->qof.write_file);
110  if(!context->qof.write_file)
111  {
112  gint test;
113  gboolean gpe_home_exists;
114 
115  /* use a fixed file location. */
116  test = 0;
117  context->qof.write_file = g_strconcat (g_get_home_dir(),
118  "/", SQLITE_DIR, NULL);
119  gpe_home_exists = g_file_test (context->qof.write_file, G_FILE_TEST_IS_DIR);
120  if (!gpe_home_exists)
121  test = g_mkdir (context->qof.write_file, 0700);
122  g_free (context->qof.write_file);
123  context->qof.write_file = g_strconcat (ACCESS_METHOD,
124  ":", g_get_home_dir(), "/", SQLITE_DIR, DEFAULT_FILE, NULL);
125  if (test)
126  context->qof.write_file = g_strconcat (ACCESS_METHOD,
127  ":", g_get_tmp_dir(), "/", DEFAULT_FILE, NULL);
128  }
129  qof_session_begin(context->qof.input_session,
130  context->qof.write_file, TRUE, FALSE);
131  gpe_expense_error (context->qof.input_session);
132  qof_session_load(context->qof.input_session, NULL);
133  context->book = qof_session_get_book(context->qof.input_session);
134  gtk_set_locale ();
135  gtk_init (&argc, &argv);
136 
137  open_expenses_window (context);
138 
139  gtk_main ();
140  qof_session_save(context->qof.input_session, NULL);
141  LEAVE (" ");
142 }
143 
144 int
145 main (int argc, char *argv[])
146 {
148  const gchar *help_header_text;
149  GpeExpenseData *gpe_expense_context;
150  gboolean debug_on;
151  poptContext pc;
152  gint optc;
153  qof_op_type exp_command;
154 
155  struct poptOption options[] = {
156  { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptionsI18N,
157  0, _("Help options:"), NULL },
158  {"list", 'l', POPT_ARG_NONE, NULL, qof_op_list,
159  _("List all databases supported by the current QOF framework and exit."), NULL},
160  {"explain", 0, POPT_ARG_NONE, NULL, qof_op_explain,
161  _("List the fields within the specified database and exit, requires -d."), NULL},
162  {"input-file", 'i', POPT_ARG_STRING, &filename, qof_op_input,
163  _("Query the QSF XML data in <filename>"), _("filename")},
164  {"date", 't', POPT_ARG_STRING, &date_time, qof_op_time,
165  _("Shorthand to only query objects that contain the specified date."), _("string")},
166  {"sql", 's', POPT_ARG_STRING, &sql_query, qof_op_sql,
167  _("Specify a SQL query on the command line."), _("string")},
168  {"sql-file", 'f', POPT_ARG_STRING, &sql_file, qof_op_sql_file,
169  _("Specify one or more SQL queries contained in a file."), _("filename")},
170  {"write", 'w', POPT_ARG_STRING, &write_file, qof_op_write,
171  _("Write the results of any query to the file"), _("filename")},
172  {"gui", 0, POPT_ARG_NONE, NULL, qof_op_gui,
173  _("Use the Gtk graphic interface"), NULL},
174  {"debug", 0, POPT_ARG_NONE, NULL, qof_op_debug,
175  _("Print debugging information to a temporary file."), NULL},
176  {"version", 0, POPT_ARG_NONE, NULL, qof_op_vers,
177  _("Display version information"), NULL},
178  {"category", 'c', POPT_ARG_STRING, &category, qof_op_category,
179  _("Shorthand to only query objects that are set to the specified category."),
180  _("string")},
181  POPT_TABLEEND
182  };
183  exp_command = qof_op_noop;
184  debug_on = FALSE;
186  database = g_strdup("gpe_expenses");
187 
188 #ifdef ENABLE_NLS
189  setlocale (LC_ALL, "");
190  bindtextdomain (GETTEXT_PACKAGE, LOCALE_DIR);
191  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
192  textdomain (GETTEXT_PACKAGE);
193 #endif
194  help_header_text = _(
195  /* Translators: please retain the line endings
196  and punctuation. -i -l --gui or --explain are commands,
197  options are as specified. Please retain 'or' in all cases,
198  options and commands can only be combined in specific ways.
199  */
200  "\n"
201  " Expenses applet for GPE using QOF - \n"
202  " the Query Object Framework.\n"
203  " Supports writing iPAQ data to SQLite.\n"
204  " SQL-type queries on the live data or SQLite file.\n"
205  " SQLite data can be imported into other QOF applications.\n\n"
206  " Use exactly one of -i -l --gui or --explain;\n"
207  " options are -c -t -w, -s or -f.\n\n");
208 
209  pc = poptGetContext (PACKAGE, argc, (const char **)argv, options, 0);
210 
211  poptSetOtherOptionHelp (pc, help_header_text);
212 
213  if (argc < 2)
214  {
215  poptPrintUsage (pc, stderr, 0);
216  return EXIT_FAILURE;
217  }
218  gpe_expense_context = gpe_expense_init();
219  g_return_val_if_fail (gpe_expense_context, 1);
220  while ((optc = poptGetNextOpt (pc)) >= 0)
221  {
222  switch (optc)
223  {
224  /* commands - mutually exclusive */
225  case qof_op_input:
226  case qof_op_list:
227  case qof_op_explain:
228  case qof_op_gui:
229  {
230  if (qof_op_noop != exp_command)
231  {
232  fprintf (stderr, _("%s: ERROR: specify only one of"
233  "-i, -l, --gui or --explain.\n"), PACKAGE);
234  return 1;
235  }
236  exp_command = optc;
237  break;
238  }
239  case qof_op_vers :
240  {
241  fprintf (stdout, "\n Copyright (c) 2005-2007 Neil Williams <linux@codehelp.co.uk>\n");
242  fprintf (stdout, _(" For gpe-expenses support, join the QOF-devel mailing list at\n"));
243  fprintf (stdout, " http://lists.sourceforge.net/mailman/listinfo/qof-devel\n");
244  fprintf (stdout, _("\n This is gpe-expenses v%s\n"), VERSION);
245  fprintf (stdout, _(" Expenses applet for GPE on iPAQ .\n"));
246  /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
247  fprintf (stdout, _(" Build target.........: %s\n"), HOST_OS);
248  /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
249  fprintf (stdout, _(" Build date...........: %s %s\n"), __DATE__, __TIME__);
250  /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
251  fprintf (stdout, _(" --debug logs to......: %s\n\n"), GPE_EXPENSE_LOG);
252  /* Translators: Add or subtract dots to keep the translated lines aligned vertically */
253  fprintf (stdout, _(" Please use --help for more detailed options.\n\n"));
254  return EXIT_SUCCESS;
255  }
256  /* optional modifiers - store to act on later. */
257  case qof_op_category:
258  {
259  qof_mod_category (category, &gpe_expense_context->qof);
260  break;
261  }
262  case qof_op_time:
263  {
264  qof_mod_time (date_time, &gpe_expense_context->qof);
265  break;
266  }
267  case qof_op_sql:
268  {
269  qof_mod_sql (sql_query, &gpe_expense_context->qof);
270  break;
271  }
272  case qof_op_sql_file:
273  {
274  qof_mod_sql_file (sql_file, &gpe_expense_context->qof);
275  break;
276  }
277  case qof_op_write:
278  {
279  qof_mod_write (write_file, &gpe_expense_context->qof);
280  break;
281  }
282  case qof_op_debug:
283  {
284  qof_log_init_filename(GPE_EXPENSE_LOG);
285  qof_log_set_default(QOF_LOG_DETAIL);
286  qof_log_set_level (GPE_MOD_CLI, QOF_LOG_DETAIL);
287  qof_log_set_level (QOF_MAIN_CLI, QOF_LOG_DETAIL);
288  qof_log_set_level (QOF_MOD_SQLITE, QOF_LOG_DETAIL);
289  qof_log_set_level (GPE_MOD_GUI, QOF_LOG_DETAIL);
290  debug_on = TRUE;
291  break;
292  }
293  default:
294  {
295  fprintf (stderr, _("%s: ERROR: got option %d, arg %s\n"), PACKAGE,
296  optc, poptGetOptArg (pc));
297  return EXIT_FAILURE;
298  }
299  }
300  }
301  if (optc < -1)
302  {
303  fprintf(stderr, "%s: %s %s\n\n", PACKAGE,
304  poptBadOption(pc, POPT_BADOPTION_NOALIAS),
305  poptStrerror(optc));
306  poptPrintUsage(pc, stderr, 0);
307  return EXIT_FAILURE;
308  }
309  if (gpe_expense_context->qof.error)
310  return EXIT_FAILURE;
311  /* If we get this far, we should have sensible options: start the work. */
312  gpe_expense_context->qof.input_session = qof_session_new();
313  switch (exp_command)
314  {
315  case qof_op_input:
316  {
317  gpe_expense_context->qof.filename = g_strdup(filename);
318  /* despite the name, this is for any supported file */
319  qof_cmd_xmlfile (&gpe_expense_context->qof);
320  break;
321  }
322  case qof_op_list:
323  {
324  qof_cmd_list ();
325  break;
326  }
327  case qof_op_gui :
328  {
329  gpe_gui_start(argc, argv, gpe_expense_context);
330  break;
331  }
332  case qof_op_explain:
333  {
334  qof_mod_database (database, &gpe_expense_context->qof);
335  if(!gpe_expense_context->qof.database)
336  {
337  /* Translators: capitalise only the initial letter of error. */
338  fprintf (stderr, _("%s: Error: please specify which "
339  "database you would like explained.\n\n"), PACKAGE);
340  break;
341  }
342  qof_cmd_explain(&gpe_expense_context->qof);
343  break;
344  }
345  default:
346  {
347  /* should be impossible */
348  break;
349  }
350  }
351  poptFreeContext(pc);
352  if(debug_on) { qof_log_shutdown(); }
353  gpe_expense_close(gpe_expense_context);
354  return EXIT_SUCCESS;
355 }