25#include <QImageReader>
26#include <QInputDialog>
33#include "moc_qgsfilecontentsourcelineedit.cpp"
42 QHBoxLayout *layout =
new QHBoxLayout(
this );
43 layout->setContentsMargins( 0, 0, 0, 0 );
45 mFileLineEdit->setShowClearButton(
true );
46 mFileToolButton =
new QToolButton(
this );
47 mFileToolButton->setText( QString( QChar( 0x2026 ) ) );
49 layout->addWidget( mFileLineEdit, 1 );
50 layout->addWidget( mFileToolButton );
51 layout->addWidget( mPropertyOverrideButton );
54 QMenu *sourceMenu =
new QMenu( mFileToolButton );
56 QAction *selectFileAction =
new QAction( tr(
"Select File…" ), sourceMenu );
57 connect( selectFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
58 sourceMenu->addAction( selectFileAction );
60 QAction *embedFileAction =
new QAction( tr(
"Embed File…" ), sourceMenu );
61 connect( embedFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::embedFile );
62 sourceMenu->addAction( embedFileAction );
64 QAction *extractFileAction =
new QAction( tr(
"Extract Embedded File…" ), sourceMenu );
65 connect( extractFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::extractFile );
66 sourceMenu->addAction( extractFileAction );
68 connect( sourceMenu, &QMenu::aboutToShow,
this, [
this, extractFileAction] {
69 extractFileAction->setEnabled( mMode == ModeBase64 );
72 QAction *enterUrlAction =
new QAction( tr(
"From URL…" ), sourceMenu );
73 connect( enterUrlAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectUrl );
74 sourceMenu->addAction( enterUrlAction );
76 mFileToolButton->setMenu( sourceMenu );
77 mFileToolButton->setPopupMode( QToolButton::MenuButtonPopup );
78 connect( mFileToolButton, &QToolButton::clicked,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
80 connect( mFileLineEdit, &QLineEdit::textEdited,
this, &QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited );
83 mFileLineEdit->setPlaceholderText( QString() );
88 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, selectFileTitle(), defaultPath(), fileFilter() );
145 const QFileInfo fi( file );
146 if ( file.isEmpty() || !fi.exists() || file ==
source() )
152 mFileLineEdit->setText( file );
153 mFileLineEdit->setPlaceholderText( QString() );
154 s.
setValue( settingsKey(), fi.absolutePath() );
158void QgsAbstractFileContentSourceLineEdit::selectUrl()
161 const QString path = QInputDialog::getText(
this, fileFromUrlTitle(), fileFromUrlText(), QLineEdit::Normal, mFileLineEdit->text(), &ok );
162 if ( ok && path !=
source() )
166 mFileLineEdit->setText( path );
167 mFileLineEdit->setPlaceholderText( QString() );
172void QgsAbstractFileContentSourceLineEdit::embedFile()
175 const QString file = QFileDialog::getOpenFileName(
nullptr, embedFileTitle(), defaultPath(), fileFilter() );
176 const QFileInfo fi( file );
177 if ( file.isEmpty() || !fi.exists() )
182 s.
setValue( settingsKey(), fi.absolutePath() );
185 QFile fileSource( file );
186 if ( !fileSource.open( QIODevice::ReadOnly ) )
191 const QByteArray blob = fileSource.readAll();
192 const QByteArray encoded = blob.toBase64();
194 QString path( encoded );
195 path.prepend( QLatin1String(
"base64:" ) );
202 mFileLineEdit->clear();
203 mFileLineEdit->setPlaceholderText( tr(
"Embedded file" ) );
208void QgsAbstractFileContentSourceLineEdit::extractFile()
211 const QString file = QFileDialog::getSaveFileName(
nullptr, extractFileTitle(), defaultPath(), fileFilter() );
215 if ( file.isEmpty() )
220 const QFileInfo fi( file );
221 s.
setValue( settingsKey(), fi.absolutePath() );
224 const QByteArray base64 = mBase64.mid( 7 ).toLocal8Bit();
225 const QByteArray decoded = QByteArray::fromBase64( base64, QByteArray::OmitTrailingEquals );
227 QFile fileOut( file );
228 if ( fileOut.open( QIODevice::WriteOnly ) )
230 fileOut.write( decoded );
235 mMessageBar->pushMessage( extractFileTitle(), tr(
"Successfully extracted file to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( file ).toString(), QDir::toNativeSeparators( file ) ),
Qgis::MessageLevel::Success, 0 );
238 else if ( mMessageBar )
240 mMessageBar->pushMessage( extractFileTitle(), tr(
"Error opening %1 for write" ).arg( QDir::toNativeSeparators( file ) ),
Qgis::MessageLevel::Critical );
244void QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited(
const QString &text )
246 mFileLineEdit->setPlaceholderText( QString() );
249 if ( !text.isEmpty() && !QFileInfo::exists( text ) )
251 const QUrl url( text );
252 if ( !url.isValid() )
260QString QgsAbstractFileContentSourceLineEdit::defaultPath()
const
262 if ( QFileInfo::exists(
source() ) )
265 return QgsSettings().value( settingsKey(), QDir::homePath() ).toString();
268QString QgsAbstractFileContentSourceLineEdit::settingsKey()
const
270 return mLastPathKey.isEmpty() ? defaultSettingsKey() : mLastPathKey;
291QString QgsPictureSourceLineEditBase::fileFilter()
const
296 return tr(
"SVG files" ) +
" (*.svg)";
299 QStringList formatsFilter;
300 const QByteArrayList supportedFormats = QImageReader::supportedImageFormats();
301 for (
const auto &format : supportedFormats )
303 formatsFilter.append( QString( QStringLiteral(
"*.%1" ) ).arg( QString( format ) ) );
305 return QString(
"%1 (%2);;%3 (*.*)" ).arg( tr(
"Images" ), formatsFilter.join( QLatin1Char(
' ' ) ), tr(
"All files" ) );
310 QStringList formatsFilter;
311 const QByteArrayList supportedFormats = QMovie::supportedFormats();
312 for (
const auto &format : supportedFormats )
314 formatsFilter.append( QString( QStringLiteral(
"*.%1" ) ).arg( QString( format ) ) );
316 return QString(
"%1 (%2);;%3 (*.*)" ).arg( tr(
"Animated Images" ), formatsFilter.join( QLatin1Char(
' ' ) ), tr(
"All files" ) );
322QString QgsPictureSourceLineEditBase::selectFileTitle()
const
327 return tr(
"Select SVG File" );
329 return tr(
"Select Image File" );
331 return tr(
"Select Animated Image File" );
336QString QgsPictureSourceLineEditBase::fileFromUrlTitle()
const
341 return tr(
"SVG From URL" );
343 return tr(
"Image From URL" );
345 return tr(
"Animated Image From URL" );
350QString QgsPictureSourceLineEditBase::fileFromUrlText()
const
355 return tr(
"Enter SVG URL" );
357 return tr(
"Enter image URL" );
359 return tr(
"Enter animated image URL" );
364QString QgsPictureSourceLineEditBase::embedFileTitle()
const
369 return tr(
"Embed SVG File" );
371 return tr(
"Embed Image File" );
373 return tr(
"Embed Animated Image File" );
378QString QgsPictureSourceLineEditBase::extractFileTitle()
const
383 return tr(
"Extract SVG File" );
385 return tr(
"Extract Image File" );
387 return tr(
"Extract Animated Image File" );
392QString QgsPictureSourceLineEditBase::defaultSettingsKey()
const
397 return QStringLiteral(
"/UI/lastSVGDir" );
399 return QStringLiteral(
"/UI/lastImageDir" );
401 return QStringLiteral(
"/UI/lastAnimatedImageDir" );
@ Critical
Critical/error message.
@ Success
Used for reporting a successful operation.
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 cleared()
Emitted when the widget is cleared.
A bar for displaying non-blocking messages to the user.
@ AnimatedImage
Animated image.
Stores settings for use within QGIS.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
#define BUILTIN_UNREACHABLE