22 #include <QFileDialog>
23 #include <QHBoxLayout>
24 #include <QImageReader>
25 #include <QInputDialog>
28 #include <QToolButton>
38 QHBoxLayout *layout =
new QHBoxLayout(
this );
39 layout->setContentsMargins( 0, 0, 0, 0 );
42 mFileToolButton =
new QToolButton(
this );
43 mFileToolButton->setText( QString( QChar( 0x2026 ) ) );
45 layout->addWidget( mFileLineEdit, 1 );
46 layout->addWidget( mFileToolButton );
47 layout->addWidget( mPropertyOverrideButton );
50 QMenu *sourceMenu =
new QMenu( mFileToolButton );
52 QAction *selectFileAction =
new QAction( tr(
"Select File…" ), sourceMenu );
53 connect( selectFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
54 sourceMenu->addAction( selectFileAction );
56 QAction *embedFileAction =
new QAction( tr(
"Embed File…" ), sourceMenu );
57 connect( embedFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::embedFile );
58 sourceMenu->addAction( embedFileAction );
60 QAction *extractFileAction =
new QAction( tr(
"Extract Embedded File…" ), sourceMenu );
61 connect( extractFileAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::extractFile );
62 sourceMenu->addAction( extractFileAction );
64 connect( sourceMenu, &QMenu::aboutToShow,
this, [
this, extractFileAction]
66 extractFileAction->setEnabled( mMode == ModeBase64 );
69 QAction *enterUrlAction =
new QAction( tr(
"From URL…" ), sourceMenu );
70 connect( enterUrlAction, &QAction::triggered,
this, &QgsAbstractFileContentSourceLineEdit::selectUrl );
71 sourceMenu->addAction( enterUrlAction );
73 mFileToolButton->setMenu( sourceMenu );
74 mFileToolButton->setPopupMode( QToolButton::MenuButtonPopup );
75 connect( mFileToolButton, &QToolButton::clicked,
this, &QgsAbstractFileContentSourceLineEdit::selectFile );
77 connect( mFileLineEdit, &QLineEdit::textEdited,
this, &QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited );
81 mFileLineEdit->setPlaceholderText( QString() );
86 mPropertyOverrideButton->setVisible( mPropertyOverrideButtonVisible );
95 return mFileLineEdit->text();
111 mPropertyOverrideButtonVisible = visible;
112 mPropertyOverrideButton->setVisible( visible );
117 const bool isBase64 =
source.startsWith( QLatin1String(
"base64:" ), Qt::CaseInsensitive );
119 if ( ( !isBase64 &&
source == mFileLineEdit->text() && mBase64.isEmpty() ) || ( isBase64 &&
source == mBase64 ) )
126 mFileLineEdit->clear();
127 mFileLineEdit->setPlaceholderText( tr(
"Embedded file" ) );
133 mFileLineEdit->setText(
source );
134 mFileLineEdit->setPlaceholderText( QString() );
140 void QgsAbstractFileContentSourceLineEdit::selectFile()
143 const QString file = QFileDialog::getOpenFileName(
nullptr,
147 const QFileInfo fi( file );
148 if ( file.isEmpty() || !fi.exists() || file ==
source() )
154 mFileLineEdit->setText( file );
155 mFileLineEdit->setPlaceholderText( QString() );
156 s.
setValue( settingsKey(), fi.absolutePath() );
160 void QgsAbstractFileContentSourceLineEdit::selectUrl()
163 const QString path = QInputDialog::getText(
this, fileFromUrlTitle(), fileFromUrlText(), QLineEdit::Normal, mFileLineEdit->text(), &ok );
164 if ( ok && path !=
source() )
168 mFileLineEdit->setText( path );
169 mFileLineEdit->setPlaceholderText( QString() );
174 void QgsAbstractFileContentSourceLineEdit::embedFile()
177 const QString file = QFileDialog::getOpenFileName(
nullptr,
181 const QFileInfo fi( file );
182 if ( file.isEmpty() || !fi.exists() )
187 s.
setValue( settingsKey(), fi.absolutePath() );
190 QFile fileSource( file );
191 if ( !fileSource.open( QIODevice::ReadOnly ) )
196 const QByteArray blob = fileSource.readAll();
197 const QByteArray encoded = blob.toBase64();
199 QString path( encoded );
200 path.prepend( QLatin1String(
"base64:" ) );
207 mFileLineEdit->clear();
208 mFileLineEdit->setPlaceholderText( tr(
"Embedded file" ) );
213 void QgsAbstractFileContentSourceLineEdit::extractFile()
216 const QString file = QFileDialog::getSaveFileName(
nullptr,
220 if ( file.isEmpty() )
225 const QFileInfo fi( file );
226 s.
setValue( settingsKey(), fi.absolutePath() );
229 const QByteArray base64 = mBase64.mid( 7 ).toLocal8Bit();
230 const QByteArray decoded = QByteArray::fromBase64( base64, QByteArray::OmitTrailingEquals );
232 QFile fileOut( file );
233 fileOut.open( QIODevice::WriteOnly );
234 fileOut.write( decoded );
240 tr(
"Successfully extracted file to <a href=\"%1\">%2</a>" ).arg( QUrl::fromLocalFile( file ).toString(), QDir::toNativeSeparators( file ) ),
241 Qgis::MessageLevel::Success, 0 );
245 void QgsAbstractFileContentSourceLineEdit::mFileLineEdit_textEdited(
const QString &text )
247 mFileLineEdit->setPlaceholderText( QString() );
250 if ( !text.isEmpty() && !QFileInfo::exists( text ) )
252 const QUrl url( text );
253 if ( !url.isValid() )
261 QString QgsAbstractFileContentSourceLineEdit::defaultPath()
const
263 if ( QFileInfo::exists(
source() ) )
269 QString QgsAbstractFileContentSourceLineEdit::settingsKey()
const
271 return mLastPathKey.isEmpty() ? defaultSettingsKey() : mLastPathKey;
293 QString QgsPictureSourceLineEditBase::fileFilter()
const
298 return tr(
"SVG files" ) +
" (*.svg)";
301 QStringList formatsFilter;
302 const QByteArrayList supportedFormats = QImageReader::supportedImageFormats();
303 for (
const auto &format : supportedFormats )
305 formatsFilter.append( QString( QStringLiteral(
"*.%1" ) ).arg( QString( format ) ) );
307 return QString(
"%1 (%2);;%3 (*.*)" ).arg( tr(
"Images" ), formatsFilter.join( QLatin1Char(
' ' ) ), tr(
"All files" ) );
313 QString QgsPictureSourceLineEditBase::selectFileTitle()
const
318 return tr(
"Select SVG File" );
320 return tr(
"Select Image File" );
325 QString QgsPictureSourceLineEditBase::fileFromUrlTitle()
const
330 return tr(
"SVG From URL" );
332 return tr(
"Image From URL" );
337 QString QgsPictureSourceLineEditBase::fileFromUrlText()
const
342 return tr(
"Enter SVG URL" );
344 return tr(
"Enter image URL" );
349 QString QgsPictureSourceLineEditBase::embedFileTitle()
const
354 return tr(
"Embed SVG File" );
356 return tr(
"Embed Image File" );
361 QString QgsPictureSourceLineEditBase::extractFileTitle()
const
366 return tr(
"Extract SVG File" );
368 return tr(
"Extract Image File" );
373 QString QgsPictureSourceLineEditBase::defaultSettingsKey()
const
378 return QStringLiteral(
"/UI/lastSVGDir" );
380 return QStringLiteral(
"/UI/lastImageDir" );
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.
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