diff options
author | Ilya Fedin <fedin-ilja2010@ya.ru> | 2021-04-12 10:16:09 +0400 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-09-29 11:17:03 +0000 |
commit | 4e7160341236dc1d8f4600493bdec7c5e672b2ce (patch) | |
tree | 6fa5487ec27c155775771007cd259232b53ed93d /src/plugins/platformthemes/gtk3 | |
parent | 71ba53e3a7b63da1ac8755dba8b9311774d46103 (diff) |
Implement preview support for GTK file dialog
This adds preview support in GTK file dialog implementation,
this is helpful for a lot of applications
like image viewers, messengers and etc.
[ChangeLog][Platform Specific Changes][Linux] A native GTK
file dialog (created via QFileDialog or QtQuick.Dialogs)
now shows an image preview pane.
Task-number: QTBUG-3796
Task-number: QTBUG-53167
Change-Id: Ib80108c09b84d774440a0445adcccab4b64652ef
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/plugins/platformthemes/gtk3')
-rw-r--r-- | src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp | 40 | ||||
-rw-r--r-- | src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h | 3 |
2 files changed, 43 insertions, 0 deletions
diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp index 16d5eb3ab4..4f417d77d8 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp +++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.cpp @@ -45,6 +45,7 @@ #include <qcolor.h> #include <qdebug.h> #include <qfont.h> +#include <qfileinfo.h> #include <private/qguiapplication_p.h> #include <qpa/qplatformfontdatabase.h> @@ -55,6 +56,14 @@ #include <gdk/gdkx.h> #include <pango/pango.h> +// The size of the preview we display for selected image files. We set height +// larger than width because generally there is more free space vertically +// than horiztonally (setting the preview image will alway expand the width of +// the dialog, but usually not the height). The image's aspect ratio will always +// be preserved. +#define PREVIEW_WIDTH 256 +#define PREVIEW_HEIGHT 512 + QT_BEGIN_NAMESPACE class QGtk3Dialog : public QWindow @@ -250,6 +259,10 @@ QGtk3FileDialogHelper::QGtk3FileDialogHelper() g_signal_connect(GTK_FILE_CHOOSER(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this); g_signal_connect_swapped(GTK_FILE_CHOOSER(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this); g_signal_connect_swapped(GTK_FILE_CHOOSER(d->gtkDialog()), "notify::filter", G_CALLBACK(onFilterChanged), this); + + previewWidget = gtk_image_new(); + g_signal_connect(G_OBJECT(d->gtkDialog()), "update-preview", G_CALLBACK(onUpdatePreview), this); + gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(d->gtkDialog()), previewWidget); } QGtk3FileDialogHelper::~QGtk3FileDialogHelper() @@ -390,6 +403,33 @@ void QGtk3FileDialogHelper::onFilterChanged(QGtk3FileDialogHelper *dialog) emit dialog->filterSelected(dialog->selectedNameFilter()); } +void QGtk3FileDialogHelper::onUpdatePreview(GtkDialog *gtkDialog, QGtk3FileDialogHelper *helper) +{ + gchar *filename = gtk_file_chooser_get_preview_filename(GTK_FILE_CHOOSER(gtkDialog)); + if (!filename) { + gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), false); + return; + } + + // Don't attempt to open anything which isn't a regular file. If a named pipe, + // this may hang. + QFileInfo fileinfo(filename); + if (!fileinfo.exists() || !fileinfo.isFile()) { + g_free(filename); + gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), false); + return; + } + + // This will preserve the image's aspect ratio. + GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file_at_size(filename, PREVIEW_WIDTH, PREVIEW_HEIGHT, 0); + g_free(filename); + if (pixbuf) { + gtk_image_set_from_pixbuf(GTK_IMAGE(helper->previewWidget), pixbuf); + g_object_unref(pixbuf); + } + gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), pixbuf ? true : false); +} + static GtkFileChooserAction gtkFileChooserAction(const QSharedPointer<QFileDialogOptions> &options) { switch (options->fileMode()) { diff --git a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h index e78a7fc6d1..1a055ac055 100644 --- a/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h +++ b/src/plugins/platformthemes/gtk3/qgtk3dialoghelpers.h @@ -47,6 +47,7 @@ #include <QtCore/qstring.h> #include <qpa/qplatformdialoghelper.h> +typedef struct _GtkWidget GtkWidget; typedef struct _GtkDialog GtkDialog; typedef struct _GtkFileFilter GtkFileFilter; @@ -108,6 +109,7 @@ private: static void onSelectionChanged(GtkDialog *dialog, QGtk3FileDialogHelper *helper); static void onCurrentFolderChanged(QGtk3FileDialogHelper *helper); static void onFilterChanged(QGtk3FileDialogHelper *helper); + static void onUpdatePreview(GtkDialog *dialog, QGtk3FileDialogHelper *helper); void applyOptions(); void setNameFilters(const QStringList &filters); void selectFileInternal(const QUrl &filename); @@ -118,6 +120,7 @@ private: QHash<QString, GtkFileFilter*> _filters; QHash<GtkFileFilter*, QString> _filterNames; QScopedPointer<QGtk3Dialog> d; + GtkWidget *previewWidget; }; class QGtk3FontDialogHelper : public QPlatformFontDialogHelper |