]> git.street.me.uk Git - andy/viking.git/blobdiff - src/vikfilelist.c
DOC: Fix typo
[andy/viking.git] / src / vikfilelist.c
index c948c8bfcb5561888a10b424f2c9ebef5f6d979a..6bd3529ed353157405ecac0c30fb0446b26ef7d4 100644 (file)
@@ -2,6 +2,7 @@
  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
  *
  * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
+ * Copyright (C) 2011, Rob Norris <rw_norris@hotmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  *
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 
 #include "vikfilelist.h"
-#include "vikfileentry.h"
 
 struct _VikFileList {
   GtkVBox parent;
-  VikFileEntry *file_entry;
   GtkWidget *treeview;
+  GtkWidget *file_selector;
   GtkTreeModel *model;
+  GtkFileFilter *filter;
 };
 
 static void file_list_add ( VikFileList *vfl )
 {
-  GtkTreeIter iter;
-  gtk_list_store_append ( GTK_LIST_STORE(vfl->model), &iter );
-  gtk_list_store_set ( GTK_LIST_STORE(vfl->model), &iter, 0, vik_file_entry_get_filename(vfl->file_entry), -1 );
+  GSList *files = NULL;
+  GSList *fiter = NULL;
+  
+  if ( ! vfl->file_selector )
+  {
+    GtkWidget *win;
+    g_assert ( (win = gtk_widget_get_toplevel(GTK_WIDGET(vfl))) );
+    vfl->file_selector = gtk_file_chooser_dialog_new (_("Choose file(s)"),
+                                     GTK_WINDOW(win),
+                                     GTK_FILE_CHOOSER_ACTION_OPEN,
+                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                     NULL);
+    gtk_file_chooser_set_select_multiple ( GTK_FILE_CHOOSER(vfl->file_selector), TRUE );
+    gtk_window_set_transient_for ( GTK_WINDOW(vfl->file_selector), GTK_WINDOW(win) );
+    gtk_window_set_destroy_with_parent ( GTK_WINDOW(vfl->file_selector), TRUE );
+
+    if ( vfl->filter )
+      gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER(vfl->file_selector), vfl->filter );
+  }
+
+  if ( gtk_dialog_run ( GTK_DIALOG(vfl->file_selector) ) == GTK_RESPONSE_ACCEPT ) {
+    files = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER(vfl->file_selector) );
+    fiter = files;
+    GtkTreeIter iter;
+    while ( fiter ) {
+      gchar *file_name = fiter->data;
+      
+      gtk_list_store_append ( GTK_LIST_STORE(vfl->model), &iter );
+      gtk_list_store_set ( GTK_LIST_STORE(vfl->model), &iter, 0, file_name, -1 );
+      
+      g_free (file_name);
+      
+      fiter = g_slist_next (fiter);
+    }
+    g_slist_free (files);
+  }
+    gtk_widget_hide ( vfl->file_selector );
+}
+
+
+static GtkTreeRowReference** file_list_get_selected_refs (GtkTreeModel *model,
+                                                         GList *list)
+{
+  GtkTreeRowReference **arr;
+  GList *iter;
+    
+  arr = g_new (GtkTreeRowReference *, g_list_length (list) + 1);
+    
+  gint pos = 0;
+  for (iter = g_list_first (list); iter != NULL; iter = g_list_next (iter)) {
+    GtkTreePath *path = (GtkTreePath *)(iter->data);
+    arr[pos] = gtk_tree_row_reference_new (model, path);
+    pos++;
+  }
+  arr[pos] = NULL;
+    
+  return arr;
+}
+
+static void file_list_store_delete_refs (GtkTreeModel *model,
+                                        GtkTreeRowReference * const *rrefs)
+{
+    GtkTreePath *path;
+    GtkTreeIter iter;
+
+    gint rr;
+    for ( rr = 0; rrefs[rr] != NULL; rr++ ) {
+      path = gtk_tree_row_reference_get_path (rrefs[rr]);
+      gtk_tree_model_get_iter (model, &iter, path);
+      gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
+    }
 }
 
+
 static void file_list_del ( VikFileList *vfl )
 {
   GtkTreeSelection *ts = gtk_tree_view_get_selection (GTK_TREE_VIEW(vfl->treeview));
-  GtkTreeIter iter;
-  if ( gtk_tree_selection_get_selected(ts, NULL, &iter) )
-    gtk_list_store_remove(GTK_LIST_STORE(vfl->model), &iter);
+  GList *list = gtk_tree_selection_get_selected_rows ( ts, &(vfl->model) );
+
+  // For multi delete need to store references to selected rows
+  GtkTreeRowReference **rrefs = file_list_get_selected_refs ( vfl->model, list );
+  // And then delete each one individually as the path will have changed
+  file_list_store_delete_refs ( vfl->model, rrefs );
+
+  // Cleanup
+  g_list_foreach ( list, (GFunc) gtk_tree_path_free, NULL );
+  g_list_free ( list );
+  g_free (rrefs);
 }
 
 GType vik_file_list_get_type (void)
@@ -70,12 +154,18 @@ GType vik_file_list_get_type (void)
   return vs_type;
 }
 
-GtkWidget *vik_file_list_new ( const gchar *title )
+/**
+ * Support just one filter, as that's all that's needed ATM
+ * Probably need to use a GList of them if more than one is required
+ */
+GtkWidget *vik_file_list_new ( const gchar *title, GtkFileFilter *filter )
 {
   GtkWidget *add_btn, *del_btn;
   GtkWidget *hbox, *scrolledwindow;
   VikFileList *vfl = VIK_FILE_LIST ( g_object_new ( VIK_FILE_LIST_TYPE, NULL ) );
 
+  vfl->filter = filter;
+
   GtkTreeViewColumn *column;
 
   vfl->model = GTK_TREE_MODEL ( gtk_list_store_new(1, G_TYPE_STRING) );
@@ -85,11 +175,12 @@ GtkWidget *vik_file_list_new ( const gchar *title )
   column = gtk_tree_view_column_new_with_attributes ( title, gtk_cell_renderer_text_new (), "text", 0, NULL);
   gtk_tree_view_append_column (GTK_TREE_VIEW (vfl->treeview), column);
 
+  gtk_tree_selection_set_mode ( gtk_tree_view_get_selection (GTK_TREE_VIEW(vfl->treeview)), GTK_SELECTION_MULTIPLE );
+
   gtk_widget_set_size_request ( vfl->treeview, 200, 100);
 
-  vfl->file_entry = VIK_FILE_ENTRY(vik_file_entry_new());
-  add_btn = gtk_button_new_with_label("Add");
-  del_btn = gtk_button_new_with_label("Delete");
+  add_btn = gtk_button_new_with_label(_("Add..."));
+  del_btn = gtk_button_new_with_label(_("Delete"));
 
   g_signal_connect_swapped ( G_OBJECT(add_btn), "clicked", G_CALLBACK(file_list_add), vfl );
   g_signal_connect_swapped ( G_OBJECT(del_btn), "clicked", G_CALLBACK(file_list_del), vfl );
@@ -103,12 +194,12 @@ GtkWidget *vik_file_list_new ( const gchar *title )
   gtk_box_pack_start ( GTK_BOX(vfl), scrolledwindow, TRUE, TRUE, 3 );
 
 
-  gtk_box_pack_start ( GTK_BOX(hbox), GTK_WIDGET(vfl->file_entry), TRUE, TRUE, 3 );
   gtk_box_pack_start ( GTK_BOX(hbox), add_btn, TRUE, TRUE, 3 );
   gtk_box_pack_start ( GTK_BOX(hbox), del_btn, TRUE, TRUE, 3 );
   gtk_box_pack_start ( GTK_BOX(vfl), hbox, FALSE, FALSE, 3 );
   gtk_widget_show_all(GTK_WIDGET(vfl));
 
+  vfl->file_selector = NULL;
 
   return GTK_WIDGET(vfl);
 }
@@ -117,8 +208,8 @@ static gboolean get_file_name(GtkTreeModel *model, GtkTreePath *path, GtkTreeIte
 {
   gchar *str;
   gtk_tree_model_get ( model, iter, 0, &str, -1 );
-  g_debug("get_file_name: %s", str);
-  (*list) = g_list_append((*list), g_strdup(str));
+  g_debug ("%s: %s", __FUNCTION__, str);
+  (*list) = g_list_append((*list), str); // NB str is already a copy
   return FALSE;
 }