gtk+ r19753 - in trunk: . gtk



Author: tml
Date: Tue Mar 11 18:43:49 2008
New Revision: 19753
URL: http://svn.gnome.org/viewvc/gtk+?rev=19753&view=rev

Log:
2008-03-11  Tor Lillqvist  <tml novell com>

	Bug 469868 - Filenames with colon ":" are not saved correctly

	* gtk/gtkfilechooserentry.c (insert_text_callback)
	(delete_text_callback) [Win32]: New functions to make sure that
	colons used otherwise than as a separator after a drive letter, or
	characters that are always illegal in file names, are rejected on
	input. This means that the GTK+ file chooser can't be used to
	input full names of alternate data streams, but oh well. There are
	still more checks that could be done on the file names, see the
	bug report. But this will do for now.
	(_gtk_file_chooser_entry_init) [Win32]: Connect above functions.



Modified:
   trunk/ChangeLog
   trunk/gtk/gtkfilechooserentry.c

Modified: trunk/gtk/gtkfilechooserentry.c
==============================================================================
--- trunk/gtk/gtkfilechooserentry.c	(original)
+++ trunk/gtk/gtkfilechooserentry.c	Tue Mar 11 18:43:49 2008
@@ -87,6 +87,19 @@
 
 static void     clear_completion_callback (GtkFileChooserEntry *chooser_entry,
 					   GParamSpec          *pspec);
+
+#ifdef G_OS_WIN32
+static gint     insert_text_callback      (GtkFileChooserEntry *widget,
+					   const gchar         *new_text,
+					   gint                 new_text_length,
+					   gint                *position,
+					   gpointer             user_data);
+static void     delete_text_callback      (GtkFileChooserEntry *widget,
+					   gint                 start_pos,
+					   gint                 end_pos,
+					   gpointer             user_data);
+#endif
+
 static gboolean match_selected_callback   (GtkEntryCompletion  *completion,
 					   GtkTreeModel        *model,
 					   GtkTreeIter         *iter,
@@ -169,6 +182,13 @@
 		    G_CALLBACK (clear_completion_callback), NULL);
   g_signal_connect (chooser_entry, "notify::selection-bound",
 		    G_CALLBACK (clear_completion_callback), NULL);
+
+#ifdef G_OS_WIN32
+  g_signal_connect (chooser_entry, "insert_text",
+		    G_CALLBACK (insert_text_callback), NULL);
+  g_signal_connect (chooser_entry, "delete_text",
+		    G_CALLBACK (delete_text_callback), NULL);
+#endif
 }
 
 static void
@@ -876,6 +896,70 @@
     }
 }
 
+#ifdef G_OS_WIN32
+static gint
+insert_text_callback (GtkFileChooserEntry *chooser_entry,
+		      const gchar	  *new_text,
+		      gint       	   new_text_length,
+		      gint       	  *position,
+		      gpointer   	   user_data)
+{
+  const gchar *colon = memchr (new_text, ':', new_text_length);
+  gint i;
+
+  /* Disallow these characters altogether */
+  for (i = 0; i < new_text_length; i++)
+    {
+      if (new_text[i] == '<' ||
+	  new_text[i] == '>' ||
+	  new_text[i] == '"' ||
+	  new_text[i] == '|' ||
+	  new_text[i] == '*' ||
+	  new_text[i] == '?')
+	break;
+    }
+
+  if (i < new_text_length ||
+      /* Disallow entering text that would cause a colon to be anywhere except
+       * after a drive letter.
+       */
+      (colon != NULL &&
+       *position + (colon - new_text) != 1) ||
+      (new_text_length > 0 &&
+       *position <= 1 &&
+       GTK_ENTRY (chooser_entry)->text_length >= 2 &&
+       gtk_entry_get_text (GTK_ENTRY (chooser_entry))[1] == ':'))
+    {
+      gtk_widget_error_bell (GTK_WIDGET (chooser_entry));
+      g_signal_stop_emission_by_name (chooser_entry, "insert_text");
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+delete_text_callback (GtkFileChooserEntry *chooser_entry,
+		      gint                 start_pos,
+		      gint                 end_pos,
+		      gpointer             user_data)
+{
+  /* If deleting a drive letter, delete the colon, too */
+  if (start_pos == 0 && end_pos == 1 &&
+      GTK_ENTRY (chooser_entry)->text_length >= 2 &&
+      gtk_entry_get_text (GTK_ENTRY (chooser_entry))[1] == ':')
+    {
+      g_signal_handlers_block_by_func (chooser_entry,
+				       G_CALLBACK (delete_text_callback),
+				       user_data);
+      gtk_editable_delete_text (GTK_EDITABLE (chooser_entry), 0, 1);
+      g_signal_handlers_unblock_by_func (chooser_entry,
+					 G_CALLBACK (delete_text_callback),
+					 user_data);
+    }
+}
+#endif
+
 /**
  * _gtk_file_chooser_entry_new:
  * @eat_tabs: If %FALSE, allow focus navigation with the tab key.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]