Phil Longstaff wrote:

First, I thought I had found something when I found the function gtk_file_chooser_set_local_only, but the wretched dialog insists on trying to display the directory of the entered URI when one clicks Save. Naturally, such a directory does not exist. Entering gda://AnActualConection results in an error.

I found that function too and thought it would fix things, but it
didn't.

I didn't see an error.  What I saw was that the returned file looked
like /path.../gda%3A%2F%2FAnActualConection.  I have some code which
looks for "%3A%2F%2F" and then searches around for the URI that was
entered.  This works, but now means I need to add the sync function to
the backend to blow away the current contents of the database and save
the new contents.  I should have this ready to commit in a few days.
This will at least allow saving to a GDA database.

What version of gtk+ do you have? Mine is 2.8.20. This might account for the different behaviour, but does not really help as neither works for us.

I have attached a patch against gda-dev (svn 15247), which changes the FileChooser to a FileSelection. It can be applied in the gda-dev directory. You will need to pass -p1 to patch.

The dialog accepted a URL like gda://MyDatabaseConnection. However, as you noted, it does not yet save anything. This code should help you to work on that part.

I combined elements of the code from 1.8.12, gda-dev (different OK Buttons), and an example from the gnome documentation (used to reduce the number of callback functions compared to 1.8.12).

Note that filters did not work in 1.8.12 with the FileSelection; they still don't work with this code either.

There are 4 type values that can be passed in. I was unable to find a way to get the function called with "Import" type. Note that "File->Import->QSF Import" puts up a FileSelection Dialog, but does not call the gnc_file_dialog function in gnc-file.c. This suggests some redundant code is now present.

This patch may also be useful in allowing users to enter URLs of the postgres://XXX sort. I was unable to find an open bug related to this problem. Let me know if there is somewhere else I should submit this patch for the postgres problem. (I only found 2 bugs for this; both closed - 332251 & 329802.)

Mark


--- gda-dev/src/gnome-utils/gnc-file.c  2006-12-23 19:40:47.000000000 -0700
+++ mj-dev/src/gnome-utils/gnc-file.c   2006-12-23 19:38:55.000000000 -0700
@@ -56,6 +56,18 @@
 static gint save_in_progress = 0;
 
 
+typedef struct
+{
+  GtkFileSelection *file_box;
+  char *file_name;
+} FileBoxInfo;
+
+/* Global filebox information */
+static FileBoxInfo fb_info = {NULL, NULL};
+
+/* PROTOTYPES *******************************************************/
+static void store_filename (GtkWidget *w, gpointer data);
+
 /********************************************************************\
  * gnc_file_dialog                                                  * 
  *   Pops up a file selection dialog (either a "Save As" or an      * 
@@ -78,112 +90,136 @@
                 GNCFileDialogType type
                 )
 {
-  GtkWidget *file_box;
-  const char *internal_name;
-  char *file_name = NULL;
-  gchar * okbutton = GTK_STOCK_OPEN;
-  const gchar *ok_icon = NULL;
-  GtkFileChooserAction action = GTK_FILE_CHOOSER_ACTION_OPEN; 
-  gint response;
+  ENTER("\n");
 
-  ENTER(" ");
+  if (fb_info.file_name != NULL)
+    g_free(fb_info.file_name);
+  fb_info.file_name = NULL;
+
+  /* Create the dialog */
+  fb_info.file_box = GTK_FILE_SELECTION(gtk_file_selection_new(title));
 
+  /* Set dialog title, OK button and File Ops buttons according to type */
   switch (type) {
-       case GNC_FILE_DIALOG_OPEN:
-                 action = GTK_FILE_CHOOSER_ACTION_OPEN;
-                 okbutton = GTK_STOCK_OPEN;
-                 if (title == NULL)
-                         title = _("Open");
-                 break;
-       case GNC_FILE_DIALOG_IMPORT:
-                 action = GTK_FILE_CHOOSER_ACTION_OPEN;
-                 okbutton = _("_Import");
-                 if (title == NULL)
-                         title = _("Import");
-                 break;
-       case GNC_FILE_DIALOG_SAVE:
-                 action = GTK_FILE_CHOOSER_ACTION_SAVE;
-                 okbutton = GTK_STOCK_SAVE;
-                 if (title == NULL)
-                         title = _("Save");
-                 break;
-       case GNC_FILE_DIALOG_EXPORT:
-                 action = GTK_FILE_CHOOSER_ACTION_SAVE;
-                 okbutton = _("_Export");
-                 ok_icon = GTK_STOCK_CONVERT;
-                 if (title == NULL)
-                         title = _("Export");
-                 break;
-       
-  }
-
-  file_box = gtk_file_chooser_dialog_new(
-                         title,
-                         NULL,
-                         action,
-                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-                         NULL);
-  if (ok_icon)
-    gnc_gtk_dialog_add_button(file_box, okbutton, ok_icon, 
GTK_RESPONSE_ACCEPT);
-  else
-    gtk_dialog_add_button(GTK_DIALOG(file_box),
-                         okbutton, GTK_RESPONSE_ACCEPT);
+    case GNC_FILE_DIALOG_OPEN:
+      /* change OK Button to Stock Open */
+      gtk_button_set_label(GTK_BUTTON(fb_info.file_box->ok_button), 
GTK_STOCK_OPEN);
+      gtk_button_set_use_stock(GTK_BUTTON(fb_info.file_box->ok_button), TRUE);
 
-  if (starting_dir) {
-    gchar *dir_name;
+      gtk_file_selection_hide_fileop_buttons(fb_info.file_box);
 
-    /* Ensure we have a directory name.  The set function fails otherwise. */
-    dir_name = g_path_get_dirname(starting_dir);
-    gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER (file_box), dir_name);
-    g_free(dir_name);
-  }
+      /* default title */
+      if (title == NULL)
+        title = _("Open");
+      break;
 
-  gtk_window_set_modal(GTK_WINDOW(file_box), TRUE);
-  /*
-  gtk_window_set_transient_for(GTK_WINDOW(file_box),
-                              GTK_WINDOW(gnc_ui_get_toplevel()));
-  */
+    case GNC_FILE_DIALOG_IMPORT:
+      /* change OK Button to Import */
+      gtk_button_set_label(GTK_BUTTON(fb_info.file_box->ok_button), 
_("Import"));
 
-  if (filters != NULL)
-  {
-    GList* filter;
-    GtkFileFilter* all_filter = gtk_file_filter_new();
+      gtk_file_selection_hide_fileop_buttons(fb_info.file_box);
 
-    for (filter=filters; filter; filter=filter->next) {
-      g_return_val_if_fail(GTK_IS_FILE_FILTER(filter->data), NULL);
-      gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_box),
-                                  GTK_FILE_FILTER (filter->data));
-    }
+      /* default title */
+      if (title == NULL)
+        title = _("Import");
+      break;
 
-    gtk_file_filter_set_name (all_filter, _("All files"));
-    gtk_file_filter_add_pattern (all_filter, "*");
-    gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (file_box), all_filter);
-
-    /* Note: You cannot set a file filter and pre-select a file name.
-     * The latter wins, and the filter ends up diabled.  Since we are
-     * only settin the starting directory for the chooser dialog,
-     * everything works as expected. */
-    gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (file_box),
-                                GTK_FILE_FILTER (filters->data));
-    g_list_free (filters);
-  }
-
-  response = gtk_dialog_run(GTK_DIALOG(file_box));
-
-  if (response == GTK_RESPONSE_ACCEPT) {
-    /* look for constructs like postgres://foo */
-    internal_name = gtk_file_chooser_get_uri(GTK_FILE_CHOOSER (file_box));
-    if (strstr (internal_name, "file://") == internal_name) {
-      /* nope, a local file name */
-      internal_name = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER 
(file_box));
-    }
-    file_name = g_strdup(internal_name);
+    case GNC_FILE_DIALOG_SAVE:
+      /* change OK Button to Stock Save */
+      gtk_button_set_label(GTK_BUTTON(fb_info.file_box->ok_button), 
GTK_STOCK_SAVE);
+      gtk_button_set_use_stock(GTK_BUTTON(fb_info.file_box->ok_button), TRUE);
+
+      /* default title */
+      if (title == NULL)
+        title = _("Save");
+      break;
+
+    case GNC_FILE_DIALOG_EXPORT:
+      /* change OK Button to Export */
+      gtk_button_set_label(GTK_BUTTON(fb_info.file_box->ok_button), 
_("Export"));
+
+      /* default title */
+      if (title == NULL)
+        title = _("Export");
+      break;
   }
-  gtk_widget_destroy(GTK_WIDGET(file_box));
-  LEAVE("%s", file_name);
-  return file_name;
+
+
+  /* hack alert - this was filtering directory names as well as file
+   * names, so I think we should not do this by default (rgmerk) */
+  /* FIXME filters ignored. */
+#if 0
+  if (filter != NULL)
+    gtk_file_selection_complete(fb_info.file_box, filter);
+#endif
+
+
+  /* Set the starting_dir. */
+  if (starting_dir) {
+    /* NOTE: To set the directory only, this must have a trailing
+    ** /.  */
+    gtk_file_selection_set_filename(fb_info.file_box, starting_dir);
+  }
+
+  gtk_window_set_modal(GTK_WINDOW(fb_info.file_box), TRUE);
+  gtk_window_set_transient_for(GTK_WINDOW(fb_info.file_box),
+                               GTK_WINDOW(gnc_ui_get_toplevel()));
+
+  /* OK Button stores filename */
+  g_signal_connect(GTK_OBJECT(fb_info.file_box->ok_button),
+                   "clicked", GTK_SIGNAL_FUNC(store_filename),
+                   (gpointer) &fb_info);
+
+  /* Ensure that the dialog box is destroyed when the user clicks a button. */
+  g_signal_connect_swapped(GTK_OBJECT(fb_info.file_box->ok_button),
+                   "clicked", G_CALLBACK (gtk_widget_destroy),
+                   fb_info.file_box);
+
+  g_signal_connect_swapped(GTK_OBJECT(fb_info.file_box->cancel_button),
+                   "clicked", G_CALLBACK (gtk_widget_destroy),
+                   fb_info.file_box);
+
+  g_signal_connect(GTK_OBJECT(fb_info.file_box), "delete_event",
+                   G_CALLBACK (gtk_widget_destroy),
+                   NULL);
+
+  g_signal_connect(GTK_OBJECT(fb_info.file_box), "destroy_event",
+                   G_CALLBACK (gtk_widget_destroy),
+                   NULL);
+
+  gtk_dialog_run(GTK_DIALOG(fb_info.file_box));
+  LEAVE("\n");
+  return fb_info.file_name;
 }
 
+/********************************************************************\
+ * store_filename                                                   *
+ *   callback that saves the name of the file                       *
+ *                                                                  *
+ * Args:   w - the widget that called us                            *
+ *         data - pointer to filebox info structure                 *
+ * Return: none                                                     *
+\********************************************************************/
+static void
+store_filename (GtkWidget *w, gpointer data)
+{
+  FileBoxInfo *fb_info = data;
+  GtkFileSelection *fs;
+  const gchar *file_name;
+
+  fs = GTK_FILE_SELECTION (fb_info->file_box);
+
+  file_name = gtk_entry_get_text (GTK_ENTRY (fs->selection_entry));
+
+  if (!strstr (file_name, "://"))
+    file_name = gtk_file_selection_get_filename (fb_info->file_box);
+
+  fb_info->file_name = g_strdup (file_name);
+}
+
+
+/********************************************************************\
+\********************************************************************/
 
 gboolean
 show_session_error (QofBackendError io_error,
_______________________________________________
gnucash-devel mailing list
[email protected]
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to