~ubuntu-branches/ubuntu/precise/gtk+2.0/precise-updates

« back to all changes in this revision

Viewing changes to gtk/gtkfilechooserdefault.c

  • Committer: Package Import Robot
  • Author(s): Ken VanDine
  • Date: 2011-12-01 11:40:06 UTC
  • mfrom: (1.14.11)
  • Revision ID: package-import@ubuntu.com-20111201114006-nrmf6qu3pg512veo
Tags: 2.24.8-0ubuntu1
* New upstream release 
  - gtkfilechooser should be more robust to malformed URIs
    in .gtk-bookmarks (LP: #189494)
* debian/patches/010_make_bg_changes_queue_repaint.patch
  - dropped it introduces performance regressions in some gtk2 
    apps (LP: #889019)
* 101_filechooser.patch, 000git_file_chooser.patch: dropped, upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
401
401
 
402
402
static void stop_loading_and_clear_list_model (GtkFileChooserDefault *impl,
403
403
                                               gboolean remove_from_treeview);
 
404
 
 
405
static void     search_setup_widgets         (GtkFileChooserDefault *impl);
404
406
static void     search_stop_searching        (GtkFileChooserDefault *impl,
405
407
                                              gboolean               remove_query);
406
408
static void     search_clear_model           (GtkFileChooserDefault *impl, 
407
409
                                              gboolean               remove_from_treeview);
408
410
static gboolean search_should_respond        (GtkFileChooserDefault *impl);
409
 
static void     search_switch_to_browse_mode (GtkFileChooserDefault *impl);
410
411
static GSList  *search_get_selected_files    (GtkFileChooserDefault *impl);
411
412
static void     search_entry_activate_cb     (GtkEntry              *entry, 
412
413
                                              gpointer               data);
413
414
static void     settings_load                (GtkFileChooserDefault *impl);
414
415
 
 
416
static void     recent_start_loading         (GtkFileChooserDefault *impl);
415
417
static void     recent_stop_loading          (GtkFileChooserDefault *impl);
416
418
static void     recent_clear_model           (GtkFileChooserDefault *impl,
417
419
                                              gboolean               remove_from_treeview);
418
420
static gboolean recent_should_respond        (GtkFileChooserDefault *impl);
419
 
static void     recent_switch_to_browse_mode (GtkFileChooserDefault *impl);
420
421
static GSList * recent_get_selected_files    (GtkFileChooserDefault *impl);
421
422
static void     set_file_system_backend      (GtkFileChooserDefault *impl);
422
423
static void     unset_file_system_backend    (GtkFileChooserDefault *impl);
3418
3419
  if (in_press)
3419
3420
    return FALSE;
3420
3421
 
3421
 
  if (event->button != 3)
 
3422
  if (!_gtk_button_event_triggers_context_menu (event))
3422
3423
    return FALSE;
3423
3424
 
3424
3425
  in_press = TRUE;
3629
3630
  /* Box for buttons */
3630
3631
 
3631
3632
  toolbar = gtk_toolbar_new ();
 
3633
  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
 
3634
 
3632
3635
  gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
3633
3636
 
3634
3637
  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
3678
3681
 
3679
3682
/* Handles key press events on the file list, so that we can trap Enter to
3680
3683
 * activate the default button on our own.  Also, checks to see if '/' has been
3681
 
 * pressed.  See comment by tree_view_keybinding_cb() for more details.
 
3684
 * pressed.
3682
3685
 */
3683
3686
static gboolean
3684
3687
browse_files_key_press_event_cb (GtkWidget   *widget,
3686
3689
                                 gpointer     data)
3687
3690
{
3688
3691
  GtkFileChooserDefault *impl;
3689
 
  int modifiers;
3690
3692
 
3691
3693
  impl = (GtkFileChooserDefault *) data;
3692
3694
 
3693
 
  modifiers = gtk_accelerator_get_default_mod_mask ();
3694
 
 
3695
3695
  if ((event->keyval == GDK_KEY_slash
3696
3696
       || event->keyval == GDK_KEY_KP_Divide
3697
3697
#ifdef G_OS_UNIX
3698
3698
       || event->keyval == GDK_KEY_asciitilde
3699
3699
#endif
3700
 
       ) && ! (event->state & (~GDK_SHIFT_MASK & modifiers)))
 
3700
       ) && !(event->state & GTK_NO_TEXT_INPUT_MOD_MASK))
3701
3701
    {
3702
3702
      location_popup_handler (impl, event->string);
3703
3703
      return TRUE;
3714
3714
       || event->keyval == GDK_KEY_KP_Enter
3715
3715
       || event->keyval == GDK_KEY_space
3716
3716
       || event->keyval == GDK_KEY_KP_Space)
3717
 
      && ((event->state & modifiers) == 0)
 
3717
      && !(event->state & gtk_accelerator_get_default_mod_mask ())
3718
3718
      && !(impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
3719
3719
           impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
3720
3720
    {
4099
4099
  if (in_press)
4100
4100
    return FALSE;
4101
4101
 
4102
 
  if (event->button != 3)
 
4102
  if (!_gtk_button_event_triggers_context_menu (event))
4103
4103
    return FALSE;
4104
4104
 
4105
4105
  in_press = TRUE;
4116
4116
  gint model_column;
4117
4117
} ColumnMap;
4118
4118
 
4119
 
/* Sets the sort column IDs for the file list based on the operation mode */
 
4119
/* Sets the sort column IDs for the file list; needs to be done whenever we
 
4120
 * change the model on the treeview.
 
4121
 */
4120
4122
static void
4121
4123
file_list_set_sort_column_ids (GtkFileChooserDefault *impl)
4122
4124
{
4354
4356
  return vbox;
4355
4357
}
4356
4358
 
 
4359
static void
 
4360
location_entry_create (GtkFileChooserDefault *impl)
 
4361
{
 
4362
  if (!impl->location_entry)
 
4363
    impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
 
4364
 
 
4365
  _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
 
4366
                                           impl->file_system);
 
4367
  _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only);
 
4368
  _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
 
4369
  gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
 
4370
  gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
 
4371
}
 
4372
 
4357
4373
/* Creates the widgets specific to Save mode */
4358
4374
static void
4359
4375
save_widgets_create (GtkFileChooserDefault *impl)
4386
4402
 
4387
4403
  /* Location entry */
4388
4404
 
4389
 
  impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4390
 
  _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4391
 
                                           impl->file_system);
4392
 
  _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only);
4393
 
  gtk_entry_set_width_chars (GTK_ENTRY (impl->location_entry), 45);
4394
 
  gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
 
4405
  location_entry_create (impl);
4395
4406
  gtk_table_attach (GTK_TABLE (impl->save_widgets_table), impl->location_entry,
4396
4407
                    1, 2, 0, 1,
4397
4408
                    GTK_EXPAND | GTK_FILL, 0,
4443
4454
  gtk_widget_hide (impl->location_entry_box);
4444
4455
}
4445
4456
 
4446
 
/* Sets the full path of the current folder as the text in the location entry. */
4447
 
static void
4448
 
location_entry_set_initial_text (GtkFileChooserDefault *impl)
4449
 
{
4450
 
  gchar *text, *filename;
4451
 
 
4452
 
  if (!impl->current_folder)
4453
 
    return;
4454
 
 
4455
 
  filename = g_file_get_path (impl->current_folder);
4456
 
 
4457
 
  if (filename)
4458
 
    {
4459
 
      text = g_filename_to_utf8 (filename, -1, NULL, NULL, NULL);
4460
 
      g_free (filename);
4461
 
    }
4462
 
  else
4463
 
    text = g_file_get_uri (impl->current_folder);
4464
 
 
4465
 
  if (text)
4466
 
    {
4467
 
      gboolean need_slash;
4468
 
      int len;
4469
 
 
4470
 
      len = strlen (text);
4471
 
      need_slash = (text[len - 1] != G_DIR_SEPARATOR);
4472
 
 
4473
 
      if (need_slash)
4474
 
        {
4475
 
          char *slash_text;
4476
 
 
4477
 
          slash_text = g_new (char, len + 2);
4478
 
          strcpy (slash_text, text);
4479
 
          slash_text[len] = G_DIR_SEPARATOR;
4480
 
          slash_text[len + 1] = 0;
4481
 
 
4482
 
          g_free (text);
4483
 
          text = slash_text;
4484
 
        }
4485
 
 
4486
 
      _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), text);
4487
 
      g_free (text);
4488
 
    }
4489
 
 
4490
 
  g_free (filename);
4491
 
}
4492
 
 
4493
4457
/* Turns on the location entry.  Can be called even if we are already in that
4494
4458
 * mode.
4495
4459
 */
4505
4469
    return;
4506
4470
 
4507
4471
  if (impl->location_entry)
4508
 
    gtk_widget_destroy (impl->location_entry);
 
4472
    {
 
4473
      gtk_widget_destroy (impl->location_entry);
 
4474
      impl->location_entry = NULL;
 
4475
    }
4509
4476
 
4510
4477
  /* Box */
4511
4478
 
4513
4480
 
4514
4481
  /* Entry */
4515
4482
 
4516
 
  impl->location_entry = _gtk_file_chooser_entry_new (TRUE);
4517
 
  _gtk_file_chooser_entry_set_file_system (GTK_FILE_CHOOSER_ENTRY (impl->location_entry),
4518
 
                                           impl->file_system);
4519
 
  gtk_entry_set_activates_default (GTK_ENTRY (impl->location_entry), TRUE);
4520
 
  _gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->action);
4521
 
 
 
4483
  location_entry_create (impl);
4522
4484
  gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_entry, TRUE, TRUE, 0);
4523
4485
  gtk_label_set_mnemonic_widget (GTK_LABEL (impl->location_label), impl->location_entry);
4524
4486
 
4525
4487
  /* Configure the entry */
4526
4488
 
4527
4489
  _gtk_file_chooser_entry_set_base_folder (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->current_folder);
4528
 
  _gtk_file_chooser_entry_set_local_only (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), impl->local_only);
4529
4490
 
4530
4491
  /* Done */
4531
4492
 
4878
4839
  GtkWidget *widget;
4879
4840
  GtkSizeGroup *size_group;
4880
4841
 
4881
 
  /* size group is used by the scrolled windows of the panes */
4882
 
  size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4883
4842
  impl->browse_widgets_box = gtk_vbox_new (FALSE, 12);
 
4843
  gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets_box, TRUE, TRUE, 0);
 
4844
  gtk_widget_show (impl->browse_widgets_box);
 
4845
 
 
4846
  impl->browse_header_box = gtk_vbox_new (FALSE, 12);
 
4847
  gtk_box_pack_start (GTK_BOX (impl->browse_widgets_box), impl->browse_header_box, FALSE, FALSE, 0);
 
4848
  gtk_widget_show (impl->browse_header_box);
4884
4849
 
4885
4850
  /* Path bar, info bar, and their respective machinery - the browse_path_bar_hbox will get packed elsewhere */
4886
4851
  path_bar_widgets_create (impl);
4888
4853
  /* Box for the location label and entry */
4889
4854
 
4890
4855
  impl->location_entry_box = gtk_hbox_new (FALSE, 12);
4891
 
  gtk_box_pack_start (GTK_BOX (impl->browse_widgets_box), impl->location_entry_box, FALSE, FALSE, 0);
 
4856
  gtk_box_pack_start (GTK_BOX (impl->browse_header_box), impl->location_entry_box, FALSE, FALSE, 0);
4892
4857
 
4893
4858
  impl->location_label = gtk_label_new_with_mnemonic (_("_Location:"));
4894
4859
  gtk_widget_show (impl->location_label);
4895
4860
  gtk_box_pack_start (GTK_BOX (impl->location_entry_box), impl->location_label, FALSE, FALSE, 0);
4896
4861
 
 
4862
  /* size group is used by the scrolled windows of the panes */
 
4863
  size_group = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
 
4864
 
4897
4865
  /* Paned widget */
4898
4866
  hpaned = gtk_hpaned_new ();
4899
4867
  gtk_widget_show (hpaned);
4931
4899
 
4932
4900
  /* The browse widgets */
4933
4901
  browse_widgets_create (impl);
4934
 
  gtk_box_pack_start (GTK_BOX (impl), impl->browse_widgets_box, TRUE, TRUE, 0);
4935
4902
 
4936
4903
  /* Alignment to hold extra widget */
4937
4904
  impl->extra_align = gtk_alignment_new (0.0, 0.5, 1.0, 1.0);
5102
5069
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
5103
5070
      || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
5104
5071
    {
5105
 
      gtk_box_pack_start (GTK_BOX (impl->browse_widgets_box), impl->browse_path_bar_hbox, FALSE, FALSE, 0);
5106
 
      gtk_box_reorder_child (GTK_BOX (impl->browse_widgets_box), impl->browse_path_bar_hbox, 0);
 
5072
      gtk_box_pack_start (GTK_BOX (impl->browse_header_box), impl->browse_path_bar_hbox, FALSE, FALSE, 0);
 
5073
      gtk_box_reorder_child (GTK_BOX (impl->browse_header_box), impl->browse_path_bar_hbox, 0);
5107
5074
    }
5108
5075
  else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
5109
5076
           || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
5185
5152
  path_bar_set_mode (impl, mode);
5186
5153
}
5187
5154
 
 
5155
static void
 
5156
operation_mode_discard_search_widgets (GtkFileChooserDefault *impl)
 
5157
{
 
5158
  if (impl->search_hbox)
 
5159
    {
 
5160
      gtk_widget_destroy (impl->search_hbox);
 
5161
 
 
5162
      impl->search_hbox = NULL;
 
5163
      impl->search_entry = NULL;
 
5164
    }
 
5165
}
 
5166
 
 
5167
/* Stops running operations like populating the browse model, searches, and the recent-files model */
 
5168
static void
 
5169
operation_mode_stop (GtkFileChooserDefault *impl, OperationMode mode)
 
5170
{
 
5171
  switch (mode)
 
5172
    {
 
5173
    case OPERATION_MODE_BROWSE:
 
5174
      stop_loading_and_clear_list_model (impl, TRUE);
 
5175
      break;
 
5176
 
 
5177
    case OPERATION_MODE_SEARCH:
 
5178
      search_stop_searching (impl, FALSE);
 
5179
      search_clear_model (impl, TRUE);
 
5180
 
 
5181
      operation_mode_discard_search_widgets (impl);
 
5182
      break;
 
5183
 
 
5184
    case OPERATION_MODE_RECENT:
 
5185
      recent_stop_loading (impl);
 
5186
      recent_clear_model (impl, TRUE);
 
5187
      break;
 
5188
 
 
5189
    default:
 
5190
      g_assert_not_reached ();
 
5191
    }
 
5192
}
 
5193
 
 
5194
static void
 
5195
operation_mode_set_browse (GtkFileChooserDefault *impl)
 
5196
{
 
5197
  path_bar_update (impl);
 
5198
 
 
5199
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
 
5200
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
 
5201
    {
 
5202
      gtk_widget_show (impl->location_button);
 
5203
      location_mode_set (impl, impl->location_mode, TRUE);
 
5204
 
 
5205
      if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
 
5206
        gtk_widget_show (impl->location_entry_box);
 
5207
    }
 
5208
}
 
5209
 
 
5210
static void
 
5211
operation_mode_set_search (GtkFileChooserDefault *impl)
 
5212
{
 
5213
  g_assert (impl->search_hbox == NULL);
 
5214
  g_assert (impl->search_entry == NULL);
 
5215
  g_assert (impl->search_model == NULL);
 
5216
 
 
5217
  search_setup_widgets (impl);
 
5218
}
 
5219
 
 
5220
static void
 
5221
operation_mode_set_recent (GtkFileChooserDefault *impl)
 
5222
{
 
5223
  path_bar_update (impl);
 
5224
 
 
5225
  /* Hide the location widgets temporarily */
 
5226
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
 
5227
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
 
5228
    {
 
5229
      gtk_widget_hide (impl->location_button);
 
5230
      gtk_widget_hide (impl->location_entry_box);
 
5231
    }
 
5232
 
 
5233
  recent_start_loading (impl);
 
5234
}
 
5235
 
 
5236
/* Sometimes we need to frob the selection in the shortcuts list manually */
 
5237
static void
 
5238
shortcuts_select_item_without_activating (GtkFileChooserDefault *impl, int pos)
 
5239
{
 
5240
  GtkTreeSelection *selection;
 
5241
  GtkTreePath *path;
 
5242
 
 
5243
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
 
5244
 
 
5245
  g_signal_handlers_block_by_func (selection, G_CALLBACK (shortcuts_selection_changed_cb), impl);
 
5246
 
 
5247
  path = gtk_tree_path_new_from_indices (pos, -1);
 
5248
  gtk_tree_selection_select_path (selection, path);
 
5249
  gtk_tree_path_free (path);
 
5250
 
 
5251
  g_signal_handlers_unblock_by_func (selection, G_CALLBACK (shortcuts_selection_changed_cb), impl);
 
5252
}
 
5253
 
 
5254
static void
 
5255
operation_mode_set (GtkFileChooserDefault *impl, OperationMode mode)
 
5256
{
 
5257
  ShortcutsIndex shortcut_to_select;
 
5258
 
 
5259
  operation_mode_stop (impl, impl->operation_mode);
 
5260
 
 
5261
  impl->operation_mode = mode;
 
5262
 
 
5263
  switch (impl->operation_mode)
 
5264
    {
 
5265
    case OPERATION_MODE_BROWSE:
 
5266
      operation_mode_set_browse (impl);
 
5267
      shortcut_to_select = SHORTCUTS_CURRENT_FOLDER;
 
5268
      break;
 
5269
 
 
5270
    case OPERATION_MODE_SEARCH:
 
5271
      operation_mode_set_search (impl);
 
5272
      shortcut_to_select = SHORTCUTS_SEARCH;
 
5273
      break;
 
5274
 
 
5275
    case OPERATION_MODE_RECENT:
 
5276
      operation_mode_set_recent (impl);
 
5277
      shortcut_to_select = SHORTCUTS_RECENT;
 
5278
      break;
 
5279
 
 
5280
    default:
 
5281
      g_assert_not_reached ();
 
5282
      return;
 
5283
    }
 
5284
 
 
5285
  if (shortcut_to_select != SHORTCUTS_CURRENT_FOLDER)
 
5286
    shortcuts_select_item_without_activating (impl, shortcuts_get_index (impl, shortcut_to_select));
 
5287
}
 
5288
 
5188
5289
/* This function is basically a do_all function.
5189
5290
 *
5190
5291
 * It sets the visibility on all the widgets based on the current state, and
5222
5323
    {
5223
5324
      gtk_widget_show (impl->location_button);
5224
5325
      save_widgets_destroy (impl);
5225
 
      gtk_widget_show (impl->browse_widgets_box);
5226
5326
      location_mode_set (impl, impl->location_mode, TRUE);
5227
5327
    }
5228
5328
 
6056
6156
  gtk_tree_view_columns_autosize (GTK_TREE_VIEW (impl->browse_files_tree_view));
6057
6157
  gtk_tree_view_set_search_column (GTK_TREE_VIEW (impl->browse_files_tree_view),
6058
6158
                                   MODEL_COL_NAME);
 
6159
  file_list_set_sort_column_ids (impl);
6059
6160
  set_sort_column (impl);
6060
6161
  profile_msg ("    gtk_tree_view_set_model end", NULL);
6061
6162
  impl->list_sort_ascending = TRUE;
7081
7182
 
7082
7183
  g_object_ref (file);
7083
7184
 
7084
 
  switch (impl->operation_mode)
7085
 
    {
7086
 
    case OPERATION_MODE_SEARCH:
7087
 
      search_switch_to_browse_mode (impl);
7088
 
      break;
7089
 
    case OPERATION_MODE_RECENT:
7090
 
      recent_switch_to_browse_mode (impl);
7091
 
      break;
7092
 
    case OPERATION_MODE_BROWSE:
7093
 
      break;
7094
 
    }
 
7185
  operation_mode_set (impl, OPERATION_MODE_BROWSE);
7095
7186
 
7096
7187
  if (impl->local_only && !g_file_is_native (file))
7097
7188
    {
8852
8943
   */
8853
8944
  gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
8854
8945
                           GTK_TREE_MODEL (impl->search_model));
 
8946
  file_list_set_sort_column_ids (impl);
8855
8947
#endif
8856
8948
 
8857
8949
  /* FMQ: if search was empty, say that we got no hits */
8921
9013
    }
8922
9014
}
8923
9015
 
8924
 
/* Stops any pending searches, clears the file list, and switches back to OPERATION_MODE_BROWSE */
8925
 
static void
8926
 
search_switch_to_browse_mode (GtkFileChooserDefault *impl)
8927
 
{
8928
 
  g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
8929
 
 
8930
 
  search_stop_searching (impl, FALSE);
8931
 
  search_clear_model (impl, TRUE);
8932
 
 
8933
 
  gtk_widget_destroy (impl->search_hbox);
8934
 
  impl->search_hbox = NULL;
8935
 
  impl->search_entry = NULL;
8936
 
 
8937
 
  impl->operation_mode = OPERATION_MODE_BROWSE;
8938
 
  path_bar_update (impl);
8939
 
 
8940
 
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
8941
 
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
8942
 
    {
8943
 
      gtk_widget_show (impl->location_button);
8944
 
 
8945
 
      if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
8946
 
        gtk_widget_show (impl->location_entry_box);
8947
 
    }
8948
 
 
8949
 
  file_list_set_sort_column_ids (impl);
8950
 
}
8951
 
 
8952
9016
/* Creates the search_model and puts it in the tree view */
8953
9017
static void
8954
9018
search_setup_model (GtkFileChooserDefault *impl)
8979
9043
   */
8980
9044
  gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
8981
9045
                           GTK_TREE_MODEL (impl->search_model));
 
9046
  file_list_set_sort_column_ids (impl);
8982
9047
}
8983
9048
 
8984
9049
/* Creates a new query with the specified text and launches it */
9128
9193
  /* FMQ: hide the filter combo? */
9129
9194
}
9130
9195
 
9131
 
/* Stops running operations like populating the browse model, searches, and the recent-files model */
9132
 
static void
9133
 
stop_operation (GtkFileChooserDefault *impl, OperationMode mode)
9134
 
{
9135
 
  switch (mode)
9136
 
    {
9137
 
    case OPERATION_MODE_BROWSE:
9138
 
      stop_loading_and_clear_list_model (impl, TRUE);
9139
 
      break;
9140
 
 
9141
 
    case OPERATION_MODE_SEARCH:
9142
 
      search_stop_searching (impl, FALSE);
9143
 
      search_clear_model (impl, TRUE);
9144
 
 
9145
 
      gtk_widget_destroy (impl->search_hbox);
9146
 
      impl->search_hbox = NULL;
9147
 
      impl->search_entry = NULL;
9148
 
      break;
9149
 
 
9150
 
    case OPERATION_MODE_RECENT:
9151
 
      recent_stop_loading (impl);
9152
 
      recent_clear_model (impl, TRUE);
9153
 
      break;
9154
 
    }
9155
 
}
9156
 
 
9157
 
/* Sometimes we need to frob the selection in the shortcuts list manually */
9158
 
static void
9159
 
shortcuts_select_item_without_activating (GtkFileChooserDefault *impl, int pos)
9160
 
{
9161
 
  GtkTreeSelection *selection;
9162
 
  GtkTreePath *path;
9163
 
 
9164
 
  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
9165
 
 
9166
 
  g_signal_handlers_block_by_func (selection, G_CALLBACK (shortcuts_selection_changed_cb), impl);
9167
 
 
9168
 
  path = gtk_tree_path_new_from_indices (pos, -1);
9169
 
  gtk_tree_selection_select_path (selection, path);
9170
 
  gtk_tree_path_free (path);
9171
 
 
9172
 
  g_signal_handlers_unblock_by_func (selection, G_CALLBACK (shortcuts_selection_changed_cb), impl);
9173
 
}
9174
 
 
9175
 
/* Main entry point to the searching functions; this gets called when the user
9176
 
 * activates the Search shortcut.
9177
 
 */
9178
 
static void
9179
 
search_activate (GtkFileChooserDefault *impl)
9180
 
{
9181
 
  OperationMode previous_mode;
9182
 
  
9183
 
  if (impl->operation_mode == OPERATION_MODE_SEARCH)
9184
 
    {
9185
 
      focus_search_entry_in_idle (impl);
9186
 
      return;
9187
 
    }
9188
 
 
9189
 
  previous_mode = impl->operation_mode;
9190
 
  impl->operation_mode = OPERATION_MODE_SEARCH;
9191
 
 
9192
 
  shortcuts_select_item_without_activating (impl, shortcuts_get_index (impl, SHORTCUTS_SEARCH));
9193
 
 
9194
 
  stop_operation (impl, previous_mode);
9195
 
 
9196
 
  g_assert (impl->search_hbox == NULL);
9197
 
  g_assert (impl->search_entry == NULL);
9198
 
  g_assert (impl->search_model == NULL);
9199
 
 
9200
 
  search_setup_widgets (impl);
9201
 
  file_list_set_sort_column_ids (impl);
9202
 
}
9203
 
 
9204
9196
/*
9205
9197
 * Recent files support
9206
9198
 */
9233
9225
    }
9234
9226
}
9235
9227
 
9236
 
/* Stops any pending load, clears the file list, and switches
9237
 
 * back to OPERATION_MODE_BROWSE
9238
 
 */
9239
 
static void
9240
 
recent_switch_to_browse_mode (GtkFileChooserDefault *impl)
9241
 
{
9242
 
  g_assert (impl->operation_mode != OPERATION_MODE_BROWSE);
9243
 
 
9244
 
  recent_stop_loading (impl);
9245
 
  recent_clear_model (impl, TRUE);
9246
 
 
9247
 
  impl->operation_mode = OPERATION_MODE_BROWSE;
9248
 
  path_bar_update (impl);
9249
 
 
9250
 
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
9251
 
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
9252
 
    {
9253
 
      gtk_widget_show (impl->location_button);
9254
 
 
9255
 
      if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
9256
 
        gtk_widget_show (impl->location_entry_box);
9257
 
    }
9258
 
 
9259
 
  gtk_tree_view_column_set_visible (impl->list_size_column, impl->show_size_column);
9260
 
 
9261
 
  file_list_set_sort_column_ids (impl);
9262
 
}
9263
 
 
9264
9228
static void
9265
9229
recent_setup_model (GtkFileChooserDefault *impl)
9266
9230
{
9291
9255
{
9292
9256
  GtkFileChooserDefault *impl;
9293
9257
  GList *items;
9294
 
  guint needs_sorting : 1;
9295
9258
} RecentLoadData;
9296
9259
 
9297
9260
static void
9302
9265
 
9303
9266
  gtk_tree_view_set_model (GTK_TREE_VIEW (impl->browse_files_tree_view),
9304
9267
                           GTK_TREE_MODEL (impl->recent_model));
 
9268
  file_list_set_sort_column_ids (impl);
 
9269
  gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (impl->recent_model), MODEL_COL_MTIME, GTK_SORT_DESCENDING);
9305
9270
 
9306
9271
  set_busy_cursor (impl, FALSE);
9307
9272
  
9311
9276
}
9312
9277
 
9313
9278
static gint
9314
 
recent_sort_mru (gconstpointer a,
9315
 
                 gconstpointer b)
9316
 
{
9317
 
  GtkRecentInfo *info_a = (GtkRecentInfo *) a;
9318
 
  GtkRecentInfo *info_b = (GtkRecentInfo *) b;
9319
 
 
9320
 
  return (gtk_recent_info_get_modified (info_b) - gtk_recent_info_get_modified (info_a));
9321
 
}
9322
 
 
9323
 
static gint
9324
9279
get_recent_files_limit (GtkWidget *widget)
9325
9280
{
9326
9281
  GtkSettings *settings;
9395
9350
  if (!impl->recent_manager)
9396
9351
    return FALSE;
9397
9352
 
9398
 
  /* first iteration: load all the items */
 
9353
  load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
9399
9354
  if (!load_data->items)
9400
 
    {
9401
 
      load_data->items = gtk_recent_manager_get_items (impl->recent_manager);
9402
 
      if (!load_data->items)
9403
 
        return FALSE;
9404
 
 
9405
 
      load_data->needs_sorting = TRUE;
9406
 
 
9407
 
      return TRUE;
9408
 
    }
9409
 
  
9410
 
  /* second iteration: MRU sorting and clamping, and populating the model */
9411
 
  if (load_data->needs_sorting)
9412
 
    {
9413
 
      load_data->items = g_list_sort (load_data->items, recent_sort_mru);
9414
 
 
9415
 
      if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
9416
 
        populate_model_with_recent_items (impl, load_data->items);
9417
 
      else
9418
 
        populate_model_with_folders (impl, load_data->items);
9419
 
 
9420
 
      g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
9421
 
      g_list_free (load_data->items);
9422
 
      load_data->items = NULL;
9423
 
    }
 
9355
    return FALSE;
 
9356
 
 
9357
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
 
9358
    populate_model_with_recent_items (impl, load_data->items);
 
9359
  else
 
9360
    populate_model_with_folders (impl, load_data->items);
 
9361
 
 
9362
  g_list_foreach (load_data->items, (GFunc) gtk_recent_info_unref, NULL);
 
9363
  g_list_free (load_data->items);
 
9364
  load_data->items = NULL;
9424
9365
 
9425
9366
  return FALSE;
9426
9367
}
9440
9381
  load_data = g_new (RecentLoadData, 1);
9441
9382
  load_data->impl = impl;
9442
9383
  load_data->items = NULL;
9443
 
  load_data->needs_sorting = TRUE;
9444
9384
 
9445
9385
  /* begin lazy loading the recent files into the model */
9446
9386
  impl->load_recent_id = gdk_threads_add_idle_full (G_PRIORITY_HIGH_IDLE + 30,
9494
9434
  return (gtk_tree_selection_count_selected_rows (selection) != 0);
9495
9435
}
9496
9436
 
9497
 
/* Hide the location widgets temporarily */
9498
 
static void
9499
 
recent_hide_entry (GtkFileChooserDefault *impl)
9500
 
{
9501
 
  path_bar_update (impl);
9502
 
 
9503
 
  /* Hide the location widgets temporarily */
9504
 
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
9505
 
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
9506
 
    {
9507
 
      gtk_widget_hide (impl->location_button);
9508
 
      gtk_widget_hide (impl->location_entry_box);
9509
 
    }
9510
 
}
9511
 
 
9512
 
/* Main entry point to the recent files functions; this gets called when
9513
 
 * the user activates the Recently Used shortcut.
9514
 
 */
9515
 
static void
9516
 
recent_activate (GtkFileChooserDefault *impl)
9517
 
{
9518
 
  OperationMode previous_mode;
9519
 
 
9520
 
  if (impl->operation_mode == OPERATION_MODE_RECENT)
9521
 
    return;
9522
 
 
9523
 
  previous_mode = impl->operation_mode;
9524
 
  impl->operation_mode = OPERATION_MODE_RECENT;
9525
 
 
9526
 
  shortcuts_select_item_without_activating (impl, shortcuts_get_index (impl, SHORTCUTS_RECENT));
9527
 
 
9528
 
  stop_operation (impl, previous_mode);
9529
 
 
9530
 
  recent_hide_entry (impl);
9531
 
 
9532
 
  file_list_set_sort_column_ids (impl);
9533
 
  recent_start_loading (impl);
9534
 
}
9535
 
 
9536
9437
static void
9537
9438
set_current_filter (GtkFileChooserDefault *impl,
9538
9439
                    GtkFileFilter         *filter)
9706
9607
{
9707
9608
  GFile *file;
9708
9609
 
9709
 
  switch (impl->operation_mode)
9710
 
    {
9711
 
    case OPERATION_MODE_BROWSE:
9712
 
      break;
9713
 
    case OPERATION_MODE_SEARCH:
9714
 
      search_switch_to_browse_mode (impl);
9715
 
      break;
9716
 
    case OPERATION_MODE_RECENT:
9717
 
      recent_switch_to_browse_mode (impl);
9718
 
      break;
9719
 
    }
 
9610
  operation_mode_set (impl, OPERATION_MODE_BROWSE);
9720
9611
 
9721
9612
  /* We ref the file chooser since volume_mount() may run a main loop, and the
9722
9613
   * user could close the file chooser window in the meantime.
9823
9714
  gpointer col_data;
9824
9715
  ShortcutType shortcut_type;
9825
9716
 
9826
 
  if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY
 
9717
  /* In the Save modes, we want to preserve what the uesr typed in the filename
 
9718
   * entry, so that he may choose another folder without erasing his typed name.
 
9719
   */
 
9720
  if (impl->location_entry
9827
9721
      && !(impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
9828
9722
           || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER))
9829
9723
    _gtk_file_chooser_entry_set_file_part (GTK_FILE_CHOOSER_ENTRY (impl->location_entry), "");
9847
9741
 
9848
9742
      volume = col_data;
9849
9743
 
 
9744
      operation_mode_set (impl, OPERATION_MODE_BROWSE);
 
9745
 
9850
9746
      shortcuts_activate_volume (impl, volume);
9851
9747
    }
9852
9748
  else if (shortcut_type == SHORTCUT_TYPE_FILE)
9854
9750
      struct ShortcutsActivateData *data;
9855
9751
      GtkFileSystemVolume *volume;
9856
9752
 
 
9753
      operation_mode_set (impl, OPERATION_MODE_BROWSE);
 
9754
 
9857
9755
      volume = _gtk_file_system_get_volume_for_file (impl->file_system, col_data);
9858
9756
 
9859
9757
      data = g_new0 (struct ShortcutsActivateData, 1);
9885
9783
    }
9886
9784
  else if (shortcut_type == SHORTCUT_TYPE_SEARCH)
9887
9785
    {
9888
 
      search_activate (impl);
 
9786
      operation_mode_set (impl, OPERATION_MODE_SEARCH);
9889
9787
    }
9890
9788
  else if (shortcut_type == SHORTCUT_TYPE_RECENT)
9891
9789
    {
9892
 
      recent_activate (impl);
 
9790
      operation_mode_set (impl, OPERATION_MODE_RECENT);
9893
9791
    }
9894
9792
}
9895
9793
 
10150
10048
  if (impl->operation_mode != OPERATION_MODE_BROWSE)
10151
10049
    {
10152
10050
      GtkWidget *widget_to_focus;
 
10051
 
 
10052
      operation_mode_set (impl, OPERATION_MODE_BROWSE);
10153
10053
      
10154
 
      /* This will give us the location widgets back */
10155
 
      switch (impl->operation_mode)
10156
 
        {
10157
 
        case OPERATION_MODE_SEARCH:
10158
 
          search_switch_to_browse_mode (impl);
10159
 
          break;
10160
 
        case OPERATION_MODE_RECENT:
10161
 
          recent_switch_to_browse_mode (impl);
10162
 
          break;
10163
 
        case OPERATION_MODE_BROWSE:
10164
 
          g_assert_not_reached ();
10165
 
          break;
10166
 
        }
10167
 
 
10168
10054
      if (impl->current_folder)
10169
10055
        change_folder_and_display_error (impl, impl->current_folder, FALSE);
10170
10056
 
10180
10066
  if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN ||
10181
10067
      impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
10182
10068
    {
10183
 
      LocationMode new_mode;
10184
 
 
10185
 
      if (path != NULL)
10186
 
        {
10187
 
          /* since the user typed something, we unconditionally want to turn on the entry */
10188
 
          new_mode = LOCATION_MODE_FILENAME_ENTRY;
10189
 
        }
10190
 
      else if (impl->location_mode == LOCATION_MODE_PATH_BAR)
10191
 
        new_mode = LOCATION_MODE_FILENAME_ENTRY;
10192
 
      else if (impl->location_mode == LOCATION_MODE_FILENAME_ENTRY)
10193
 
        new_mode = LOCATION_MODE_PATH_BAR;
10194
 
      else
10195
 
        {
10196
 
          g_assert_not_reached ();
10197
 
          return;
10198
 
        }
10199
 
 
10200
 
      location_mode_set (impl, new_mode, TRUE);
10201
 
      if (new_mode == LOCATION_MODE_FILENAME_ENTRY)
10202
 
        {
10203
 
          if (path != NULL)
10204
 
            location_set_user_text (impl, path);
10205
 
          else
10206
 
            {
10207
 
              location_entry_set_initial_text (impl);
10208
 
              gtk_editable_select_region (GTK_EDITABLE (impl->location_entry), 0, -1);
10209
 
            }
10210
 
        }
 
10069
      if (!path)
 
10070
        return;
 
10071
 
 
10072
      location_mode_set (impl, LOCATION_MODE_FILENAME_ENTRY, TRUE);
 
10073
      location_set_user_text (impl, path);
10211
10074
    }
10212
10075
  else if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE ||
10213
10076
           impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)