mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
feat(ICCProfile): Add an action to save an ICC profile file
This commit is contained in:
parent
b1181118a7
commit
76a4202f7e
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -138,6 +138,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 8, 0)
|
||||
connect( mAddIccProfile, &QToolButton::clicked, this, static_cast<void ( QgsProjectProperties::* )()>( &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,
|
||||
@ -1042,6 +1043,7 @@ QgsProjectProperties::QgsProjectProperties( QgsMapCanvas *mapCanvas, QWidget *pa
|
||||
mColorSpaceName->setVisible( false );
|
||||
mAddIccProfile->setVisible( false );
|
||||
mRemoveIccProfile->setVisible( false );
|
||||
mSaveIccProfile->setVisible( false );
|
||||
#endif
|
||||
// Default alpha transparency
|
||||
mDefaultOpacityWidget->setOpacity( QgsProject::instance()->styleSettings()->defaultSymbolOpacity() );
|
||||
@ -2736,10 +2738,27 @@ void QgsProjectProperties::removeIccProfile()
|
||||
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;
|
||||
|
||||
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( "<i>None</i>" ) );
|
||||
mRemoveIccProfile->setEnabled( mColorSpace.isValid() );
|
||||
mSaveIccProfile->setEnabled( mColorSpace.isValid() );
|
||||
|
||||
// force color model index according to color space one
|
||||
if ( mColorSpace.isValid() )
|
||||
|
||||
@ -222,6 +222,11 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
|
||||
*/
|
||||
void removeIccProfile();
|
||||
|
||||
/**
|
||||
* Called whenever user select the save ICC profile button
|
||||
*/
|
||||
void saveIccProfile();
|
||||
|
||||
/**
|
||||
* Update color space widget according to current project color space
|
||||
*/
|
||||
|
||||
@ -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 )
|
||||
|
||||
@ -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)
|
||||
|
||||
/**
|
||||
|
||||
@ -1500,17 +1500,45 @@
|
||||
<string notr="true">projstyles</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_4">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="cbxStyleRandomColors">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mIccProfileLabel">
|
||||
<property name="text">
|
||||
<string>Assign random colors to symbols</string>
|
||||
<string>ICC Profile</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<property name="text">
|
||||
<string>Color model</string>
|
||||
<string>Opacity</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="4">
|
||||
<widget class="QgsOpacityWidget" name="mDefaultOpacityWidget" native="true">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="4">
|
||||
<widget class="QToolButton" name="mAddIccProfile">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionFileOpen.svg</normaloff>:/images/themes/default/mActionFileOpen.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="4">
|
||||
<widget class="QComboBox" name="mColorModel">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@ -1535,45 +1563,31 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_27">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_14">
|
||||
<property name="text">
|
||||
<string>Opacity</string>
|
||||
<string>Color model</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="mIccProfileLabel">
|
||||
<item row="6" column="0" colspan="3">
|
||||
<widget class="QCheckBox" name="cbxStyleRandomColors">
|
||||
<property name="text">
|
||||
<string>ICC Profile</string>
|
||||
<string>Assign random colors to symbols</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QToolButton" name="mAddIccProfile">
|
||||
<widget class="QToolButton" name="mSaveIccProfile">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
<string><html><head/><body><p>Save ICC profile</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mActionFileOpen.svg</normaloff>:/images/themes/default/mActionFileOpen.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="mColorModel">
|
||||
<property name="toolTip">
|
||||
<string><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></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1" colspan="3">
|
||||
<widget class="QgsOpacityWidget" name="mDefaultOpacityWidget" native="true">
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::StrongFocus</enum>
|
||||
<normaloff>:/images/themes/default/mActionFileSave.svg</normaloff>:/images/themes/default/mActionFileSave.svg</iconset>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
@ -272,6 +272,7 @@ void TestQgsProjectProperties::testColorSettings()
|
||||
#else
|
||||
QVERIFY( !pp->mRemoveIccProfile->isVisible() );
|
||||
QVERIFY( !pp->mAddIccProfile->isVisible() );
|
||||
QVERIFY( !pp->mSaveIccProfile->isVisible() );
|
||||
QVERIFY( !pp->mColorSpaceName->isVisible() );
|
||||
QVERIFY( !pp->mIccProfileLabel->isVisible() );
|
||||
#endif
|
||||
|
||||
@ -9,11 +9,18 @@ __author__ = 'Nyall Dawson'
|
||||
__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 @@ class TestQgsColorUtils(unittest.TestCase):
|
||||
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()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user