1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt Designer of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include "dialoggui_p.h"
30
31#include <QtWidgets/qfileiconprovider.h>
32#include <QtGui/qicon.h>
33#include <QtGui/qimage.h>
34#include <QtGui/qimagereader.h>
35#include <QtGui/qpixmap.h>
36
37#include <QtCore/qfileinfo.h>
38#include <QtCore/qfile.h>
39#include <QtCore/qset.h>
40
41// QFileDialog on X11 does not provide an image preview. Display icons.
42#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
43# define IMAGE_PREVIEW
44#endif
45
46QT_BEGIN_NAMESPACE
47
48namespace qdesigner_internal {
49
50// Icon provider that reads out the known image formats
51class IconProvider : public QFileIconProvider {
52 Q_DISABLE_COPY_MOVE(IconProvider)
53
54public:
55 IconProvider();
56 QIcon icon (const QFileInfo &info) const override;
57
58 inline bool loadCheck(const QFileInfo &info) const;
59 QImage loadImage(const QString &fileName) const;
60
61private:
62 QSet<QString> m_imageFormats;
63};
64
65IconProvider::IconProvider()
66{
67 // Determine a list of readable extensions (upper and lower case)
68 const auto &fmts = QImageReader::supportedImageFormats();
69 for (const QByteArray &fmt : fmts) {
70 const QString suffix = QString::fromUtf8(str: fmt);
71 m_imageFormats.insert(value: suffix.toLower());
72 m_imageFormats.insert(value: suffix.toUpper());
73 }
74}
75
76// Check by extension and type if this appears to be a loadable image
77bool IconProvider::loadCheck(const QFileInfo &info) const
78{
79 if (info.isFile() && info.isReadable()) {
80 const QString suffix = info.suffix();
81 if (!suffix.isEmpty())
82 return m_imageFormats.contains(value: suffix);
83 }
84 return false;
85}
86
87QImage IconProvider::loadImage(const QString &fileName) const
88{
89 QFile file(fileName);
90 if (file.open(flags: QIODevice::ReadOnly)) {
91 QImageReader imgReader(&file);
92 if (imgReader.canRead()) {
93 QImage image;
94 if (imgReader.read(image: &image))
95 return image;
96 }
97 }
98 return QImage();
99}
100
101QIcon IconProvider::icon (const QFileInfo &info) const
102{
103 // Don't get stuck on large images.
104 const qint64 maxSize = 131072;
105 if (loadCheck(info) && info.size() < maxSize) {
106 const QImage image = loadImage(fileName: info.absoluteFilePath());
107 if (!image.isNull())
108 return QIcon(QPixmap::fromImage(image, flags: Qt::ThresholdDither|Qt::AutoColor));
109 }
110 return QFileIconProvider::icon(info);
111}
112
113// ---------------- DialogGui
114DialogGui::DialogGui() = default;
115
116DialogGui::~DialogGui()
117{
118 delete m_iconProvider;
119}
120
121QFileIconProvider *DialogGui::ensureIconProvider()
122{
123 if (!m_iconProvider)
124 m_iconProvider = new IconProvider;
125 return m_iconProvider;
126}
127
128QMessageBox::StandardButton
129 DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
130 const QString &title, const QString &text, QMessageBox::StandardButtons buttons,
131 QMessageBox::StandardButton defaultButton)
132{
133 QMessageBox::StandardButton rc = QMessageBox::NoButton;
134 switch (icon) {
135 case QMessageBox::Information:
136 rc = QMessageBox::information(parent, title, text, buttons, defaultButton);
137 break;
138 case QMessageBox::Warning:
139 rc = QMessageBox::warning(parent, title, text, buttons, defaultButton);
140 break;
141 case QMessageBox::Critical:
142 rc = QMessageBox::critical(parent, title, text, buttons, defaultButton);
143 break;
144 case QMessageBox::Question:
145 rc = QMessageBox::question(parent, title, text, buttons, defaultButton);
146 break;
147 case QMessageBox::NoIcon:
148 break;
149 }
150 return rc;
151}
152
153QMessageBox::StandardButton
154 DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
155 const QString &title, const QString &text, const QString &informativeText,
156 QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
157{
158 QMessageBox msgBox(icon, title, text, buttons, parent);
159 msgBox.setDefaultButton(defaultButton);
160 msgBox.setInformativeText(informativeText);
161 return static_cast<QMessageBox::StandardButton>(msgBox.exec());
162}
163
164QMessageBox::StandardButton
165 DialogGui::message(QWidget *parent, Message /*context*/, QMessageBox::Icon icon,
166 const QString &title, const QString &text, const QString &informativeText, const QString &detailedText,
167 QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton)
168{
169 QMessageBox msgBox(icon, title, text, buttons, parent);
170 msgBox.setDefaultButton(defaultButton);
171 msgBox.setInformativeText(informativeText);
172 msgBox.setDetailedText(detailedText);
173 return static_cast<QMessageBox::StandardButton>(msgBox.exec());
174}
175
176QString DialogGui::getExistingDirectory(QWidget *parent, const QString &caption, const QString &dir, QFileDialog::Options options)
177{
178 return QFileDialog::getExistingDirectory(parent, caption, dir, options);
179}
180
181QString DialogGui::getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
182{
183 return QFileDialog::getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
184}
185
186QStringList DialogGui::getOpenFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
187{
188 return QFileDialog::getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
189}
190
191QString DialogGui::getSaveFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options)
192{
193 return QFileDialog::getSaveFileName(parent, caption, dir, filter, selectedFilter, options);
194}
195
196void DialogGui::initializeImageFileDialog(QFileDialog &fileDialog, QFileDialog::Options options, QFileDialog::FileMode fm)
197{
198 fileDialog.setOption(option: QFileDialog::DontConfirmOverwrite, on: options.testFlag(flag: QFileDialog::DontConfirmOverwrite));
199 fileDialog.setOption(option: QFileDialog::DontResolveSymlinks, on: options.testFlag(flag: QFileDialog::DontResolveSymlinks));
200 fileDialog.setIconProvider(ensureIconProvider());
201 fileDialog.setFileMode(fm);
202}
203
204QString DialogGui::getOpenImageFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
205{
206
207#ifdef IMAGE_PREVIEW
208 QFileDialog fileDialog(parent, caption, dir, filter);
209 initializeImageFileDialog(fileDialog, options, fm: QFileDialog::ExistingFile);
210 if (fileDialog.exec() != QDialog::Accepted)
211 return QString();
212
213 const QStringList selectedFiles = fileDialog.selectedFiles();
214 if (selectedFiles.isEmpty())
215 return QString();
216
217 if (selectedFilter)
218 *selectedFilter = fileDialog.selectedNameFilter();
219
220 return selectedFiles.constFirst();
221#else
222 return getOpenFileName(parent, caption, dir, filter, selectedFilter, options);
223#endif
224}
225
226QStringList DialogGui::getOpenImageFileNames(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFileDialog::Options options )
227{
228#ifdef IMAGE_PREVIEW
229 QFileDialog fileDialog(parent, caption, dir, filter);
230 initializeImageFileDialog(fileDialog, options, fm: QFileDialog::ExistingFiles);
231 if (fileDialog.exec() != QDialog::Accepted)
232 return QStringList();
233
234 const QStringList selectedFiles = fileDialog.selectedFiles();
235 if (!selectedFiles.isEmpty() && selectedFilter)
236 *selectedFilter = fileDialog.selectedNameFilter();
237
238 return selectedFiles;
239#else
240 return getOpenFileNames(parent, caption, dir, filter, selectedFilter, options);
241#endif
242}
243
244}
245
246QT_END_NAMESPACE
247

source code of qttools/src/designer/src/lib/shared/dialoggui.cpp