Example #1
0
/**
 * thunar_navigator_set_current_directory:
 * @navigator         : a #ThunarNavigator instance.
 * @current_directory : the new directory to display or %NULL.
 *
 * Sets a new current directory that should be displayed by
 * the @navigator.
 **/
void
thunar_navigator_set_current_directory (ThunarNavigator *navigator,
                                        ThunarFile      *current_directory)
{
  _thunar_return_if_fail (THUNAR_IS_NAVIGATOR (navigator));
  _thunar_return_if_fail (current_directory == NULL || THUNAR_IS_FILE (current_directory));
  THUNAR_NAVIGATOR_GET_IFACE (navigator)->set_current_directory (navigator, current_directory);
}
/**
 * thunar_location_dialog_set_selected_file:
 * @location_dialog : a #ThunarLocationDialog.
 * @selected_file   : a #ThunarFile or %NULL.
 *
 * Sets the file for @location_dialog to @selected_file.
 **/
void
thunar_location_dialog_set_selected_file (ThunarLocationDialog *location_dialog,
                                          ThunarFile           *selected_file)
{
  _thunar_return_if_fail (THUNAR_IS_LOCATION_DIALOG (location_dialog));
  _thunar_return_if_fail (selected_file == NULL || THUNAR_IS_FILE (selected_file));
  thunar_path_entry_set_current_file (THUNAR_PATH_ENTRY (location_dialog->entry), selected_file);
}
static void
thunar_chooser_button_file_changed (ThunarChooserButton *chooser_button,
                                    ThunarFile          *file)
{
  ThunarVfsMimeApplication *application;
  ThunarVfsMimeInfo        *info;
  ThunarIconFactory        *icon_factory;
  GtkIconTheme             *icon_theme;
  const gchar              *icon_name;
  GdkPixbuf                *icon = NULL;
  gint                      icon_size;

  _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
  _thunar_return_if_fail (chooser_button->file == file);
  _thunar_return_if_fail (THUNAR_IS_FILE (file));

  /* determine the mime info for the file */
  info = thunar_file_get_mime_info (file);

  /* determine the default application for that mime info */
  application = thunar_vfs_mime_database_get_default_application (chooser_button->database, info);
  if (G_LIKELY (application != NULL))
    {
      /* determine the icon size for menus */
      gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_size, &icon_size);

      /* setup the image for the application */
      icon_factory = thunar_icon_factory_get_default ();
      icon_theme = thunar_icon_factory_get_icon_theme (icon_factory);
      icon_name = thunar_vfs_mime_handler_lookup_icon_name (THUNAR_VFS_MIME_HANDLER (application), icon_theme);
      if (G_LIKELY (icon_name != NULL))
        icon = thunar_icon_factory_load_icon (icon_factory, icon_name, icon_size, NULL, FALSE);
      gtk_image_set_from_pixbuf (GTK_IMAGE (chooser_button->image), icon);
      g_object_unref (G_OBJECT (icon_factory));
      if (G_LIKELY (icon != NULL))
        g_object_unref (G_OBJECT (icon));

      /* setup the label for the application */
      gtk_label_set_attributes (GTK_LABEL (chooser_button->label), NULL);
      gtk_label_set_text (GTK_LABEL (chooser_button->label), thunar_vfs_mime_handler_get_name (THUNAR_VFS_MIME_HANDLER (application)));

      /* cleanup */
      g_object_unref (G_OBJECT (application));
    }
  else
    {
      /* no default application specified */
      gtk_label_set_attributes (GTK_LABEL (chooser_button->label), thunar_pango_attr_list_italic ());
      gtk_label_set_text (GTK_LABEL (chooser_button->label), _("No application selected"));
      gtk_image_set_from_pixbuf (GTK_IMAGE (chooser_button->image), NULL);
    }

  /* setup a useful tooltip for the button */
  thunar_gtk_widget_set_tooltip (chooser_button->button,
                                 _("The selected application is used to open "
                                   "this and other files of type \"%s\"."),
                                 thunar_vfs_mime_info_get_comment (info));
}
/**
 * thunar_location_dialog_set_working_directory:
 * @location_dialog : a #ThunarLocationDialog.
 * @directory       : a #ThunarFile or %NULL.
 *
 * Sets the working directory of @location_dialog to @directory.
 **/
void
thunar_location_dialog_set_working_directory (ThunarLocationDialog *location_dialog,
                                              ThunarFile           *directory)
{
  _thunar_return_if_fail (THUNAR_IS_LOCATION_DIALOG (location_dialog));
  _thunar_return_if_fail (directory == NULL || THUNAR_IS_FILE (directory));

  thunar_path_entry_set_working_directory (THUNAR_PATH_ENTRY (location_dialog->entry),
                                           directory);
}
Example #5
0
/**
 * thunar_navigator_change_directory:
 * @navigator : a #ThunarNavigator instance.
 * @directory : a #ThunarFile referring to a directory.
 *
 * Emits the "change-directory" signal on @navigator with
 * the specified @directory.
 *
 * Derived classes should invoke this method whenever the user
 * selects a new directory from within @navigator. The derived
 * class should not perform any directory changing operations
 * itself, but leave it up to the surrounding module (usually
 * a #ThunarWindow instance) to change the directory.
 *
 * It should never ever be called from outside a #ThunarNavigator
 * implementation, as that may led to unexpected results!
 **/
void
thunar_navigator_change_directory (ThunarNavigator *navigator,
                                   ThunarFile      *directory)
{
  _thunar_return_if_fail (THUNAR_IS_NAVIGATOR (navigator));
  _thunar_return_if_fail (THUNAR_IS_FILE (directory));
  _thunar_return_if_fail (thunar_file_is_directory (directory));

  g_signal_emit (G_OBJECT (navigator), navigator_signals[CHANGE_DIRECTORY], 0, directory);
}
Example #6
0
void
thunar_navigator_open_new_tab (ThunarNavigator *navigator,
                               ThunarFile      *directory)
{
  _thunar_return_if_fail (THUNAR_IS_NAVIGATOR (navigator));
  _thunar_return_if_fail (THUNAR_IS_FILE (directory));
  _thunar_return_if_fail (thunar_file_is_directory (directory));

  g_signal_emit (G_OBJECT (navigator), navigator_signals[OPEN_NEW_TAB], 0, directory);
}
Example #7
0
static void
thunar_image_file_changed (ThunarFileMonitor *monitor,
                           ThunarFile        *file,
                           ThunarImage       *image)
{
  _thunar_return_if_fail (THUNAR_IS_FILE_MONITOR (monitor));
  _thunar_return_if_fail (THUNAR_IS_FILE (file));
  _thunar_return_if_fail (THUNAR_IS_IMAGE (image));

  if (file == image->priv->file)
    thunar_image_update (image);
}
Example #8
0
/**
 * thunar_renamer_pair_new:
 * @file : a #ThunarFile.
 * @name : the new name for @file.
 *
 * Allocates a new #ThunarRenamerPair for the
 * given @file and @name.
 *
 * The caller is responsible to free the returned pair
 * using thunar_renamer_pair_free() when no longer
 * needed.
 *
 * Return value: the newly allocated #ThunarRenamerPair.
 **/
ThunarRenamerPair*
thunar_renamer_pair_new (ThunarFile  *file,
                         const gchar *name)
{
  ThunarRenamerPair *renamer_pair;

  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
  _thunar_return_val_if_fail (g_utf8_validate (name, -1, NULL), NULL);

  renamer_pair = g_slice_new (ThunarRenamerPair);
  renamer_pair->file = g_object_ref (G_OBJECT (file));
  renamer_pair->name = g_strdup (name);

  return renamer_pair;
}
Example #9
0
static void
thunar_folder_file_changed (ThunarFileMonitor *file_monitor,
                            ThunarFile        *file,
                            ThunarFolder      *folder)
{
  _thunar_return_if_fail (THUNAR_IS_FILE (file));
  _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
  _thunar_return_if_fail (THUNAR_IS_FILE_MONITOR (file_monitor));

  /* check if the corresponding file changed... */
  if (G_UNLIKELY (folder->corresponding_file == file))
    {
      /* ...and if so, reload the folder */
      thunar_folder_reload (folder);
    }
}
Example #10
0
/**
 * thunar_folder_get_for_file:
 * @file : a #ThunarFile.
 *
 * Opens the specified @file as #ThunarFolder and
 * returns a reference to the folder.
 *
 * The caller is responsible to free the returned
 * object using g_object_unref() when no longer
 * needed.
 *
 * Return value: the #ThunarFolder which corresponds
 *               to @file.
 **/
ThunarFolder*
thunar_folder_get_for_file (ThunarFile *file)
{
  ThunarFolder *folder;

  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), NULL);
  _thunar_return_val_if_fail (thunar_file_is_directory (file), NULL);

  /* determine the "thunar-folder" quark on-demand */
  if (G_UNLIKELY (thunar_folder_quark == 0))
    thunar_folder_quark = g_quark_from_static_string ("thunar-folder");

  /* check if we already know that folder */
  folder = g_object_get_qdata (G_OBJECT (file), thunar_folder_quark);
  if (G_UNLIKELY (folder != NULL))
    {
      g_object_ref (G_OBJECT (folder));
    }
  else
    {
      /* allocate the new instance */
      folder = g_object_new (THUNAR_TYPE_FOLDER, NULL);
      folder->corresponding_file = file;
      g_object_ref (G_OBJECT (file));

      /* drop the floating reference */
      exo_gtk_object_ref_sink (GTK_OBJECT (folder));

      /* connect the folder to the file */
      g_object_set_qdata (G_OBJECT (file), thunar_folder_quark, folder);

      /* schedule the loading of the folder */
      thunar_folder_reload (folder);
    }

  return folder;
}
/**
 * thunar_chooser_button_set_file:
 * @chooser_button : a #ThunarChooserButton instance.
 * @file           : a #ThunarFile or %NULL.
 *
 * Associates @chooser_button with the specified @file.
 **/
void
thunar_chooser_button_set_file (ThunarChooserButton *chooser_button,
                                ThunarFile          *file)
{
  _thunar_return_if_fail (THUNAR_IS_CHOOSER_BUTTON (chooser_button));
  _thunar_return_if_fail (file == NULL || THUNAR_IS_FILE (file));

  /* check if we already use that file */
  if (G_UNLIKELY (chooser_button->file == file))
    return;

  /* disconnect from the previous file */
  if (G_UNLIKELY (chooser_button->file != NULL))
    {
      g_signal_handlers_disconnect_by_func (G_OBJECT (chooser_button->file), thunar_chooser_button_file_changed, chooser_button);
      g_object_unref (G_OBJECT (chooser_button->file));
    }

  /* activate the new file */
  chooser_button->file = file;

  /* connect to the new file */
  if (G_LIKELY (file != NULL))
    {
      /* take a reference */
      g_object_ref (G_OBJECT (file));

      /* stay informed about changes */
      g_signal_connect_swapped (G_OBJECT (file), "changed", G_CALLBACK (thunar_chooser_button_file_changed), chooser_button);

      /* update our state now */
      thunar_chooser_button_file_changed (chooser_button, file);
    }

  /* notify listeners */
  g_object_notify (G_OBJECT (chooser_button), "file");
}
Example #12
0
static void
thunar_folder_file_destroyed (ThunarFileMonitor *file_monitor,
                              ThunarFile        *file,
                              ThunarFolder      *folder)
{
  GList  files;
  GList *lp;

  _thunar_return_if_fail (THUNAR_IS_FILE (file));
  _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
  _thunar_return_if_fail (THUNAR_IS_FILE_MONITOR (file_monitor));

  /* check if the corresponding file was destroyed */
  if (G_UNLIKELY (folder->corresponding_file == file))
    {
      /* the folder is useless now */
      gtk_object_destroy (GTK_OBJECT (folder));
    }
  else
    {
      /* check if we have that file */
      lp = g_list_find (folder->files, file);
      if (G_LIKELY (lp != NULL))
        {
          /* remove the file from our list */
          folder->files = g_list_delete_link (folder->files, lp);

          /* tell everybody that the file is gone */
          files.data = file; files.next = files.prev = NULL;
          g_signal_emit (G_OBJECT (folder), folder_signals[FILES_REMOVED], 0, &files);

          /* drop our reference to the file */
          g_object_unref (G_OBJECT (file));
        }
    }
}
Example #13
0
static void
thunar_image_update (ThunarImage *image)
{
  ThunarIconFactory *icon_factory;
  GtkIconTheme      *icon_theme;
  GdkPixbuf         *icon;
  GdkScreen         *screen;

  _thunar_return_if_fail (THUNAR_IS_IMAGE (image));
          
  if (THUNAR_IS_FILE (image->priv->file))
    {
      screen = gtk_widget_get_screen (GTK_WIDGET (image));
      icon_theme = gtk_icon_theme_get_for_screen (screen);
      icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);

      icon = thunar_icon_factory_load_file_icon (icon_factory, image->priv->file,
                                                 THUNAR_FILE_ICON_STATE_DEFAULT, 48);

      gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);

      g_object_unref (icon_factory);
    }
}
Example #14
0
/**
 * thunar_dialogs_show_job_ask_replace:
 * @parent   : the parent #GtkWindow or %NULL.
 * @src_file : the #ThunarFile of the source file.
 * @dst_file : the #ThunarFile of the destination file that
 *             may be replaced with the source file.
 *
 * Asks the user whether to replace the destination file with the
 * source file identified by @src_file.
 *
 * Return value: the selected #ThunarJobResponse.
 **/
ThunarJobResponse
thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
                                     ThunarFile *src_file,
                                     ThunarFile *dst_file)
{
  ThunarIconFactory *icon_factory;
  ThunarPreferences *preferences;
  ThunarDateStyle    date_style;
  GtkIconTheme      *icon_theme;
  GtkWidget         *dialog;
  GtkWidget         *grid;
  GtkWidget         *image;
  GtkWidget         *label;
  GdkPixbuf         *icon;
  gchar             *date_custom_style;
  gchar             *date_string;
  gchar             *size_string;
  gchar             *text;
  gint               response;
  gboolean           file_size_binary;

  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL);

  /* determine the style used to format dates */
  preferences = thunar_preferences_get ();
  g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, NULL);
  g_object_get (G_OBJECT (preferences), "misc-date-custom-style", &date_custom_style, NULL);
  g_object_get (G_OBJECT (preferences), "misc-file-size-binary", &file_size_binary, NULL);
  g_object_unref (G_OBJECT (preferences));

  /* setup the confirmation dialog */
  dialog = gtk_dialog_new_with_buttons (_("Confirm to replace files"),
                                        parent,
                                        GTK_DIALOG_MODAL
                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
                                        _("_Cancel"), GTK_RESPONSE_CANCEL,
                                        _("S_kip All"), THUNAR_JOB_RESPONSE_NO_ALL,
                                        _("_Skip"), THUNAR_JOB_RESPONSE_NO,
                                        _("Replace _All"), THUNAR_JOB_RESPONSE_YES_ALL,
                                        _("_Replace"), THUNAR_JOB_RESPONSE_YES,
                                        NULL);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_JOB_RESPONSE_YES);

  /* determine the icon factory to use */
  icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
  icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);

  grid = gtk_grid_new ();
  gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
  gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
  gtk_container_set_border_width (GTK_CONTAINER (grid), 10);
  gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), grid, TRUE, TRUE, 0);
  gtk_widget_show (grid);

  image = gtk_image_new_from_icon_name ("stock_folder-copy", GTK_ICON_SIZE_BUTTON);
  gtk_widget_set_halign (image, GTK_ALIGN_CENTER);
  gtk_widget_set_valign (image, GTK_ALIGN_START);
  gtk_widget_set_margin_start (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_end (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_top (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_bottom (GTK_WIDGET(image), 6);
  gtk_widget_set_vexpand (image, TRUE);
  gtk_grid_attach (GTK_GRID (grid), image, 0, 0, 1, 1);
  gtk_widget_show (image);

  if (thunar_file_is_symlink (dst_file))
    {
      text = g_strdup_printf (_("This folder already contains a symbolic link \"%s\"."),
                              thunar_file_get_display_name (dst_file));
    }
  else if (thunar_file_is_directory (dst_file))
    {
      text = g_strdup_printf (_("This folder already contains a folder \"%s\"."),
                              thunar_file_get_display_name (dst_file));
    }
  else
    {
      text = g_strdup_printf (_("This folder already contains a file \"%s\"."),
                              thunar_file_get_display_name (dst_file));
    }

  label = gtk_label_new (text);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big ());
  gtk_widget_set_hexpand (label, TRUE);
  gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 2, 1);
  gtk_widget_show (label);
  g_free (text);

  if (thunar_file_is_symlink (dst_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the link"));
  else if (thunar_file_is_directory (dst_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing folder"));
  else
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing file"));

  label = gtk_label_new (text);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
  gtk_widget_set_hexpand (label, TRUE);
  gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 2, 1);
  gtk_widget_show (label);
  g_free (text);

  icon = thunar_icon_factory_load_file_icon (icon_factory, dst_file, THUNAR_FILE_ICON_STATE_DEFAULT, 48);
  image = gtk_image_new_from_pixbuf (icon);
  gtk_widget_set_margin_start (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_end (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_top (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_bottom (GTK_WIDGET(image), 6);
  gtk_grid_attach (GTK_GRID (grid), image, 1, 2, 1, 1);
  g_object_unref (G_OBJECT (icon));
  gtk_widget_show (image);

  size_string = thunar_file_get_size_string_long (dst_file, file_size_binary);
  date_string = thunar_file_get_date_string (dst_file, THUNAR_FILE_DATE_MODIFIED, date_style, date_custom_style);
  text = g_strdup_printf ("%s %s\n%s %s", _("Size:"), size_string, _("Modified:"), date_string);
  label = gtk_label_new (text);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
  gtk_widget_set_hexpand (label, TRUE);
  gtk_grid_attach (GTK_GRID (grid), label, 2, 2, 1, 1);
  gtk_widget_show (label);
  g_free (size_string);
  g_free (date_string);
  g_free (text);

  if (thunar_file_is_symlink (src_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following link?"));
  else if (thunar_file_is_directory (src_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following folder?"));
  else
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following file?"));

  label = gtk_label_new (text);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
  gtk_widget_set_hexpand (label, TRUE);
  gtk_grid_attach (GTK_GRID (grid), label, 1, 3, 2, 1);
  gtk_widget_show (label);
  g_free (text);

  icon = thunar_icon_factory_load_file_icon (icon_factory, src_file, THUNAR_FILE_ICON_STATE_DEFAULT, 48);
  image = gtk_image_new_from_pixbuf (icon);
  gtk_widget_set_margin_start (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_end (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_top (GTK_WIDGET(image), 6);
  gtk_widget_set_margin_bottom (GTK_WIDGET(image), 6);
  gtk_grid_attach (GTK_GRID (grid), image, 1, 4, 1, 1);
  g_object_unref (G_OBJECT (icon));
  gtk_widget_show (image);

  size_string = thunar_file_get_size_string_long (src_file, file_size_binary);
  date_string = thunar_file_get_date_string (src_file, THUNAR_FILE_DATE_MODIFIED, date_style, date_custom_style);
  text = g_strdup_printf ("%s %s\n%s %s", _("Size:"), size_string, _("Modified:"), date_string);
  label = gtk_label_new (text);
  gtk_label_set_xalign (GTK_LABEL (label), 0.0f);
  gtk_widget_set_hexpand (label, TRUE);
  gtk_grid_attach (GTK_GRID (grid), label, 2, 4, 1, 1);
  gtk_widget_show (label);
  g_free (size_string);
  g_free (date_string);
  g_free (text);

  /* run the dialog */
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);

  /* cleanup */
  g_object_unref (G_OBJECT (icon_factory));

  /* translate GTK responses */
  if (G_UNLIKELY (response < 0))
    response = THUNAR_JOB_RESPONSE_CANCEL;

  return response;
}
Example #15
0
static void
thunar_folder_finished (ThunarVfsJob *job,
                        ThunarFolder *folder)
{
  ThunarFile *file;
  GList      *files;
  GList      *lp;

  _thunar_return_if_fail (THUNAR_IS_FOLDER (folder));
  _thunar_return_if_fail (THUNAR_VFS_IS_JOB (job));
  _thunar_return_if_fail (THUNAR_IS_FILE (folder->corresponding_file));
  _thunar_return_if_fail (folder->handle == NULL);
  _thunar_return_if_fail (folder->job == job);

  /* check if we need to merge new files with existing files */
  if (G_UNLIKELY (folder->files != NULL))
    {
      /* determine all added files (files on new_files, but not on files) */
      for (files = NULL, lp = folder->new_files; lp != NULL; lp = lp->next)
        if (g_list_find (folder->files, lp->data) == NULL)
          {
            /* put the file on the added list */
            files = g_list_prepend (files, lp->data);

            /* add to the internal files list */
            folder->files = g_list_prepend (folder->files, lp->data);
            g_object_ref (G_OBJECT (lp->data));
          }

      /* check if any files were added */
      if (G_UNLIKELY (files != NULL))
        {
          /* emit a "files-added" signal for the added files */
          g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, files);

          /* release the added files list */
          g_list_free (files);
        }

      /* determine all removed files (files on files, but not on new_files) */
      for (files = NULL, lp = folder->files; lp != NULL; )
        {
          /* determine the file */
          file = THUNAR_FILE (lp->data);

          /* determine the next list item */
          lp = lp->next;

          /* check if the file is not on new_files */
          if (g_list_find (folder->new_files, file) == NULL)
            {
              /* put the file on the removed list (owns the reference now) */
              files = g_list_prepend (files, file);

              /* remove from the internal files list */
              folder->files = g_list_remove (folder->files, file);
            }
        }

      /* check if any files were removed */
      if (G_UNLIKELY (files != NULL))
        {
          /* emit a "files-removed" signal for the removed files */
          g_signal_emit (G_OBJECT (folder), folder_signals[FILES_REMOVED], 0, files);

          /* release the removed files list */
          thunar_file_list_free (files);
        }

      /* drop the temporary new_files list */
      thunar_file_list_free (folder->new_files);
      folder->new_files = NULL;
    }
  else
    {
      /* just use the new files for the files list */
      folder->files = folder->new_files;
      folder->new_files = NULL;

      /* emit a "files-added" signal for the new files */
      g_signal_emit (G_OBJECT (folder), folder_signals[FILES_ADDED], 0, folder->files);
    }

  /* we did it, the folder is loaded */
  g_signal_handlers_disconnect_matched (folder->job, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, folder);
  g_object_unref (G_OBJECT (folder->job));
  folder->job = NULL;

  /* add us to the file alteration monitor */
  folder->handle = thunar_vfs_monitor_add_directory (folder->monitor, thunar_file_get_path (folder->corresponding_file),
                                                     thunar_folder_monitor, folder);

  /* tell the consumers that we have loaded the directory */
  g_object_notify (G_OBJECT (folder), "loading");
}
Example #16
0
/**
 * thunar_dnd_perform:
 * @widget            : the #GtkWidget on which the drop was done.
 * @file              : the #ThunarFile on which the @file_list was dropped.
 * @file_list         : the list of #GFile<!---->s that was dropped.
 * @action            : the #GdkDragAction that was performed.
 * @new_files_closure : a #GClosure to connect to the job's "new-files" signal,
 *                      which will be emitted when the job finishes with the
 *                      list of #GFile<!---->s created by the job, or
 *                      %NULL if you're not interested in the signal.
 *
 * Performs the drop of @file_list on @file in @widget, as given in
 * @action and returns %TRUE if the drop was started successfully
 * (or even completed successfully), else %FALSE.
 *
 * Return value: %TRUE if the DnD operation was started
 *               successfully, else %FALSE.
 **/
gboolean
thunar_dnd_perform (GtkWidget    *widget,
                    ThunarFile   *file,
                    GList        *file_list,
                    GdkDragAction action,
                    GClosure     *new_files_closure)
{
  ThunarApplication *application;
  gboolean           succeed = TRUE;
  GError            *error = NULL;

  _thunar_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
  _thunar_return_val_if_fail (gtk_widget_get_realized (widget), FALSE);

  /* query a reference on the application object */
  application = thunar_application_get ();

  /* check if the file is a directory */
  if (thunar_file_is_directory (file))
    {
      /* perform the given directory operation */
      switch (action)
        {
        case GDK_ACTION_COPY:
          thunar_application_copy_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure);
          break;

        case GDK_ACTION_MOVE:
          thunar_application_move_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure);
          break;

        case GDK_ACTION_LINK:
          thunar_application_link_into (application, widget, file_list, thunar_file_get_file (file), new_files_closure);
          break;

        default:
          succeed = FALSE;
        }
    }
  else if (thunar_file_is_executable (file))
    {
      /* TODO any chance to determine the working dir here? */
      succeed = thunar_file_execute (file, NULL, widget, file_list, &error);
      if (G_UNLIKELY (!succeed))
        {
          /* display an error to the user */
          thunar_dialogs_show_error (widget, error, _("Failed to execute file \"%s\""), thunar_file_get_display_name (file));

          /* release the error */
          g_error_free (error);
        }
    }
  else
    {
      succeed = FALSE;
    }

  /* release the application reference */
  g_object_unref (G_OBJECT (application));

  return succeed;
}
Example #17
0
/**
 * thunar_dialogs_show_job_ask_replace:
 * @parent   : the parent #GtkWindow or %NULL.
 * @src_file : the #ThunarFile of the source file.
 * @dst_file : the #ThunarFile of the destination file that
 *             may be replaced with the source file.
 *
 * Asks the user whether to replace the destination file with the
 * source file identified by @src_file.
 *
 * Return value: the selected #ThunarJobResponse.
 **/
ThunarJobResponse
thunar_dialogs_show_job_ask_replace (GtkWindow  *parent,
                                     ThunarFile *src_file,
                                     ThunarFile *dst_file)
{
  ThunarIconFactory *icon_factory;
  ThunarPreferences *preferences;
  ThunarDateStyle    date_style;
  GtkIconTheme      *icon_theme;
  GtkWidget         *dialog;
  GtkWidget         *table;
  GtkWidget         *image;
  GtkWidget         *label;
  GdkPixbuf         *icon;
  gchar             *date_string;
  gchar             *size_string;
  gchar             *text;
  gint               response;
  gboolean           file_size_binary;

  _thunar_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), THUNAR_JOB_RESPONSE_CANCEL);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (src_file), THUNAR_JOB_RESPONSE_CANCEL);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (dst_file), THUNAR_JOB_RESPONSE_CANCEL);

  /* determine the style used to format dates */
  preferences = thunar_preferences_get ();
  g_object_get (G_OBJECT (preferences), "misc-date-style", &date_style, NULL);
  g_object_get (G_OBJECT (preferences), "misc-file-size-binary", &file_size_binary, NULL);
  g_object_unref (G_OBJECT (preferences));

  /* setup the confirmation dialog */
  dialog = gtk_dialog_new_with_buttons (_("Confirm to replace files"),
                                        parent,
                                        GTK_DIALOG_MODAL
                                        | GTK_DIALOG_NO_SEPARATOR
                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        _("S_kip All"), THUNAR_JOB_RESPONSE_NO_ALL,
                                        _("_Skip"), THUNAR_JOB_RESPONSE_NO,
                                        _("Replace _All"), THUNAR_JOB_RESPONSE_YES_ALL,
                                        _("_Replace"), THUNAR_JOB_RESPONSE_YES,
                                        NULL);
  gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog),
                                           THUNAR_JOB_RESPONSE_YES,
                                           THUNAR_JOB_RESPONSE_YES_ALL,
                                           THUNAR_JOB_RESPONSE_NO,
                                           THUNAR_JOB_RESPONSE_NO_ALL,
                                           GTK_RESPONSE_CANCEL,
                                           -1);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), THUNAR_JOB_RESPONSE_YES);

  /* determine the icon factory to use */
  icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
  icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);

  table = g_object_new (GTK_TYPE_TABLE,
                        "border-width", 10,
                        "n-columns", 3,
                        "n-rows", 5,
                        "row-spacing", 6,
                        "column-spacing", 5,
                        NULL);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
  gtk_widget_show (table);

  image = gtk_image_new_from_icon_name ("stock_folder-copy", GTK_ICON_SIZE_BUTTON);
  gtk_misc_set_alignment (GTK_MISC (image), 0.5f, 0.0f);
  gtk_misc_set_padding (GTK_MISC (image), 6, 6);
  gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 1, GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
  gtk_widget_show (image);

  if (thunar_file_is_symlink (dst_file))
    {
      text = g_strdup_printf (_("This folder already contains a symbolic link \"%s\"."), 
                              thunar_file_get_display_name (dst_file));
    }
  else if (thunar_file_is_directory (dst_file))
    {
      text = g_strdup_printf (_("This folder already contains a folder \"%s\"."),
                              thunar_file_get_display_name (dst_file));
    }
  else
    { 
      text = g_strdup_printf (_("This folder already contains a file \"%s\"."), 
                              thunar_file_get_display_name (dst_file));
    }

  label = gtk_label_new (text);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_label_set_attributes (GTK_LABEL (label), thunar_pango_attr_list_big ());
  gtk_table_attach (GTK_TABLE (table), label, 1, 3, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);
  g_free (text);

  if (thunar_file_is_symlink (dst_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the link"));
  else if (thunar_file_is_directory (dst_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing folder"));
  else
    text = g_strdup_printf (Q_("ReplaceDialogPart1|Do you want to replace the existing file"));

  label = gtk_label_new (text);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_table_attach (GTK_TABLE (table), label, 1, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);
  g_free (text);

  icon = thunar_icon_factory_load_file_icon (icon_factory, dst_file, THUNAR_FILE_ICON_STATE_DEFAULT, 48);
  image = gtk_image_new_from_pixbuf (icon);
  gtk_misc_set_padding (GTK_MISC (image), 6, 6);
  gtk_table_attach (GTK_TABLE (table), image, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 0, 0);
  g_object_unref (G_OBJECT (icon));
  gtk_widget_show (image);

  size_string = thunar_file_get_size_string_formatted (dst_file, file_size_binary);
  date_string = thunar_file_get_date_string (dst_file, THUNAR_FILE_DATE_MODIFIED, date_style);
  text = g_strdup_printf ("%s %s\n%s %s", _("Size:"), size_string, _("Modified:"), date_string);
  label = gtk_label_new (text);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);
  g_free (size_string);
  g_free (date_string);
  g_free (text);

  if (thunar_file_is_symlink (src_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following link?"));
  else if (thunar_file_is_directory (src_file))
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following folder?"));
  else
    text = g_strdup_printf (Q_("ReplaceDialogPart2|with the following file?"));

  label = gtk_label_new (text);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_table_attach (GTK_TABLE (table), label, 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);
  g_free (text);

  icon = thunar_icon_factory_load_file_icon (icon_factory, src_file, THUNAR_FILE_ICON_STATE_DEFAULT, 48);
  image = gtk_image_new_from_pixbuf (icon);
  gtk_misc_set_padding (GTK_MISC (image), 6, 6);
  gtk_table_attach (GTK_TABLE (table), image, 1, 2, 4, 5, GTK_FILL, GTK_FILL, 0, 0);
  g_object_unref (G_OBJECT (icon));
  gtk_widget_show (image);

  size_string = thunar_file_get_size_string_formatted (src_file, file_size_binary);
  date_string = thunar_file_get_date_string (src_file, THUNAR_FILE_DATE_MODIFIED, date_style);
  text = g_strdup_printf ("%s %s\n%s %s", _("Size:"), size_string, _("Modified:"), date_string);
  label = gtk_label_new (text);
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);
  g_free (size_string);
  g_free (date_string);
  g_free (text);

  /* run the dialog */
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);

  /* cleanup */
  g_object_unref (G_OBJECT (icon_factory));

  /* translate GTK responses */
  if (G_UNLIKELY (response < 0))
    response = THUNAR_JOB_RESPONSE_CANCEL;

  return response;
}
Example #18
0
gboolean
thunar_dialogs_show_insecure_program (gpointer     parent,
                                      const gchar *primary,
                                      ThunarFile  *file,
                                      const gchar *command)
{
  GdkScreen      *screen;
  GtkWindow      *window;
  gint            response;
  GtkWidget      *dialog;
  GString        *secondary;
  ThunarFileMode  old_mode;
  ThunarFileMode  new_mode;
  GFileInfo      *info;
  GError         *err = NULL;

  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);
  _thunar_return_val_if_fail (g_utf8_validate (command, -1, NULL), FALSE);

  /* parse the parent window and screen */
  screen = thunar_util_parse_parent (parent, &window);

  /* secondary text */
  secondary = g_string_new (NULL);
  g_string_append_printf (secondary, _("The desktop file \"%s\" is in an insecure location "
                                       "and not marked as executable. If you do not trust "
                                       "this program, click Cancel."),
                                       thunar_file_get_display_name (file));
  g_string_append (secondary, "\n\n");
  if (exo_str_looks_like_an_uri (command))
    g_string_append_printf (secondary, G_KEY_FILE_DESKTOP_KEY_URL"=%s", command);
  else
    g_string_append_printf (secondary, G_KEY_FILE_DESKTOP_KEY_EXEC"=%s", command);

  /* allocate and display the error message dialog */
  dialog = gtk_message_dialog_new (window,
                                   GTK_DIALOG_MODAL |
                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                   GTK_MESSAGE_WARNING,
                                   GTK_BUTTONS_NONE,
                                   "%s", primary);
  gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Launch Anyway"), GTK_RESPONSE_OK);
  if (thunar_file_is_chmodable (file))
    gtk_dialog_add_button (GTK_DIALOG (dialog), _("Mark _Executable"), GTK_RESPONSE_APPLY);
  gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
  if (screen != NULL && window == NULL)
    gtk_window_set_screen (GTK_WINDOW (dialog), screen);
  gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", secondary->str);
  g_string_free (secondary, TRUE);
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  gtk_widget_destroy (dialog);

  /* check if we should make the file executable */
  if (response == GTK_RESPONSE_APPLY)
    {
      /* try to query information about the file */
      info = g_file_query_info (thunar_file_get_file (file),
                                G_FILE_ATTRIBUTE_UNIX_MODE,
                                G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                NULL, &err);

      if (G_LIKELY (info != NULL))
        {
          if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE))
            {
              /* determine the current mode */
              old_mode = g_file_info_get_attribute_uint32 (info, G_FILE_ATTRIBUTE_UNIX_MODE);

              /* generate the new mode */
              new_mode = old_mode | THUNAR_FILE_MODE_USR_EXEC | THUNAR_FILE_MODE_GRP_EXEC | THUNAR_FILE_MODE_OTH_EXEC;

              if (old_mode != new_mode)
                {
                  g_file_set_attribute_uint32 (thunar_file_get_file (file),
                                               G_FILE_ATTRIBUTE_UNIX_MODE, new_mode,
                                               G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
                                               NULL, &err);
                }
            }
          else
            {
              g_warning ("No %s attribute found", G_FILE_ATTRIBUTE_UNIX_MODE);
            }

          g_object_unref (info);
        }

      if (err != NULL)
        {
          thunar_dialogs_show_error (parent, err, ("Unable to mark launcher executable"));
          g_error_free (err);
        }

      /* just launch */
      response = GTK_RESPONSE_OK;
    }

  return (response == GTK_RESPONSE_OK);
}
Example #19
0
/**
 * thunar_dialogs_show_rename_file:
 * @parent : a #GtkWidget on which the error dialog should be shown, or a #GdkScreen
 *           if no #GtkWidget is known. May also be %NULL, in which case the default
 *           #GdkScreen will be used.
 * @file   : the #ThunarFile we're going to rename.
 *
 * Displays the Thunar rename dialog for a single file rename.
 *
 * Return value: The #ThunarJob responsible for renaming the file or
 *               %NULL if there was no renaming required.
 **/
ThunarJob *
thunar_dialogs_show_rename_file (gpointer    parent,
                                 ThunarFile *file)
{
  ThunarIconFactory *icon_factory;
  GtkIconTheme      *icon_theme;
  const gchar       *filename;
  const gchar       *text;
  ThunarJob         *job = NULL;
  GtkWidget         *dialog;
  GtkWidget         *entry;
  GtkWidget         *label;
  GtkWidget         *image;
  GtkWidget         *table;
  GtkWindow         *window;
  GdkPixbuf         *icon;
  GdkScreen         *screen;
  glong              offset;
  gchar             *title;
  gint               response;
  PangoLayout       *layout;
  gint               layout_width;
  gint               layout_offset;
  gint               parent_width = 500;

  _thunar_return_val_if_fail (parent == NULL || GDK_IS_SCREEN (parent) || GTK_IS_WINDOW (parent), FALSE);
  _thunar_return_val_if_fail (THUNAR_IS_FILE (file), FALSE);

  /* parse the parent window and screen */
  screen = thunar_util_parse_parent (parent, &window);

  /* get the filename of the file */
  filename = thunar_file_get_display_name (file);

  /* create a new dialog window */
  title = g_strdup_printf (_("Rename \"%s\""), filename);
  dialog = gtk_dialog_new_with_buttons (title,
                                        window,
                                        GTK_DIALOG_MODAL
                                        | GTK_DIALOG_NO_SEPARATOR
                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                        _("_Rename"), GTK_RESPONSE_OK,
                                        NULL);
  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
  g_free (title);

  /* move the dialog to the appropriate screen */
  if (G_UNLIKELY (window == NULL && screen != NULL))
    gtk_window_set_screen (GTK_WINDOW (dialog), screen);

  table = g_object_new (GTK_TYPE_TABLE, "border-width", 6, "column-spacing", 6, "row-spacing", 3, NULL);
  gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), table, TRUE, TRUE, 0);
  gtk_widget_show (table);

  icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (dialog));
  icon_factory = thunar_icon_factory_get_for_icon_theme (icon_theme);
  icon = thunar_icon_factory_load_file_icon (icon_factory, file, THUNAR_FILE_ICON_STATE_DEFAULT, 48);
  g_object_unref (G_OBJECT (icon_factory));

  image = gtk_image_new_from_pixbuf (icon);
  gtk_misc_set_padding (GTK_MISC (image), 6, 6);
  gtk_table_attach (GTK_TABLE (table), image, 0, 1, 0, 2, GTK_FILL, GTK_FILL, 0, 0);
  g_object_unref (G_OBJECT (icon));
  gtk_widget_show (image);

  label = gtk_label_new (_("Enter the new name:"));
  gtk_misc_set_alignment (GTK_MISC (label), 0.0f, 0.5f);
  gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (label);

  entry = gtk_entry_new ();
  gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
  gtk_table_attach (GTK_TABLE (table), entry, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0);
  gtk_widget_show (entry);

  /* setup the old filename */
  gtk_entry_set_text (GTK_ENTRY (entry), filename);

  /* check if we don't have a directory here */
  if (!thunar_file_is_directory (file))
    {
      /* check if the filename contains an extension */
      text = thunar_util_str_get_extension (filename);
      if (G_LIKELY (text != NULL))
        {
          /* grab focus to the entry first, else the selection will be altered later */
          gtk_widget_grab_focus (entry);

          /* determine the UTF-8 char offset */
          offset = g_utf8_pointer_to_offset (filename, text);

          /* select the text prior to the dot */
          if (G_LIKELY (offset > 0))
            gtk_editable_select_region (GTK_EDITABLE (entry), 0, offset);
        }
    }

  /* get the size the entry requires to render the full text */
  layout = gtk_entry_get_layout (GTK_ENTRY (entry));
  pango_layout_get_pixel_size (layout, &layout_width, NULL);
  gtk_entry_get_layout_offsets (GTK_ENTRY (entry), &layout_offset, NULL);
  layout_width += (layout_offset * 2) + (12 * 4) + 48; /* 12px free space in entry */

  /* parent window width */
  if (G_LIKELY (window != NULL))
    {
      /* keep below 90% of the parent window width */
      gtk_window_get_size (GTK_WINDOW (window), &parent_width, NULL);
      parent_width *= 0.90f;
    }

  /* resize the dialog to make long names fit as much as possible */
  gtk_window_set_default_size (GTK_WINDOW (dialog), CLAMP (layout_width, 300, parent_width), -1);

  /* run the dialog */
  response = gtk_dialog_run (GTK_DIALOG (dialog));
  if (G_LIKELY (response == GTK_RESPONSE_OK))
    {
      /* hide the dialog */
      gtk_widget_hide (dialog);
      
      /* determine the new filename */
      text = gtk_entry_get_text (GTK_ENTRY (entry));

      /* check if we have a new name here */
      if (G_LIKELY (!exo_str_is_equal (filename, text)))
        {
          /* try to rename the file */
          job = thunar_io_jobs_rename_file (file, text);
        }
    }

  /* cleanup */
  gtk_widget_destroy (dialog);

  return job;
}