00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00032 #include "config.h"
00033
00034 #include <gtk/gtk.h>
00035 #include <glib/gi18n.h>
00036 #include <glib/gprintf.h>
00037 #include <string.h>
00038
00039 #include "gnc-gkeyfile-utils.h"
00040 #include "gnc-file.h"
00041 #include "gnc-main-window.h"
00042 #include "gnc-plugin-file-history.h"
00043 #include "gnc-window.h"
00044 #include "gnc-engine.h"
00045 #include "gnc-gconf-utils.h"
00046
00047 static GObjectClass *parent_class = NULL;
00048
00049 #define FILENAME_STRING "filename"
00050
00051 static void gnc_plugin_file_history_class_init (GncPluginFileHistoryClass *klass);
00052 static void gnc_plugin_file_history_init (GncPluginFileHistory *plugin);
00053 static void gnc_plugin_file_history_finalize (GObject *object);
00054
00055 static void gnc_plugin_file_history_add_to_window (GncPlugin *plugin, GncMainWindow *window, GQuark type);
00056 static void gnc_plugin_file_history_remove_from_window (GncPlugin *plugin, GncMainWindow *window, GQuark type);
00057
00058
00060 static QofLogModule log_module = GNC_MOD_GUI;
00061
00062
00063 static void gnc_plugin_file_history_cmd_open_file (GtkAction *action, GncMainWindowActionData *data);
00064
00065
00067 #define PLUGIN_ACTIONS_NAME "gnc-plugin-file-history-actions"
00068
00069 #define PLUGIN_UI_FILENAME "gnc-plugin-file-history-ui.xml"
00070
00071 #define GNOME1_HISTORY "History"
00072 #define GNOME1_MAXFILES "MaxFiles"
00073
00079 static GtkActionEntry gnc_plugin_actions [] = {
00080 { "RecentFile0Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00081 { "RecentFile1Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00082 { "RecentFile2Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00083 { "RecentFile3Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00084 { "RecentFile4Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00085 { "RecentFile5Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00086 { "RecentFile6Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00087 { "RecentFile7Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00088 { "RecentFile8Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00089 { "RecentFile9Action", NULL, "", NULL, NULL, G_CALLBACK (gnc_plugin_file_history_cmd_open_file) },
00090 };
00092 static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions);
00093
00094
00097 typedef struct GncPluginFileHistoryPrivate
00098 {
00099 gpointer dummy;
00100 } GncPluginFileHistoryPrivate;
00101
00102
00103 #define GNC_PLUGIN_FILE_HISTORY_GET_PRIVATE(o) \
00104 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN_FILE_HISTORY, GncPluginFileHistoryPrivate))
00105
00106
00107
00108
00109
00118 static gchar *
00119 gnc_history_gconf_index_to_key (guint index)
00120 {
00121 return g_strdup_printf(HISTORY_STRING_FILE_N, index);
00122 }
00123
00124
00133 static gint
00134 gnc_history_gconf_key_to_index (const gchar *key)
00135 {
00136 gint index, result;
00137
00138 result = sscanf(key, HISTORY_STRING_FILE_N, &index);
00139 if (result != 1)
00140 return -1;
00141 if ((index < 0) || (index >= gnc_plugin_n_actions))
00142 return -1;
00143 return index;
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 void
00153 gnc_history_add_file (const char *newfile)
00154 {
00155 gchar *filename, *from, *to;
00156 gint i, last;
00157
00158 if (newfile == NULL)
00159 return;
00160 if (!g_utf8_validate(newfile, -1, NULL))
00161 return;
00162
00163
00164
00165
00166 last = MAX_HISTORY_FILES - 1;
00167 for (i = 0; i < MAX_HISTORY_FILES; i++) {
00168 from = gnc_history_gconf_index_to_key(i);
00169 filename = gnc_gconf_get_string(HISTORY_STRING_SECTION, from, NULL);
00170 g_free(from);
00171
00172 if (!filename) {
00173 last = i;
00174 break;
00175 }
00176 if (g_utf8_collate(newfile, filename) == 0) {
00177 g_free(filename);
00178 last = i;
00179 break;
00180 }
00181 g_free(filename);
00182 }
00183
00184
00185
00186
00187 to = gnc_history_gconf_index_to_key(last);
00188 for (i = last - 1; i >= 0; i--) {
00189 from = gnc_history_gconf_index_to_key(i);
00190 filename = gnc_gconf_get_string(HISTORY_STRING_SECTION, from, NULL);
00191 if (filename) {
00192 gnc_gconf_set_string(HISTORY_STRING_SECTION, to, filename, NULL);
00193 g_free(filename);
00194 } else {
00195 gnc_gconf_unset(HISTORY_STRING_SECTION, to, NULL);
00196 }
00197 g_free(to);
00198 to = from;
00199 }
00200
00201
00202
00203
00204 gnc_gconf_set_string(HISTORY_STRING_SECTION, to, newfile, NULL);
00205 g_free(to);
00206 }
00207
00208
00214 void
00215 gnc_history_remove_file (const char *oldfile)
00216 {
00217 gchar *filename, *from, *to;
00218 gint i, j;
00219
00220 if (!oldfile)
00221 return;
00222 if (!g_utf8_validate(oldfile, -1, NULL))
00223 return;
00224
00225 for (i=0, j=0; i<MAX_HISTORY_FILES; i++) {
00226 from = gnc_history_gconf_index_to_key(i);
00227 filename = gnc_gconf_get_string(HISTORY_STRING_SECTION, from, NULL);
00228
00229 if (filename) {
00230 if (g_utf8_collate(oldfile, filename) == 0) {
00231 gnc_gconf_unset(HISTORY_STRING_SECTION, from, NULL);
00232 } else {
00233 if (i != j) {
00234 to = gnc_history_gconf_index_to_key(j);
00235 gnc_gconf_set_string(HISTORY_STRING_SECTION, to, filename, NULL);
00236 gnc_gconf_unset(HISTORY_STRING_SECTION, from, NULL);
00237 g_free(to);
00238 }
00239 j++;
00240 }
00241 }
00242 g_free(from);
00243 }
00244 }
00245
00246
00247
00248
00249
00250 char *
00251 gnc_history_get_last (void)
00252 {
00253 char *filename, *key;
00254
00255 key = gnc_history_gconf_index_to_key(0);
00256 filename = gnc_gconf_get_string(HISTORY_STRING_SECTION, key, NULL);
00257 g_free(key);
00258
00259 return filename;
00260 }
00261
00262
00263
00264
00265
00266
00276 static gchar *
00277 gnc_history_generate_label (int index, const gchar *filename)
00278 {
00279 const gchar *src;
00280 gchar *result, *dst;
00281 gunichar unichar;
00282
00283
00284 result = g_malloc(strlen(filename) * 2);
00285
00286 dst = result;
00287 if (index < 10)
00288 dst += g_sprintf(result, "_%d ", (index + 1) % 10);
00289
00290
00291 src = g_utf8_strrchr(filename, -1, G_DIR_SEPARATOR);
00292 if (src) {
00293 src = g_utf8_next_char(src);
00294
00295
00296
00297 for ( ; *src; src = g_utf8_next_char(src)) {
00298 unichar = g_utf8_get_char(src);
00299 dst += g_unichar_to_utf8 (unichar, dst);
00300
00301 if (unichar == '_')
00302 dst += g_unichar_to_utf8 ('_', dst);
00303 }
00304 }
00305
00306 *dst = '\0';
00307 return result;
00308 }
00309
00310
00328 static void
00329 gnc_history_update_action (GncMainWindow *window,
00330 gint index,
00331 const gchar *filename)
00332 {
00333 GtkActionGroup *action_group;
00334 GtkAction *action;
00335 gchar *action_name, *label_name, *old_filename;
00336 gint limit;
00337
00338 ENTER("window %p, index %d, filename %s", window, index,
00339 filename ? filename : "(null)");
00340
00341 action_group =
00342 gnc_main_window_get_action_group(window, PLUGIN_ACTIONS_NAME);
00343
00344 action_name = g_strdup_printf("RecentFile%dAction", index);
00345 action = gtk_action_group_get_action (action_group, action_name);
00346
00347 limit = gnc_gconf_get_int (HISTORY_STRING_SECTION,
00348 HISTORY_STRING_MAXFILES,
00349 NULL);
00350
00351 if (filename && (strlen(filename) > 0) && (index < limit)) {
00352
00353 label_name = gnc_history_generate_label(index, filename);
00354 g_object_set(G_OBJECT(action), "label", label_name, "visible", TRUE, NULL);
00355 g_free(label_name);
00356
00357
00358 old_filename = g_object_get_data(G_OBJECT(action), FILENAME_STRING);
00359 if (old_filename)
00360 g_free(old_filename);
00361 g_object_set_data(G_OBJECT(action), FILENAME_STRING, g_strdup(filename));
00362 } else {
00363 gtk_action_set_visible(action, FALSE);
00364 }
00365 g_free(action_name);
00366 LEAVE("");
00367 }
00368
00369
00378 static void
00379 gnc_history_update_menus (GncMainWindow *window)
00380 {
00381 gchar *filename, *key;
00382 guint i;
00383
00384 ENTER("");
00385 for (i = 0; i < MAX_HISTORY_FILES; i++) {
00386 key = gnc_history_gconf_index_to_key(i);
00387 filename = gnc_gconf_get_string(HISTORY_STRING_SECTION, key, NULL);
00388 gnc_history_update_action(window, i, filename);
00389 g_free(filename);
00390 g_free(key);
00391 }
00392 LEAVE("");
00393 }
00394
00395
00411 static void
00412 gnc_plugin_history_list_changed (GConfClient *client,
00413 guint cnxn_id,
00414 GConfEntry *entry,
00415 gpointer user_data)
00416 {
00417 GncMainWindow *window;
00418 GConfValue *value;
00419 const gchar *fullkey, *key, *filename;
00420 gint index;
00421
00422 ENTER("");
00423 window = GNC_MAIN_WINDOW(user_data);
00424
00425 fullkey = gconf_entry_get_key(entry);
00426 key = strrchr(fullkey, '/') + 1;
00427 if (strcmp(key, HISTORY_STRING_MAXFILES) == 0) {
00428 gnc_history_update_menus (window);
00429 LEAVE("updated maxfiles");
00430 return;
00431 }
00432 index = gnc_history_gconf_key_to_index(key);
00433 if (index < 0) {
00434 LEAVE("bad index");
00435 return;
00436 }
00437
00438 value = gconf_entry_get_value(entry);
00439 if (!value) {
00440 LEAVE("No gconf value");
00441 return;
00442 }
00443 filename = gconf_value_get_string(value);
00444 gnc_history_update_action (window, index, filename);
00445
00446 gnc_main_window_actions_updated (window);
00447 LEAVE("");
00448 }
00449
00450
00451
00452
00453 static void
00454 gnc_plugin_history_list_from_gnucash1 (void)
00455 {
00456 GKeyFile *keyfile;
00457 const gchar *home;
00458 gchar *mdi_file, *value;
00459 gchar **keys, **key, *new_key;
00460 gint file_id, max;
00461
00462
00463
00464 value = gnc_gconf_get_string(HISTORY_STRING_SECTION, "file0", NULL);
00465 if (value) {
00466 g_free(value);
00467 return;
00468 }
00469
00470 home = g_get_home_dir();
00471 if (!home)
00472 return;
00473
00474
00475
00476 mdi_file = g_build_filename(home, ".gnome", "GnuCash", (gchar *)NULL);
00477 keyfile = gnc_key_file_load_from_file (mdi_file, FALSE, FALSE, NULL);
00478 if (keyfile) {
00479 keys = g_key_file_get_keys(keyfile, GNOME1_HISTORY, NULL, NULL);
00480 if (keys) {
00481 for (key = keys; *key; key++) {
00482 if (!strcmp(*key, GNOME1_MAXFILES)) {
00483 max = g_key_file_get_integer(keyfile, GNOME1_HISTORY,
00484 GNOME1_MAXFILES, NULL);
00485 printf("Found old maxfiles: %d\n", max);
00486 if ((max > 0) && (max < MAX_HISTORY_FILES))
00487 printf("Setting maxfiles: %d\n\n", max);
00488 gnc_gconf_set_int(HISTORY_STRING_SECTION, HISTORY_STRING_MAXFILES,
00489 max, NULL);
00490 continue;
00491 }
00492
00493 if (sscanf(*key, "File%d", &file_id) == 1) {
00494 value = g_key_file_get_string(keyfile, GNOME1_HISTORY, *key, NULL);
00495 if (!value)
00496 continue;
00497 printf("Found old file %d: %s\n", file_id, value);
00498 new_key = g_strdup_printf(HISTORY_STRING_FILE_N, file_id);
00499 gnc_gconf_set_string (HISTORY_STRING_SECTION, new_key, value, NULL);
00500 printf("Setting %s: %s\n\n", new_key, value);
00501 g_free(new_key);
00502 g_free(value);
00503 }
00504 }
00505 g_strfreev(keys);
00506 }
00507 g_key_file_free(keyfile);
00508 }
00509
00510 g_free(mdi_file);
00511 }
00512
00513
00514
00515
00516
00517
00518 GType
00519 gnc_plugin_file_history_get_type (void)
00520 {
00521 static GType gnc_plugin_file_history_type = 0;
00522
00523 if (gnc_plugin_file_history_type == 0) {
00524 static const GTypeInfo our_info = {
00525 sizeof (GncPluginFileHistoryClass),
00526 NULL,
00527 NULL,
00528 (GClassInitFunc) gnc_plugin_file_history_class_init,
00529 NULL,
00530 NULL,
00531 sizeof (GncPluginFileHistory),
00532 0,
00533 (GInstanceInitFunc) gnc_plugin_file_history_init
00534 };
00535
00536 gnc_plugin_file_history_type =
00537 g_type_register_static (GNC_TYPE_PLUGIN,
00538 "GncPluginFileHistory",
00539 &our_info, 0);
00540 }
00541
00542 return gnc_plugin_file_history_type;
00543 }
00544
00545
00547 static void
00548 gnc_plugin_file_history_class_init (GncPluginFileHistoryClass *klass)
00549 {
00550 GObjectClass *object_class = G_OBJECT_CLASS (klass);
00551 GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass);
00552
00553 parent_class = g_type_class_peek_parent (klass);
00554
00555 object_class->finalize = gnc_plugin_file_history_finalize;
00556
00557
00558 plugin_class->plugin_name = GNC_PLUGIN_FILE_HISTORY_NAME;
00559
00560
00561 plugin_class->add_to_window = gnc_plugin_file_history_add_to_window;
00562 plugin_class->remove_from_window =
00563 gnc_plugin_file_history_remove_from_window;
00564
00565
00566 plugin_class->actions_name = PLUGIN_ACTIONS_NAME;
00567 plugin_class->actions = gnc_plugin_actions;
00568 plugin_class->n_actions = gnc_plugin_n_actions;
00569 plugin_class->ui_filename = PLUGIN_UI_FILENAME;
00570
00571 plugin_class->gconf_section = HISTORY_STRING_SECTION;
00572 plugin_class->gconf_notifications = gnc_plugin_history_list_changed;
00573
00574 g_type_class_add_private(klass, sizeof(GncPluginFileHistoryPrivate));
00575
00576 gnc_plugin_history_list_from_gnucash1();
00577 }
00578
00579
00581 static void
00582 gnc_plugin_file_history_init (GncPluginFileHistory *plugin)
00583 {
00584 ENTER("plugin %p", plugin);
00585 LEAVE("");
00586 }
00587
00588
00590 static void
00591 gnc_plugin_file_history_finalize (GObject *object)
00592 {
00593 GncPluginFileHistory *plugin;
00594 GncPluginFileHistoryPrivate *priv;
00595
00596 g_return_if_fail (GNC_IS_PLUGIN_FILE_HISTORY (object));
00597
00598 ENTER("plugin %p", object);
00599 plugin = GNC_PLUGIN_FILE_HISTORY (object);
00600 priv = GNC_PLUGIN_FILE_HISTORY_GET_PRIVATE (plugin);
00601
00602 G_OBJECT_CLASS (parent_class)->finalize (object);
00603 LEAVE("");
00604 }
00605
00606
00607
00608
00609
00610 GncPlugin *
00611 gnc_plugin_file_history_new (void)
00612 {
00613 GncPlugin *plugin_page = NULL;
00614
00615 ENTER("");
00616 plugin_page = GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_FILE_HISTORY, NULL));
00617 LEAVE("plugin %p", plugin_page);
00618 return plugin_page;
00619 }
00620
00621
00622
00623
00624
00641 static void
00642 gnc_plugin_file_history_add_to_window (GncPlugin *plugin,
00643 GncMainWindow *window,
00644 GQuark type)
00645 {
00646 gnc_history_update_menus(window);
00647 }
00648
00649
00662 static void
00663 gnc_plugin_file_history_remove_from_window (GncPlugin *plugin,
00664 GncMainWindow *window,
00665 GQuark type)
00666 {
00667 }
00668
00669
00670
00671
00672
00685 static void
00686 gnc_plugin_file_history_cmd_open_file (GtkAction *action,
00687 GncMainWindowActionData *data)
00688 {
00689 gchar *filename;
00690
00691 g_return_if_fail(GTK_IS_ACTION(action));
00692 g_return_if_fail(data != NULL);
00693
00694
00695
00696
00697
00698 filename = g_object_get_data(G_OBJECT(action), FILENAME_STRING);
00699 gnc_window_set_progressbar_window (GNC_WINDOW(data->window));
00700
00701 if (!gnc_file_open_file (filename))
00702 gnc_history_remove_file (filename);
00703 gnc_window_set_progressbar_window (NULL);
00704 }
00705