File indexing completed on 2024-05-12 15:58:22
0001 /* 0002 * SPDX-FileCopyrightText: 2010 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "kis_image_config.h" 0008 0009 #include <ksharedconfig.h> 0010 0011 #include <KoConfig.h> 0012 #include <KoColorProfile.h> 0013 #include <KoColorSpaceRegistry.h> 0014 #include <KoColorConversionTransformation.h> 0015 #include <kis_properties_configuration.h> 0016 0017 #include "kis_debug.h" 0018 0019 #include <QThread> 0020 #include <QApplication> 0021 #include <QColor> 0022 #include <QDir> 0023 0024 #include "kis_global.h" 0025 #include <cmath> 0026 #include <QTemporaryFile> 0027 0028 #ifdef Q_OS_MACOS 0029 #include <errno.h> 0030 #endif 0031 0032 KisImageConfig::KisImageConfig(bool readOnly) 0033 : m_config(KSharedConfig::openConfig()->group(QString())) 0034 , m_readOnly(readOnly) 0035 { 0036 if (!readOnly) { 0037 KIS_SAFE_ASSERT_RECOVER_RETURN(qApp->thread() == QThread::currentThread()); 0038 } 0039 #ifdef Q_OS_MACOS 0040 // clear /var/folders/ swap path set by old broken Krita swap implementation in order to use new default swap dir. 0041 QString swap = m_config.readEntry("swaplocation", ""); 0042 if (swap.startsWith("/var/folders/")) { 0043 m_config.deleteEntry("swaplocation"); 0044 } 0045 #endif 0046 } 0047 0048 KisImageConfig::~KisImageConfig() 0049 { 0050 if (m_readOnly) return; 0051 0052 if (qApp->thread() != QThread::currentThread()) { 0053 dbgKrita << "KisImageConfig: requested config synchronization from nonGUI thread! Called from" << kisBacktrace(); 0054 return; 0055 } 0056 0057 m_config.sync(); 0058 } 0059 0060 bool KisImageConfig::enableProgressReporting(bool requestDefault) const 0061 { 0062 return !requestDefault ? 0063 m_config.readEntry("enableProgressReporting", true) : true; 0064 } 0065 0066 void KisImageConfig::setEnableProgressReporting(bool value) 0067 { 0068 m_config.writeEntry("enableProgressReporting", value); 0069 } 0070 0071 bool KisImageConfig::enablePerfLog(bool requestDefault) const 0072 { 0073 return !requestDefault ? 0074 m_config.readEntry("enablePerfLog", false) :false; 0075 } 0076 0077 void KisImageConfig::setEnablePerfLog(bool value) 0078 { 0079 m_config.writeEntry("enablePerfLog", value); 0080 } 0081 0082 qreal KisImageConfig::transformMaskOffBoundsReadArea() const 0083 { 0084 return m_config.readEntry("transformMaskOffBoundsReadArea", 0.5); 0085 } 0086 0087 int KisImageConfig::updatePatchHeight() const 0088 { 0089 int patchHeight = m_config.readEntry("updatePatchHeight", 512); 0090 if (patchHeight <= 0) return 512; 0091 return patchHeight; 0092 } 0093 0094 void KisImageConfig::setUpdatePatchHeight(int value) 0095 { 0096 m_config.writeEntry("updatePatchHeight", value); 0097 } 0098 0099 int KisImageConfig::updatePatchWidth() const 0100 { 0101 int patchWidth = m_config.readEntry("updatePatchWidth", 512); 0102 if (patchWidth <= 0) return 512; 0103 return patchWidth; 0104 } 0105 0106 void KisImageConfig::setUpdatePatchWidth(int value) 0107 { 0108 m_config.writeEntry("updatePatchWidth", value); 0109 } 0110 0111 qreal KisImageConfig::maxCollectAlpha() const 0112 { 0113 return m_config.readEntry("maxCollectAlpha", 2.5); 0114 } 0115 0116 qreal KisImageConfig::maxMergeAlpha() const 0117 { 0118 return m_config.readEntry("maxMergeAlpha", 1.); 0119 } 0120 0121 qreal KisImageConfig::maxMergeCollectAlpha() const 0122 { 0123 return m_config.readEntry("maxMergeCollectAlpha", 1.5); 0124 } 0125 0126 qreal KisImageConfig::schedulerBalancingRatio() const 0127 { 0128 /** 0129 * updates-queue-size / strokes-queue-size 0130 */ 0131 return m_config.readEntry("schedulerBalancingRatio", 100.); 0132 } 0133 0134 void KisImageConfig::setSchedulerBalancingRatio(qreal value) 0135 { 0136 m_config.writeEntry("schedulerBalancingRatio", value); 0137 } 0138 0139 int KisImageConfig::maxSwapSize(bool requestDefault) const 0140 { 0141 return !requestDefault ? 0142 m_config.readEntry("maxSwapSize", 4096) : 4096; // in MiB 0143 } 0144 0145 void KisImageConfig::setMaxSwapSize(int value) 0146 { 0147 m_config.writeEntry("maxSwapSize", value); 0148 } 0149 0150 int KisImageConfig::swapSlabSize() const 0151 { 0152 return m_config.readEntry("swapSlabSize", 64); // in MiB 0153 } 0154 0155 void KisImageConfig::setSwapSlabSize(int value) 0156 { 0157 m_config.writeEntry("swapSlabSize", value); 0158 } 0159 0160 int KisImageConfig::swapWindowSize() const 0161 { 0162 return m_config.readEntry("swapWindowSize", 16); // in MiB 0163 } 0164 0165 void KisImageConfig::setSwapWindowSize(int value) 0166 { 0167 m_config.writeEntry("swapWindowSize", value); 0168 } 0169 0170 int KisImageConfig::tilesHardLimit() const 0171 { 0172 qreal hp = qreal(memoryHardLimitPercent()) / 100.0; 0173 qreal pp = qreal(memoryPoolLimitPercent()) / 100.0; 0174 0175 return totalRAM() * hp * (1 - pp); 0176 } 0177 0178 int KisImageConfig::tilesSoftLimit() const 0179 { 0180 qreal sp = qreal(memorySoftLimitPercent()) / 100.0; 0181 0182 return tilesHardLimit() * sp; 0183 } 0184 0185 int KisImageConfig::poolLimit() const 0186 { 0187 qreal hp = qreal(memoryHardLimitPercent()) / 100.0; 0188 qreal pp = qreal(memoryPoolLimitPercent()) / 100.0; 0189 0190 return totalRAM() * hp * pp; 0191 } 0192 0193 qreal KisImageConfig::memoryHardLimitPercent(bool requestDefault) const 0194 { 0195 return !requestDefault ? 0196 m_config.readEntry("memoryHardLimitPercent", 50.) : 50.; 0197 } 0198 0199 void KisImageConfig::setMemoryHardLimitPercent(qreal value) 0200 { 0201 m_config.writeEntry("memoryHardLimitPercent", value); 0202 } 0203 0204 qreal KisImageConfig::memorySoftLimitPercent(bool requestDefault) const 0205 { 0206 return !requestDefault ? 0207 m_config.readEntry("memorySoftLimitPercent", 2.) : 2.; 0208 } 0209 0210 void KisImageConfig::setMemorySoftLimitPercent(qreal value) 0211 { 0212 m_config.writeEntry("memorySoftLimitPercent", value); 0213 } 0214 0215 qreal KisImageConfig::memoryPoolLimitPercent(bool requestDefault) const 0216 { 0217 return !requestDefault ? 0218 m_config.readEntry("memoryPoolLimitPercent", 0.0) : 0.0; 0219 } 0220 0221 void KisImageConfig::setMemoryPoolLimitPercent(qreal value) 0222 { 0223 m_config.writeEntry("memoryPoolLimitPercent", value); 0224 } 0225 0226 QString KisImageConfig::safelyGetWritableTempLocation(const QString &suffix, const QString &configKey, bool requestDefault) const 0227 { 0228 #ifdef Q_OS_MACOS 0229 // On OSX, QDir::tempPath() gives us a folder we cannot reply upon (usually 0230 // something like /var/folders/.../...) and that will have vanished when we 0231 // try to create the tmp file in KisMemoryWindow::KisMemoryWindow using 0232 // swapFileTemplate. thus, we just pick the home folder if swapDir does not 0233 // tell us otherwise. 0234 0235 // the other option here would be to use a "garbled name" temp file (i.e. no name 0236 // KRITA_SWAP_FILE_XXXXXX) in an obscure /var/folders place, which is not 0237 // nice to the user. having a clearly named swap file in the home folder is 0238 // much nicer to Krita's users. 0239 0240 // furthermore, this is just a default and swapDir can always be configured 0241 // to another location. 0242 0243 QString swap = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + '/' + suffix; 0244 #else 0245 Q_UNUSED(suffix); 0246 QString swap = QDir::tempPath(); 0247 #endif 0248 if (requestDefault) { 0249 return swap; 0250 } 0251 const QString configuredSwap = m_config.readEntry(configKey, swap); 0252 if (!configuredSwap.isEmpty()) { 0253 swap = configuredSwap; 0254 } 0255 0256 QString chosenLocation; 0257 QStringList proposedSwapLocations; 0258 proposedSwapLocations << swap; 0259 proposedSwapLocations << QDir::tempPath(); 0260 proposedSwapLocations << QDir::homePath(); 0261 0262 Q_FOREACH (const QString location, proposedSwapLocations) { 0263 if (!QFileInfo(location).isWritable()) continue; 0264 0265 /** 0266 * On NTFS, isWritable() doesn't check for attributes due to performance 0267 * reasons, so we should try it in a brute-force way... 0268 * (yes, there is a hacky-global-variable workaround, but let's be safe) 0269 */ 0270 QTemporaryFile tempFile; 0271 tempFile.setFileTemplate(location + '/' + "krita_test_swap_location"); 0272 if (tempFile.open() && !tempFile.fileName().isEmpty()) { 0273 chosenLocation = location; 0274 break; 0275 } 0276 } 0277 0278 if (chosenLocation.isEmpty()) { 0279 qCritical() << "CRITICAL: no writable location for a swap file found! Tried the following paths:" << proposedSwapLocations; 0280 qCritical() << "CRITICAL: hope I don't crash..."; 0281 chosenLocation = swap; 0282 } 0283 0284 if (chosenLocation != swap) { 0285 qWarning() << "WARNING: configured swap location is not writable, using a fall-back location" << swap << "->" << chosenLocation; 0286 } 0287 0288 return chosenLocation; 0289 } 0290 0291 0292 QString KisImageConfig::swapDir(bool requestDefault) 0293 { 0294 return safelyGetWritableTempLocation("swap", "swaplocation", requestDefault); 0295 } 0296 0297 void KisImageConfig::setSwapDir(const QString &swapDir) 0298 { 0299 m_config.writeEntry("swaplocation", swapDir); 0300 } 0301 0302 int KisImageConfig::numberOfOnionSkins() const 0303 { 0304 return m_config.readEntry("numberOfOnionSkins", 10); 0305 } 0306 0307 void KisImageConfig::setNumberOfOnionSkins(int value) 0308 { 0309 m_config.writeEntry("numberOfOnionSkins", value); 0310 } 0311 0312 int KisImageConfig::onionSkinTintFactor() const 0313 { 0314 return m_config.readEntry("onionSkinTintFactor", 192); 0315 } 0316 0317 void KisImageConfig::setOnionSkinTintFactor(int value) 0318 { 0319 m_config.writeEntry("onionSkinTintFactor", value); 0320 } 0321 0322 int KisImageConfig::onionSkinOpacity(int offset) const 0323 { 0324 int value = m_config.readEntry("onionSkinOpacity_" + QString::number(offset), -1); 0325 0326 if (value < 0) { 0327 const int num = numberOfOnionSkins(); 0328 const qreal dx = qreal(qAbs(offset)) / num; 0329 value = 0.7 * exp(-pow2(dx) / 0.5) * 255; 0330 } 0331 0332 return value; 0333 } 0334 0335 void KisImageConfig::setOnionSkinOpacity(int offset, int value) 0336 { 0337 m_config.writeEntry("onionSkinOpacity_" + QString::number(offset), value); 0338 } 0339 0340 bool KisImageConfig::onionSkinState(int offset) const 0341 { 0342 bool enableByDefault = (qAbs(offset) <= 2); 0343 return m_config.readEntry("onionSkinState_" + QString::number(offset), enableByDefault); 0344 } 0345 0346 void KisImageConfig::setOnionSkinState(int offset, bool value) 0347 { 0348 m_config.writeEntry("onionSkinState_" + QString::number(offset), value); 0349 } 0350 0351 QColor KisImageConfig::onionSkinTintColorBackward() const 0352 { 0353 return m_config.readEntry("onionSkinTintColorBackward", QColor(Qt::red)); 0354 } 0355 0356 void KisImageConfig::setOnionSkinTintColorBackward(const QColor &value) 0357 { 0358 m_config.writeEntry("onionSkinTintColorBackward", value); 0359 } 0360 0361 QColor KisImageConfig::onionSkinTintColorForward() const 0362 { 0363 return m_config.readEntry("oninSkinTintColorForward", QColor(Qt::green)); 0364 } 0365 0366 void KisImageConfig::setOnionSkinTintColorForward(const QColor &value) 0367 { 0368 m_config.writeEntry("oninSkinTintColorForward", value); 0369 } 0370 0371 bool KisImageConfig::autoKeyEnabled(bool requestDefault) const 0372 { 0373 return !requestDefault ? 0374 m_config.readEntry("lazyFrameCreationEnabled", true) : true; 0375 } 0376 0377 void KisImageConfig::setAutoKeyEnabled(bool value) 0378 { 0379 m_config.writeEntry("lazyFrameCreationEnabled", value); 0380 } 0381 0382 bool KisImageConfig::autoKeyModeDuplicate(bool requestDefault) const 0383 { 0384 return !requestDefault ? 0385 m_config.readEntry("lazyFrameModeDuplicate", true) : true; 0386 } 0387 0388 void KisImageConfig::setAutoKeyModeDuplicate(bool value) 0389 { 0390 m_config.writeEntry("lazyFrameModeDuplicate", value); 0391 } 0392 0393 #if defined Q_OS_LINUX 0394 #include <sys/sysinfo.h> 0395 #elif defined Q_OS_FREEBSD || defined Q_OS_NETBSD || defined Q_OS_OPENBSD 0396 #include <sys/sysctl.h> 0397 #elif defined Q_OS_WIN 0398 #include <windows.h> 0399 #elif defined Q_OS_MACOS 0400 #include <sys/types.h> 0401 #include <sys/sysctl.h> 0402 #endif 0403 0404 int KisImageConfig::totalRAM() 0405 { 0406 // let's think that default memory size is 1000MiB 0407 int totalMemory = 1000; // MiB 0408 int error = 1; 0409 0410 #if defined Q_OS_LINUX 0411 struct sysinfo info; 0412 0413 error = sysinfo(&info); 0414 if(!error) { 0415 totalMemory = info.totalram * info.mem_unit / (1UL << 20); 0416 } 0417 #elif defined Q_OS_FREEBSD || defined Q_OS_NETBSD || defined Q_OS_OPENBSD 0418 u_long physmem; 0419 # if defined HW_PHYSMEM64 // NetBSD only 0420 int mib[] = {CTL_HW, HW_PHYSMEM64}; 0421 # else 0422 int mib[] = {CTL_HW, HW_PHYSMEM}; 0423 # endif 0424 size_t len = sizeof(physmem); 0425 0426 error = sysctl(mib, 2, &physmem, &len, 0, 0); 0427 if(!error) { 0428 totalMemory = physmem >> 20; 0429 } 0430 #elif defined Q_OS_WIN 0431 MEMORYSTATUSEX status; 0432 status.dwLength = sizeof(status); 0433 error = !GlobalMemoryStatusEx(&status); 0434 0435 if (!error) { 0436 totalMemory = status.ullTotalPhys >> 20; 0437 } 0438 0439 // For 32 bit windows, the total memory available is at max the 2GB per process memory limit. 0440 # if defined ENV32BIT 0441 totalMemory = qMin(totalMemory, 2000); 0442 # endif 0443 #elif defined Q_OS_MACOS 0444 int mib[2] = { CTL_HW, HW_MEMSIZE }; 0445 u_int namelen = sizeof(mib) / sizeof(mib[0]); 0446 uint64_t size; 0447 size_t len = sizeof(size); 0448 0449 errno = 0; 0450 if (sysctl(mib, namelen, &size, &len, 0, 0) >= 0) { 0451 totalMemory = size >> 20; 0452 error = 0; 0453 } 0454 else { 0455 dbgKrita << "sysctl(\"hw.memsize\") raised error" << strerror(errno); 0456 } 0457 #endif 0458 0459 if (error) { 0460 warnKrita << "Cannot get the size of your RAM. Using 1 GiB by default."; 0461 } 0462 0463 return totalMemory; 0464 } 0465 0466 bool KisImageConfig::showAdditionalOnionSkinsSettings(bool requestDefault) const 0467 { 0468 return !requestDefault ? 0469 m_config.readEntry("showAdditionalOnionSkinsSettings", true) : true; 0470 } 0471 0472 void KisImageConfig::setShowAdditionalOnionSkinsSettings(bool value) 0473 { 0474 m_config.writeEntry("showAdditionalOnionSkinsSettings", value); 0475 } 0476 0477 int KisImageConfig::defaultFrameColorLabel() const 0478 { 0479 return m_config.readEntry("defaultFrameColorLabel", 0); 0480 } 0481 0482 void KisImageConfig::setDefaultFrameColorLabel(int label) 0483 { 0484 m_config.writeEntry("defaultFrameColorLabel", label); 0485 } 0486 0487 KisProofingConfigurationSP KisImageConfig::defaultProofingconfiguration() 0488 { 0489 KisProofingConfiguration *proofingConfig= new KisProofingConfiguration(); 0490 proofingConfig->proofingProfile = m_config.readEntry("defaultProofingProfileName", "Chemical proof"); 0491 proofingConfig->proofingModel = m_config.readEntry("defaultProofingProfileModel", "CMYKA"); 0492 proofingConfig->proofingDepth = m_config.readEntry("defaultProofingProfileDepth", "U8"); 0493 proofingConfig->intent = (KoColorConversionTransformation::Intent)m_config.readEntry("defaultProofingProfileIntent", 3); 0494 if (m_config.readEntry("defaultProofingBlackpointCompensation", true)) { 0495 proofingConfig->conversionFlags |= KoColorConversionTransformation::ConversionFlag::BlackpointCompensation; 0496 } else { 0497 proofingConfig->conversionFlags = proofingConfig->conversionFlags & ~KoColorConversionTransformation::ConversionFlag::BlackpointCompensation; 0498 } 0499 QColor def(Qt::green); 0500 m_config.readEntry("defaultProofingGamutwarning", def); 0501 KoColor col(KoColorSpaceRegistry::instance()->rgb8()); 0502 col.fromQColor(def); 0503 col.setOpacity(1.0); 0504 proofingConfig->warningColor = col; 0505 proofingConfig->adaptationState = (double)m_config.readEntry("defaultProofingAdaptationState", 1.0); 0506 return toQShared(proofingConfig); 0507 } 0508 0509 void KisImageConfig::setDefaultProofingConfig(const KoColorSpace *proofingSpace, int proofingIntent, bool blackPointCompensation, KoColor warningColor, double adaptationState) 0510 { 0511 if (!proofingSpace || !proofingSpace->profile()) { 0512 return; 0513 } 0514 0515 m_config.writeEntry("defaultProofingProfileName", proofingSpace->profile()->name()); 0516 m_config.writeEntry("defaultProofingProfileModel", proofingSpace->colorModelId().id()); 0517 m_config.writeEntry("defaultProofingProfileDepth", proofingSpace->colorDepthId().id()); 0518 m_config.writeEntry("defaultProofingProfileIntent", proofingIntent); 0519 m_config.writeEntry("defaultProofingBlackpointCompensation", blackPointCompensation); 0520 QColor c; 0521 c = warningColor.toQColor(); 0522 m_config.writeEntry("defaultProofingGamutwarning", c); 0523 m_config.writeEntry("defaultProofingAdaptationState",adaptationState); 0524 } 0525 0526 bool KisImageConfig::useLodForColorizeMask(bool requestDefault) const 0527 { 0528 return !requestDefault ? 0529 m_config.readEntry("useLodForColorizeMask", false) : false; 0530 } 0531 0532 void KisImageConfig::setUseLodForColorizeMask(bool value) 0533 { 0534 m_config.writeEntry("useLodForColorizeMask", value); 0535 } 0536 0537 int KisImageConfig::maxNumberOfThreads(bool defaultValue) const 0538 { 0539 return (defaultValue ? QThread::idealThreadCount() : m_config.readEntry("maxNumberOfThreads", QThread::idealThreadCount())); 0540 } 0541 0542 void KisImageConfig::setMaxNumberOfThreads(int value) 0543 { 0544 if (value == QThread::idealThreadCount()) { 0545 m_config.deleteEntry("maxNumberOfThreads"); 0546 } else { 0547 m_config.writeEntry("maxNumberOfThreads", value); 0548 } 0549 } 0550 0551 int KisImageConfig::frameRenderingClones(bool defaultValue) const 0552 { 0553 const int defaultClonesCount = qMax(1, maxNumberOfThreads(defaultValue) / 2); 0554 return defaultValue ? defaultClonesCount : m_config.readEntry("frameRenderingClones", defaultClonesCount); 0555 } 0556 0557 void KisImageConfig::setFrameRenderingClones(int value) 0558 { 0559 m_config.writeEntry("frameRenderingClones", value); 0560 } 0561 0562 int KisImageConfig::frameRenderingTimeout(bool defaultValue) const 0563 { 0564 const int defaultFrameRenderingTimeout = 30000; // 30 ms 0565 return defaultValue ? defaultFrameRenderingTimeout : m_config.readEntry("frameRenderingTimeout", defaultFrameRenderingTimeout); 0566 } 0567 0568 void KisImageConfig::setFrameRenderingTimeout(int value) 0569 { 0570 m_config.writeEntry("frameRenderingTimeout", value); 0571 } 0572 0573 int KisImageConfig::fpsLimit(bool defaultValue) const 0574 { 0575 int limit = defaultValue ? 100 : m_config.readEntry("fpsLimit", 100); 0576 return limit > 0 ? limit : 1; 0577 } 0578 0579 void KisImageConfig::setFpsLimit(int value) 0580 { 0581 m_config.writeEntry("fpsLimit", value); 0582 } 0583 0584 bool KisImageConfig::useOnDiskAnimationCacheSwapping(bool defaultValue) const 0585 { 0586 return defaultValue ? true : m_config.readEntry("useOnDiskAnimationCacheSwapping", true); 0587 } 0588 0589 void KisImageConfig::setUseOnDiskAnimationCacheSwapping(bool value) 0590 { 0591 m_config.writeEntry("useOnDiskAnimationCacheSwapping", value); 0592 } 0593 0594 QString KisImageConfig::animationCacheDir(bool defaultValue) const 0595 { 0596 return safelyGetWritableTempLocation("animation_cache", "animationCacheDir", defaultValue); 0597 } 0598 0599 void KisImageConfig::setAnimationCacheDir(const QString &value) 0600 { 0601 m_config.writeEntry("animationCacheDir", value); 0602 } 0603 0604 bool KisImageConfig::useAnimationCacheFrameSizeLimit(bool defaultValue) const 0605 { 0606 return defaultValue ? true : m_config.readEntry("useAnimationCacheFrameSizeLimit", true); 0607 } 0608 0609 void KisImageConfig::setUseAnimationCacheFrameSizeLimit(bool value) 0610 { 0611 m_config.writeEntry("useAnimationCacheFrameSizeLimit", value); 0612 } 0613 0614 int KisImageConfig::animationCacheFrameSizeLimit(bool defaultValue) const 0615 { 0616 return defaultValue ? 2500 : m_config.readEntry("animationCacheFrameSizeLimit", 2500); 0617 } 0618 0619 void KisImageConfig::setAnimationCacheFrameSizeLimit(int value) 0620 { 0621 m_config.writeEntry("animationCacheFrameSizeLimit", value); 0622 } 0623 0624 bool KisImageConfig::useAnimationCacheRegionOfInterest(bool defaultValue) const 0625 { 0626 return defaultValue ? true : m_config.readEntry("useAnimationCacheRegionOfInterest", true); 0627 } 0628 0629 void KisImageConfig::setUseAnimationCacheRegionOfInterest(bool value) 0630 { 0631 m_config.writeEntry("useAnimationCacheRegionOfInterest", value); 0632 } 0633 0634 qreal KisImageConfig::animationCacheRegionOfInterestMargin(bool defaultValue) const 0635 { 0636 return defaultValue ? 0.25 : m_config.readEntry("animationCacheRegionOfInterestMargin", 0.25); 0637 } 0638 0639 void KisImageConfig::setAnimationCacheRegionOfInterestMargin(qreal value) 0640 { 0641 m_config.writeEntry("animationCacheRegionOfInterestMargin", value); 0642 } 0643 0644 QColor KisImageConfig::selectionOverlayMaskColor(bool defaultValue) const 0645 { 0646 QColor def(255, 0, 0, 128); 0647 return (defaultValue ? def : m_config.readEntry("selectionOverlayMaskColor", def)); 0648 } 0649 0650 void KisImageConfig::setSelectionOverlayMaskColor(const QColor &color) 0651 { 0652 m_config.writeEntry("selectionOverlayMaskColor", color); 0653 } 0654 0655 int KisImageConfig::maxBrushSize(bool defaultValue) const 0656 { 0657 return !defaultValue ? m_config.readEntry("maximumBrushSize", 1000) : 1000; 0658 } 0659 0660 void KisImageConfig::setMaxBrushSize(int value) 0661 { 0662 m_config.writeEntry("maximumBrushSize", value); 0663 } 0664 0665 int KisImageConfig::maxMaskingBrushSize() const 0666 { 0667 return qMin(15000, 3 * maxBrushSize()); 0668 } 0669 0670 QString KisImageConfig::exportConfigurationXML(const QString &exportConfigId, bool defaultValue) const 0671 { 0672 return (defaultValue ? QString() : m_config.readEntry("ExportConfiguration-" + exportConfigId, QString())); 0673 } 0674 0675 bool KisImageConfig::hasExportConfiguration(const QString &exportConfigID) 0676 { 0677 return m_config.hasKey("ExportConfiguration-" + exportConfigID); 0678 } 0679 0680 KisPropertiesConfigurationSP KisImageConfig::exportConfiguration(const QString &exportConfigId, bool defaultValue) const 0681 { 0682 KisPropertiesConfigurationSP cfg = new KisPropertiesConfiguration(); 0683 const QString xmlData = exportConfigurationXML(exportConfigId, defaultValue); 0684 cfg->fromXML(xmlData); 0685 return cfg; 0686 } 0687 0688 void KisImageConfig::setExportConfiguration(const QString &exportConfigId, KisPropertiesConfigurationSP properties) 0689 { 0690 const QString exportConfig = properties->toXML(); 0691 QString configId = "ExportConfiguration-" + exportConfigId; 0692 m_config.writeEntry(configId, exportConfig); 0693 } 0694 0695 void KisImageConfig::resetConfig() 0696 { 0697 KConfigGroup config = KSharedConfig::openConfig()->group(QString()); 0698 config.deleteGroup(); 0699 }