34#include <QDesktopServices>
40 , mMapCanvas( canvas )
44 mRendererWidget =
new QgsVectorTileBasicRendererWidget(
nullptr, canvas, messageBar,
this );
45 mOptsPage_Style->layout()->addWidget( mRendererWidget );
46 mOptsPage_Style->layout()->setContentsMargins( 0, 0, 0, 0 );
48 mLabelingWidget =
new QgsVectorTileBasicLabelingWidget(
nullptr, canvas, messageBar,
this );
49 mOptsPage_Labeling->layout()->addWidget( mLabelingWidget );
50 mOptsPage_Labeling->layout()->setContentsMargins( 0, 0, 0, 0 );
52 connect(
this, &QDialog::accepted,
this, &QgsVectorTileLayerProperties::apply );
53 connect(
this, &QDialog::rejected,
this, &QgsVectorTileLayerProperties::onCancel );
54 connect( buttonBox->button( QDialogButtonBox::Apply ), &QAbstractButton::clicked,
this, &QgsVectorTileLayerProperties::apply );
55 connect( buttonBox, &QDialogButtonBox::helpRequested,
this, &QgsVectorTileLayerProperties::showHelp );
65 const int horizontalDpi = logicalDpiX();
68 if ( horizontalDpi > 96 )
70 mMetadataViewer->setZoomFactor( mMetadataViewer->zoomFactor() * 0.9 );
72 mMetadataViewer->page()->setLinkDelegationPolicy( QWebPage::LinkDelegationPolicy::DelegateAllLinks );
73 connect( mMetadataViewer->page(), &QWebPage::linkClicked,
this, &QgsVectorTileLayerProperties::urlClicked );
74 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled,
true );
75 mMetadataViewer->page()->settings()->setAttribute( QWebSettings::JavascriptEnabled,
true );
78 mOptsPage_Information->setContentsMargins( 0, 0, 0, 0 );
80 QVBoxLayout *layout =
new QVBoxLayout( metadataFrame );
81 layout->setContentsMargins( 0, 0, 0, 0 );
82 metadataFrame->setContentsMargins( 0, 0, 0, 0 );
84 mMetadataWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
86 layout->addWidget( mMetadataWidget );
87 metadataFrame->setLayout( layout );
88 mOptsPage_Metadata->setContentsMargins( 0, 0, 0, 0 );
96 if ( !settings.
contains( QStringLiteral(
"/Windows/VectorTileLayerProperties/tab" ) ) )
98 settings.
setValue( QStringLiteral(
"Windows/VectorTileLayerProperties/tab" ),
102 QString title = tr(
"Layer Properties - %1" ).arg( mLayer->
name() );
104 mBtnStyle =
new QPushButton( tr(
"Style" ) );
105 QMenu *menuStyle =
new QMenu(
this );
106 menuStyle->addAction( tr(
"Load Style…" ),
this, &QgsVectorTileLayerProperties::loadStyle );
107 menuStyle->addAction( tr(
"Save Style…" ),
this, &QgsVectorTileLayerProperties::saveStyleAs );
108 menuStyle->addSeparator();
109 menuStyle->addAction( tr(
"Save as Default" ),
this, &QgsVectorTileLayerProperties::saveDefaultStyle );
110 menuStyle->addAction( tr(
"Restore Default" ),
this, &QgsVectorTileLayerProperties::loadDefaultStyle );
111 mBtnStyle->setMenu( menuStyle );
112 connect( menuStyle, &QMenu::aboutToShow,
this, &QgsVectorTileLayerProperties::aboutToShowStyleMenu );
114 buttonBox->addButton( mBtnStyle, QDialogButtonBox::ResetRole );
116 mBtnMetadata =
new QPushButton( tr(
"Metadata" ),
this );
117 QMenu *menuMetadata =
new QMenu(
this );
118 mActionLoadMetadata = menuMetadata->addAction( tr(
"Load Metadata…" ),
this, &QgsVectorTileLayerProperties::loadMetadata );
119 mActionSaveMetadataAs = menuMetadata->addAction( tr(
"Save Metadata…" ),
this, &QgsVectorTileLayerProperties::saveMetadataAs );
120 mBtnMetadata->setMenu( menuMetadata );
121 buttonBox->addButton( mBtnMetadata, QDialogButtonBox::ResetRole );
128void QgsVectorTileLayerProperties::apply()
130 mRendererWidget->apply();
131 mLabelingWidget->apply();
135void QgsVectorTileLayerProperties::onCancel()
141 QDomDocument doc( QStringLiteral(
"qgis" ) );
142 int errorLine, errorColumn;
143 doc.setContent( mOldStyle.
xmlData(),
false, &myMessage, &errorLine, &errorColumn );
149void QgsVectorTileLayerProperties::syncToLayer()
156 const QString html { mLayer->
htmlMetadata().replace( QLatin1String(
"<head>" ), QStringLiteral( R
"raw(<head><style type="text/css">%1</style>)raw" ) ).arg( myStyle ) };
157 mMetadataViewer->setHtml( html );
162 mRendererWidget->setLayer( mLayer );
167 mLabelingWidget->setLayer( mLayer );
171void QgsVectorTileLayerProperties::loadDefaultStyle()
173 bool defaultLoadedFlag =
false;
176 if ( defaultLoadedFlag )
183 QMessageBox::information(
this,
184 tr(
"Default Style" ),
190void QgsVectorTileLayerProperties::saveDefaultStyle()
195 bool defaultSavedFlag =
false;
203 if ( !defaultSavedFlag )
206 QMessageBox::information(
this,
207 tr(
"Default Style" ),
213void QgsVectorTileLayerProperties::loadStyle()
222 const QgsMapLayer::StyleCategories categories = dlg.styleCategories();
223 const QString type = dlg.fileExtension();
224 if ( type.compare( QLatin1String(
"qml" ), Qt::CaseInsensitive ) == 0 )
227 bool defaultLoadedFlag =
false;
228 const QString filePath = dlg.filePath();
229 message = mLayer->
loadNamedStyle( filePath, defaultLoadedFlag, categories );
232 if ( defaultLoadedFlag )
239 QMessageBox::warning(
this, tr(
"Load Style" ), message );
242 else if ( type.compare( QLatin1String(
"json" ), Qt::CaseInsensitive ) == 0 )
244 QFile file( dlg.filePath() );
245 if ( !file.open( QIODevice::ReadOnly | QIODevice::Text ) )
247 QMessageBox::warning(
this, tr(
"Load Style" ), tr(
"Could not read %1" ).arg( QDir::toNativeSeparators( dlg.filePath() ) ) );
251 QTextStream in( &file );
252#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
253 in.setCodec(
"UTF-8" );
255 const QString content = in.readAll();
268 QMessageBox::warning(
this, tr(
"Load Style" ), converter.
errorMessage() );
272 if ( dlg.styleCategories().testFlag( QgsMapLayer::StyleCategory::Symbology ) )
276 if ( dlg.styleCategories().testFlag( QgsMapLayer::StyleCategory::Labeling ) )
288void QgsVectorTileLayerProperties::saveStyleAs()
291 const QString lastUsedDir = settings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
293 QString outputFileName = QFileDialog::getSaveFileName(
295 tr(
"Save layer properties as style file" ),
297 tr(
"QGIS Layer Style File" ) +
" (*.qml)" );
298 if ( outputFileName.isEmpty() )
307 bool defaultLoadedFlag =
false;
309 message = mLayer->
saveNamedStyle( outputFileName, defaultLoadedFlag );
311 if ( defaultLoadedFlag )
313 settings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( outputFileName ).absolutePath() );
316 QMessageBox::information(
this, tr(
"Save Style" ), message );
319void QgsVectorTileLayerProperties::aboutToShowStyleMenu()
321 QMenu *m = qobject_cast<QMenu *>( sender() );
329void QgsVectorTileLayerProperties::loadMetadata()
332 const QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
334 const QString myFileName = QFileDialog::getOpenFileName(
this, tr(
"Load layer metadata from metadata file" ), myLastUsedDir,
335 tr(
"QGIS Layer Metadata File" ) +
" (*.qmd)" );
336 if ( myFileName.isNull() )
342 bool defaultLoadedFlag =
false;
346 if ( defaultLoadedFlag )
353 QMessageBox::warning(
this, tr(
"Load Metadata" ), myMessage );
356 const QFileInfo myFI( myFileName );
357 const QString myPath = myFI.path();
358 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), myPath );
363void QgsVectorTileLayerProperties::saveMetadataAs()
366 const QString myLastUsedDir = myQSettings.
value( QStringLiteral(
"style/lastStyleDir" ), QDir::homePath() ).toString();
368 QString myOutputFileName = QFileDialog::getSaveFileName(
this, tr(
"Save Layer Metadata as QMD" ),
369 myLastUsedDir, tr(
"QMD File" ) +
" (*.qmd)" );
370 if ( myOutputFileName.isNull() )
383 bool defaultLoadedFlag =
false;
384 const QString message = mLayer->
saveNamedMetadata( myOutputFileName, defaultLoadedFlag );
385 if ( defaultLoadedFlag )
386 myQSettings.
setValue( QStringLiteral(
"style/lastStyleDir" ), QFileInfo( myOutputFileName ).absolutePath() );
388 QMessageBox::information(
this, tr(
"Save Metadata" ), message );
391void QgsVectorTileLayerProperties::showHelp()
393 const QVariant helpPage = mOptionsStackedWidget->currentWidget()->property(
"helpPage" );
395 if ( helpPage.isValid() )
401 QgsHelp::openHelp( QStringLiteral(
"working_with_vector_tiles/vector_tiles_properties.html" ) );
405void QgsVectorTileLayerProperties::urlClicked(
const QUrl &url )
407 const QFileInfo file( url.toLocalFile() );
408 if ( file.exists() && !file.isDir() )
411 QDesktopServices::openUrl( url );
418 const bool isMetadataPanel = ( index ==
mOptStackedWidget->indexOf( mOptsPage_Metadata ) );
419 mBtnStyle->setVisible( ! isMetadataPanel );
420 mBtnMetadata->setVisible( isMetadataPanel );
static QString reportStyleSheet(QgsApplication::StyleSheetType styleSheetType=QgsApplication::StyleSheetType::Qt)
Returns a css style sheet for reports, the styleSheetType argument determines what type of stylesheet...
static QString ensureFileNameHasExtension(const QString &fileName, const QStringList &extensions)
Ensures that a fileName ends with an extension from the provided list of extensions.
static QgsNative * nativePlatformInterface()
Returns the global native interface, which offers abstraction to the host OS's underlying public inte...
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Context for a MapBox GL style conversion operation.
void setTargetUnit(Qgis::RenderUnit targetUnit)
Sets the target unit type.
void setPixelSizeConversionFactor(double sizeConversionFactor)
Sets the pixel size conversion factor, used to scale the original pixel sizes when converting styles.
Handles conversion of MapBox GL styles to QGIS vector tile renderers and labeling settings.
QgsVectorTileRenderer * renderer() const
Returns a new instance of a vector tile renderer representing the converted style,...
QgsVectorTileLabeling * labeling() const
Returns a new instance of a vector tile labeling representing the converted style,...
Result convert(const QVariantMap &style, QgsMapBoxGlStyleConversionContext *context=nullptr)
Converts a JSON style map, and returns the resultant status of the conversion.
@ Success
Conversion was successful.
QString errorMessage() const
Returns a descriptive error message if an error was encountered during the style conversion,...
Map canvas is a class for displaying all GIS data types on a canvas.
A reusable dialog which allows users to select stored layer styles and categories to load for a map l...
void removesExtraMenuSeparators(QMenu *m)
removes extra separators from the menu
void addStyleManagerActions(QMenu *m, QgsMapLayer *layer)
adds actions to the menu in accordance to the layer
static QgsMapLayerStyleGuiUtils * instance()
returns a singleton instance of this class
QString currentStyle() const
Returns name of the current style.
static bool isDefault(const QString &styleName)
Returns true if this is the default style.
QgsMapLayerStyle style(const QString &name) const
Returns data of a stored style - accessed by its unique name.
QString xmlData() const
Returns XML content of the style.
virtual bool importNamedStyle(QDomDocument &doc, QString &errorMsg, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Import the properties of this layer from a QDomDocument.
virtual QString loadNamedMetadata(const QString &uri, bool &resultFlag)
Retrieve a named metadata for this layer if one exists (either as a .qmd file on disk or as a record ...
QgsLayerMetadata metadata
virtual QString loadNamedStyle(const QString &uri, bool &resultFlag, QgsMapLayer::StyleCategories categories=QgsMapLayer::AllStyleCategories)
Retrieve a named style for this layer if one exists (either as a .qml file on disk or as a record in ...
static QString extensionPropertyType(PropertyType type)
Returns the extension of a Property.
QString saveNamedMetadata(const QString &uri, bool &resultFlag)
Save the current metadata of this layer as a named metadata (either as a .qmd file on disk or as a re...
QgsMapLayerStyleManager * styleManager() const
Gets access to the layer's style manager.
virtual QString saveNamedStyle(const QString &uri, bool &resultFlag, StyleCategories categories=AllStyleCategories)
Save the properties of this layer as a named style (either as a .qml file on disk or as a record in t...
virtual QString saveDefaultStyle(bool &resultFlag, StyleCategories categories)
Save the properties of this layer as the default style (either as a .qml file on disk or as a record ...
A bar for displaying non-blocking messages to the user.
A base dialog for options and properties dialogs that offers vertical tabs.
virtual void optionsStackedWidget_CurrentChanged(int index)
Select relevant tab on current page change.
void restoreOptionsBaseUi(const QString &title=QString())
Restore the base ui.
QStackedWidget * mOptStackedWidget
void initOptionsBase(bool restoreUi=true, const QString &title=QString())
Set up the base ui connections for vertical tabs.
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.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
void optionsStackedWidget_CurrentChanged(int index) override
QgsVectorTileLayerProperties(QgsVectorTileLayer *lyr, QgsMapCanvas *canvas, QgsMessageBar *messageBar, QWidget *parent=nullptr, Qt::WindowFlags=QgsGuiUtils::ModalDialogFlags)
Constructor.
Implements a map layer that is dedicated to rendering of vector tiles.
void setRenderer(QgsVectorTileRenderer *r)
Sets renderer for the map layer.
void setLabeling(QgsVectorTileLabeling *labeling)
Sets labeling for the map layer.
QString loadDefaultStyle(bool &resultFlag) override
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
QString htmlMetadata() const override
Obtain a formatted HTML string containing assorted metadata for this layer.
#define Q_NOWARN_DEPRECATED_POP
#define Q_NOWARN_DEPRECATED_PUSH