24#include <QImageReader>
25#include <QInputDialog>
39 QHBoxLayout *layout =
new QHBoxLayout(
this );
40 layout->setContentsMargins( 0, 0, 0, 0 );
43 mFileToolButton =
new QToolButton(
this );
44 mFileToolButton->setText( QString( QChar( 0x2026 ) ) );
46 layout->addWidget( mFileLineEdit, 1 );
47 layout->addWidget( mFileToolButton );
48 layout->addWidget( mPropertyOverrideButton );
51 QMenu *sourceMenu =
new QMenu( mFileToolButton );
53 QAction *selectFileAction =
new QAction( tr(
"Select File…" ), sourceMenu );
54 connect( selectFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
55 sourceMenu->addAction( selectFileAction );
57 QAction *embedFileAction =
new QAction( tr(
"Embed File…" ), sourceMenu );
58 connect( embedFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::embedFile );
59 sourceMenu->addAction( embedFileAction );
61 QAction *extractFileAction =
new QAction( tr(
"Extract Embedded File…" ), sourceMenu );
62 connect( extractFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::extractFile );
63 sourceMenu->addAction( extractFileAction );
65 connect( sourceMenu, &QMenu::aboutToShow,
this, [
this, extractFileAction]
67 extractFileAction->setEnabled( mMode == ModeBase64 );
70 QAction *enterUrlAction =
new QAction( tr(
"From URL…" ), sourceMenu );
71 connect( enterUrlAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectUrl );
72 sourceMenu->addAction( enterUrlAction );
74 mFileToolButton->setMenu( sourceMenu );
75 mFileToolButton->setPopupMode( QToolButton::MenuButtonPopup );
76 connect( mFileToolButton, &QToolButton::clicked,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
78 connect( mFileLineEdit, &QLineEdit::textEdited,
this, &QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited );
82 mFileLineEdit->setPlaceholderText( QString() );
87 mPropertyOverrideButton->setVisible( mPropertyOverrideButtonVisible );
96 return mFileLineEdit->text();
112 mPropertyOverrideButtonVisible = visible;
113 mPropertyOverrideButton->setVisible( visible );
118 const bool isBase64 =
source.startsWith( QLatin1String(
"base64:" ), Qt::CaseInsensitive );
120 if ( ( !isBase64 &&
source == mFileLineEdit->text() && mBase64.isEmpty() ) || ( isBase64 &&
source == mBase64 ) )
127 mFileLineEdit->clear();
128 mFileLineEdit->setPlaceholderText( tr(
"Embedded file" ) );
134 mFileLineEdit->setText(
source );
135 mFileLineEdit->setPlaceholderText( QString() );
141void QgsAbstractFileContentSourceLineEdit::selectFile()
144 const QString file = QFileDialog::getOpenFileName(
nullptr,
148 const QFileInfo fi( file );
149 if ( file.isEmpty() || !fi.exists() || file ==
source() )
155 mFileLineEdit->setText( file );
156 mFileLineEdit->setPlaceholderText( QString() );
157 s.
setValue( settingsKey(), fi.absolutePath() );
161void QgsAbstractFileContentSourceLineEdit::selectUrl()
164 const QString path = QInputDialog::getText(
this, fileFromUrlTitle(), fileFromUrlText(), QLineEdit::Normal, mFileLineEdit->text(), &ok );
165 if ( ok && path !=
source() )
169 mFileLineEdit->setText( path );
170 mFileLineEdit->setPlaceholderText( QString() );
175void QgsAbstractFileContentSourceLineEdit::embedFile()
178 const QString file = QFileDialog::getOpenFileName(
nullptr,
182 const QFileInfo fi( file );
183 if ( file.isEmpty() || !fi.exists() )
188 s.
setValue( settingsKey(), fi.absolutePath() );
191 QFile fileSource( file );
192 if ( !fileSource.open( QIODevice::ReadOnly ) )
197 const QByteArray blob = fileSource.readAll();
198 const QByteArray encoded = blob.toBase64();
200 QString path( encoded );
201 path.prepend( QLatin1String(
"base64:" ) );
208 mFileLineEdit->clear();
209 mFileLineEdit->setPlaceholderText( tr(
"Embedded file" ) );
214void QgsAbstractFileContentSourceLineEdit::extractFile()
217 const QString file = QFileDialog::getSaveFileName(
nullptr,
221 if ( file.isEmpty() )
226 const QFileInfo fi( file );
227 s.
setValue( settingsKey(), fi.absolutePath() );
230 const QByteArray base64 = mBase64.mid( 7 ).toLocal8Bit();
231 const QByteArray decoded = QByteArray::fromBase64( base64, QByteArray::OmitTrailingEquals );
233 QFile fileOut( file );
234 fileOut.open( QIODevice::WriteOnly );
235 fileOut.write( decoded );
241 tr(
"Successfully extracted file to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( file ).toString(), QDir::toNativeSeparators( file ) ),
242 Qgis::MessageLevel::Success, 0 );
246void QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited(
const QString &text )
248 mFileLineEdit->setPlaceholderText( QString() );
251 if ( !text.isEmpty() && !QFileInfo::exists( text ) )
253 const QUrl url( text );
254 if ( !url.isValid() )
262QString QgsAbstractFileContentSourceLineEdit::defaultPath()
const
264 if ( QFileInfo::exists(
source() ) )
270QString QgsAbstractFileContentSourceLineEdit::settingsKey()
const
272 return mLastPathKey.isEmpty() ? defaultSettingsKey() : mLastPathKey;
294QString QgsPictureSourceLineEditBase::fileFilter()
const
299 return tr(
"SVG files" ) +
" (*.svg)";
302 QStringList formatsFilter;
303 const QByteArrayList supportedFormats = QImageReader::supportedImageFormats();
304 for (
const auto &format : supportedFormats )
306 formatsFilter.append( QString( QStringLiteral(
"*.%1" ) ).arg( QString( format ) ) );
308 return QString(
"%1 (%2);;%3 (*.*)" ).arg( tr(
"Images" ), formatsFilter.join( QLatin1Char(
' ' ) ), tr(
"All files" ) );
313 QStringList formatsFilter;
314 const QByteArrayList supportedFormats = QMovie::supportedFormats();
315 for (
const auto &format : supportedFormats )
317 formatsFilter.append( QString( QStringLiteral(
"*.%1" ) ).arg( QString( format ) ) );
319 return QString(
"%1 (%2);;%3 (*.*)" ).arg( tr(
"Animated Images" ), formatsFilter.join( QLatin1Char(
' ' ) ), tr(
"All files" ) );
325QString QgsPictureSourceLineEditBase::selectFileTitle()
const
330 return tr(
"Select SVG File" );
332 return tr(
"Select Image File" );
334 return tr(
"Select Animated Image File" );
339QString QgsPictureSourceLineEditBase::fileFromUrlTitle()
const
344 return tr(
"SVG From URL" );
346 return tr(
"Image From URL" );
348 return tr(
"Animated Image From URL" );
353QString QgsPictureSourceLineEditBase::fileFromUrlText()
const
358 return tr(
"Enter SVG URL" );
360 return tr(
"Enter image URL" );
362 return tr(
"Enter animated image URL" );
367QString QgsPictureSourceLineEditBase::embedFileTitle()
const
372 return tr(
"Embed SVG File" );
374 return tr(
"Embed Image File" );
376 return tr(
"Embed Animated Image File" );
381QString QgsPictureSourceLineEditBase::extractFileTitle()
const
386 return tr(
"Extract SVG File" );
388 return tr(
"Extract Image File" );
390 return tr(
"Extract Animated Image File" );
395QString QgsPictureSourceLineEditBase::defaultSettingsKey()
const
400 return QStringLiteral(
"/UI/lastSVGDir" );
402 return QStringLiteral(
"/UI/lastImageDir" );
404 return QStringLiteral(
"/UI/lastAnimatedImageDir" );
void setLastPathSettingsKey(const QString &key)
Sets a specific settings key to use when storing the last used path for the file source.
void sourceChanged(const QString &source)
Emitted whenever the file source is changed in the widget.
void setMessageBar(QgsMessageBar *bar)
Sets the message bar associated with the widget.
void setPropertyOverrideToolButtonVisible(bool visible)
Sets the visibility of the property override tool button.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
void setSource(const QString &source)
Sets a new source to show in the widget.
QgsAbstractFileContentSourceLineEdit(QWidget *parent=nullptr)
Constructor for QgsAbstractFileContentSourceLineEdit, with the specified parent widget.
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
void setShowClearButton(bool visible)
Sets whether the widget's clear button is visible.
void cleared()
Emitted when the widget is cleared.
A bar for displaying non-blocking messages to the user.
void pushMessage(const QString &text, Qgis::MessageLevel level=Qgis::MessageLevel::Info, int duration=-1)
A convenience method for pushing a message with the specified text to the bar.
@ AnimatedImage
Animated image (since QGIS 3.26)
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define BUILTIN_UNREACHABLE