feat: add file preview for GTK file picker (#16447)
This commit is contained in:
parent
c363eed543
commit
46f818b0c3
1 changed files with 43 additions and 0 deletions
|
@ -23,6 +23,9 @@ DialogSettings::~DialogSettings() = default;
|
|||
|
||||
namespace {
|
||||
|
||||
static const int kPreviewWidth = 256;
|
||||
static const int kPreviewHeight = 512;
|
||||
|
||||
// Makes sure that .jpg also shows .JPG.
|
||||
gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
|
||||
std::string* file_extension) {
|
||||
|
@ -86,6 +89,11 @@ class FileChooserDialog {
|
|||
|
||||
if (!settings.filters.empty())
|
||||
AddFilters(settings.filters);
|
||||
|
||||
preview_ = gtk_image_new();
|
||||
g_signal_connect(dialog_, "update-preview",
|
||||
G_CALLBACK(OnUpdatePreviewThunk), this);
|
||||
gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(dialog_), preview_);
|
||||
}
|
||||
|
||||
~FileChooserDialog() {
|
||||
|
@ -162,11 +170,15 @@ class FileChooserDialog {
|
|||
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
||||
|
||||
GtkWidget* dialog_;
|
||||
GtkWidget* preview_;
|
||||
|
||||
Filters filters_;
|
||||
SaveDialogCallback save_callback_;
|
||||
OpenDialogCallback open_callback_;
|
||||
|
||||
// Callback for when we update the preview for the selection.
|
||||
CHROMEG_CALLBACK_0(FileChooserDialog, void, OnUpdatePreview, GtkWidget*);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FileChooserDialog);
|
||||
};
|
||||
|
||||
|
@ -207,6 +219,37 @@ void FileChooserDialog::AddFilters(const Filters& filters) {
|
|||
}
|
||||
}
|
||||
|
||||
void FileChooserDialog::OnUpdatePreview(GtkWidget* chooser) {
|
||||
gchar* filename =
|
||||
gtk_file_chooser_get_preview_filename(GTK_FILE_CHOOSER(chooser));
|
||||
if (!filename) {
|
||||
gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser),
|
||||
FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't attempt to open anything which isn't a regular file. If a named pipe,
|
||||
// this may hang. See https://crbug.com/534754.
|
||||
struct stat stat_buf;
|
||||
if (stat(filename, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode)) {
|
||||
g_free(filename);
|
||||
gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser),
|
||||
FALSE);
|
||||
return;
|
||||
}
|
||||
|
||||
// This will preserve the image's aspect ratio.
|
||||
GdkPixbuf* pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth,
|
||||
kPreviewHeight, nullptr);
|
||||
g_free(filename);
|
||||
if (pixbuf) {
|
||||
gtk_image_set_from_pixbuf(GTK_IMAGE(preview_), pixbuf);
|
||||
g_object_unref(pixbuf);
|
||||
}
|
||||
gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(chooser),
|
||||
pixbuf ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ShowOpenDialog(const DialogSettings& settings,
|
||||
|
|
Loading…
Add table
Reference in a new issue