44 mProjectStyle->deleteLater();
45 mProjectStyle =
nullptr;
54 return mDefaultMarkerSymbol ? mDefaultMarkerSymbol->clone() :
nullptr;
57 return mDefaultLineSymbol ? mDefaultLineSymbol->clone() :
nullptr;
60 return mDefaultFillSymbol ? mDefaultFillSymbol->clone() :
nullptr;
74 mDefaultMarkerSymbol.reset( symbol ? symbol->
clone() : nullptr );
78 mDefaultLineSymbol.reset( symbol ? symbol->
clone() : nullptr );
82 mDefaultFillSymbol.reset( symbol ? symbol->
clone() : nullptr );
92 return mDefaultColorRamp ? mDefaultColorRamp->clone() :
nullptr;
97 mDefaultColorRamp.reset( colorRamp ? colorRamp->
clone() : nullptr );
102 return mDefaultTextFormat;
107 mDefaultTextFormat = textFormat;
112 mDefaultMarkerSymbol.reset();
113 mDefaultLineSymbol.reset();
114 mDefaultFillSymbol.reset();
115 mDefaultColorRamp.reset();
117 mRandomizeDefaultSymbolColor =
true;
118 mDefaultSymbolOpacity = 1.0;
124 const QString stylePath = mProject->
createAttachedFile( QStringLiteral(
"styles.db" ) );
127 style->
setName( tr(
"Project Style" ) );
140 delete mProjectStyle;
141 mProjectStyle =
nullptr;
150 mProjectStyle->deleteLater();
152 mProjectStyle = style;
153 mProjectStyle->
setName( tr(
"Project Styles" ) );
161 mCombinedStyleModel->
addStyle( mProjectStyle );
168 return mProjectStyle;
173 mRandomizeDefaultSymbolColor = element.attribute( QStringLiteral(
"RandomizeDefaultSymbolColor" ), QStringLiteral(
"0" ) ).toInt();
174 mDefaultSymbolOpacity = element.attribute( QStringLiteral(
"DefaultSymbolOpacity" ), QStringLiteral(
"1.0" ) ).toDouble();
177 QDomElement elem = element.firstChildElement( QStringLiteral(
"markerSymbol" ) );
178 if ( !elem.isNull() )
180 QDomElement symbolElem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
181 mDefaultMarkerSymbol.reset( !symbolElem.isNull() ? QgsSymbolLayerUtils::loadSymbol<QgsMarkerSymbol>( symbolElem, context ) : nullptr );
185 mDefaultMarkerSymbol.reset();
188 elem = element.firstChildElement( QStringLiteral(
"lineSymbol" ) );
189 if ( !elem.isNull() )
191 QDomElement symbolElem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
192 mDefaultLineSymbol.reset( !symbolElem.isNull() ? QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( symbolElem, context ) : nullptr );
196 mDefaultLineSymbol.reset();
199 elem = element.firstChildElement( QStringLiteral(
"fillSymbol" ) );
200 if ( !elem.isNull() )
202 QDomElement symbolElem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
203 mDefaultFillSymbol.reset( !symbolElem.isNull() ? QgsSymbolLayerUtils::loadSymbol<QgsFillSymbol>( symbolElem, context ) : nullptr );
207 mDefaultFillSymbol.reset();
210 elem = element.firstChildElement( QStringLiteral(
"colorramp" ) );
213 elem = element.firstChildElement( QStringLiteral(
"text-style" ) );
214 if ( !elem.isNull() )
216 mDefaultTextFormat.
readXml( elem, context );
227 const QDomElement styleDatabases = element.firstChildElement( QStringLiteral(
"databases" ) );
228 if ( !styleDatabases.isNull() )
230 const QDomNodeList styleEntries = styleDatabases.childNodes();
231 for (
int i = 0; i < styleEntries.count(); ++i )
233 const QDomElement styleElement = styleEntries.at( i ).toElement();
234 const QString path = styleElement.attribute( QStringLiteral(
"path" ) );
237 mStyleDatabases.append( fullPath );
238 loadStyleAtPath( fullPath );
245 const QString projectStyleId = element.attribute( QStringLiteral(
"projectStyleId" ) );
248 if ( !projectStyleFile.isEmpty() && QFile::exists( projectStyleFile ) )
250 style->
load( projectStyleFile );
255 const QString stylePath = mProject->
createAttachedFile( QStringLiteral(
"styles.db" ) );
259 style->
setName( tr(
"Project Style" ) );
265 const QString iccProfileId = element.attribute( QStringLiteral(
"iccProfileId" ) );
267 if ( !mIccProfileFilePath.isEmpty() )
271 if ( !errorMsg.isEmpty() )
284 QDomElement element = doc.createElement( QStringLiteral(
"ProjectStyleSettings" ) );
286 element.setAttribute( QStringLiteral(
"RandomizeDefaultSymbolColor" ), mRandomizeDefaultSymbolColor ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
287 element.setAttribute( QStringLiteral(
"DefaultSymbolOpacity" ), QString::number( mDefaultSymbolOpacity ) );
289 element.setAttribute( QStringLiteral(
"colorModel" ),
qgsEnumValueToKey( mColorModel ) );
291 if ( mDefaultMarkerSymbol )
293 QDomElement markerSymbolElem = doc.createElement( QStringLiteral(
"markerSymbol" ) );
295 element.appendChild( markerSymbolElem );
298 if ( mDefaultLineSymbol )
300 QDomElement lineSymbolElem = doc.createElement( QStringLiteral(
"lineSymbol" ) );
302 element.appendChild( lineSymbolElem );
305 if ( mDefaultFillSymbol )
307 QDomElement fillSymbolElem = doc.createElement( QStringLiteral(
"fillSymbol" ) );
309 element.appendChild( fillSymbolElem );
312 if ( mDefaultColorRamp )
315 element.appendChild( colorRampElem );
318 if ( mDefaultTextFormat.
isValid() )
320 QDomElement textFormatElem = mDefaultTextFormat.
writeXml( doc, context );
321 element.appendChild( textFormatElem );
325 QDomElement styleDatabases = doc.createElement( QStringLiteral(
"databases" ) );
326 for (
const QString &db : mStyleDatabases )
328 QDomElement dbElement = doc.createElement( QStringLiteral(
"db" ) );
330 styleDatabases.appendChild( dbElement );
332 element.appendChild( styleDatabases );
335 if ( mProject && mProjectStyle )
342 element.setAttribute( QStringLiteral(
"iccProfileId" ), mProject->
attachmentIdentifier( mIccProfileFilePath ) );
350 QList< QgsStyle * > res;
351 res.reserve( mStyles.size() );
365 if ( mProjectStyle && path == mProjectStyle->
fileName() )
366 return mProjectStyle;
368 for (
QgsStyle *style : std::as_const( mStyles ) )
370 if ( style->fileName() == path )
379 if ( mStyleDatabases.contains( path ) )
383 mStyleDatabases.append( path );
384 loadStyleAtPath( path );
392 if ( paths == mStyleDatabases )
397 for (
const QString &path : paths )
400 mStyleDatabases.append( path );
401 loadStyleAtPath( path );
407void QgsProjectStyleSettings::loadStyleAtPath(
const QString &path )
411 const QFileInfo fileInfo( path );
412 if ( fileInfo.suffix().compare( QLatin1String(
"xml" ), Qt::CaseInsensitive ) == 0 )
423 style->
setName( fileInfo.completeBaseName() );
424 mStyles.append( style );
425 mCombinedStyleModel->
addStyle( style );
435void QgsProjectStyleSettings::clearStyles()
437 const QStringList pathsToRemove = mStyleDatabases;
438 for (
const QString &path : pathsToRemove )
441 mStyleDatabases.removeAll( path );
445 style->deleteLater();
446 mStyles.removeAll( style );
452 for (
QgsStyle *style : std::as_const( mStyles ) )
456 qDeleteAll( mStyles );
462 return mCombinedStyleModel;
468#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
485 QgsDebugError(
"Impossible to attach ICC profile, no project defined" );
489 auto clearIccProfile = [
this]()
492 mIccProfileFilePath.clear();
493 mColorSpace = QColorSpace();
496 if ( !mIccProfileFilePath.isEmpty() )
499#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
502 mColorSpace = ok ?
colorSpace : QColorSpace();
507 if ( !mColorSpace.isValid() )
510#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
515 mIccProfileFilePath = mProject->
createAttachedFile( QStringLiteral(
"profile.icc" ) );
516 QFile file( mIccProfileFilePath );
517 if ( !file.open( QIODevice::WriteOnly ) || file.write(
colorSpace.iccProfile() ) < 0 )
532 : QAbstractListModel( parent )
533 , mSettings( settings )
548 return ( mSettings ? mSettings->
styleDatabasePaths().count() : 0 ) + ( mProjectStyle ? 1 : 0 ) + ( mShowDefault ? 1 : 0 );
553 if ( index.row() < 0 || index.row() >=
rowCount( QModelIndex() ) )
556 const bool isProjectStyle = index.row() == 0 && mProjectStyle;
557 const bool isDefault = mShowDefault && ( ( index.row() == 0 && !mProjectStyle ) || ( index.row() == 1 && mProjectStyle ) );
558 const int styleRow = index.row() - ( mShowDefault ? 1 : 0 ) - ( mProjectStyle ? 1 : 0 );
562 case Qt::DisplayRole:
566 else if ( isProjectStyle )
567 return mProjectStyle->name();
569 return mSettings ? mSettings->
styles().at( styleRow )->name() : QVariant();
571 case Qt::ToolTipRole:
574 else if ( isProjectStyle )
575 return mProjectStyle->name();
577 return mSettings ? QDir::toNativeSeparators( mSettings->
styles().at( styleRow )->fileName() ) : QVariant();
583 else if ( isProjectStyle )
584 return QVariant::fromValue( mProjectStyle.data() );
585 else if (
QgsStyle *style = mSettings->
styles().value( styleRow ) )
586 return QVariant::fromValue( style );
594 else if ( isProjectStyle )
595 return mProjectStyle->fileName();
597 return mSettings ? mSettings->
styles().at( styleRow )->fileName() : QVariant();
606 if ( index.row() == 0 && mProjectStyle )
607 return mProjectStyle;
608 else if ( mShowDefault && ( ( index.row() == 0 && !mProjectStyle ) || ( index.row() == 1 && mProjectStyle ) ) )
610 else if (
QgsStyle *style = qobject_cast< QgsStyle * >( qvariant_cast<QObject *>(
data( index,
static_cast< int >(
CustomRole::Style ) ) ) ) )
618 if ( style == mProjectStyle )
619 return index( 0, 0, QModelIndex() );
621 return index( mProjectStyle ? 1 : 0, 0, QModelIndex() );
625 return QModelIndex();
628 const int r = mSettings->
styles().indexOf( style );
630 return QModelIndex();
632 QModelIndex idx = index( r + ( mShowDefault ? 1 : 0 ) + ( mProjectStyle ? 1 : 0 ), 0, QModelIndex() );
638 return QModelIndex();
643 if ( show == mShowDefault )
646 const int row = mProjectStyle ? 1 : 0;
649 beginInsertRows( QModelIndex(), row, row );
655 beginRemoveRows( QModelIndex(), row, row );
656 mShowDefault =
false;
661void QgsProjectStyleDatabaseModel::setProjectStyle(
QgsStyle *style )
663 if ( style == mProjectStyle )
669 disconnect( mProjectStyle, &QgsStyle::destroyed,
this, &QgsProjectStyleDatabaseModel::projectStyleDestroyed );
670 beginRemoveRows( QModelIndex(), 0, 0 );
671 mProjectStyle =
nullptr;
677 beginInsertRows( QModelIndex(), 0, 0 );
678 mProjectStyle = style;
682 connect( mProjectStyle, &QgsStyle::destroyed,
this, &QgsProjectStyleDatabaseModel::projectStyleDestroyed );
686void QgsProjectStyleDatabaseModel::styleDatabaseAboutToBeAdded(
const QString & )
688 int row = mSettings->
styles().count() + ( mShowDefault ? 1 : 0 ) + ( mProjectStyle ? 1 : 0 );
689 beginInsertRows( QModelIndex(), row, row );
692void QgsProjectStyleDatabaseModel::styleDatabaseAboutToBeRemoved(
const QString &path )
695 int row = mSettings->
styles().indexOf( style ) + ( mShowDefault ? 1 : 0 ) + ( mProjectStyle ? 1 : 0 );
697 beginRemoveRows( QModelIndex(), row, row );
700void QgsProjectStyleDatabaseModel::styleDatabaseAdded(
const QString & )
705void QgsProjectStyleDatabaseModel::styleDatabaseRemoved(
const QString & )
710void QgsProjectStyleDatabaseModel::projectStyleAboutToBeDestroyed()
712 beginRemoveRows( QModelIndex(), 0, 0 );
715void QgsProjectStyleDatabaseModel::projectStyleDestroyed()
720void QgsProjectStyleDatabaseModel::projectStyleChanged()
730 : QSortFilterProxyModel( parent )
732 setSourceModel( model );
733 setDynamicSortFilter(
true );
QFlags< ProjectReadFlag > ProjectReadFlags
Project load flags.
@ ProjectStyles
Enable the project embedded style library. Enabling this flag can increase the time required to clear...
ColorModel
Color model types.
Abstract base class for color ramps.
virtual QgsColorRamp * clone() const =0
Creates a clone of the color ramp.
static Qgis::ColorModel toColorModel(QColorSpace::ColorModel colorModel, bool *ok=nullptr)
Convert and returns Qt colorModel to Qgis::ColorModel.
static QColorSpace iccProfile(const QString &iccProfileFilePath, QString &errorMsg)
Loads an ICC profile from iccProfileFilePath and returns associated color space.
A model which contains entities from multiple QgsStyle databases.
void removeStyle(QgsStyle *style)
Removes a style from the model.
void addStyle(QgsStyle *style)
Adds a style to the model.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
List model representing the style databases associated with a QgsProject.
QVariant data(const QModelIndex &index, int role) const override
void setShowDefaultStyle(bool show)
Sets whether the default style should also be included in the model.
QModelIndex indexFromStyle(QgsStyle *style) const
Returns the model index corresponding to a style.
QgsProjectStyleDatabaseModel(QgsProjectStyleSettings *settings, QObject *parent=nullptr)
Constructor for QgsProjectStyleDatabaseModel, showing the styles from the specified settings.
QgsStyle * styleFromIndex(const QModelIndex &index) const
Returns the style at the corresponding index.
int rowCount(const QModelIndex &parent) const override
@ FilterHideReadOnly
Hide read-only style databases.
QgsProjectStyleDatabaseProxyModel::Filters filters() const
Returns the current filters used for filtering available style.
QFlags< Filter > Filters
Available filter flags for filtering the model.
void setFilters(QgsProjectStyleDatabaseProxyModel::Filters filters)
Sets the current filters used for filtering available styles.
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
QgsProjectStyleDatabaseProxyModel(QgsProjectStyleDatabaseModel *model, QObject *parent=nullptr)
Constructor for QgsProjectStyleDatabaseProxyModel, for the specified style database model.
Contains settings and properties relating to how a QgsProject should handle styling.
QColorSpace colorSpace() const
Returns the project's color space.
void setDefaultTextFormat(const QgsTextFormat &textFormat)
Sets the project default text format.
QList< QgsStyle * > styles() const
Returns a list of all the styles associated with the project.
void setStyleDatabasePaths(const QStringList &paths)
Sets the paths to all style databases associated with the project.
QgsStyle * styleAtPath(const QString &path)
Returns a reference to the style database associated with the project with matching file path.
QgsTextFormat defaultTextFormat() const
Returns the project default text format.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Returns a DOM element representing the settings.
~QgsProjectStyleSettings() override
void setProjectStyle(QgsStyle *style)
Sets the style database to use for the project style.
Qgis::ColorModel colorModel() const
Returns the project's color model.
void projectStyleChanged()
Emitted when the style returned by projectStyle() is changed.
QgsColorRamp * defaultColorRamp() const
Returns the project default color ramp.
QgsSymbol * defaultSymbol(Qgis::SymbolType symbolType) const
Returns the project default symbol for a given type.
void setDefaultSymbol(Qgis::SymbolType symbolType, QgsSymbol *symbol)
Sets the project default symbol for a given type.
QStringList styleDatabasePaths() const
Returns a list of all style databases (file paths) associated with the project.
void reset()
Resets the settings to a default state.
QgsProjectStyleSettings(QgsProject *project=nullptr)
Constructor for QgsProjectStyleSettings for the specified project.
void styleDatabaseAdded(const QString &path)
Emitted when a style database path is added.
void styleDatabaseAboutToBeRemoved(const QString &path)
Emitted when a style database path is about to be removed.
void removeProjectStyle()
Removes and deletes the project style database.
void setColorModel(Qgis::ColorModel colorModel)
Set the project's color model to colorModel.
void setColorSpace(const QColorSpace &colorSpace)
Set the project's current color space to colorSpace.
void setDefaultColorRamp(QgsColorRamp *colorRamp)
Sets the project default color ramp.
void addStyleDatabasePath(const QString &path)
Adds a style database path to the project.
void styleDatabaseRemoved(const QString &path)
Emitted when a style database path is removed.
bool readXml(const QDomElement &element, const QgsReadWriteContext &context, Qgis::ProjectReadFlags flags=Qgis::ProjectReadFlags())
Reads the settings's state from a DOM element.
QgsStyle * projectStyle()
Returns the style database to use for project specific styles.
QgsCombinedStyleModel * combinedStyleModel()
Returns the combined style model which includes all style databases associated with the project.
void styleDatabaseAboutToBeAdded(const QString &path)
Emitted when a style database path is about to be added.
void styleDatabasesChanged()
Emitted whenever the set of style databases associated with the project is changed.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
bool removeAttachedFile(const QString &path)
Removes the attached file.
QString createAttachedFile(const QString &nameTemplate)
Attaches a file to the project.
QString attachmentIdentifier(const QString &attachedFile) const
Returns an identifier for an attachment file path An attachment identifier is a string which does not...
QString resolveAttachmentIdentifier(const QString &identifier) const
Resolves an attachment identifier to a attachment file path.
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
Qgis::ProjectCapabilities capabilities() const
Returns the project's capabilities, which dictate optional functionality which can be selectively ena...
The class is used as a container of context for various read/write operations on other objects.
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
void setFileName(const QString &filename)
Sets the current file name of the style database.
void aboutToBeDestroyed()
Emitted just before the style object is destroyed.
bool createDatabase(const QString &filename)
Creates an on-disk database.
void triggerIconRebuild()
Triggers emission of the rebuildIconPreviews() signal.
void setName(const QString &name)
Sets the name of the style.
QString fileName() const
Returns the current file name of the style database.
bool isReadOnly() const
Returns true if the style is considered a read-only library.
static QgsStyle * defaultStyle(bool initialize=true)
Returns the default application-wide style.
bool createMemoryDatabase()
Creates a temporary memory database.
bool load(const QString &filename)
Loads a file into the style.
QString name() const
Returns the name of the style.
void setReadOnly(bool readOnly)
Sets whether the style is considered a read-only library.
bool importXml(const QString &filename)
Imports the symbols and colorramps into the default style database from the given XML file.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
Abstract base class for all rendered symbols.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
Container for all settings relating to text rendering.
void readXml(const QDomElement &elem, const QgsReadWriteContext &context)
Read settings from a DOM element.
bool isValid() const
Returns true if the format is valid.
QDomElement writeXml(QDomDocument &doc, const QgsReadWriteContext &context) const
Write settings into a DOM element.
T qgsEnumKeyToValue(const QString &key, const T &defaultValue, bool tryValueAsKey=true, bool *returnOk=nullptr)
Returns the value corresponding to the given key of an enum.
QString qgsEnumValueToKey(const T &value, bool *returnOk=nullptr)
Returns the value for the given key of an enum.
#define QgsDebugError(str)