/** * 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); }
/** * 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); }
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); }
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); }
/** * 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; }
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); } }
/** * 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"); }
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)); } } }
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); } }
/** * 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; }
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"); }
/** * 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; }
/** * 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; }
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); }
/** * 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; }