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 {
|
namespace {
|
||||||
|
|
||||||
|
static const int kPreviewWidth = 256;
|
||||||
|
static const int kPreviewHeight = 512;
|
||||||
|
|
||||||
// Makes sure that .jpg also shows .JPG.
|
// Makes sure that .jpg also shows .JPG.
|
||||||
gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
|
gboolean FileFilterCaseInsensitive(const GtkFileFilterInfo* file_info,
|
||||||
std::string* file_extension) {
|
std::string* file_extension) {
|
||||||
|
@ -86,6 +89,11 @@ class FileChooserDialog {
|
||||||
|
|
||||||
if (!settings.filters.empty())
|
if (!settings.filters.empty())
|
||||||
AddFilters(settings.filters);
|
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() {
|
~FileChooserDialog() {
|
||||||
|
@ -162,11 +170,15 @@ class FileChooserDialog {
|
||||||
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
atom::UnresponsiveSuppressor unresponsive_suppressor_;
|
||||||
|
|
||||||
GtkWidget* dialog_;
|
GtkWidget* dialog_;
|
||||||
|
GtkWidget* preview_;
|
||||||
|
|
||||||
Filters filters_;
|
Filters filters_;
|
||||||
SaveDialogCallback save_callback_;
|
SaveDialogCallback save_callback_;
|
||||||
OpenDialogCallback open_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);
|
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
|
} // namespace
|
||||||
|
|
||||||
bool ShowOpenDialog(const DialogSettings& settings,
|
bool ShowOpenDialog(const DialogSettings& settings,
|
||||||
|
|
Loading…
Add table
Reference in a new issue