diff --git a/python/PyQt6/core/auto_generated/qgscolorutils.sip.in b/python/PyQt6/core/auto_generated/qgscolorutils.sip.in index 81063d529b11..728550ba916e 100644 --- a/python/PyQt6/core/auto_generated/qgscolorutils.sip.in +++ b/python/PyQt6/core/auto_generated/qgscolorutils.sip.in @@ -95,6 +95,16 @@ message .. versionadded:: 3.40 %End + static QString saveIccProfile( const QColorSpace &colorSpace, const QString &iccProfileFilePath ); +%Docstring +Save color space ``colorSpace`` to an ICC profile file ``iccProfileFilePath``. + +:return: error message if an error occurred else empty string. + +.. versionadded:: 3.40 +%End + + diff --git a/python/core/auto_generated/qgscolorutils.sip.in b/python/core/auto_generated/qgscolorutils.sip.in index 81063d529b11..728550ba916e 100644 --- a/python/core/auto_generated/qgscolorutils.sip.in +++ b/python/core/auto_generated/qgscolorutils.sip.in @@ -95,6 +95,16 @@ message .. versionadded:: 3.40 %End + static QString saveIccProfile( const QColorSpace &colorSpace, const QString &iccProfileFilePath ); +%Docstring +Save color space ``colorSpace`` to an ICC profile file ``iccProfileFilePath``. + +:return: error message if an error occurred else empty string. + +.. versionadded:: 3.40 +%End + + diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index 34afe36d8854..db37d483f98d 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -12595,6 +12595,7 @@ QMap< QString, QString > QgisApp::projectPropertiesPagesMap() sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "CRS" ), QStringLiteral( "mProjOptsCRS" ) ); sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Transformations" ), QStringLiteral( "mProjTransformations" ) ); sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Styles" ), QStringLiteral( "mProjOptsSymbols" ) ); + sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Colors" ), QStringLiteral( "mTabColors" ) ); sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Data Sources" ), QStringLiteral( "mTab_DataSources" ) ); sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Relations" ), QStringLiteral( "mTabRelations" ) ); sProjectPropertiesPagesMap.insert( QCoreApplication::translate( "QgsProjectPropertiesBase", "Variables" ), QStringLiteral( "mTab_Variables" ) ); diff --git a/src/app/qgsprojectproperties.cpp b/src/app/qgsprojectproperties.cpp index b72df719d596..93f7e2744baa 100644 --- a/src/app/qgsprojectproperties.cpp +++ b/src/app/qgsprojectproperties.cpp @@ -22,6 +22,7 @@ #include "qgsapplication.h" #include "qgisapp.h" #include "qgis.h" +#include "qgscolorutils.h" #include "qgscoordinatetransform.h" #include "qgsdatumtransformtablewidget.h" #include "qgslayoutmanager.h" @@ -134,6 +135,11 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa connect( mButtonNewStyleDatabase, &QAbstractButton::clicked, this, &QgsProjectProperties::newStyleDatabase ); connect( mCoordinateDisplayComboBox, qOverload( &QComboBox::currentIndexChanged ), this, [ = ]( int ) { updateGuiForCoordinateType(); } ); connect( mCoordinateCrs, &QgsProjectionSelectionWidget::crsChanged, this, [ = ]( const QgsCoordinateReferenceSystem & ) { updateGuiForCoordinateCrs(); } ); +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + connect( mAddIccProfile, &QToolButton::clicked, this, static_cast( &QgsProjectProperties::addIccProfile ) ); + connect( mRemoveIccProfile, &QToolButton::clicked, this, &QgsProjectProperties::removeIccProfile ); + connect( mSaveIccProfile, &QToolButton::clicked, this, &QgsProjectProperties::saveIccProfile ); +#endif // QgsOptionsDialogBase handles saving/restoring of geometry, splitter and current tab states, // switching vertical tabs between icon/text to icon-only modes (splitter collapsed to left), @@ -1025,6 +1031,20 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa // Random colors cbxStyleRandomColors->setChecked( QgsProject::instance()->styleSettings()->randomizeDefaultSymbolColor() ); + mColorModel->addItem( tr( "RGB" ), QVariant::fromValue( Qgis::ColorModel::Rgb ) ); + mColorModel->addItem( tr( "CMYK" ), QVariant::fromValue( Qgis::ColorModel::Cmyk ) ); + mColorModel->setCurrentIndex( mColorModel->findData( QVariant::fromValue( QgsProject::instance()->styleSettings()->colorModel() ) ) ); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + mColorSpace = QgsProject::instance()->styleSettings()->colorSpace(); + updateColorSpaceWidgets(); +#else + mIccProfileLabel->setVisible( false ); + mColorSpaceName->setVisible( false ); + mAddIccProfile->setVisible( false ); + mRemoveIccProfile->setVisible( false ); + mSaveIccProfile->setVisible( false ); +#endif // Default alpha transparency mDefaultOpacityWidget->setOpacity( QgsProject::instance()->styleSettings()->defaultSymbolOpacity() ); @@ -1733,6 +1753,8 @@ void QgsProjectProperties::apply() QgsProject::instance()->styleSettings()->setDefaultTextFormat( mStyleTextFormat->textFormat() ); QgsProject::instance()->styleSettings()->setRandomizeDefaultSymbolColor( cbxStyleRandomColors->isChecked() ); QgsProject::instance()->styleSettings()->setDefaultSymbolOpacity( mDefaultOpacityWidget->opacity() ); + QgsProject::instance()->styleSettings()->setColorModel( mColorModel->currentData().value() ); + QgsProject::instance()->styleSettings()->setColorSpace( mColorSpace ); { QStringList styleDatabasePaths; @@ -2680,6 +2702,77 @@ void QgsProjectProperties::removeStyleDatabase() delete mListStyleDatabases->takeItem( currentRow ); } +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + +void QgsProjectProperties::addIccProfile() +{ + const QString iccProfileFilePath = QFileDialog::getOpenFileName( + this, + tr( "Load ICC Profile" ), + QDir::homePath(), + tr( "ICC Profile" ) + QStringLiteral( " (*.icc)" ) ); + + addIccProfile( iccProfileFilePath ); +} + +void QgsProjectProperties::addIccProfile( const QString &iccProfileFilePath ) +{ + if ( iccProfileFilePath.isEmpty() ) + return; + + QString errorMsg; + QColorSpace colorSpace = QgsColorUtils::iccProfile( iccProfileFilePath, errorMsg ); + if ( !colorSpace.isValid() ) + { + QMessageBox::warning( this, tr( "Load ICC Profile" ), errorMsg ); + return; + } + + mColorSpace = colorSpace; + updateColorSpaceWidgets(); +} + +void QgsProjectProperties::removeIccProfile() +{ + mColorSpace = QColorSpace(); + updateColorSpaceWidgets(); +} + +void QgsProjectProperties::saveIccProfile() +{ + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save ICC Profile" ), QDir::homePath(), + tr( "ICC profile files (*.icc *.ICC)" ) ); + + if ( fileName.isEmpty() ) + return; + + fileName = QgsFileUtils::ensureFileNameHasExtension( fileName, { QStringLiteral( "icc" ) } ); + const QString error = QgsColorUtils::saveIccProfile( mColorSpace, fileName ); + if ( !error.isEmpty() ) + { + QMessageBox::warning( this, tr( "Save ICC profile" ), error ); + } +} + + +void QgsProjectProperties::updateColorSpaceWidgets() +{ + mColorSpaceName->setText( mColorSpace.isValid() ? mColorSpace.description() : tr( "None" ) ); + mRemoveIccProfile->setEnabled( mColorSpace.isValid() ); + mSaveIccProfile->setEnabled( mColorSpace.isValid() ); + + // force color model index according to color space one + if ( mColorSpace.isValid() ) + { + const Qgis::ColorModel colorModel = QgsColorUtils::toColorModel( mColorSpace.colorModel() ); + mColorModel->setCurrentIndex( mColorModel->findData( QVariant::fromValue( colorModel ) ) ); + } + + mColorModel->setEnabled( !mColorSpace.isValid() ); +} + +#endif + QListWidgetItem *QgsProjectProperties::addScaleToScaleList( const double newScaleDenominator ) { // TODO QGIS3: Rework the scale list widget to be a reusable piece of code, see PR #2558 diff --git a/src/app/qgsprojectproperties.h b/src/app/qgsprojectproperties.h index 5c092c74b2f5..d0ba5799a4f7 100644 --- a/src/app/qgsprojectproperties.h +++ b/src/app/qgsprojectproperties.h @@ -29,6 +29,7 @@ #include "qgis_app.h" #include +#include class QgsMapCanvas; class QgsRelationManagerDialog; @@ -204,6 +205,35 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui: void removeStyleDatabase(); void newStyleDatabase(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + + /** + * Called whenever user select the add ICC profile button + */ + void addIccProfile(); + + /** + * load \a iccProfileFilePath and set resulting color space to project + */ + void addIccProfile( const QString &iccProfileFilePath ); + + /** + * Called whenever user select the remove ICC profile button + */ + void removeIccProfile(); + + /** + * Called whenever user select the save ICC profile button + */ + void saveIccProfile(); + + /** + * Update color space widget according to current project color space + */ + void updateColorSpaceWidgets(); + +#endif + private: /** @@ -240,6 +270,7 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui: QList mEllipsoidList; int mEllipsoidIndex; bool mBlockCrsUpdates = false; + QColorSpace mColorSpace; QList< QgsOptionsPageWidget * > mAdditionalProjectPropertiesWidgets; diff --git a/src/core/qgscolorutils.cpp b/src/core/qgscolorutils.cpp index 514d6173b4e9..4c37a41d2412 100644 --- a/src/core/qgscolorutils.cpp +++ b/src/core/qgscolorutils.cpp @@ -377,6 +377,22 @@ QColorSpace QgsColorUtils::iccProfile( const QString &iccProfileFilePath, QStrin return colorSpace; } + +QString QgsColorUtils::saveIccProfile( const QColorSpace &colorSpace, const QString &iccProfileFilePath ) +{ + if ( !colorSpace.isValid() ) + return QObject::tr( "Invalid ICC profile" ); + + QFile iccProfile( iccProfileFilePath ); + if ( !iccProfile.open( QIODevice::WriteOnly ) ) + return QObject::tr( "File access error '%1'" ).arg( iccProfileFilePath ); + + if ( iccProfile.write( colorSpace.iccProfile() ) < 0 ) + return QObject::tr( "Error while writing to file '%1'" ).arg( iccProfileFilePath ); + + return QString(); +} + #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) Qgis::ColorModel QgsColorUtils::toColorModel( QColorSpace::ColorModel colorModel, bool *ok ) diff --git a/src/core/qgscolorutils.h b/src/core/qgscolorutils.h index 593fc3133243..a31b8081eac8 100644 --- a/src/core/qgscolorutils.h +++ b/src/core/qgscolorutils.h @@ -108,6 +108,15 @@ class CORE_EXPORT QgsColorUtils */ static QColorSpace iccProfile( const QString &iccProfileFilePath, QString &errorMsg SIP_OUT ); + /** + * Save color space \a colorSpace to an ICC profile file \a iccProfileFilePath. + * \returns error message if an error occurred else empty string. + * + * \since QGIS 3.40 + */ + static QString saveIccProfile( const QColorSpace &colorSpace, const QString &iccProfileFilePath ); + + #if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) /** diff --git a/src/ui/qgsprojectpropertiesbase.ui b/src/ui/qgsprojectpropertiesbase.ui index da4b036e333e..153253a3dbec 100644 --- a/src/ui/qgsprojectpropertiesbase.ui +++ b/src/ui/qgsprojectpropertiesbase.ui @@ -161,6 +161,15 @@ :/images/themes/default/propertyicons/symbology.svg:/images/themes/default/propertyicons/symbology.svg + + + Colors + + + + :/images/themes/default/propertyicons/colors.svg:/images/themes/default/propertyicons/colors.svg + + Data Sources @@ -269,7 +278,7 @@ - 10 + 6 @@ -298,8 +307,8 @@ 0 0 - 640 - 971 + 673 + 852 @@ -317,7 +326,7 @@ General Settings - + projgeneral @@ -578,7 +587,7 @@ Measurements - + projgeneral @@ -647,7 +656,7 @@ Coordinate and Bearing Display - + projgeneral @@ -797,7 +806,7 @@ - + false @@ -901,7 +910,7 @@ false - + projgeneral @@ -1042,8 +1051,8 @@ 0 0 - 340 - 57 + 694 + 789 @@ -1107,8 +1116,8 @@ 0 0 - 634 - 90 + 694 + 789 @@ -1179,11 +1188,11 @@ 0 0 - 344 - 817 + 694 + 789 - + 0 @@ -1201,7 +1210,7 @@ Default Symbols - + projstyles @@ -1219,7 +1228,7 @@ - + 0 @@ -1353,7 +1362,7 @@ - + 0 @@ -1388,155 +1397,6 @@ - - - - Options - - - projstyles - - - - - - - - Opacity - - - - - - - Qt::StrongFocus - - - - - - - - - Assign random colors to symbols - - - - - - - - - - Project Colors - - - - - - Copy colors - - - - - - - :/images/themes/default/mActionEditCopy.svg:/images/themes/default/mActionEditCopy.svg - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - Add color - - - - - - - :/images/themes/default/symbologyAdd.svg:/images/themes/default/symbologyAdd.svg - - - - - - - Paste colors - - - - - - - :/images/themes/default/mActionEditPaste.svg:/images/themes/default/mActionEditPaste.svg - - - - - - - Remove color - - - - - - - :/images/themes/default/symbologyRemove.svg:/images/themes/default/symbologyRemove.svg - - - - - - - - - - Import colors - - - - - - - - - - :/images/themes/default/mActionFileOpen.svg:/images/themes/default/mActionFileOpen.svg - - - - - - - Export colors - - - - - - - :/images/themes/default/mActionFileSave.svg:/images/themes/default/mActionFileSave.svg - - - - - - @@ -1554,7 +1414,7 @@ false - + projgeneral @@ -1629,6 +1489,225 @@ + + + + + + Options + + + projstyles + + + + + + ICC Profile + + + + + + + Opacity + + + + + + + Qt::StrongFocus + + + + + + + <html><head/><body><p>Load an ICC profile file and attach it to the project.</p><p>Color model will be updated accordingly.</p></body></html> + + + + + + + :/images/themes/default/mActionFileOpen.svg:/images/themes/default/mActionFileOpen.svg + + + + + + + <html><head/><body><p>Color model used as default when selecting a color in the whole application.</p><p>Any color defined in a different color model than the one specified here will be converted to this color model when exporting a layout.</p></body></html> + + + + + + + <html><head/><body><p>Remove selected ICC profile</p></body></html> + + + ... + + + + :/images/themes/default/mActionDeleteSelected.svg:/images/themes/default/mActionDeleteSelected.svg + + + + + + + + + + + + + + Color model + + + + + + + Assign random colors to symbols + + + + + + + <html><head/><body><p>Save ICC profile</p></body></html> + + + + + + + :/images/themes/default/mActionFileSave.svg:/images/themes/default/mActionFileSave.svg + + + + + + + + + + Project Colors + + + + + + Copy colors + + + + + + + :/images/themes/default/mActionEditCopy.svg:/images/themes/default/mActionEditCopy.svg + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Add color + + + + + + + :/images/themes/default/symbologyAdd.svg:/images/themes/default/symbologyAdd.svg + + + + + + + Paste colors + + + + + + + :/images/themes/default/mActionEditPaste.svg:/images/themes/default/mActionEditPaste.svg + + + + + + + Remove color + + + + + + + :/images/themes/default/symbologyRemove.svg:/images/themes/default/symbologyRemove.svg + + + + + + + + + + Import colors + + + + + + + + + + :/images/themes/default/mActionFileOpen.svg:/images/themes/default/mActionFileOpen.svg + + + + + + + Export colors + + + + + + + :/images/themes/default/mActionFileSave.svg:/images/themes/default/mActionFileSave.svg + + + + + + + + @@ -1852,8 +1931,8 @@ 0 0 - 176 - 45 + 694 + 789 @@ -1935,8 +2014,8 @@ 0 0 - 679 - 1515 + 673 + 1503 @@ -1990,13 +2069,13 @@ false - + false - + projowsserver - + true @@ -2692,10 +2771,10 @@ false - + false - + true @@ -3445,54 +3524,22 @@
qgscolorbutton.h
1 - - QgsDateTimeEdit - QDateTimeEdit -
qgsdatetimeedit.h
-
- - QgsExtentGroupBox - QgsCollapsibleGroupBox -
qgsextentgroupbox.h
- 1 -
QgsFilterLineEdit QLineEdit
qgsfilterlineedit.h
- - QgsFontButton - QToolButton -
qgsfontbutton.h
-
- - QgsOpacityWidget - QWidget -
qgsopacitywidget.h
- 1 -
QgsProjectionSelectionWidget QWidget
qgsprojectionselectionwidget.h
1
- - QgsPropertyOverrideButton - QToolButton -
qgspropertyoverridebutton.h
-
QgsSpinBox QSpinBox
qgsspinbox.h
- - QgsSymbolButton - QToolButton -
qgssymbolbutton.h
-
QgsScrollArea QScrollArea @@ -3517,6 +3564,38 @@
qgsdatumtransformtablewidget.h
1
+ + QgsDateTimeEdit + QDateTimeEdit +
qgsdatetimeedit.h
+
+ + QgsExtentGroupBox + QgsCollapsibleGroupBox +
qgsextentgroupbox.h
+ 1 +
+ + QgsFontButton + QToolButton +
qgsfontbutton.h
+
+ + QgsOpacityWidget + QWidget +
qgsopacitywidget.h
+ 1 +
+ + QgsPropertyOverrideButton + QToolButton +
qgspropertyoverridebutton.h
+
+ + QgsSymbolButton + QToolButton +
qgssymbolbutton.h
+
QgsProjectionSelectionTreeWidget QWidget @@ -3591,14 +3670,6 @@ mStyleFillSymbol mStyleColorRampSymbol mStyleTextFormat - mDefaultOpacityWidget - cbxStyleRandomColors - mButtonAddColor - mButtonRemoveColor - mButtonCopyColors - mButtonPasteColors - mButtonImportColors - mButtonExportColors mListStyleDatabases mButtonAddStyleDatabase mButtonRemoveStyleDatabase diff --git a/tests/src/app/testqgsprojectproperties.cpp b/tests/src/app/testqgsprojectproperties.cpp index f2eede7fae91..624ba5cda1b5 100644 --- a/tests/src/app/testqgsprojectproperties.cpp +++ b/tests/src/app/testqgsprojectproperties.cpp @@ -24,6 +24,7 @@ #include "qgsbearingnumericformat.h" #include "qgsrasterlayer.h" #include "qgsprojecttimesettings.h" +#include "qgsprojectstylesettings.h" #include "qgsmaplayertemporalproperties.h" #include "qgsrasterlayertemporalproperties.h" @@ -48,6 +49,7 @@ class TestQgsProjectProperties : public QObject void testEllipsoidCrsSync(); void testBearingFormat(); void testTimeSettings(); + void testColorSettings(); private: QgisApp *mQgisApp = nullptr; @@ -255,6 +257,54 @@ void TestQgsProjectProperties::testTimeSettings() QCOMPARE( secondProjectRange, expectedRange ); } +void TestQgsProjectProperties::testColorSettings() +{ + QgsProject::instance()->clear(); + QCOMPARE( QgsProject::instance()->styleSettings()->colorModel(), Qgis::ColorModel::Rgb ); + QVERIFY( !QgsProject::instance()->styleSettings()->colorSpace().isValid() ); + + std::unique_ptr< QgsProjectProperties > pp = std::make_unique< QgsProjectProperties >( mQgisApp->mapCanvas() ); + QCOMPARE( static_cast( pp->mColorModel->currentData().toInt() ), Qgis::ColorModel::Rgb ); + QVERIFY( !pp->mColorSpace.isValid() ); +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + QCOMPARE( pp->mColorSpaceName->text(), QStringLiteral( "None" ) ); + QVERIFY( !pp->mRemoveIccProfile->isEnabled() ); +#else + QVERIFY( !pp->mRemoveIccProfile->isVisible() ); + QVERIFY( !pp->mAddIccProfile->isVisible() ); + QVERIFY( !pp->mSaveIccProfile->isVisible() ); + QVERIFY( !pp->mColorSpaceName->isVisible() ); + QVERIFY( !pp->mIccProfileLabel->isVisible() ); +#endif + + pp->mColorModel->setCurrentIndex( pp->mColorModel->findData( QVariant::fromValue( Qgis::ColorModel::Cmyk ) ) ); + QCOMPARE( static_cast( pp->mColorModel->currentData().toInt() ), Qgis::ColorModel::Cmyk ); + +#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0) + + const QString iccProfileFilePath = QStringLiteral( TEST_DATA_DIR ) + "/sRGB2014.icc"; + pp->addIccProfile( iccProfileFilePath ); + QCOMPARE( pp->mColorSpaceName->text(), QStringLiteral( "sRGB2014" ) ); + QVERIFY( pp->mRemoveIccProfile->isEnabled() ); + QVERIFY( !pp->mColorModel->isEnabled() ); + QCOMPARE( static_cast( pp->mColorModel->currentData().toInt() ), Qgis::ColorModel::Rgb ); + + pp->apply(); + QCOMPARE( QgsProject::instance()->styleSettings()->colorModel(), Qgis::ColorModel::Rgb ); + QVERIFY( QgsProject::instance()->styleSettings()->colorSpace().isValid() ); + QCOMPARE( QgsProject::instance()->styleSettings()->colorSpace().description(), QStringLiteral( "sRGB2014" ) ); + + pp->removeIccProfile(); + QVERIFY( !pp->mColorSpace.isValid() ); + QCOMPARE( pp->mColorSpaceName->text(), QStringLiteral( "None" ) ); + QVERIFY( !pp->mRemoveIccProfile->isEnabled() ); + +#endif + +} + + + QGSTEST_MAIN( TestQgsProjectProperties ) #include "testqgsprojectproperties.moc" diff --git a/tests/src/python/test_qgscolorutils.py b/tests/src/python/test_qgscolorutils.py index 59716feeaaf5..ad452132ff24 100644 --- a/tests/src/python/test_qgscolorutils.py +++ b/tests/src/python/test_qgscolorutils.py @@ -9,11 +9,18 @@ __date__ = '06/07/2022' __copyright__ = 'Copyright 2022, The QGIS Project' +import os + +from qgis.PyQt.QtCore import QTemporaryDir from qgis.PyQt.QtGui import QColor from qgis.PyQt.QtXml import QDomDocument from qgis.core import QgsColorUtils, QgsReadWriteContext, QgsSymbolLayerUtils from qgis.testing import unittest +from utilities import unitTestDataPath + +TEST_DATA_DIR = unitTestDataPath() + class TestQgsColorUtils(unittest.TestCase): @@ -288,6 +295,21 @@ def test_color_string_compat(self): self.assertAlmostEqual(res.blue(), 23, delta=1) self.assertEqual(res.alpha(), 220) + def test_icc_profile(self): + """ + Test ICC profile load and save method + """ + + iccProfileFilePath = os.path.join(TEST_DATA_DIR, "sRGB2014.icc") + colorSpace, errorMsg = QgsColorUtils.iccProfile(iccProfileFilePath) + self.assertTrue(colorSpace.isValid()) + + tmpDir = QTemporaryDir() + tmpFile = f"{tmpDir.path()}/test.icc" + + error = QgsColorUtils.saveIccProfile(colorSpace, tmpFile) + self.assertTrue(not error) + if __name__ == '__main__': unittest.main()