17 #include "qgssettings.h"
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 QString file = QFileDialog::getOpenFileName(
nullptr,
147 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 QString file = QFileDialog::getOpenFileName(
nullptr,
181 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 QByteArray blob = fileSource.readAll();
197 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 QString file = QFileDialog::getSaveFileName(
nullptr,
220 if ( file.isEmpty() )
225 QFileInfo fi( file );
226 s.setValue( settingsKey(), fi.absolutePath() );
229 QByteArray base64 = mBase64.mid( 7 ).toLocal8Bit();
230 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 ) )
253 if ( !url.isValid() )
261 QString QgsAbstractFileContentSourceLineEdit::defaultPath()
const
263 if ( QFileInfo::exists(
source() ) )
266 return QgsSettings().value( settingsKey(), QDir::homePath() ).toString();
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" );
321 return tr(
"Select Image File" );
328 QString QgsPictureSourceLineEditBase::fileFromUrlTitle()
const
333 return tr(
"SVG From URL" );
336 return tr(
"Image From URL" );
343 QString QgsPictureSourceLineEditBase::fileFromUrlText()
const
348 return tr(
"Enter SVG URL" );
351 return tr(
"Enter image URL" );
358 QString QgsPictureSourceLineEditBase::embedFileTitle()
const
363 return tr(
"Embed SVG File" );
366 return tr(
"Embed Image File" );
373 QString QgsPictureSourceLineEditBase::extractFileTitle()
const
378 return tr(
"Extract SVG File" );
381 return tr(
"Extract Image File" );
388 QString QgsPictureSourceLineEditBase::defaultSettingsKey()
const
393 return QStringLiteral(
"/UI/lastSVGDir" );
396 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 setValue(const QString &value)
Sets the current text for the widget with support for handling null values.
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.
#define DEFAULT_BUILTIN_UNREACHABLE