From c877d257fed8ff721d23d9e5d841be08bd769559 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 30 Sep 2012 14:15:19 +0900 Subject: Fix for 681625 : sort template names under File->New (bzr r11717) --- src/interface.cpp | 150 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 99 insertions(+), 51 deletions(-) (limited to 'src/interface.cpp') diff --git a/src/interface.cpp b/src/interface.cpp index fdfdce5ae..f26b7ac74 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -778,69 +778,117 @@ sp_file_new_from_template(GtkWidget */*widget*/, gchar const *uri) sp_file_new(uri); } -void -sp_menu_append_new_templates(GtkWidget *menu, Inkscape::UI::View::View *view) -{ - std::list sources; - sources.push_back( profile_path("templates") ); // first try user's local dir - sources.push_back( g_strdup(INKSCAPE_TEMPLATESDIR) ); // then the system templates dir - // Use this loop to iterate through a list of possible document locations. - while (!sources.empty()) { - gchar *dirname = sources.front(); +static bool +compare_file_basenames(gchar const *a, gchar const *b) { + bool rc; + gchar *ba, *bb; - if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) { - GError *err = 0; - GDir *dir = g_dir_open(dirname, 0, &err); + bool sort_by_fullname = true; // Sort by full name (including path) or just filename + if (sort_by_fullname) { + ba = g_strdup(a); + bb = g_strdup(b); + } else { + ba = g_path_get_basename(a); + bb = g_path_get_basename(b); + } - if (dir) { - for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { - if (!g_str_has_suffix(file, ".svg") && !g_str_has_suffix(file, ".svgz")) { - continue; // skip non-svg files - } + gchar *fa = g_filename_to_utf8(ba, -1, NULL, NULL, NULL); + gchar *fb = g_filename_to_utf8(bb, -1, NULL, NULL, NULL); + g_free(ba); + g_free(bb); - { - gchar *basename = g_path_get_basename(file); - if (g_str_has_suffix(basename, ".svg") && g_str_has_prefix(basename, "default.")) { - g_free(basename); - basename = 0; - continue; // skip default.*.svg (i.e. default.svg and translations) - it's in the menu already - } + rc = g_utf8_collate(fa, fb) < 0; + + g_free(fa); + g_free(fb); + + return rc; +} + +void +sp_menu_get_svg_filenames_from_dir(gchar const *dirname, std::list *files) +{ + if ( Inkscape::IO::file_test( dirname, (GFileTest)(G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR) ) ) { + GError *err = 0; + GDir *dir = g_dir_open(dirname, 0, &err); + + if (dir) { + for (gchar const *file = g_dir_read_name(dir); file != NULL; file = g_dir_read_name(dir)) { + if (!g_str_has_suffix(file, ".svg") && !g_str_has_suffix(file, ".svgz")) { + continue; // skip non-svg files + } + + { + gchar *basename = g_path_get_basename(file); + if (g_str_has_suffix(basename, ".svg") && g_str_has_prefix(basename, "default.")) { g_free(basename); basename = 0; + continue; // skip default.*.svg (i.e. default.svg and translations) - it's in the menu already } - - gchar const *filepath = g_build_filename(dirname, file, NULL); - gchar *dupfile = g_strndup(file, strlen(file) - 4); - gchar *filename = g_filename_to_utf8(dupfile, -1, NULL, NULL, NULL); - g_free(dupfile); - GtkWidget *item = gtk_menu_item_new_with_label(filename); - g_free(filename); - - gtk_widget_show(item); - // how does "filepath" ever get freed? - g_signal_connect(G_OBJECT(item), - "activate", - G_CALLBACK(sp_file_new_from_template), - (gpointer) filepath); - - if (view) { - // set null tip for now; later use a description from the template file - g_object_set_data(G_OBJECT(item), "view", (gpointer) view); - g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) NULL ); - g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); - } - - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + g_free(basename); + basename = 0; } - g_dir_close(dir); + + gchar const *filepath = g_build_filename(dirname, file, NULL); + files->push_front(filepath); } + g_dir_close(dir); + } + } + + files->sort(compare_file_basenames); +} + +void +sp_menu_add_filenames_to_menu(GtkWidget *menu, Inkscape::UI::View::View *view, std::list *files) +{ + if (!files->empty()) { + GtkWidget *sep = gtk_separator_menu_item_new(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep); + } + + for(std::list::iterator it=files->begin(); it != files->end(); ++it) { + gchar const *filepath = *it; + gchar const *file = g_path_get_basename(filepath); + gchar *dupfile = g_strndup(file, strlen(file) - 4); + gchar *filename = g_filename_to_utf8(dupfile, -1, NULL, NULL, NULL); + g_free(dupfile); + + GtkWidget *item = gtk_menu_item_new_with_label(filename); + g_free(filename); + + gtk_widget_show(item); + // how does "filepath" ever get freed? + g_signal_connect(G_OBJECT(item), + "activate", + G_CALLBACK(sp_file_new_from_template), + (gpointer) filepath); + + if (view) { + // set null tip for now; later use a description from the template file + g_object_set_data(G_OBJECT(item), "view", (gpointer) view); + g_signal_connect( G_OBJECT(item), "select", G_CALLBACK(sp_ui_menu_select), (gpointer) NULL ); + g_signal_connect( G_OBJECT(item), "deselect", G_CALLBACK(sp_ui_menu_deselect), NULL); } - // toss the dirname - g_free(dirname); - sources.pop_front(); + gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); } + +} +void +sp_menu_append_new_templates(GtkWidget *menu, Inkscape::UI::View::View *view) +{ + // user's local dir + std::list userfiles; + sp_menu_get_svg_filenames_from_dir(profile_path("templates"), &userfiles); + sp_menu_add_filenames_to_menu(menu, view, &userfiles); + + // system templates dir + std::list templatefiles; + sp_menu_get_svg_filenames_from_dir(INKSCAPE_TEMPLATESDIR, &templatefiles); + sp_menu_add_filenames_to_menu(menu, view, &templatefiles); + } void -- cgit v1.2.3