* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
GtkEntryClass parent_class;
};
-/* Action to take when the current folder finishes loading (for explicit or automatic completion) */
-typedef enum {
- LOAD_COMPLETE_NOTHING,
- LOAD_COMPLETE_EXPLICIT_COMPLETION
-} LoadCompleteAction;
-
struct _GtkFileChooserEntry
{
GtkEntry parent_instance;
static void gtk_file_chooser_entry_finalize (GObject *object);
static void gtk_file_chooser_entry_dispose (GObject *object);
static void gtk_file_chooser_entry_grab_focus (GtkWidget *widget);
-static gboolean gtk_file_chooser_entry_key_press_event (GtkWidget *widget,
- GdkEventKey *event);
+static gboolean gtk_file_chooser_entry_tab_handler (GtkWidget *widget,
+ GdkEventKey *event);
static gboolean gtk_file_chooser_entry_focus_out_event (GtkWidget *widget,
GdkEventFocus *event);
gobject_class->dispatch_properties_changed = gtk_file_chooser_entry_dispatch_properties_changed;
widget_class->grab_focus = gtk_file_chooser_entry_grab_focus;
- widget_class->key_press_event = gtk_file_chooser_entry_key_press_event;
widget_class->focus_out_event = gtk_file_chooser_entry_focus_out_event;
}
GtkCellRenderer *cell;
chooser_entry->local_only = TRUE;
- chooser_entry->base_folder = g_file_new_for_path (g_get_home_dir ());
g_object_set (chooser_entry, "truncate-multiline", TRUE, NULL);
gtk_entry_set_completion (GTK_ENTRY (chooser_entry), comp);
g_object_unref (comp);
+ /* NB: This needs to happen after the completion is set, so this handler
+ * runs before the handler installed by entrycompletion */
+ g_signal_connect (chooser_entry, "key-press-event",
+ G_CALLBACK (gtk_file_chooser_entry_tab_handler), NULL);
#ifdef G_OS_WIN32
g_signal_connect (chooser_entry, "insert-text",
{
GtkFileChooserEntry *chooser_entry = GTK_FILE_CHOOSER_ENTRY (object);
- g_object_unref (chooser_entry->base_folder);
+ if (chooser_entry->base_folder)
+ g_object_unref (chooser_entry->base_folder);
if (chooser_entry->current_folder_file)
g_object_unref (chooser_entry->current_folder_file);
/* Match functions for the GtkEntryCompletion */
static gboolean
match_selected_callback (GtkEntryCompletion *completion,
- GtkTreeModel *model,
- GtkTreeIter *iter,
- GtkFileChooserEntry *chooser_entry)
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ GtkFileChooserEntry *chooser_entry)
{
char *path;
-
+ gint pos;
+
gtk_tree_model_get (model, iter,
- FULL_PATH_COLUMN, &path,
+ FULL_PATH_COLUMN, &path,
-1);
gtk_editable_delete_text (GTK_EDITABLE (chooser_entry),
- 0,
+ 0,
gtk_editable_get_position (GTK_EDITABLE (chooser_entry)));
+ pos = 0;
gtk_editable_insert_text (GTK_EDITABLE (chooser_entry),
- path,
- 0,
- NULL);
+ path,
+ -1,
+ &pos);
g_free (path);
if (str[0] == '~' || g_path_is_absolute (str) || has_uri_scheme (str))
file = g_file_parse_name (str);
- else
+ else if (chooser_entry->base_folder != NULL)
file = g_file_resolve_relative_path (chooser_entry->base_folder, str);
+ else
+ file = NULL;
return file;
}
file = gtk_file_chooser_get_file_for_text (chooser_entry, text);
+ if (file == NULL)
+ return NULL;
+
if (text[0] == 0 || text[strlen (text) - 1] == G_DIR_SEPARATOR)
return file;
}
static gboolean
-gtk_file_chooser_entry_key_press_event (GtkWidget *widget,
- GdkEventKey *event)
+gtk_file_chooser_entry_tab_handler (GtkWidget *widget,
+ GdkEventKey *event)
{
GtkFileChooserEntry *chooser_entry;
GtkEditable *editable;
GdkModifierType state;
- gboolean control_pressed;
+ gint start, end;
chooser_entry = GTK_FILE_CHOOSER_ENTRY (widget);
editable = GTK_EDITABLE (widget);
if (!chooser_entry->eat_tabs)
- return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->key_press_event (widget, event);
+ return FALSE;
- control_pressed = FALSE;
+ if (event->keyval != GDK_KEY_Tab)
+ return FALSE;
- if (gtk_get_current_event_state (&state))
- {
- if ((state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
- control_pressed = TRUE;
- }
+ if (gtk_get_current_event_state (&state) &&
+ (state & GDK_CONTROL_MASK) == GDK_CONTROL_MASK)
+ return FALSE;
/* This is a bit evil -- it makes Tab never leave the entry. It basically
* makes it 'safe' for people to hit. */
- if (event->keyval == GDK_KEY_Tab && !control_pressed)
- {
- gint start, end;
-
- gtk_editable_get_selection_bounds (editable, &start, &end);
+ gtk_editable_get_selection_bounds (editable, &start, &end);
- if (start != end)
- gtk_editable_set_position (editable, MAX (start, end));
- else
- start_explicit_completion (chooser_entry);
-
- return TRUE;
- }
-
- return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->key_press_event (widget, event);
+ if (start != end)
+ gtk_editable_set_position (editable, MAX (start, end));
+ else
+ start_explicit_completion (chooser_entry);
+ return TRUE;
}
static gboolean
return GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->focus_out_event (widget, event);
}
+static void
+update_inline_completion (GtkFileChooserEntry *chooser_entry)
+{
+ GtkEntryCompletion *completion = gtk_entry_get_completion (GTK_ENTRY (chooser_entry));
+
+ if (!chooser_entry->current_folder_loaded)
+ {
+ gtk_entry_completion_set_inline_completion (completion, FALSE);
+ return;
+ }
+
+ switch (chooser_entry->action)
+ {
+ case GTK_FILE_CHOOSER_ACTION_OPEN:
+ case GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER:
+ gtk_entry_completion_set_inline_completion (completion, TRUE);
+ break;
+ case GTK_FILE_CHOOSER_ACTION_SAVE:
+ case GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER:
+ gtk_entry_completion_set_inline_completion (completion, FALSE);
+ break;
+ }
+}
+
static void
discard_completion_store (GtkFileChooserEntry *chooser_entry)
{
return;
gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), NULL);
- gtk_entry_completion_set_inline_completion (gtk_entry_get_completion (GTK_ENTRY (chooser_entry)), FALSE);
+ update_inline_completion (chooser_entry);
g_object_unref (chooser_entry->completion_store);
chooser_entry->completion_store = NULL;
}
gtk_widget_set_tooltip_text (GTK_WIDGET (chooser_entry), NULL);
completion = gtk_entry_get_completion (GTK_ENTRY (chooser_entry));
- gtk_entry_completion_set_inline_completion (completion, TRUE);
+ update_inline_completion (chooser_entry);
gtk_entry_completion_complete (completion);
gtk_entry_completion_insert_prefix (completion);
}
{
if (folder_file &&
chooser_entry->local_only
- && !g_file_is_native (folder_file))
+ && !_gtk_file_has_native_path (folder_file))
folder_file = NULL;
if ((chooser_entry->current_folder_file
_gtk_file_chooser_entry_set_base_folder (GtkFileChooserEntry *chooser_entry,
GFile *file)
{
+ g_return_if_fail (GTK_IS_FILE_CHOOSER_ENTRY (chooser_entry));
+ g_return_if_fail (file == NULL || G_IS_FILE (file));
+
+ if (chooser_entry->base_folder == file ||
+ (file != NULL && chooser_entry->base_folder != NULL
+ && g_file_equal (chooser_entry->base_folder, file)))
+ return;
+
if (file)
g_object_ref (file);
- else
- file = g_file_new_for_path (g_get_home_dir ());
-
- if (g_file_equal (chooser_entry->base_folder, file))
- {
- g_object_unref (file);
- return;
- }
if (chooser_entry->base_folder)
g_object_unref (chooser_entry->base_folder);
_gtk_file_system_model_set_show_files (GTK_FILE_SYSTEM_MODEL (chooser_entry->completion_store),
action == GTK_FILE_CHOOSER_ACTION_OPEN ||
action == GTK_FILE_CHOOSER_ACTION_SAVE);
+
+ update_inline_completion (chooser_entry);
}
}