Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_dlg_preferences.cc
Go to the documentation of this file.
1/*
2 * preferencesdlg.cc - part of KImageShop
3 *
4 * SPDX-FileCopyrightText: 1999 Michael Koch <koch@kde.org>
5 * SPDX-FileCopyrightText: 2003-2011 Boudewijn Rempt <boud@valdyas.org>
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10#include "kis_dlg_preferences.h"
11
12#include <config-hdr.h>
13#include <opengl/kis_opengl.h>
14
15#include <QBitmap>
16#include <QCheckBox>
17#include <QComboBox>
18#include <QClipboard>
19#include <QCursor>
20#include <QScreen>
21#include <QFileDialog>
22#include <QFormLayout>
23#include <QGridLayout>
24#include <QGroupBox>
25#include <QLabel>
26#include <QLayout>
27#include <QLineEdit>
28#include <QMdiArea>
29#include <QMessageBox>
30#include <QPushButton>
31#include <QRadioButton>
32#include <QSettings>
33#include <QSlider>
34#include <QStandardPaths>
35#include <QThread>
36#include <QStyleFactory>
37#include <QScreen>
38#include <QFontComboBox>
39#include <QFont>
40#include <QSurfaceFormat>
41#include <QColorSpace>
42#include <QTextBrowser>
43
44#include <KisApplication.h>
45#include <KisDocument.h>
46#include <kis_icon.h>
47#include <KisPart.h>
50#include <KoColorProfile.h>
51#include <KoColorSpaceEngine.h>
52#include <KoConfigAuthorPage.h>
53#include <KoConfig.h>
54#include <KoPointerEvent.h>
55
56#include <KoFileDialog.h>
58#include "KoID.h"
59#include <KoVBox.h>
60
61#include <KTitleWidget>
62#include <KoResourcePaths.h>
63#include <kformat.h>
64#include <klocalizedstring.h>
65#include <kstandardguiitem.h>
66#include <kundo2stack.h>
67
68#include <KisResourceCacheDb.h>
69#include <KisResourceLocator.h>
70
74#include "kis_action_registry.h"
75#include <kis_image.h>
76#include <KisSqueezedComboBox.h>
78#include "kis_clipboard.h"
80#include "KoColorSpace.h"
83#include "kis_color_manager.h"
84#include "kis_config.h"
85#include "kis_image_config.h"
87#include "KisMainWindow.h"
88#include "KisMimeDatabase.h"
93#ifdef Q_OS_LINUX
94#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
96#include <KisColorimetryUtils.h>
97#endif
98#endif
99
101
102// for the performance update
103#include <kis_cubic_curve.h>
104#include <kis_signals_blocker.h>
105
108
110#include <config-qt-patches-present.h>
111
112#ifdef Q_OS_WIN
113#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
114// this include is Qt5-only, the switch to WinTab is embedded in Qt
115# include "config_qt5_has_wintab_switch.h"
116#else
117# include <QtGui/private/qguiapplication_p.h>
118# include <QtGui/qpa/qplatformintegration.h>
119#endif
120#include "config-high-dpi-scale-factor-rounding-policy.h"
122#endif
123
129Q_GUI_EXPORT int qt_defaultDpi();
130
131QString shortNameOfDisplay(int index)
132{
133 if (QGuiApplication::screens().length() <= index) {
134 return QString();
135 }
136 QScreen* screen = QGuiApplication::screens()[index];
137 QString resolution = QString::number(screen->geometry().width()).append("x").append(QString::number(screen->geometry().height()));
138 QString name = screen->name();
139 // name and resolution for a specific screen can change, so they are not used in the identifier; but they can help people understand which screen is which
140
141 KisConfig cfg(true);
142 QString shortName = resolution + " " + name + " " + cfg.getScreenStringIdentfier(index);
143 return shortName;
144}
145
146
147struct WritableLocationValidator : public QValidator {
149 : QValidator(parent)
150 {
151 }
152
153 State validate(QString &line, int &/*pos*/) const override
154 {
155 QFileInfo fi(line);
156 if (!fi.isWritable()) {
157 return Invalid;
158 }
159 return Acceptable;
160 }
161};
162
163struct BackupSuffixValidator : public QValidator {
164 BackupSuffixValidator(QObject *parent)
165 : QValidator(parent)
167 << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"
168 << "/" << "\\" << ":" << ";" << " ")
169 {}
170
172
174
175 State validate(QString &line, int &/*pos*/) const override
176 {
177 Q_FOREACH(const QString invalidChar, invalidCharacters) {
178 if (line.contains(invalidChar)) {
179 return Invalid;
180 }
181 }
182 return Acceptable;
183 }
184};
185
186/*
187 * We need this because the final item in the ComboBox is a used as an action to launch file selection dialog.
188 * So disabling it makes sure that user doesn't accidentally scroll and select it and get confused why the
189 * file picker launched.
190 */
191class UnscrollableComboBox : public QObject
192{
193public:
194 UnscrollableComboBox(QObject *parent)
195 : QObject(parent)
196 {
197 }
198
199 bool eventFilter(QObject *, QEvent *event) override
200 {
201 if (event->type() == QEvent::Wheel) {
202 event->accept();
203 return true;
204 }
205 return false;
206 }
207};
208
209GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
210 : WdgGeneralSettings(_parent, _name)
211{
212 KisConfig cfg(true);
213
214 // HACK ALERT!
215 // QScrollArea contents are opaque at multiple levels
216 // The contents themselves AND the viewport widget
217 {
218 scrollAreaWidgetContents->setAutoFillBackground(false);
219 scrollAreaWidgetContents->parentWidget()->setAutoFillBackground(false);
220 }
221
222 //
223 // Cursor Tab
224 //
225
226 QStringList cursorItems = QStringList()
227 << i18n("No Cursor")
228 << i18n("Tool Icon")
229 << i18n("Arrow")
230 << i18n("Small Circle")
231 << i18n("Crosshair")
232 << i18n("Triangle Righthanded")
233 << i18n("Triangle Lefthanded")
234 << i18n("Black Pixel")
235 << i18n("White Pixel");
236
237 QStringList outlineItems = QStringList()
238 << i18nc("Display options label to not DISPLAY brush outline", "No Outline")
239 << i18n("Circle Outline")
240 << i18n("Preview Outline")
241 << i18n("Tilt Outline");
242
243 // brush
244
245 m_cmbCursorShape->addItems(cursorItems);
246
247 m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());
248
249 m_cmbOutlineShape->addItems(outlineItems);
250
251 m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());
252
253 m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting());
254 m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline());
255
256 KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
257 cursorColor.fromQColor(cfg.getCursorMainColor());
258 cursorColorButton->setColor(cursorColor);
259
260 // eraser
261
262 m_chkSeparateEraserCursor->setChecked(cfg.separateEraserCursor());
263
264 m_cmbEraserCursorShape->addItems(cursorItems);
265 m_cmbEraserCursorShape->addItem(i18n("Eraser"));
266
267 m_cmbEraserCursorShape->setCurrentIndex(cfg.eraserCursorStyle());
268
269 m_cmbEraserOutlineShape->addItems(outlineItems);
270
271 m_cmbEraserOutlineShape->setCurrentIndex(cfg.eraserOutlineStyle());
272
273 m_showEraserOutlinePainting->setChecked(cfg.showEraserOutlineWhilePainting());
274 m_changeEraserBrushOutline->setChecked(!cfg.forceAlwaysFullSizedEraserOutline());
275
276 KoColor eraserCursorColor(KoColorSpaceRegistry::instance()->rgb8());
277 eraserCursorColor.fromQColor(cfg.getEraserCursorMainColor());
278 eraserCursorColorButton->setColor(eraserCursorColor);
279
280 // Color sampler
281
282 setColorSamplerPreviewStyleItems(m_cmbColorSamplerPreviewStyle);
283 setColorSamplerPreviewStyleIndexByValue(m_cmbColorSamplerPreviewStyle, cfg.colorSamplerPreviewStyle());
284 connect(m_cmbColorSamplerPreviewStyle,
285 QOverload<int>::of(&QComboBox::currentIndexChanged),
286 this,
288 colorSamplePreviewStyleChanged(m_cmbColorSamplerPreviewStyle->currentIndex());
289
290 m_nmbColorSamplerPreviewSize->setRange(1, 400);
291 m_nmbColorSamplerPreviewSize->setValue(cfg.colorSamplerPreviewCircleDiameter());
292 m_lblColorSamplerPreviewSizePreview->setDiameter(cfg.colorSamplerPreviewCircleDiameter());
293 connect(m_nmbColorSamplerPreviewSize,SIGNAL(valueChanged(int)), SLOT(colorSamplePreviewSizeChanged(int)));
294
295 m_ssbColorSamplerPreviewThickness->setRange(1, 50);
296 m_ssbColorSamplerPreviewThickness->setValue(cfg.colorSamplerPreviewCircleThickness());
297 m_lblColorSamplerPreviewSizePreview->setThickness(cfg.colorSamplerPreviewCircleThickness()/100.0);
298 connect(m_ssbColorSamplerPreviewThickness,SIGNAL(valueChanged(qreal)), SLOT(colorSamplePreviewThicknessChanged(qreal)));
299
300 m_chkColorSamplerPreviewOutlineEnabled->setChecked(cfg.colorSamplerPreviewCircleOutlineEnabled());
301 m_lblColorSamplerPreviewSizePreview->setOutlineEnabled(cfg.colorSamplerPreviewCircleOutlineEnabled());
302 connect(m_chkColorSamplerPreviewOutlineEnabled,SIGNAL(stateChanged(int)), SLOT(colorSamplePreviewOutlineEnabledChanged(int)));
303
304 m_chkColorSamplerPreviewExtraCircles->setChecked(cfg.colorSamplerPreviewCircleExtraCirclesEnabled());
305
306
307 KisSpinBoxI18nHelper::setText(m_ssbColorSamplerPreviewThickness, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
308
309
310
311
312
313
314
315
316 //
317 // Window Tab
318 //
319 chkUseCustomFont->setChecked(cfg.readEntry<bool>("use_custom_system_font", false));
320 cmbCustomFont->findChild <QComboBox*>("stylesComboBox")->setVisible(false);
321
322 QString fontName = cfg.readEntry<QString>("custom_system_font", "");
323 if (fontName.isEmpty()) {
324 cmbCustomFont->setCurrentFont(qApp->font());
325
326 }
327 else {
328 int pointSize = qApp->font().pointSize();
329 cmbCustomFont->setCurrentFont(QFont(fontName, pointSize));
330 }
331 int fontSize = cfg.readEntry<int>("custom_font_size", -1);
332 if (fontSize < 0) {
333 intFontSize->setValue(qApp->font().pointSize());
334 }
335 else {
336 intFontSize->setValue(fontSize);
337 }
338
339 m_cmbMDIType->setCurrentIndex(cfg.readEntry<int>("mdi_viewmode", (int)QMdiArea::TabbedView));
340 enableSubWindowOptions(m_cmbMDIType->currentIndex());
341 connect(m_cmbMDIType, SIGNAL(currentIndexChanged(int)), SLOT(enableSubWindowOptions(int)));
342
343 m_backgroundimage->setText(cfg.getMDIBackgroundImage());
344 connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
345 connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));
346
347 QString xml = cfg.getMDIBackgroundColor();
348 KoColor mdiColor = KoColor::fromXML(xml);
349 m_mdiColor->setColor(mdiColor);
350
351 m_chkRubberBand->setChecked(cfg.readEntry<int>("mdi_rubberband", cfg.useOpenGL()));
352
353 m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());
354
355 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
356 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
357 m_chkHiDPI->setChecked(kritarc.value("EnableHiDPI", true).toBool());
358#if defined(Q_OS_WIN) && defined(HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY)
359 m_chkHiDPIFractionalScaling->setChecked(kritarc.value("EnableHiDPIFractionalScaling", false).toBool());
360#else
361 m_wdgHiDPIFractionalScaling->setEnabled(false);
362#endif
363 chkUsageLogging->setChecked(kritarc.value("LogUsage", true).toBool());
364
365
366 //
367 // Tools tab
368 //
369 m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
370 cmbFlowMode->setCurrentIndex((int)!cfg.readEntry<bool>("useCreamyAlphaDarken", true));
371 cmbCmykBlendingMode->setCurrentIndex((int)!cfg.readEntry<bool>("useSubtractiveBlendingForCmykColorSpaces", true));
372 m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
373 cmbTouchPainting->addItem(
374 KoPointerEvent::tabletInputReceived() ? i18nc("touch painting", "Auto (Disabled)")
375 : i18nc("touch painting", "Auto (Enabled)"));
376 cmbTouchPainting->addItem(i18nc("touch painting", "Enabled"));
377 cmbTouchPainting->addItem(i18nc("touch painting", "Disabled"));
378 cmbTouchPainting->setCurrentIndex(int(cfg.touchPainting()));
379 chkTouchPressureSensitivity->setChecked(cfg.readEntry("useTouchPressureSensitivity", true));
380 connect(cmbTouchPainting, SIGNAL(currentIndexChanged(int)),
382 updateTouchPressureSensitivityEnabled(cmbTouchPainting->currentIndex());
383
384 chkEnableTransformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste());
385 chkZoomHorizontally->setChecked(cfg.zoomHorizontal());
386
387 chkEnableLongPress->setChecked(cfg.longPressEnabled());
388
389 m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled());
390
391 m_cmbKineticScrollingGesture->addItem(i18n("On Touch Drag"));
392 m_cmbKineticScrollingGesture->addItem(i18n("On Click Drag"));
393 m_cmbKineticScrollingGesture->addItem(i18n("On Middle-Click Drag"));
394 //m_cmbKineticScrollingGesture->addItem(i18n("On Right Click Drag"));
395
396 spnZoomSteps->setValue(cfg.zoomSteps());
397
398
399 m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture());
400 m_kineticScrollingSensitivitySlider->setRange(0, 100);
401 m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity());
402 m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars());
403
404 intZoomMarginSize->setValue(cfg.zoomMarginSize());
405
406 chkEnableSelectionActionBar->setChecked(cfg.selectionActionBar());
407
408 //
409 // File handling
410 //
411 int autosaveInterval = cfg.autoSaveInterval();
412 //convert to minutes
413 m_autosaveSpinBox->setValue(autosaveInterval / 60);
414 m_autosaveCheckBox->setChecked(autosaveInterval > 0);
415 chkHideAutosaveFiles->setChecked(cfg.readEntry<bool>("autosavefileshidden", true));
416
417 m_chkCompressKra->setChecked(cfg.compressKra());
418 chkZip64->setChecked(cfg.useZip64());
419 m_chkTrimKra->setChecked(cfg.trimKra());
420 m_chkTrimFramesImport->setChecked(cfg.trimFramesImport());
421
422 m_backupFileCheckBox->setChecked(cfg.backupFile());
423 cmbBackupFileLocation->setCurrentIndex(cfg.readEntry<int>("backupfilelocation", 0));
424 txtBackupFileSuffix->setText(cfg.readEntry<QString>("backupfilesuffix", "~"));
425 QValidator *validator = new BackupSuffixValidator(txtBackupFileSuffix);
426 txtBackupFileSuffix->setValidator(validator);
427 intNumBackupFiles->setValue(cfg.readEntry<int>("numberofbackupfiles", 1));
428
429 cmbDefaultExportFileType->clear();
431
432 QMap<QString, QString> mimeTypeMap;
433
434 foreach (const QString &mimeType, mimeFilter) {
435 QString description = KisMimeDatabase::descriptionForMimeType(mimeType);
436 mimeTypeMap.insert(description, mimeType);
437 }
438
439 // Sort after we get the description because mimeType values have image, application, etc... in front
440 QStringList sortedDescriptions = mimeTypeMap.keys();
441 sortedDescriptions.sort(Qt::CaseInsensitive);
442
443 cmbDefaultExportFileType->addItem(i18n("All Supported Files"), "all/mime");
444 foreach (const QString &description, sortedDescriptions) {
445 const QString &mimeType = mimeTypeMap.value(description);
446 cmbDefaultExportFileType->addItem(description, mimeType);
447 }
448
449 const QString mimeTypeToFind = cfg.exportMimeType(false).toUtf8();
450 const int index = cmbDefaultExportFileType->findData(mimeTypeToFind);
451
452 if (index >= 0) {
453 cmbDefaultExportFileType->setCurrentIndex(index);
454 } else {
455 // Index can't be found, default set to image/png
456 const QString defaultMimeType = "image/png";
457 const int defaultIndex = cmbDefaultExportFileType->findData(defaultMimeType);
458 if (defaultIndex >= 0) {
459 cmbDefaultExportFileType->setCurrentIndex(defaultIndex);
460 } else {
461 // Case where the default mime type is also not found in the combo box
462 qDebug() << "Default mime type not found in the combo box.";
463 }
464 }
465
466 QString selectedMimeType = cmbDefaultExportFileType->currentData().toString();
467
468 //
469 // Animation tab
470 //
471 m_chkAutoPin->setChecked(cfg.autoPinLayersToTimeline());
472 m_chkAdaptivePlaybackRange->setChecked(cfg.adaptivePlaybackRange());
473 m_chkAutoZoom->setChecked(cfg.autoZoomTimelineToPlaybackRange());
474
475 //
476 // Miscellaneous tab
477 //
478 cmbStartupSession->addItem(i18n("Open default window"));
479 cmbStartupSession->addItem(i18n("Load previous session"));
480 cmbStartupSession->addItem(i18n("Show session manager"));
481 cmbStartupSession->setCurrentIndex(cfg.sessionOnStartup());
482
483 chkSaveSessionOnQuit->setChecked(cfg.saveSessionOnQuit(false));
484
485 m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport());
486
487 m_undoStackSize->setValue(cfg.undoStackLimit());
488 chkCumulativeUndo->setChecked(cfg.useCumulativeUndoRedo());
489 connect(chkCumulativeUndo, SIGNAL(toggled(bool)), btnAdvancedCumulativeUndo, SLOT(setEnabled(bool)));
490 btnAdvancedCumulativeUndo->setEnabled(chkCumulativeUndo->isChecked());
491 connect(btnAdvancedCumulativeUndo, SIGNAL(clicked()), SLOT(showAdvancedCumulativeUndoSettings()));
493
494 chkShowRootLayer->setChecked(cfg.showRootLayer());
495
496 chkRenameMergedLayers->setChecked(KisImageConfig(true).renameMergedLayers());
497 chkRenamePastedLayers->setChecked(cfg.renamePastedLayers());
498 chkRenameDuplicatedLayers->setChecked(KisImageConfig(true).renameDuplicatedLayers());
499
500 KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
501 bool dontUseNative = true;
502#ifdef Q_OS_ANDROID
503 dontUseNative = false;
504#endif
505#ifdef Q_OS_UNIX
506 if (qgetenv("XDG_CURRENT_DESKTOP") == "KDE") {
507 dontUseNative = false;
508 }
509#endif
510#ifdef Q_OS_MACOS
511 dontUseNative = false;
512#endif
513#ifdef Q_OS_WIN
514 dontUseNative = false;
515#endif
516 m_chkNativeFileDialog->setChecked(!group.readEntry("DontUseNativeFileDialog", dontUseNative));
517
518 if (!qEnvironmentVariable("APPIMAGE").isEmpty()) {
519 // AppImages don't have access to platform plugins. BUG: 447805
520 // Setting the checkbox to false is
521 m_chkNativeFileDialog->setChecked(false);
522 m_chkNativeFileDialog->setEnabled(false);
523 }
524
525 intMaxBrushSize->setValue(KisImageConfig(true).maxBrushSize());
526 chkIgnoreHighFunctionKeys->setChecked(cfg.ignoreHighFunctionKeys());
527#ifndef Q_OS_WIN
528 // we properly support ignoring high F-keys on Windows only. To support on other platforms
529 // we should synchronize KisExtendedModifiersMatcher to ignore the keys as well.
530 chkIgnoreHighFunctionKeys->setVisible(false);
531#endif
532
533 //
534 // Resources
535 //
536 m_urlResourceFolder->setMode(KoFileDialog::OpenDirectory);
537 m_urlResourceFolder->setConfigurationName("resource_directory");
538 const QString resourceLocation = KoResourcePaths::getAppDataLocation();
539 if (QFileInfo(resourceLocation).isWritable()) {
540 m_urlResourceFolder->setFileName(resourceLocation);
541 }
542 else {
543 m_urlResourceFolder->setFileName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
544 }
545 QValidator *writableValidator = new WritableLocationValidator(m_urlResourceFolder);
546 txtBackupFileSuffix->setValidator(writableValidator);
547 connect(m_urlResourceFolder, SIGNAL(textChanged(QString)), SLOT(checkResourcePath()));
549
550 grpRestartMessage->setPixmap(
551 grpRestartMessage->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
552 grpRestartMessage->setText(i18n("You will need to Restart Krita for the changes to take an effect."));
553
554 grpAndroidWarningMessage->setVisible(false);
555 grpAndroidWarningMessage->setPixmap(
556 grpAndroidWarningMessage->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
557 grpAndroidWarningMessage->setText(
558 i18n("Saving at a Location picked from the File Picker may slow down the startup!"));
559
560#ifdef Q_OS_ANDROID
561 m_urlResourceFolder->setVisible(false);
562
563 m_resourceFolderSelector->setVisible(true);
564 m_resourceFolderSelector->installEventFilter(new UnscrollableComboBox(this));
565
566 const QList<QPair<QString, QString>> writableLocations = []() {
567 QList<QPair<QString, QString>> writableLocationsAndText;
568 // filters out the duplicates
569 const QList<QString> locations = []() {
570 QStringList filteredLocations;
571 const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
572 Q_FOREACH(const QString &location, locations) {
573 if (!filteredLocations.contains(location)) {
574 filteredLocations.append(location);
575 }
576 }
577 return filteredLocations;
578 }();
579
580 bool isFirst = true;
581
582 Q_FOREACH (QString location, locations) {
583 QString text;
584 QFileInfo fileLocation(location);
585 // The first one that we get from is the "Default"
586 if (isFirst) {
587 text = i18n("Default");
588 isFirst = false;
589 } else if (location.startsWith("/data")) {
590 text = i18n("Internal Storage");
591 } else {
592 text = i18n("SD-Card");
593 }
594 if (fileLocation.isWritable()) {
595 writableLocationsAndText.append({text, location});
596 }
597 }
598 return writableLocationsAndText;
599 }();
600
601 for (auto it = writableLocations.constBegin(); it != writableLocations.constEnd(); ++it) {
602 m_resourceFolderSelector->addItem(it->first + " - " + it->second);
603 // we need it to extract out the path
604 m_resourceFolderSelector->setItemData(m_resourceFolderSelector->count() - 1, it->second, Qt::UserRole);
605 }
606
607 // if the user has selected a custom location, we add it to the list as well.
608 if (resourceLocation.startsWith("content://")) {
609 m_resourceFolderSelector->addItem(resourceLocation);
610 int index = m_resourceFolderSelector->count() - 1;
611 m_resourceFolderSelector->setItemData(index, resourceLocation, Qt::UserRole);
612 m_resourceFolderSelector->setCurrentIndex(index);
613 grpAndroidWarningMessage->setVisible(true);
614 } else {
615 // find the index of the current resource location in the writableLocation, so we can set our view to that
616 auto iterator = std::find_if(writableLocations.constBegin(),
617 writableLocations.constEnd(),
618 [&resourceLocation](QPair<QString, QString> location) {
619 return location.second == resourceLocation;
620 });
621
622 if (iterator != writableLocations.constEnd()) {
623 int index = writableLocations.indexOf(*iterator);
624 KIS_SAFE_ASSERT_RECOVER_NOOP(index < m_resourceFolderSelector->count());
625 m_resourceFolderSelector->setCurrentIndex(index);
626 }
627 }
628
629 // this should be the last item we add.
630 m_resourceFolderSelector->addItem(i18n("Choose Manually"));
631
632 connect(m_resourceFolderSelector, qOverload<int>(&QComboBox::activated), [this](int index) {
633 const int previousIndex = m_resourceFolderSelector->currentIndex();
634
635 // if it is the last item in the last item, then open file picker and set the name returned as the filename
636 if (m_resourceFolderSelector->count() - 1 == index) {
637 KoFileDialog dialog(this, KoFileDialog::OpenDirectory, "Select Directory");
638 const QString selectedDirectory = dialog.filename();
639
640 if (!selectedDirectory.isEmpty()) {
641 // if the index above "Choose Manually" is a content Uri, then we just modify it, and then set that as
642 // the index.
643 if (m_resourceFolderSelector->itemData(index - 1, Qt::DisplayRole)
644 .value<QString>()
645 .startsWith("content://")) {
646 m_resourceFolderSelector->setItemText(index - 1, selectedDirectory);
647 m_resourceFolderSelector->setItemData(index - 1, selectedDirectory, Qt::UserRole);
648 m_resourceFolderSelector->setCurrentIndex(index - 1);
649 } else {
650 // There isn't any content Uri in the ComboBox list, so just insert one, and set that as the index.
651 m_resourceFolderSelector->insertItem(index, selectedDirectory);
652 m_resourceFolderSelector->setItemData(index, selectedDirectory, Qt::UserRole);
653 m_resourceFolderSelector->setCurrentIndex(index);
654 }
655 // since we have selected the custom location, make the warning visible.
656 grpAndroidWarningMessage->setVisible(true);
657 } else {
658 m_resourceFolderSelector->setCurrentIndex(previousIndex);
659 }
660 }
661
662 // hide-unhide based on the selection of user.
663 grpAndroidWarningMessage->setVisible(
664 m_resourceFolderSelector->currentData(Qt::UserRole).value<QString>().startsWith("content://"));
665 });
666
667#else
668 m_resourceFolderSelector->setVisible(false);
669#endif
670
671 grpWindowsAppData->setVisible(false);
672#ifdef Q_OS_WIN
673 QString folderInStandardAppData;
674 QString folderInPrivateAppData;
675 KoResourcePaths::getAllUserResourceFoldersLocationsForWindowsStore(folderInStandardAppData, folderInPrivateAppData);
676
677 if (!folderInPrivateAppData.isEmpty()) {
678 const auto pathToDisplay = [](const QString &path) {
679 // Due to how Unicode word wrapping works, the string does not
680 // wrap after backslashes in Qt 5.12. We don't want the path to
681 // become too long, so we add a U+200B ZERO WIDTH SPACE to allow
682 // wrapping. The downside is that we cannot let the user select
683 // and copy the path because it now contains invisible unicode
684 // code points.
685 // See: https://bugreports.qt.io/browse/QTBUG-80892
686 return QDir::toNativeSeparators(path).replace(QChar('\\'), QStringLiteral(u"\\\u200B"));
687 };
688
689 const QDir privateResourceDir(folderInPrivateAppData);
690 const QDir appDataDir(folderInStandardAppData);
691 grpWindowsAppData->setPixmap(
692 grpWindowsAppData->style()->standardIcon(QStyle::SP_MessageBoxInformation).pixmap(QSize(32, 32)));
693 // Similar text is also used in KisViewManager.cpp
694 grpWindowsAppData->setText(i18nc("@info resource folder",
695 "<p>You are using the Microsoft Store package version of Krita. "
696 "Even though Krita can be configured to place resources under the "
697 "user AppData location, Windows may actually store the files "
698 "inside a private app location.</p>\n"
699 "<p>You should check both locations to determine where "
700 "the files are located.</p>\n"
701 "<p><b>User AppData</b> (<a href=\"copyuser\">Copy</a>):<br/>\n"
702 "%1</p>\n"
703 "<p><b>Private app location</b> (<a href=\"copyprivate\">Copy</a>):<br/>\n"
704 "%2</p>",
705 pathToDisplay(appDataDir.absolutePath()),
706 pathToDisplay(privateResourceDir.absolutePath())));
707 grpWindowsAppData->setVisible(true);
708
709 connect(grpWindowsAppData,
711 [userPath = appDataDir.absolutePath(),
712 privatePath = privateResourceDir.absolutePath()](const QString &link) {
713 if (link == QStringLiteral("copyuser")) {
714 qApp->clipboard()->setText(QDir::toNativeSeparators(userPath));
715 } else if (link == QStringLiteral("copyprivate")) {
716 qApp->clipboard()->setText(QDir::toNativeSeparators(privatePath));
717 } else {
718 qWarning() << "Unexpected link activated in lblWindowsAppDataNote:" << link;
719 }
720 });
721 }
722#endif
723
724
725 const int forcedFontDPI = cfg.readEntry("forcedDpiForQtFontBugWorkaround", -1);
726 chkForcedFontDPI->setChecked(forcedFontDPI > 0);
727 intForcedFontDPI->setValue(forcedFontDPI > 0 ? forcedFontDPI : qt_defaultDpi());
728 intForcedFontDPI->setEnabled(forcedFontDPI > 0);
729 connect(chkForcedFontDPI, SIGNAL(toggled(bool)), intForcedFontDPI, SLOT(setEnabled(bool)));
730
731 m_pasteFormatGroup.addButton(btnDownload, KisClipboard::PASTE_FORMAT_DOWNLOAD);
732 m_pasteFormatGroup.addButton(btnLocal, KisClipboard::PASTE_FORMAT_LOCAL);
733 m_pasteFormatGroup.addButton(btnBitmap, KisClipboard::PASTE_FORMAT_CLIP);
734 m_pasteFormatGroup.addButton(btnAsk, KisClipboard::PASTE_FORMAT_ASK);
735
736 QAbstractButton *button = m_pasteFormatGroup.button(cfg.pasteFormat(false));
737
738 Q_ASSERT(button);
739
740 if (button) {
741 button->setChecked(true);
742 }
743}
744
746{
747 KisConfig cfg(true);
748
749 m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle(true));
750 m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle(true));
751 m_chkSeparateEraserCursor->setChecked(cfg.readEntry<bool>("separateEraserCursor", false));
752 m_cmbEraserCursorShape->setCurrentIndex(cfg.eraserCursorStyle(true));
753 m_cmbEraserOutlineShape->setCurrentIndex(cfg.eraserOutlineStyle(true));
754 setColorSamplerPreviewStyleIndexByValue(m_cmbColorSamplerPreviewStyle, cfg.colorSamplerPreviewStyle(true));
755 m_ssbColorSamplerPreviewThickness->setValue(cfg.colorSamplerPreviewCircleThickness(true));
756 m_nmbColorSamplerPreviewSize->setValue(cfg.colorSamplerPreviewCircleDiameter(true));
757 m_chkColorSamplerPreviewOutlineEnabled->setChecked(cfg.colorSamplerPreviewCircleOutlineEnabled(true));
758
759
760 chkShowRootLayer->setChecked(cfg.showRootLayer(true));
761 m_autosaveCheckBox->setChecked(cfg.autoSaveInterval(true) > 0);
762 //convert to minutes
763 m_autosaveSpinBox->setValue(cfg.autoSaveInterval(true) / 60);
764 chkHideAutosaveFiles->setChecked(true);
765
766 m_undoStackSize->setValue(cfg.undoStackLimit(true));
767 chkCumulativeUndo->setChecked(cfg.useCumulativeUndoRedo(true));
769
770 m_backupFileCheckBox->setChecked(cfg.backupFile(true));
771 cmbBackupFileLocation->setCurrentIndex(0);
772 txtBackupFileSuffix->setText("~");
773 intNumBackupFiles->setValue(1);
774
775 m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true));
776 m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline(true));
777 m_showEraserOutlinePainting->setChecked(cfg.showEraserOutlineWhilePainting(true));
778 m_changeEraserBrushOutline->setChecked(!cfg.forceAlwaysFullSizedEraserOutline(true));
779
780#if defined Q_OS_ANDROID || defined Q_OS_MACOS || defined Q_OS_WIN
781 m_chkNativeFileDialog->setChecked(true);
782#else
783 m_chkNativeFileDialog->setChecked(false);
784#endif
785
786 intMaxBrushSize->setValue(1000);
787
788 chkIgnoreHighFunctionKeys->setChecked(cfg.ignoreHighFunctionKeys(true));
789
790
791 chkUseCustomFont->setChecked(false);
792 cmbCustomFont->setCurrentFont(qApp->font());
793 intFontSize->setValue(qApp->font().pointSize());
794
795
796 m_cmbMDIType->setCurrentIndex((int)QMdiArea::TabbedView);
797 m_chkRubberBand->setChecked(cfg.useOpenGL(true));
798 KoColor mdiColor;
799 mdiColor.fromXML(cfg.getMDIBackgroundColor(true));
800 m_mdiColor->setColor(mdiColor);
801 m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
802 m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
803 m_chkCompressKra->setChecked(cfg.compressKra(true));
804 m_chkTrimKra->setChecked(cfg.trimKra(true));
805 m_chkTrimFramesImport->setChecked(cfg.trimFramesImport(true));
806 chkZip64->setChecked(cfg.useZip64(true));
807 m_chkHiDPI->setChecked(true);
808#if defined(Q_OS_WIN) && defined(HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY)
809 m_chkHiDPIFractionalScaling->setChecked(true);
810#endif
811 chkUsageLogging->setChecked(true);
812 m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
813 cmbFlowMode->setCurrentIndex(0);
814 chkEnableLongPress->setChecked(cfg.longPressEnabled(true));
815 m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled(true));
816 m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true));
817 spnZoomSteps->setValue(cfg.zoomSteps(true));
818 m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity(true));
819 m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars(true));
820 intZoomMarginSize->setValue(cfg.zoomMarginSize(true));
821 m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
822 cmbTouchPainting->setCurrentIndex(int(cfg.touchPainting(true)));
823 chkTouchPressureSensitivity->setChecked(true);
824 chkEnableTransformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste(true));
825 chkZoomHorizontally->setChecked(cfg.zoomHorizontal(true));
826 m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true));
827
828 KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
829 cursorColor.fromQColor(cfg.getCursorMainColor(true));
830 cursorColorButton->setColor(cursorColor);
831
832 KoColor eraserCursorColor(KoColorSpaceRegistry::instance()->rgb8());
833 eraserCursorColor.fromQColor(cfg.getEraserCursorMainColor(true));
834 eraserCursorColorButton->setColor(eraserCursorColor);
835
836
837 m_chkAutoPin->setChecked(cfg.autoPinLayersToTimeline(true));
838 m_chkAdaptivePlaybackRange->setChecked(cfg.adaptivePlaybackRange(false));
839
840 m_urlResourceFolder->setFileName(KoResourcePaths::getAppDataLocation());
841
842 chkForcedFontDPI->setChecked(false);
843 intForcedFontDPI->setValue(qt_defaultDpi());
844 intForcedFontDPI->setEnabled(false);
845
846 chkRenameMergedLayers->setChecked(KisImageConfig(true).renameMergedLayers(true));
847 chkRenamePastedLayers->setChecked(cfg.renamePastedLayers(true));
848 chkRenameDuplicatedLayers->setChecked(KisImageConfig(true).renameDuplicatedLayers(true));
849
850 QAbstractButton *button = m_pasteFormatGroup.button(cfg.pasteFormat(true));
851 Q_ASSERT(button);
852
853 if (button) {
854 button->setChecked(true);
855 }
856}
857
859{
860 KisDlgConfigureCumulativeUndo dlg(m_cumulativeUndoData, m_undoStackSize->value(), this);
861 if (dlg.exec() == KoDialog::Accepted) {
863 }
864}
865
867{
868 bool circleSettingsVisible = index == int(KisConfig::ColorSamplerPreviewStyle::Circle);
869 m_frmColorSamplerCircleSettings->setVisible(circleSettingsVisible);
870}
871
873{
874 m_lblColorSamplerPreviewSizePreview->setDiameter(value);
875}
876
878{
879 m_lblColorSamplerPreviewSizePreview->setThickness(value/100.0);
880}
881
883{
884 m_lblColorSamplerPreviewSizePreview->setOutlineEnabled(value);
885}
886
888{
889 return (CursorStyle)m_cmbCursorShape->currentIndex();
890}
891
893{
894 return (OutlineStyle)m_cmbOutlineShape->currentIndex();
895}
896
898{
899 return (CursorStyle)m_cmbEraserCursorShape->currentIndex();
900}
901
903{
904 return (OutlineStyle)m_cmbEraserOutlineShape->currentIndex();
905}
906
911
913{
914 return m_nmbColorSamplerPreviewSize->value();
915}
916
918{
919 return m_ssbColorSamplerPreviewThickness->value();
920}
921
923{
924 return m_chkColorSamplerPreviewOutlineEnabled->isChecked();
925}
926
928{
929 return m_chkColorSamplerPreviewExtraCircles->isChecked();
930}
931
932
934{
935 return (KisConfig::SessionOnStartup)cmbStartupSession->currentIndex();
936}
937
939{
940 return chkSaveSessionOnQuit->isChecked();
941}
942
944{
945 return chkShowRootLayer->isChecked();
946}
947
949{
950 //convert to seconds
951 return m_autosaveCheckBox->isChecked() ? m_autosaveSpinBox->value() * 60 : 0;
952}
953
955{
956 return m_undoStackSize->value();
957}
958
960{
961 return m_showOutlinePainting->isChecked();
962}
963
965{
966 return m_showEraserOutlinePainting->isChecked();
967}
968
970{
971 return m_cmbMDIType->currentIndex();
972}
973
975{
976 return m_chkCanvasMessages->isChecked();
977}
978
980{
981 return m_chkCompressKra->isChecked();
982}
983
985{
986 return m_chkTrimKra->isChecked();
987}
988
990{
991 return m_chkTrimFramesImport->isChecked();
992}
993
995{
996 return cmbDefaultExportFileType->currentData().toString();
997}
998
1000{
1001 return chkZip64->isChecked();
1002}
1003
1005{
1006 return m_radioToolOptionsInDocker->isChecked();
1007}
1008
1010{
1011 return spnZoomSteps->value();
1012}
1013
1015{
1016 return chkEnableLongPress->isChecked();
1017}
1018
1020{
1021 return m_groupBoxKineticScrollingSettings->isChecked();
1022}
1023
1025{
1026 return m_cmbKineticScrollingGesture->currentIndex();
1027}
1028
1030{
1031 return m_kineticScrollingSensitivitySlider->value();
1032}
1033
1035{
1036 return m_chkKineticScrollingHideScrollbars->isChecked();
1037}
1038
1040{
1041 return intZoomMarginSize->value();
1042}
1043
1045{
1046 return m_chkSwitchSelectionCtrlAlt->isChecked();
1047}
1048
1050{
1051 return m_chkConvertOnImport->isChecked();
1052}
1053
1055{
1056 return m_chkAutoPin->isChecked();
1057}
1058
1060{
1061 return m_chkAdaptivePlaybackRange->isChecked();
1062}
1063
1065{
1066 return m_chkAutoZoom->isChecked();
1067}
1068
1070{
1071 return chkForcedFontDPI->isChecked() ? intForcedFontDPI->value() : -1;
1072}
1073
1075{
1076 // Order is synchronized with KisConfig::ColorSamplerPreviewStyle.
1077 cmb->addItems({
1078 i18nc("Preview option for no color sampler", "None"),
1079 i18nc("Preview option for a circular/ring-shaped color sampler", "Circle"),
1080 i18nc("Preview option for a rectangular color sampler left of the cursor", "Rectangle Left"),
1081 i18nc("Preview option for a rectangular color sampler right of the cursor", "Rectangle Right"),
1082 i18nc("Preview option for a rectangular color sampler above the cursor", "Rectangle Above"),
1083 });
1084}
1085
1087{
1088 cmb->setCurrentIndex(int(style));
1089}
1090
1095
1097{
1098 return chkRenameMergedLayers->isChecked();
1099}
1100
1102{
1103 return chkRenamePastedLayers->isChecked();
1104}
1105
1107{
1108 return chkRenameDuplicatedLayers->isChecked();
1109}
1110
1112{
1113 KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
1114 dialog.setCaption(i18n("Select a Background Image"));
1115 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
1116 dialog.setImageFilters();
1117
1118 QString fn = dialog.filename();
1119 // dialog box was canceled or somehow no file was selected
1120 if (fn.isEmpty()) {
1121 return;
1122 }
1123
1124 QImage image(fn);
1125 if (image.isNull()) {
1126 QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("%1 is not a valid image file!", fn));
1127 }
1128 else {
1129 m_backgroundimage->setText(fn);
1130 }
1131}
1132
1134{
1135 // clearing the background image text will implicitly make the background color be used
1136 m_backgroundimage->setText("");
1137}
1138
1140{
1141 const QFileInfo fi(m_urlResourceFolder->fileName());
1142 if (!fi.isWritable()) {
1143 grpNonWritableLocation->setPixmap(
1144 grpNonWritableLocation->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
1145 grpNonWritableLocation->setText(
1146 i18nc("@info resource folder", "<b>Warning:</b> this location is not writable."));
1147 grpNonWritableLocation->setVisible(true);
1148 } else {
1149 grpNonWritableLocation->setVisible(false);
1150 }
1151}
1152
1154{
1155 group_subWinMode->setEnabled(mdi_mode == QMdiArea::SubWindowView);
1156}
1157
1159{
1160 chkTouchPressureSensitivity->setEnabled(touchPainting != int(KisConfig::TOUCH_PAINTING_DISABLED));
1161}
1162
1163
1164#include "kactioncollection.h"
1165#include "KisActionsSnapshot.h"
1166
1167ShortcutSettingsTab::ShortcutSettingsTab(QWidget *parent, const char *name)
1168 : QWidget(parent)
1169{
1170 setObjectName(name);
1171
1172 QGridLayout * l = new QGridLayout(this);
1173 l->setContentsMargins(0, 0, 0, 0);
1174 m_page = new WdgShortcutSettings(this);
1175 l->addWidget(m_page, 0, 0);
1176
1177
1178 m_snapshot.reset(new KisActionsSnapshot);
1179
1180 KisKActionCollection *collection =
1182
1183 Q_FOREACH (QAction *action, collection->actions()) {
1184 m_snapshot->addAction(action->objectName(), action);
1185 }
1186
1187 QMap<QString, KisKActionCollection*> sortedCollections =
1188 m_snapshot->actionCollections();
1189
1190 for (auto it = sortedCollections.constBegin(); it != sortedCollections.constEnd(); ++it) {
1191 m_page->addCollection(it.value(), it.key());
1192 }
1193}
1194
1198
1203
1209
1214
1215ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
1216 : QWidget(parent)
1217 , m_proofModel(new KisProofingConfigModel())
1218{
1219 setObjectName(name);
1220
1221 // XXX: Make sure only profiles that fit the specified color model
1222 // are shown in the profile combos
1223
1224 QGridLayout * l = new QGridLayout(this);
1225 l->setContentsMargins(0, 0, 0, 0);
1226 m_page = new WdgColorSettings(this);
1227 l->addWidget(m_page, 0, 0);
1228
1229 KisConfig cfg(true);
1230
1232
1233 if (!m_colorManagedByOS) {
1234 m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile());
1235 connect(m_page->chkUseSystemMonitorProfile, SIGNAL(toggled(bool)), this, SLOT(toggleAllowMonitorProfileSelection(bool)));
1236 }
1237 m_page->chkUseSystemMonitorProfile->setVisible(!m_colorManagedByOS);
1238
1239 m_page->useDefColorSpace->setChecked(cfg.useDefaultColorSpace());
1240 connect(m_page->useDefColorSpace, SIGNAL(toggled(bool)), this, SLOT(toggleUseDefaultColorSpace(bool)));
1242 for (QList<KoID>::iterator id = colorSpaces.begin(); id != colorSpaces.end(); /* nop */) {
1244 id = colorSpaces.erase(id);
1245 } else {
1246 ++id;
1247 }
1248 }
1249 m_page->cmbWorkingColorSpace->setIDList(colorSpaces);
1250 m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
1251 m_page->cmbWorkingColorSpace->setEnabled(cfg.useDefaultColorSpace());
1252
1253 if (!m_colorManagedByOS) {
1254 m_page->bnAddColorProfile->setIcon(koIcon("document-import-16"));
1255 connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));
1256 }
1257 m_page->bnAddColorProfile->setVisible(!m_colorManagedByOS);
1258
1259 {
1260 QStringList profiles;
1261 QMap<QString, const KoColorProfile *> profileList;
1262 Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(RGBAColorModelID.id())) {
1263 profileList[profile->name()] = profile;
1264 profiles.append(profile->name());
1265 }
1266
1267 std::sort(profiles.begin(), profiles.end());
1268 Q_FOREACH (const QString profile, profiles) {
1269 m_page->cmbColorProfileForEXR->addSqueezedItem(profile);
1270 }
1271
1273 const QString defaultProfile = KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId);
1274 const QString userProfile = cfg.readEntry("ExrDefaultColorProfile", defaultProfile);
1275
1276 m_page->cmbColorProfileForEXR->setCurrent(profiles.contains(userProfile) ? userProfile : defaultProfile);
1277 }
1278
1279
1280 if (!m_colorManagedByOS) {
1281 QFormLayout *monitorProfileGrid = new QFormLayout(m_page->monitorprofileholder);
1282 monitorProfileGrid->setContentsMargins(0, 0, 0, 0);
1283 for(int i = 0; i < QGuiApplication::screens().count(); ++i) {
1284 QLabel *lbl = new QLabel(i18nc("The number of the screen (ordinal) and shortened 'name' of the screen (model + resolution)", "Screen %1 (%2):", i + 1, shortNameOfDisplay(i)));
1285 lbl->setWordWrap(true);
1288 cmb->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1289 monitorProfileGrid->addRow(lbl, cmb);
1291 }
1292
1293 // disable if not Linux as KisColorManager is not yet implemented outside Linux
1294#ifndef Q_OS_LINUX
1295 m_page->chkUseSystemMonitorProfile->setChecked(false);
1296 m_page->chkUseSystemMonitorProfile->setDisabled(true);
1297 m_page->chkUseSystemMonitorProfile->setHidden(true);
1298#endif
1299
1300 refillMonitorProfiles(KoID("RGBA"));
1301
1302 for(int i = 0; i < QApplication::screens().count(); ++i) {
1303 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1304 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1305 }
1306 }
1307 } else {
1308 QVBoxLayout *vboxLayout = new QVBoxLayout(m_page->monitorprofileholder);
1309 vboxLayout->setContentsMargins(0, 0, 0, 0);
1310 vboxLayout->addItem(new QSpacerItem(20,20));
1311
1312 QGroupBox *groupBox = new QGroupBox(i18n("Display's color space is managed by the operating system"));
1313 vboxLayout->addWidget(groupBox);
1314
1315 QFormLayout *monitorProfileGrid = new QFormLayout(groupBox);
1316 monitorProfileGrid->setContentsMargins(0, 0, 0, 0);
1317
1319 new QCheckBox(i18n("Enable canvas color management"), this);
1320
1322 i18n("<p>Enabling canvas color management automatically creates "
1323 "a separate native surface for the canvas. It might cause "
1324 "performance issues on some systems.</p>"
1325 ""
1326 "<p>If color management is disabled, Krita will render "
1327 "the canvas into the surface of the main window, which "
1328 "is considered sRGB. It will cause two limitations:"
1329 ""
1330 "<ol>"
1331 " <li>the color gamut will be limited to sRGB</li>"
1332 " <li>color proofing mode will be limited to \"use global display settings\", "
1333 " i.e. paper white proofing will become impossible</li>"
1334 "</ol>"
1335 "</p>"));
1336
1337 monitorProfileGrid->addRow(m_chkEnableCanvasColorSpaceManagement);
1338
1339 // surface color space
1341 m_canvasSurfaceColorSpace->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1342 QLabel *canvasSurfaceColorSpaceLbl = new QLabel(i18n("Canvas surface color space:"), this);
1343 monitorProfileGrid->addRow(canvasSurfaceColorSpaceLbl, m_canvasSurfaceColorSpace);
1344
1345 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Preferred by operating system"), QVariant::fromValue(CanvasSurfaceMode::Preferred));
1346 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Rec 709 Gamma 2.2"), QVariant::fromValue(CanvasSurfaceMode::Rec709g22));
1347 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Rec 709 Linear"), QVariant::fromValue(CanvasSurfaceMode::Rec709g10));
1348 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Rec 2020 PQ"), QVariant::fromValue(CanvasSurfaceMode::Rec2020pq));
1349 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Unmanaged (testing only)"), QVariant::fromValue(CanvasSurfaceMode::Unmanaged));
1350
1351 m_canvasSurfaceColorSpace->setToolTip(
1352 i18n("<p>Color space of the pixels that are transferred to the "
1353 "window compositor. Use \"preferred\" space unless you know "
1354 "what you are doing</p>"));
1355
1356 // surface bit depth
1358 m_canvasSurfaceBitDepth->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1359 QLabel *canvasSurfaceBitDepthLbl = new QLabel(i18n("Canvas surface bit depth (needs restart):"), this);
1360 monitorProfileGrid->addRow(canvasSurfaceBitDepthLbl, m_canvasSurfaceBitDepth);
1361
1362 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("Auto"), QVariant::fromValue(CanvasSurfaceBitDepthMode::DepthAuto));
1363 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("8-bit"), QVariant::fromValue(CanvasSurfaceBitDepthMode::Depth8Bit));
1364 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("10-bit"), QVariant::fromValue(CanvasSurfaceBitDepthMode::Depth10Bit));
1365
1366 m_canvasSurfaceBitDepth->setToolTip(
1367 i18n("<p>The bit depth of the color that is passed to the window "
1368 "compositor. You should switch into 10-bit mode if you want to use "
1369 "HDR capabilities of your display</p>"));
1370
1371 const QString currentBitBepthString = QSurfaceFormat::defaultFormat().redBufferSize() == 10 ? i18n("10-bit") : i18n("8-bit");
1372 QLabel *currentCanvasSurfaceBitDepthLbl = new QLabel(i18n("Current canvas surface bit depth:"), this);
1373 QLabel *currentCanvasSurfaceBitDepth = new QLabel(currentBitBepthString, this);
1374 monitorProfileGrid->addRow(currentCanvasSurfaceBitDepthLbl, currentCanvasSurfaceBitDepth);
1375
1376 vboxLayout->addItem(new QSpacerItem(20,20));
1377
1379 QTextBrowser *preferredLbl = new QTextBrowser(this);
1380 preferredLbl->setText(i18n("Color space preferred by the operating system:\n%1", KisPlatformPluginInterfaceFactory::instance()->osPreferredColorSpaceReport(mainWindow)));
1381 preferredLbl->setReadOnly(true);
1382
1383 QHBoxLayout *colorDescriptionChoice = new QHBoxLayout();
1384 vboxLayout->addLayout(colorDescriptionChoice);
1385
1386 QLabel *descriptionChoiceLabel = new QLabel(i18n("Diagram:"));
1387 colorDescriptionChoice->addWidget(descriptionChoiceLabel);
1388
1389 QRadioButton *containerSpace = new QRadioButton(i18nc("@info:radiobutton", "Preferred Space"), this);
1390 colorDescriptionChoice->addWidget(containerSpace);
1391 containerSpace->setToolTip(i18nc("@info:tooltip", "This is the space preferred by the operating system."));
1392 m_preferredSpaceGraphicMode.addButton(containerSpace, PreferredSpace);
1393
1394 QRadioButton *masteringSpace = new QRadioButton(i18nc("@info:radiobutton", "Current Display"), this);
1395 colorDescriptionChoice->addWidget(masteringSpace);
1396 m_preferredSpaceGraphicMode.addButton(masteringSpace, MasteringSpace);
1397 masteringSpace->setToolTip(i18nc("@info:tooltip", "This is the space representing the currently active display."));
1398
1399 QHBoxLayout *colorDescriptionLayout = new QHBoxLayout();
1400 vboxLayout->addLayout(colorDescriptionLayout);
1402 colorDescriptionLayout->addWidget(m_preferredSpaceGraphic);
1403 colorDescriptionLayout->addWidget(preferredLbl);
1404
1405 containerSpace->setChecked(true);
1406 colorDescriptionChoice->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding));
1407
1408 m_preferredSpaceGraphic->setFixedSize(QSize(200, 200));
1410 connect(&m_preferredSpaceGraphicMode, SIGNAL(buttonClicked(QAbstractButton*)), this, SLOT(updatePreferredSpaceGraphic()));
1414
1416
1417 {
1418 auto mode = cfg.canvasSurfaceColorSpaceManagementMode();
1419 int index = m_canvasSurfaceColorSpace->findData(QVariant::fromValue(mode));
1420 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1421 index = 0;
1422 }
1423 m_canvasSurfaceColorSpace->setCurrentIndex(index);
1424 }
1425
1426 {
1427 auto mode = cfg.canvasSurfaceBitDepthMode();
1428 int index = m_canvasSurfaceBitDepth->findData(QVariant::fromValue(mode));
1429 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1430 index = 0;
1431 }
1432 m_canvasSurfaceBitDepth->setCurrentIndex(index);
1433 }
1434
1435 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, m_canvasSurfaceColorSpace, &QWidget::setEnabled);
1437
1438 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, canvasSurfaceColorSpaceLbl, &QWidget::setEnabled);
1439 canvasSurfaceColorSpaceLbl->setEnabled(m_chkEnableCanvasColorSpaceManagement->isChecked());
1440
1441 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, m_canvasSurfaceBitDepth, &QWidget::setEnabled);
1443
1444 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, canvasSurfaceBitDepthLbl, &QWidget::setEnabled);
1445 canvasSurfaceBitDepthLbl->setEnabled(m_chkEnableCanvasColorSpaceManagement->isChecked());
1446 }
1447
1448 m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
1449 m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
1450 m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors());
1451 m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent());
1452 KisImageConfig cfgImage(true);
1453
1457 KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration();
1458
1459 m_page->wdgProofingOptions->setProofingConfig(proofingConfig);
1460
1461 m_proofModel->data.set(*proofingConfig.data());
1462
1463 connect(m_page->chkBlackpoint, SIGNAL(toggled(bool)), this, SLOT(updateProofingDisplayInfo()));
1464 connect(m_page->cmbMonitorIntent, SIGNAL(currentIndexChanged(int)), this, SLOT(updateProofingDisplayInfo()));
1466
1469 m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, KisClipboard::PASTE_ASK);
1470
1471 QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour());
1472 Q_ASSERT(button);
1473
1474 if (button) {
1475 button->setChecked(true);
1476 }
1477
1478 if (!m_colorManagedByOS) {
1480 }
1481}
1482
1484{
1486
1487 KoFileDialog dialog(this, KoFileDialog::OpenFiles, "OpenDocumentICC");
1488 dialog.setCaption(i18n("Install Color Profiles"));
1489 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
1490 dialog.setMimeTypeFilters(QStringList() << "application/vnd.iccprofile", "application/vnd.iccprofile");
1491 QStringList profileNames = dialog.filenames();
1492
1494 Q_ASSERT(iccEngine);
1495
1496 QString saveLocation = KoResourcePaths::saveLocation("icc_profiles");
1497
1498 Q_FOREACH (const QString &profileName, profileNames) {
1499 if (!QFile::copy(profileName, saveLocation + QFileInfo(profileName).fileName())) {
1500 qWarning() << "Could not install profile!" << saveLocation + QFileInfo(profileName).fileName();
1501 continue;
1502 }
1503 iccEngine->addProfile(saveLocation + QFileInfo(profileName).fileName());
1504 }
1505
1506 KisConfig cfg(true);
1507 refillMonitorProfiles(KoID("RGBA"));
1508
1509 for(int i = 0; i < QApplication::screens().count(); ++i) {
1510 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1511 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1512 }
1513 }
1514
1515}
1516
1518{
1520
1521 KisConfig cfg(true);
1522
1523 if (useSystemProfile) {
1525 if (devices.size() == QApplication::screens().count()) {
1526 for(int i = 0; i < QApplication::screens().count(); ++i) {
1527 m_monitorProfileWidgets[i]->clear();
1528 QString monitorForScreen = cfg.monitorForScreen(i, devices[i]);
1529 Q_FOREACH (const QString &device, devices) {
1530 m_monitorProfileLabels[i]->setText(i18nc("The number of the screen (ordinal) and shortened 'name' of the screen (model + resolution)", "Screen %1 (%2):", i + 1, shortNameOfDisplay(i)));
1531 m_monitorProfileWidgets[i]->addSqueezedItem(KisColorManager::instance()->deviceName(device), device);
1532 if (devices[i] == monitorForScreen) {
1533 m_monitorProfileWidgets[i]->setCurrentIndex(i);
1534 }
1535 }
1536 }
1537 }
1538 }
1539 else {
1540 refillMonitorProfiles(KoID("RGBA"));
1541
1542 for(int i = 0; i < QApplication::screens().count(); ++i) {
1543 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1544 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1545 }
1546 }
1547 }
1548}
1549
1551{
1552 m_page->cmbWorkingColorSpace->setEnabled(useDefColorSpace);
1553}
1554
1556{
1557 m_page->cmbWorkingColorSpace->setCurrent("RGBA");
1558
1560 const QString defaultProfile = KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId);
1561 m_page->cmbColorProfileForEXR->setCurrent(defaultProfile);
1562
1563 KisConfig cfg(true);
1564
1565 if (!m_colorManagedByOS) {
1566 refillMonitorProfiles(KoID("RGBA"));
1567 } else {
1569
1570 {
1571 auto mode = cfg.canvasSurfaceColorSpaceManagementMode(true);
1572 int index = m_canvasSurfaceColorSpace->findData(QVariant::fromValue(mode));
1573 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1574 index = 0;
1575 }
1576 m_canvasSurfaceColorSpace->setCurrentIndex(index);
1577 }
1578
1579 {
1580 auto mode = cfg.canvasSurfaceBitDepthMode(true);
1581 int index = m_canvasSurfaceBitDepth->findData(QVariant::fromValue(mode));
1582 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1583 index = 0;
1584 }
1585 m_canvasSurfaceBitDepth->setCurrentIndex(index);
1586 }
1587 }
1588
1589 KisImageConfig cfgImage(true);
1590 KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration(true);
1591 m_page->wdgProofingOptions->setProofingConfig(proofingConfig);
1592
1593 m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
1594 m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
1595 m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors(true));
1596 m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent(true));
1597 if (!m_colorManagedByOS) {
1598 m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile(true));
1599 }
1600 QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour(true));
1601 Q_ASSERT(button);
1602 if (button) {
1603 button->setChecked(true);
1604 }
1605}
1606
1607
1609{
1611
1612 for (int i = 0; i < QApplication::screens().count(); ++i) {
1613 m_monitorProfileWidgets[i]->clear();
1614 }
1615
1616 QMap<QString, const KoColorProfile *> profileList;
1617 Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(colorSpaceId.id())) {
1618 profileList[profile->name()] = profile;
1619 }
1620
1621 Q_FOREACH (const KoColorProfile *profile, profileList.values()) {
1622 //qDebug() << "Profile" << profile->name() << profile->isSuitableForDisplay() << csf->defaultProfile();
1623 if (profile->isSuitableForDisplay()) {
1624 for (int i = 0; i < QApplication::screens().count(); ++i) {
1625 m_monitorProfileWidgets[i]->addSqueezedItem(profile->name());
1626 }
1627 }
1628 }
1629
1630 for (int i = 0; i < QApplication::screens().count(); ++i) {
1631 m_monitorProfileLabels[i]->setText(i18nc("The number of the screen (ordinal) and shortened 'name' of the screen (model + resolution)", "Screen %1 (%2):", i + 1, shortNameOfDisplay(i)));
1633 }
1634}
1635
1638 options.first = KoColorConversionTransformation::Intent(m_page->cmbMonitorIntent->currentIndex());
1640 options.second.setFlag(KoColorConversionTransformation::BlackpointCompensation, m_page->chkBlackpoint->isChecked());
1641 m_page->wdgProofingOptions->setDisplayConfigOptions(options);
1642}
1643
1645{
1646 if (!m_preferredSpaceGraphic) return;
1647 if (!KisPlatformPluginInterfaceFactory::instance()->surfaceColorManagedByOS()) return;
1649 QVector<double> colorants;
1650 QVector <double> whitePoint;
1651
1652#ifdef Q_OS_LINUX
1653#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1654 KisRootSurfaceInfoProxy proxy(mainWindow);
1655 std::optional<KisSurfaceColorimetry::SurfaceDescription> currentDescription = proxy.currentSurfaceDescription();
1656 if (m_preferredSpaceGraphicMode.checkedId() == PreferredSpace) {
1657 if (currentDescription) {
1658 if (std::holds_alternative<KisSurfaceColorimetry::Colorimetry>(currentDescription->colorSpace.primaries)) {
1659 auto col = std::get<KisSurfaceColorimetry::Colorimetry>(currentDescription->colorSpace.primaries);
1660 colorants << col.red().toxy().x << col.red().toxy().y << col.red().toxyY().Y
1661 << col.green().toxy().x << col.green().toxy().y << col.green().toxyY().Y
1662 << col.blue().toxy().x << col.blue().toxy().y << col.blue().toxyY().Y;
1663 whitePoint << col.white().toxy().x << col.white().toxy().y << col.white().toxyY().Y;
1664 m_preferredSpaceGraphic->setRGBData(whitePoint, colorants);
1665 } else {
1666 bool enable = true;
1667 auto named = std::get<KisSurfaceColorimetry::NamedPrimaries>(currentDescription->colorSpace.primaries);
1679 } else {
1680 enable = false;
1681 }
1682
1683 if (enable) {
1684 colorants << col.red().toxy().x << col.red().toxy().y << col.red().toxyY().Y
1685 << col.green().toxy().x << col.green().toxy().y << col.green().toxyY().Y
1686 << col.blue().toxy().x << col.blue().toxy().y << col.blue().toxyY().Y;
1687 whitePoint << col.white().toxy().x << col.white().toxy().y << col.white().toxyY().Y;
1688 m_preferredSpaceGraphic->setRGBData(whitePoint, colorants);
1689 } else {
1690 m_preferredSpaceGraphic->setProfileDataAvailable(false);
1691 }
1692
1693 }
1694 } else {
1695 m_preferredSpaceGraphic->setProfileDataAvailable(false);
1696 }
1697 } else if(m_preferredSpaceGraphicMode.checkedId() == MasteringSpace) {
1698 if (currentDescription && currentDescription->masteringInfo) {
1699 auto col = currentDescription->masteringInfo->primaries;
1700 colorants << col.red().toxy().x << col.red().toxy().y << col.red().toxyY().Y
1701 << col.green().toxy().x << col.green().toxy().y << col.green().toxyY().Y
1702 << col.blue().toxy().x << col.blue().toxy().y << col.blue().toxyY().Y;
1703 whitePoint << col.white().toxy().x << col.white().toxy().y << col.white().toxyY().Y;
1704
1705 m_preferredSpaceGraphic->setRGBData(whitePoint, colorants);
1706 } else {
1707 m_preferredSpaceGraphic->setProfileDataAvailable(false);
1708 }
1709 }
1710#endif
1711#endif
1712 m_preferredSpaceGraphic->update();
1713}
1714
1715//---------------------------------------------------------------------------------------------------
1716
1718{
1719 KisConfig cfg(true);
1720 const KisCubicCurve curve(cfg.pressureTabletCurve(true));
1721 m_page->pressureCurve->setCurve(curve);
1722
1723 m_page->chkUseRightMiddleClickWorkaround->setChecked(
1724 KisConfig(true).useRightMiddleTabletButtonWorkaround(true));
1725
1726#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1727 m_page->radioWintab->setChecked(!cfg.useWin8PointerInput(true));
1728 m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput(true));
1729#else
1730 m_page->grpTabletApi->setVisible(false);
1731#endif
1732
1733#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN
1734 m_page->chkUsePageUpDownMouseButtonEmulationWorkaround->setChecked(
1735 cfg.usePageUpDownMouseButtonEmulationWorkaround(true));
1736#endif
1737
1738#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS
1739 m_page->chkUseHighFunctionKeyMouseButtonEmulationWorkaround->setChecked(
1740 cfg.useHighFunctionKeyMouseButtonEmulationWorkaround(true));
1741#endif
1742
1743#if KRITA_QT_HAS_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS
1744 m_page->chkUseIgnoreHistoricTabletEventsWorkaround->setChecked(cfg.useIgnoreHistoricTabletEventsWorkaround(true));
1745#endif
1746
1747 m_page->chkUseTimestampsForBrushSpeed->setChecked(false);
1748 m_page->intMaxAllowedBrushSpeed->setValue(30);
1749 m_page->intBrushSpeedSmoothing->setValue(3);
1750 m_page->tiltDirectionOffsetAngle->setAngle(0);
1751}
1752
1753TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget(parent)
1754{
1755 setObjectName(name);
1756
1757 QGridLayout * l = new QGridLayout(this);
1758 l->setContentsMargins(0, 0, 0, 0);
1759 m_page = new WdgTabletSettings(this);
1760 l->addWidget(m_page, 0, 0);
1761
1762 KisConfig cfg(true);
1763 const KisCubicCurve curve(cfg.pressureTabletCurve());
1764 m_page->pressureCurve->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
1765 m_page->pressureCurve->setCurve(curve);
1766
1767 m_page->chkUseRightMiddleClickWorkaround->setChecked(
1769
1770#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1771# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1772 QString actualTabletProtocol = "<unknown>";
1773 using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
1774 if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) {
1775 actualTabletProtocol = nativeWindowsApp->isWinTabEnabled() ? "WinTab" : "Windows Ink";
1776 }
1777 m_page->grpTabletApi->setTitle(i18n("Tablet Input API (currently active API: \"%1\")", actualTabletProtocol));
1778# endif
1779 m_page->radioWintab->setChecked(!cfg.useWin8PointerInput());
1780 m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput());
1781
1782 connect(m_page->btnResolutionSettings, SIGNAL(clicked()), SLOT(slotResolutionSettings()));
1783 connect(m_page->radioWintab, SIGNAL(toggled(bool)), m_page->btnResolutionSettings, SLOT(setEnabled(bool)));
1784 m_page->btnResolutionSettings->setEnabled(m_page->radioWintab->isChecked());
1785#else
1786 m_page->grpTabletApi->setVisible(false);
1787#endif
1788 connect(m_page->btnTabletTest, SIGNAL(clicked()), SLOT(slotTabletTest()));
1789
1790#ifdef Q_OS_WIN
1791 m_page->chkUseTimestampsForBrushSpeed->setText(i18n("Use tablet driver timestamps for brush speed (may cause severe artifacts when using WinTab tablet API)"));
1792#else
1793 m_page->chkUseTimestampsForBrushSpeed->setText(i18n("Use tablet driver timestamps for brush speed"));
1794#endif
1795 m_page->chkUseTimestampsForBrushSpeed->setChecked(cfg.readEntry("useTimestampsForBrushSpeed", false));
1796
1797#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN
1798 m_page->chkUsePageUpDownMouseButtonEmulationWorkaround->setChecked(
1799 cfg.usePageUpDownMouseButtonEmulationWorkaround());
1800#else
1801 m_page->chkUsePageUpDownMouseButtonEmulationWorkaround->hide();
1802#endif
1803
1804#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS
1805 m_page->chkUseHighFunctionKeyMouseButtonEmulationWorkaround->setChecked(
1806 cfg.useHighFunctionKeyMouseButtonEmulationWorkaround());
1807#else
1808 m_page->chkUseHighFunctionKeyMouseButtonEmulationWorkaround->hide();
1809#endif
1810
1811#if KRITA_QT_HAS_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS
1812 m_page->chkUseIgnoreHistoricTabletEventsWorkaround->setChecked(cfg.useIgnoreHistoricTabletEventsWorkaround());
1813#else
1814 m_page->chkUseIgnoreHistoricTabletEventsWorkaround->hide();
1815#endif
1816
1817 m_page->intMaxAllowedBrushSpeed->setRange(1, 100);
1818 m_page->intMaxAllowedBrushSpeed->setValue(cfg.readEntry("maxAllowedSpeedValue", 30));
1819 KisSpinBoxI18nHelper::install(m_page->intMaxAllowedBrushSpeed, [](int value) {
1820 // i18n: This is meant to be used in a spinbox so keep the {n} in the text
1821 // and it will be substituted by the number. The text before will be
1822 // used as the prefix and the text after as the suffix
1823 return i18np("Maximum brush speed: {n} px/ms", "Maximum brush speed: {n} px/ms", value);
1824 });
1825
1826 m_page->intBrushSpeedSmoothing->setRange(3, 100);
1827 m_page->intBrushSpeedSmoothing->setValue(cfg.readEntry("speedValueSmoothing", 3));
1828 KisSpinBoxI18nHelper::install(m_page->intBrushSpeedSmoothing, [](int value) {
1829 // i18n: This is meant to be used in a spinbox so keep the {n} in the text
1830 // and it will be substituted by the number. The text before will be
1831 // used as the prefix and the text after as the suffix
1832 return i18np("Brush speed smoothing: {n} sample", "Brush speed smoothing: {n} samples", value);
1833 });
1834
1835 m_page->tiltDirectionOffsetAngle->setDecimals(0);
1836 m_page->tiltDirectionOffsetAngle->setRange(-180, 180);
1837 // the angle is saved in clockwise direction to be consistent with Drawing Angle, so negate
1838 m_page->tiltDirectionOffsetAngle->setAngle(-cfg.readEntry("tiltDirectionOffset", 0.0));
1839 m_page->tiltDirectionOffsetAngle->setPrefix(i18n("Pen tilt direction offset: "));
1840 m_page->tiltDirectionOffsetAngle->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_MenuButton);
1841}
1842
1844{
1845 TabletTestDialog tabletTestDialog(this);
1846 tabletTestDialog.exec();
1847}
1848
1849#ifdef Q_OS_WIN
1851#endif
1852
1854{
1855#ifdef Q_OS_WIN
1857 dlg.exec();
1858#endif
1859}
1860
1861
1862//---------------------------------------------------------------------------------------------------
1864
1866{
1867 return KisImageConfig(true).totalRAM();
1868}
1869
1871{
1872 return intMemoryLimit->value() - intPoolLimit->value();
1873}
1874
1875PerformanceTab::PerformanceTab(QWidget *parent, const char *name)
1876 : WdgPerformanceSettings(parent, name)
1877 , m_frameRateModel(new KisFrameRateLimitModel())
1878{
1879 KisImageConfig cfg(true);
1880 const double totalRAM = cfg.totalRAM();
1881 lblTotalMemory->setText(KFormat().formatByteSize(totalRAM * 1024 * 1024, 0, KFormat::IECBinaryDialect, KFormat::UnitMegaByte));
1882
1883 KisSpinBoxI18nHelper::setText(sliderMemoryLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1884 sliderMemoryLimit->setRange(1, 100, 2);
1885 sliderMemoryLimit->setSingleStep(0.01);
1886
1887 KisSpinBoxI18nHelper::setText(sliderPoolLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1888 sliderPoolLimit->setRange(0, 20, 2);
1889 sliderPoolLimit->setSingleStep(0.01);
1890
1891 KisSpinBoxI18nHelper::setText(sliderUndoLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1892 sliderUndoLimit->setRange(0, 50, 2);
1893 sliderUndoLimit->setSingleStep(0.01);
1894
1895 intMemoryLimit->setMinimumWidth(80);
1896 intPoolLimit->setMinimumWidth(80);
1897 intUndoLimit->setMinimumWidth(80);
1898
1899 {
1900 formLayout->takeRow(2);
1901 label_5->setVisible(false);
1902 intPoolLimit->setVisible(false);
1903 sliderPoolLimit->setVisible(false);
1904 }
1905
1906 SliderAndSpinBoxSync *sync1 =
1907 new SliderAndSpinBoxSync(sliderMemoryLimit,
1908 intMemoryLimit,
1909 getTotalRAM);
1910
1911 sync1->slotParentValueChanged();
1912 m_syncs << sync1;
1913
1914 SliderAndSpinBoxSync *sync2 =
1915 new SliderAndSpinBoxSync(sliderPoolLimit,
1916 intPoolLimit,
1917 std::bind(&KisIntParseSpinBox::value,
1918 intMemoryLimit));
1919
1920
1921 connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync2, SLOT(slotParentValueChanged()));
1922 sync2->slotParentValueChanged();
1923 m_syncs << sync2;
1924
1925 SliderAndSpinBoxSync *sync3 =
1926 new SliderAndSpinBoxSync(sliderUndoLimit,
1927 intUndoLimit,
1929 this));
1930
1931
1932 connect(intPoolLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
1933 connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
1934 sync3->slotParentValueChanged();
1935 m_syncs << sync3;
1936
1937 sliderSwapSize->setSuffix(i18n(" GiB"));
1938 sliderSwapSize->setRange(1, 64);
1939 intSwapSize->setRange(1, 64);
1940
1941
1942 KisAcyclicSignalConnector *swapSizeConnector = new KisAcyclicSignalConnector(this);
1943
1944 swapSizeConnector->connectForwardInt(sliderSwapSize, SIGNAL(valueChanged(int)),
1945 intSwapSize, SLOT(setValue(int)));
1946
1947 swapSizeConnector->connectBackwardInt(intSwapSize, SIGNAL(valueChanged(int)),
1948 sliderSwapSize, SLOT(setValue(int)));
1949
1950 swapFileLocation->setMode(KoFileDialog::OpenDirectory);
1951 swapFileLocation->setConfigurationName("swapfile_location");
1952 swapFileLocation->setFileName(cfg.swapDir());
1953
1954 sliderThreadsLimit->setRange(1, QThread::idealThreadCount());
1955 sliderFrameClonesLimit->setRange(1, QThread::idealThreadCount());
1956
1957 sliderFrameTimeout->setRange(5, 600);
1958 sliderFrameTimeout->setSuffix(i18nc("suffix for \"seconds\"", " sec"));
1959 sliderFrameTimeout->setValue(cfg.frameRenderingTimeout() / 1000);
1960
1961 sliderFpsLimit->setSuffix(i18n(" fps"));
1962
1963 KisWidgetConnectionUtils::connectControlState(sliderFpsLimit, m_frameRateModel.data(), "frameRateState", "frameRate");
1964 KisWidgetConnectionUtils::connectControl(chkDetectFps, m_frameRateModel.data(), "detectFrameRate");
1965
1966 connect(sliderThreadsLimit, SIGNAL(valueChanged(int)), SLOT(slotThreadsLimitChanged(int)));
1967 connect(sliderFrameClonesLimit, SIGNAL(valueChanged(int)), SLOT(slotFrameClonesLimitChanged(int)));
1968
1969 intCachedFramesSizeLimit->setRange(256, 10000);
1970 intCachedFramesSizeLimit->setSuffix(i18n(" px"));
1971 intCachedFramesSizeLimit->setSingleStep(1);
1972 intCachedFramesSizeLimit->setPageStep(1000);
1973
1974 intRegionOfInterestMargin->setRange(1, 100);
1975 KisSpinBoxI18nHelper::setText(intRegionOfInterestMargin,
1976 i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1977 intRegionOfInterestMargin->setSingleStep(1);
1978 intRegionOfInterestMargin->setPageStep(10);
1979
1980 connect(chkCachedFramesSizeLimit, SIGNAL(toggled(bool)), intCachedFramesSizeLimit, SLOT(setEnabled(bool)));
1981 connect(chkUseRegionOfInterest, SIGNAL(toggled(bool)), intRegionOfInterestMargin, SLOT(setEnabled(bool)));
1982
1983 connect(chkTransformToolUseInStackPreview, SIGNAL(toggled(bool)), chkTransformToolForceLodMode, SLOT(setEnabled(bool)));
1984
1985#ifndef Q_OS_WIN
1986 // AVX workaround is needed on Windows+GCC only
1987 chkDisableAVXOptimizations->setVisible(false);
1988#endif
1989
1990 load(false);
1991}
1992
1994{
1995 qDeleteAll(m_syncs);
1996}
1997
1998void PerformanceTab::load(bool requestDefault)
1999{
2000 KisImageConfig cfg(true);
2001
2002 sliderMemoryLimit->setValue(cfg.memoryHardLimitPercent(requestDefault));
2003 sliderPoolLimit->setValue(cfg.memoryPoolLimitPercent(requestDefault));
2004 sliderUndoLimit->setValue(cfg.memorySoftLimitPercent(requestDefault));
2005
2006 chkPerformanceLogging->setChecked(cfg.enablePerfLog(requestDefault));
2007 chkProgressReporting->setChecked(cfg.enableProgressReporting(requestDefault));
2008
2009 sliderSwapSize->setValue(cfg.maxSwapSize(requestDefault) / 1024);
2010 swapFileLocation->setFileName(cfg.swapDir(requestDefault));
2011
2012 m_lastUsedThreadsLimit = cfg.maxNumberOfThreads(requestDefault);
2013 m_lastUsedClonesLimit = cfg.frameRenderingClones(requestDefault);
2014
2015 sliderThreadsLimit->setValue(m_lastUsedThreadsLimit);
2016 sliderFrameClonesLimit->setValue(m_lastUsedClonesLimit);
2017
2018#if KRITA_QT_HAS_UPDATE_COMPRESSION_PATCH
2019 m_frameRateModel->data.set(std::make_tuple(cfg.detectFpsLimit(requestDefault), cfg.fpsLimit(requestDefault)));
2020#else
2021 m_frameRateModel->data.set(std::make_tuple(false, cfg.fpsLimit(requestDefault)));
2022 chkDetectFps->setVisible(false);
2023#endif
2024 {
2025 KisConfig cfg2(true);
2026 chkOpenGLFramerateLogging->setChecked(cfg2.enableOpenGLFramerateLogging(requestDefault));
2027 chkBrushSpeedLogging->setChecked(cfg2.enableBrushSpeedLogging(requestDefault));
2028 chkDisableVectorOptimizations->setChecked(cfg2.disableVectorOptimizations(requestDefault));
2029#ifdef Q_OS_WIN
2030 chkDisableAVXOptimizations->setChecked(cfg2.disableAVXOptimizations(requestDefault));
2031#endif
2032 chkBackgroundCacheGeneration->setChecked(cfg2.calculateAnimationCacheInBackground(requestDefault));
2033 }
2034
2035 if (cfg.useOnDiskAnimationCacheSwapping(requestDefault)) {
2036 optOnDisk->setChecked(true);
2037 } else {
2038 optInMemory->setChecked(true);
2039 }
2040
2041 chkCachedFramesSizeLimit->setChecked(cfg.useAnimationCacheFrameSizeLimit(requestDefault));
2042 intCachedFramesSizeLimit->setValue(cfg.animationCacheFrameSizeLimit(requestDefault));
2043 intCachedFramesSizeLimit->setEnabled(chkCachedFramesSizeLimit->isChecked());
2044
2045 chkUseRegionOfInterest->setChecked(cfg.useAnimationCacheRegionOfInterest(requestDefault));
2046 intRegionOfInterestMargin->setValue(cfg.animationCacheRegionOfInterestMargin(requestDefault) * 100.0);
2047 intRegionOfInterestMargin->setEnabled(chkUseRegionOfInterest->isChecked());
2048
2049 {
2050 KConfigGroup group = KSharedConfig::openConfig()->group("KisToolTransform");
2051 chkTransformToolUseInStackPreview->setChecked(!group.readEntry("useOverlayPreviewStyle", false));
2052 chkTransformToolForceLodMode->setChecked(group.readEntry("forceLodMode", true));
2053 chkTransformToolForceLodMode->setEnabled(chkTransformToolUseInStackPreview->isChecked());
2054 }
2055
2056 {
2057 KConfigGroup group = KSharedConfig::openConfig()->group("KritaTransform/KisToolMove");
2058 chkMoveToolForceLodMode->setChecked(group.readEntry("forceLodMode", false));
2059 }
2060
2061 {
2062 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
2063 chkFiltersForceLodMode->setChecked(group.readEntry("forceLodMode", true));
2064 }
2065}
2066
2068{
2069 KisImageConfig cfg(false);
2070
2071 cfg.setMemoryHardLimitPercent(sliderMemoryLimit->value());
2072 cfg.setMemorySoftLimitPercent(sliderUndoLimit->value());
2073 cfg.setMemoryPoolLimitPercent(sliderPoolLimit->value());
2074
2075 cfg.setEnablePerfLog(chkPerformanceLogging->isChecked());
2076 cfg.setEnableProgressReporting(chkProgressReporting->isChecked());
2077
2078 cfg.setMaxSwapSize(sliderSwapSize->value() * 1024);
2079
2080 cfg.setSwapDir(swapFileLocation->fileName());
2081
2082 cfg.setMaxNumberOfThreads(sliderThreadsLimit->value());
2083 cfg.setFrameRenderingClones(sliderFrameClonesLimit->value());
2084 cfg.setFrameRenderingTimeout(sliderFrameTimeout->value() * 1000);
2085 cfg.setFpsLimit(std::get<int>(*m_frameRateModel->data));
2086#if KRITA_QT_HAS_UPDATE_COMPRESSION_PATCH
2087 cfg.setDetectFpsLimit(std::get<bool>(*m_frameRateModel->data));
2088#endif
2089
2090 {
2091 KisConfig cfg2(true);
2092 cfg2.setEnableOpenGLFramerateLogging(chkOpenGLFramerateLogging->isChecked());
2093 cfg2.setEnableBrushSpeedLogging(chkBrushSpeedLogging->isChecked());
2094 cfg2.setDisableVectorOptimizations(chkDisableVectorOptimizations->isChecked());
2095#ifdef Q_OS_WIN
2096 cfg2.setDisableAVXOptimizations(chkDisableAVXOptimizations->isChecked());
2097#endif
2098 cfg2.setCalculateAnimationCacheInBackground(chkBackgroundCacheGeneration->isChecked());
2099 }
2100
2101 cfg.setUseOnDiskAnimationCacheSwapping(optOnDisk->isChecked());
2102
2103 cfg.setUseAnimationCacheFrameSizeLimit(chkCachedFramesSizeLimit->isChecked());
2104 cfg.setAnimationCacheFrameSizeLimit(intCachedFramesSizeLimit->value());
2105
2106 cfg.setUseAnimationCacheRegionOfInterest(chkUseRegionOfInterest->isChecked());
2107 cfg.setAnimationCacheRegionOfInterestMargin(intRegionOfInterestMargin->value() / 100.0);
2108
2109 {
2110 KConfigGroup group = KSharedConfig::openConfig()->group("KisToolTransform");
2111 group.writeEntry("useOverlayPreviewStyle", !chkTransformToolUseInStackPreview->isChecked());
2112 group.writeEntry("forceLodMode", chkTransformToolForceLodMode->isChecked());
2113 }
2114
2115 {
2116 KConfigGroup group = KSharedConfig::openConfig()->group("KritaTransform/KisToolMove");
2117 group.writeEntry("forceLodMode", chkMoveToolForceLodMode->isChecked());
2118 }
2119
2120 {
2121 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
2122 group.writeEntry("forceLodMode", chkFiltersForceLodMode->isChecked());
2123 }
2124
2125}
2126
2128{
2129 KisSignalsBlocker b(sliderFrameClonesLimit);
2130 sliderFrameClonesLimit->setValue(qMin(m_lastUsedClonesLimit, value));
2132}
2133
2135{
2136 KisSignalsBlocker b(sliderThreadsLimit);
2137 sliderThreadsLimit->setValue(qMax(m_lastUsedThreadsLimit, value));
2139}
2140
2141//---------------------------------------------------------------------------------------------------
2142
2143#include "KoColor.h"
2146#include <QOpenGLContext>
2147#include <QScreen>
2148
2149namespace {
2150
2151QString colorSpaceString(const KisSurfaceColorSpaceWrapper &cs, int depth)
2152{
2153 const QString csString =
2154#ifdef HAVE_HDR
2156 cs == KisSurfaceColorSpaceWrapper::scRGBColorSpace ? "Rec. 709 Linear" :
2157#endif
2160 "Unknown Color Space";
2161
2162 return QString("%1 (%2 bit)").arg(csString).arg(depth);
2163}
2164
2165int formatToIndex(KisConfig::RootSurfaceFormat fmt)
2166{
2167 return fmt == KisConfig::BT2020_PQ ? 1 :
2168 fmt == KisConfig::BT709_G10 ? 2 :
2169 0;
2170}
2171
2172KisConfig::RootSurfaceFormat indexToFormat(int value)
2173{
2174 return value == 1 ? KisConfig::BT2020_PQ :
2177}
2178
2179int assistantDrawModeToIndex(KisConfig::AssistantsDrawMode mode)
2180{
2183 0;
2184}
2185
2186KisConfig::AssistantsDrawMode indexToAssistantDrawMode(int value)
2187{
2191}
2192
2193} // anonymous namespace
2194
2195DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
2196 : WdgDisplaySettings(parent, name)
2197{
2198 KisConfig cfg(true);
2199
2200 const QString rendererOpenGLText = i18nc("canvas renderer", "OpenGL");
2201 const QString rendererSoftwareText = i18nc("canvas renderer", "Software Renderer (very slow)");
2202#ifdef Q_OS_WIN
2203 const QString rendererOpenGLESText =
2204 qEnvironmentVariable("QT_ANGLE_PLATFORM") != "opengl"
2205 ? i18nc("canvas renderer", "Direct3D 11 via ANGLE")
2206 : i18nc("canvas renderer", "OpenGL via ANGLE");
2207#else
2208 const QString rendererOpenGLESText = i18nc("canvas renderer", "OpenGL ES");
2209#endif
2210
2212 lblCurrentRenderer->setText(renderer == KisOpenGL::RendererOpenGLES ? rendererOpenGLESText :
2213 renderer == KisOpenGL::RendererDesktopGL ? rendererOpenGLText :
2214 renderer == KisOpenGL::RendererSoftware ? rendererSoftwareText :
2215 i18nc("canvas renderer", "Unknown"));
2216
2217 cmbPreferredRenderer->clear();
2218
2219 const KisOpenGL::OpenGLRenderers supportedRenderers = KisOpenGL::getSupportedOpenGLRenderers();
2220 const bool onlyOneRendererSupported =
2221 supportedRenderers == KisOpenGL::RendererDesktopGL ||
2222 supportedRenderers == KisOpenGL::RendererOpenGLES ||
2223 supportedRenderers == KisOpenGL::RendererSoftware;
2224
2225
2226 if (!onlyOneRendererSupported) {
2227 QString qtPreferredRendererText;
2229 qtPreferredRendererText = rendererOpenGLESText;
2231 qtPreferredRendererText = rendererSoftwareText;
2232 } else {
2233 qtPreferredRendererText = rendererOpenGLText;
2234 }
2235 cmbPreferredRenderer->addItem(i18nc("canvas renderer", "Auto (%1)", qtPreferredRendererText), KisOpenGL::RendererAuto);
2236 cmbPreferredRenderer->setCurrentIndex(0);
2237 } else {
2238 cmbPreferredRenderer->setEnabled(false);
2239 }
2240
2241 if (supportedRenderers & KisOpenGL::RendererDesktopGL) {
2242 cmbPreferredRenderer->addItem(rendererOpenGLText, KisOpenGL::RendererDesktopGL);
2244 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
2245 }
2246 }
2247
2248 if (supportedRenderers & KisOpenGL::RendererOpenGLES) {
2249 cmbPreferredRenderer->addItem(rendererOpenGLESText, KisOpenGL::RendererOpenGLES);
2251 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
2252 }
2253 }
2254
2255 if (supportedRenderers & KisOpenGL::RendererSoftware) {
2256 cmbPreferredRenderer->addItem(rendererSoftwareText, KisOpenGL::RendererSoftware);
2258 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
2259 }
2260 }
2261
2262 if (!(supportedRenderers &
2266
2267 grpOpenGL->setEnabled(false);
2268 grpOpenGL->setChecked(false);
2269 chkUseTextureBuffer->setEnabled(false);
2270 cmbAssistantsDrawMode->setEnabled(false);
2271 cmbFilterMode->setEnabled(false);
2272 } else {
2273 grpOpenGL->setEnabled(true);
2274 grpOpenGL->setChecked(cfg.useOpenGL());
2275 chkUseTextureBuffer->setEnabled(cfg.useOpenGL());
2276 chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer());
2277 cmbAssistantsDrawMode->setEnabled(cfg.useOpenGL());
2278 cmbAssistantsDrawMode->setCurrentIndex(assistantDrawModeToIndex(cfg.assistantsDrawMode()));
2279 cmbFilterMode->setEnabled(cfg.useOpenGL());
2280 cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode());
2281 // Don't show the high quality filtering mode if it's not available
2282 if (!KisOpenGL::supportsLoD()) {
2283 cmbFilterMode->removeItem(3);
2284 }
2285 }
2286
2287 {
2288 std::optional<KisOpenGL::XcbGLProviderProtocol> currentXcbGlProvider = KisOpenGL::xcbGlProviderProtocol();
2289
2290 lblPreferredXcbGlApi->setVisible(currentXcbGlProvider.has_value());
2291 cmbPreferredXcbGlApi->setVisible(currentXcbGlProvider.has_value());
2292
2293 if (currentXcbGlProvider.has_value()) {
2294 const QString glxCurrent = i18nc("@item:inlistbox", "GLX (current)");
2295 const QString glxNotCurrent = i18nc("@item:inlistbox", "GLX");
2296 const QString eglCurrent = i18nc("@item:inlistbox", "EGL (current)");
2297 const QString eglNotCurrent = i18nc("@item:inlistbox", "EGL");
2298
2299 cmbPreferredXcbGlApi->addItem(*currentXcbGlProvider == KisOpenGL::XCB_GLX ? glxCurrent : glxNotCurrent, KisOpenGL::XCB_GLX);
2300 cmbPreferredXcbGlApi->addItem(*currentXcbGlProvider == KisOpenGL::XCB_EGL ? eglCurrent : eglNotCurrent, KisOpenGL::XCB_EGL);
2301
2302 cmbPreferredXcbGlApi->setToolTip(i18nc("@info:tooltip",
2303 "<p>If you are using Krita on X11 or XWayland and experience slowness, "
2304 "try switching between EGL and GLX</p>"));
2305
2306 KisOpenGL::XcbGLProviderProtocol preferredValue =
2308
2309 int index = cmbPreferredXcbGlApi->findData(preferredValue);
2310
2311 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
2312 index = 0;
2313 }
2314 cmbPreferredXcbGlApi->setCurrentIndex(index);
2315 }
2316 }
2317
2318 lblCurrentDisplayFormat->setText("");
2319 lblCurrentRootSurfaceFormat->setText("");
2320 grpHDRWarning->setVisible(false);
2321 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::sRGBColorSpace, 8));
2322#ifdef HAVE_HDR
2323 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::bt2020PQColorSpace, 10));
2324 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::scRGBColorSpace, 16));
2325#endif
2326 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
2327 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2328
2329 QOpenGLContext *context = QOpenGLContext::currentContext();
2330
2331 if (!context) {
2332 context = QOpenGLContext::globalShareContext();
2333 }
2334
2335 if (context) {
2336 QScreen *screen = KisPart::instance()->currentMainwindow()->screen();
2337 KisScreenInformationAdapter adapter(context);
2338 if (screen && adapter.isValid()) {
2340 if (info.isValid()) {
2341 QStringList toolTip;
2342
2343 toolTip << i18n("Display Id: %1", info.screen->name());
2344 toolTip << i18n("Display Name: %1 %2", info.screen->manufacturer(), info.screen->model());
2345 toolTip << i18n("Min Luminance: %1", info.minLuminance);
2346 toolTip << i18n("Max Luminance: %1", info.maxLuminance);
2347 toolTip << i18n("Max Full Frame Luminance: %1", info.maxFullFrameLuminance);
2348 toolTip << i18n("Red Primary: %1, %2", info.redPrimary[0], info.redPrimary[1]);
2349 toolTip << i18n("Green Primary: %1, %2", info.greenPrimary[0], info.greenPrimary[1]);
2350 toolTip << i18n("Blue Primary: %1, %2", info.bluePrimary[0], info.bluePrimary[1]);
2351 toolTip << i18n("White Point: %1, %2", info.whitePoint[0], info.whitePoint[1]);
2352
2353 lblCurrentDisplayFormat->setToolTip(toolTip.join('\n'));
2354 lblCurrentDisplayFormat->setText(colorSpaceString(info.colorSpace, info.bitsPerColor));
2355 } else {
2356 lblCurrentDisplayFormat->setToolTip("");
2357 lblCurrentDisplayFormat->setText(i18n("Unknown"));
2358 }
2359 } else {
2360 lblCurrentDisplayFormat->setToolTip("");
2361 lblCurrentDisplayFormat->setText(i18n("Unknown"));
2362 qWarning() << "Failed to fetch display info:" << adapter.errorString();
2363 }
2364
2365 const QSurfaceFormat currentFormat = KisOpenGLModeProber::instance()->surfaceformatInUse();
2366 const auto colorSpace = KisSurfaceColorSpaceWrapper::fromQtColorSpace(currentFormat.colorSpace());
2367 lblCurrentRootSurfaceFormat->setText(colorSpaceString(colorSpace, currentFormat.redBufferSize()));
2368 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(cfg.rootSurfaceFormat()));
2369 connect(cmbPreferedRootSurfaceFormat, SIGNAL(currentIndexChanged(int)), SLOT(slotPreferredSurfaceFormatChanged(int)));
2370 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2371 }
2372
2373#ifndef HAVE_HDR
2374 HDR->setEnabled(false);
2375
2381 if (KisPlatformPluginInterfaceFactory::instance()->surfaceColorManagedByOS()) {
2382 const int hdrTabIndex = tabWidget->indexOf(HDR);
2383 KIS_SAFE_ASSERT_RECOVER_NOOP(hdrTabIndex >= 0);
2384 if (hdrTabIndex >= 0) {
2385 tabWidget->setTabVisible(hdrTabIndex, false);
2386 }
2387 }
2388#endif
2389
2390 const QStringList openglWarnings = KisOpenGL::getOpenGLWarnings();
2391 if (openglWarnings.isEmpty()) {
2392 grpOpenGLWarnings->setVisible(false);
2393 } else {
2394 QString text = QString("<p><b>%1</b>").arg(i18n("Warning(s):"));
2395 text.append("<ul>");
2396 Q_FOREACH (const QString &warning, openglWarnings) {
2397 text.append("<li>");
2398 text.append(warning.toHtmlEscaped());
2399 text.append("</li>");
2400 }
2401 text.append("</ul></p>");
2402 grpOpenGLWarnings->setText(text);
2403 grpOpenGLWarnings->setPixmap(
2404 grpOpenGLWarnings->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
2405 grpOpenGLWarnings->setVisible(true);
2406 }
2407
2408 KisImageConfig imageCfg(false);
2409
2410 KoColor c;
2412 c.setOpacity(1.0);
2413 btnSelectionOverlayColor->setColor(c);
2414 sldSelectionOverlayOpacity->setRange(0.0, 1.0, 2);
2415 sldSelectionOverlayOpacity->setSingleStep(0.05);
2416 sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor().alphaF());
2417
2418 sldSelectionOutlineOpacity->setRange(0.0, 1.0, 2);
2419 sldSelectionOutlineOpacity->setSingleStep(0.05);
2420 sldSelectionOutlineOpacity->setValue(imageCfg.selectionOutlineOpacity());
2421
2422 intCheckSize->setValue(cfg.checkSize());
2423 chkMoving->setChecked(cfg.scrollCheckers());
2425 ck1.fromQColor(cfg.checkersColor1());
2426 colorChecks1->setColor(ck1);
2428 ck2.fromQColor(cfg.checkersColor2());
2429 colorChecks2->setColor(ck2);
2431 cb.fromQColor(cfg.canvasBorderColor());
2432 canvasBorder->setColor(cb);
2433 hideScrollbars->setChecked(cfg.hideScrollbars());
2434 chkCurveAntialiasing->setChecked(cfg.antialiasCurves());
2435 chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline());
2436 chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor());
2437 chkHidePopups->setChecked(cfg.hidePopups());
2438
2439 connect(grpOpenGL, SIGNAL(toggled(bool)), SLOT(slotUseOpenGLToggled(bool)));
2440
2441 KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
2442 gridColor.fromQColor(cfg.getPixelGridColor());
2443 pixelGridColorButton->setColor(gridColor);
2444 pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold() * 100);
2445 KisSpinBoxI18nHelper::setText(pixelGridDrawingThresholdBox, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
2446}
2447
2449{
2450 KisConfig cfg(true);
2451 cmbPreferredRenderer->setCurrentIndex(0);
2454 grpOpenGL->setEnabled(false);
2455 grpOpenGL->setChecked(false);
2456 chkUseTextureBuffer->setEnabled(false);
2457 cmbAssistantsDrawMode->setEnabled(false);
2458 cmbFilterMode->setEnabled(false);
2459 }
2460 else {
2461 grpOpenGL->setEnabled(true);
2462 grpOpenGL->setChecked(cfg.useOpenGL(true));
2463 chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer(true));
2464 chkUseTextureBuffer->setEnabled(true);
2465 cmbAssistantsDrawMode->setEnabled(true);
2466 cmbAssistantsDrawMode->setCurrentIndex(assistantDrawModeToIndex(cfg.assistantsDrawMode(true)));
2467 cmbFilterMode->setEnabled(true);
2468 cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode(true));
2469 }
2470
2471 chkMoving->setChecked(cfg.scrollCheckers(true));
2472
2473 KisImageConfig imageCfg(false);
2474
2475 KoColor c;
2476 c.fromQColor(imageCfg.selectionOverlayMaskColor(true));
2477 c.setOpacity(1.0);
2478 btnSelectionOverlayColor->setColor(c);
2479 sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor(true).alphaF());
2480
2481 sldSelectionOutlineOpacity->setValue(imageCfg.selectionOutlineOpacity(true));
2482
2483 intCheckSize->setValue(cfg.checkSize(true));
2485 ck1.fromQColor(cfg.checkersColor1(true));
2486 colorChecks1->setColor(ck1);
2488 ck2.fromQColor(cfg.checkersColor2(true));
2489 colorChecks2->setColor(ck2);
2491 cvb.fromQColor(cfg.canvasBorderColor(true));
2492 canvasBorder->setColor(cvb);
2493 hideScrollbars->setChecked(cfg.hideScrollbars(true));
2494 chkCurveAntialiasing->setChecked(cfg.antialiasCurves(true));
2495 chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline(true));
2496 chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor(true));
2497 chkHidePopups->setChecked(cfg.hidePopups(true));
2498
2499 KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
2500 gridColor.fromQColor(cfg.getPixelGridColor(true));
2501 pixelGridColorButton->setColor(gridColor);
2502 pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold(true) * 100);
2503 KisSpinBoxI18nHelper::setText(pixelGridDrawingThresholdBox, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
2504
2505 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
2506 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2507}
2508
2510{
2511 chkUseTextureBuffer->setEnabled(isChecked);
2512 cmbFilterMode->setEnabled(isChecked);
2513 cmbAssistantsDrawMode->setEnabled(isChecked);
2514}
2515
2517{
2518 Q_UNUSED(index);
2519
2520 QOpenGLContext *context = QOpenGLContext::currentContext();
2521 if (context) {
2522 QScreen *screen = KisPart::instance()->currentMainwindow()->screen();
2523 KisScreenInformationAdapter adapter(context);
2524 if (adapter.isValid()) {
2526 if (info.isValid()) {
2527 if (cmbPreferedRootSurfaceFormat->currentIndex() != formatToIndex(KisConfig::BT709_G22) &&
2529 grpHDRWarning->setVisible(true);
2530 grpHDRWarning->setPixmap(
2531 grpHDRWarning->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
2532 grpHDRWarning->setText(i18n("<b>Warning:</b> current display doesn't support HDR rendering"));
2533 } else {
2534 grpHDRWarning->setVisible(false);
2535 }
2536 }
2537 }
2538 }
2539}
2540
2541//---------------------------------------------------------------------------------------------------
2543{
2544 KisConfig cfg(true);
2545
2546 chkDockers->setChecked(cfg.hideDockersFullscreen());
2547 chkMenu->setChecked(cfg.hideMenuFullscreen());
2548 chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen());
2549 chkStatusbar->setChecked(cfg.hideStatusbarFullscreen());
2550 chkTitlebar->setChecked(cfg.hideTitlebarFullscreen());
2551 chkToolbar->setChecked(cfg.hideToolbarFullscreen());
2552
2553}
2554
2556{
2557 KisConfig cfg(true);
2558 chkDockers->setChecked(cfg.hideDockersFullscreen(true));
2559 chkMenu->setChecked(cfg.hideMenuFullscreen(true));
2560 chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen(true));
2561 chkStatusbar->setChecked(cfg.hideStatusbarFullscreen(true));
2562 chkTitlebar->setChecked(cfg.hideTitlebarFullscreen(true));
2563 chkToolbar->setChecked(cfg.hideToolbarFullscreen(true));
2564}
2565
2566
2567//---------------------------------------------------------------------------------------------------
2568
2570static const QStringList allowedColorHistorySortingValues({"none", "hsv"});
2571}
2572
2573PopupPaletteTab::PopupPaletteTab(QWidget *parent, const char *name)
2574 : WdgPopupPaletteSettingsBase(parent, name)
2575{
2576 using namespace PopupPaletteTabPrivate;
2577
2578 load();
2579
2580 connect(chkShowColorHistory, SIGNAL(toggled(bool)), cmbColorHistorySorting, SLOT(setEnabled(bool)));
2581 connect(chkShowColorHistory, SIGNAL(toggled(bool)), lblColorHistorySorting, SLOT(setEnabled(bool)));
2582 connect(cmbSelectorType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSelectorTypeChanged(int)));
2583 KIS_SAFE_ASSERT_RECOVER_NOOP(cmbColorHistorySorting->count() == allowedColorHistorySortingValues.size());
2584}
2585
2587{
2588 using namespace PopupPaletteTabPrivate;
2589
2590 KisConfig config(true);
2591 sbNumPresets->setValue(config.favoritePresets());
2592 sbPaletteSize->setValue(config.readEntry("popuppalette/size", 385));
2593 sbSelectorSize->setValue(config.readEntry("popuppalette/selectorSize", 140));
2594 cmbSelectorType->setCurrentIndex(config.readEntry<bool>("popuppalette/usevisualcolorselector", false) ? 1 : 0);
2595 chkShowColorHistory->setChecked(config.readEntry("popuppalette/showColorHistory", true));
2596 chkShowRotationTrack->setChecked(config.readEntry("popuppalette/showRotationTrack", true));
2597 chkUseDynamicSlotCount->setChecked(config.readEntry("popuppalette/useDynamicSlotCount", true));
2598 grpFixTriangleRotation->setChecked(config.readEntry("popuppalette/fixTriangleRotation", false));
2599 sbTriangleRotationAngle->setValue(config.readEntry("popuppalette/triangleRotationAngle", 0));
2600
2601 QString currentSorting = config.readEntry("popuppalette/colorHistorySorting", QString("hsv"));
2602 if (!allowedColorHistorySortingValues.contains(currentSorting)) {
2603 currentSorting = "hsv";
2604 }
2605 cmbColorHistorySorting->setCurrentIndex(allowedColorHistorySortingValues.indexOf(currentSorting));
2606 cmbColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2607 lblColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2608 grpFixTriangleRotation->setEnabled(!cmbSelectorType->currentIndex());
2609}
2610
2612{
2613 using namespace PopupPaletteTabPrivate;
2614
2615 KisConfig config(true);
2616 config.setFavoritePresets(sbNumPresets->value());
2617 config.writeEntry("popuppalette/size", sbPaletteSize->value());
2618 config.writeEntry("popuppalette/selectorSize", sbSelectorSize->value());
2619 config.writeEntry<bool>("popuppalette/usevisualcolorselector", cmbSelectorType->currentIndex() > 0);
2620 config.writeEntry<bool>("popuppalette/showColorHistory", chkShowColorHistory->isChecked());
2621 config.writeEntry<bool>("popuppalette/showRotationTrack", chkShowRotationTrack->isChecked());
2622 config.writeEntry<bool>("popuppalette/useDynamicSlotCount", chkUseDynamicSlotCount->isChecked());
2623 config.writeEntry("popuppalette/colorHistorySorting",
2624 allowedColorHistorySortingValues[cmbColorHistorySorting->currentIndex()]);
2625 config.writeEntry<bool>("popuppalette/fixTriangleRotation", grpFixTriangleRotation->isChecked());
2626 config.writeEntry("popuppalette/triangleRotationAngle", sbTriangleRotationAngle->value());
2627}
2628
2630{
2631 KisConfig config(true);
2632 sbNumPresets->setValue(config.favoritePresets(true));
2633 sbPaletteSize->setValue(385);
2634 sbSelectorSize->setValue(140);
2635 cmbSelectorType->setCurrentIndex(0);
2636 chkShowColorHistory->setChecked(true);
2637 chkShowRotationTrack->setChecked(true);
2638 chkUseDynamicSlotCount->setChecked(true);
2639 cmbColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2640 lblColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2641 grpFixTriangleRotation->setChecked(false);
2642 sbTriangleRotationAngle->setValue(0);
2643}
2644
2646 grpFixTriangleRotation->setEnabled(!index);
2647}
2648
2649//---------------------------------------------------------------------------------------------------
2650
2651KisDlgPreferences::KisDlgPreferences(QWidget* parent, const char* name)
2652 : KPageDialog(parent)
2653{
2654 Q_UNUSED(name);
2655 setWindowTitle(i18n("Configure Krita"));
2656 setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
2657
2658 setFaceType(KPageDialog::List);
2659
2660 // General
2661 KoVBox *vbox = new KoVBox();
2662 KPageWidgetItem *page = new KPageWidgetItem(vbox, i18n("General"));
2663 page->setObjectName("general");
2664 page->setHeader(i18n("General"));
2665 page->setIcon(KisIconUtils::loadIcon("config-general"));
2666 m_pages << page;
2667 addPage(page);
2668 m_general = new GeneralTab(vbox);
2669
2670 // Shortcuts
2671 vbox = new KoVBox();
2672 page = new KPageWidgetItem(vbox, i18n("Keyboard Shortcuts"));
2673 page->setObjectName("shortcuts");
2674 page->setHeader(i18n("Shortcuts"));
2675 page->setIcon(KisIconUtils::loadIcon("config-keyboard"));
2676 m_pages << page;
2677 addPage(page);
2679 connect(this, SIGNAL(accepted()), m_shortcutSettings, SLOT(saveChanges()));
2680 connect(this, SIGNAL(rejected()), m_shortcutSettings, SLOT(cancelChanges()));
2681
2682 // Canvas input settings
2684 page = addPage(m_inputConfiguration, i18n("Canvas Input Settings"));
2685 page->setHeader(i18n("Canvas Input"));
2686 page->setObjectName("canvasinput");
2687 page->setIcon(KisIconUtils::loadIcon("config-canvas-input"));
2688 m_pages << page;
2689
2690 // Display
2691 vbox = new KoVBox();
2692 page = new KPageWidgetItem(vbox, i18n("Display"));
2693 page->setObjectName("display");
2694 page->setHeader(i18n("Display"));
2695 page->setIcon(KisIconUtils::loadIcon("config-display"));
2696 m_pages << page;
2697 addPage(page);
2699
2700 // Color
2701 vbox = new KoVBox();
2702 page = new KPageWidgetItem(vbox, i18n("Color Management"));
2703 page->setObjectName("colormanagement");
2704 page->setHeader(i18nc("Label of color as in Color Management", "Color"));
2705 page->setIcon(KisIconUtils::loadIcon("config-color-manage"));
2706 m_pages << page;
2707 addPage(page);
2709
2710 // Performance
2711 vbox = new KoVBox();
2712 page = new KPageWidgetItem(vbox, i18n("Performance"));
2713 page->setObjectName("performance");
2714 page->setHeader(i18n("Performance"));
2715 page->setIcon(KisIconUtils::loadIcon("config-performance"));
2716 m_pages << page;
2717 addPage(page);
2719
2720 // Tablet
2721 vbox = new KoVBox();
2722 page = new KPageWidgetItem(vbox, i18n("Tablet settings"));
2723 page->setObjectName("tablet");
2724 page->setHeader(i18n("Tablet"));
2725 page->setIcon(KisIconUtils::loadIcon("config-tablet"));
2726 m_pages << page;
2727 addPage(page);
2729
2730 // full-screen mode
2731 vbox = new KoVBox();
2732 page = new KPageWidgetItem(vbox, i18n("Canvas-only settings"));
2733 page->setObjectName("canvasonly");
2734 page->setHeader(i18n("Canvas-only"));
2735 page->setIcon(KisIconUtils::loadIcon("config-canvas-only"));
2736 m_pages << page;
2737 addPage(page);
2739
2740 // Pop-up Palette
2741 vbox = new KoVBox();
2742 page = new KPageWidgetItem(vbox, i18n("Pop-up Palette"));
2743 page->setObjectName("popuppalette");
2744 page->setHeader(i18n("Pop-up Palette"));
2745 page->setIcon(KisIconUtils::loadIcon("config-popup-palette"));
2746 m_pages << page;
2747 addPage(page);
2749
2750 // Author profiles
2752 page = addPage(m_authorPage, i18nc("@title:tab Author page", "Author" ));
2753 page->setObjectName("author");
2754 page->setHeader(i18n("Author"));
2755 page->setIcon(KisIconUtils::loadIcon("user-identity"));
2756 m_pages << page;
2757
2758 KGuiItem::assign(button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
2759 KGuiItem::assign(button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
2760 QPushButton *restoreDefaultsButton = button(QDialogButtonBox::RestoreDefaults);
2761 restoreDefaultsButton->setText(i18nc("@action:button", "Restore Defaults"));
2762
2763 connect(this, SIGNAL(accepted()), m_inputConfiguration, SLOT(saveChanges()));
2764 connect(this, SIGNAL(rejected()), m_inputConfiguration, SLOT(revertChanges()));
2765
2767 QStringList keys = preferenceSetRegistry->keys();
2768 keys.sort();
2769 Q_FOREACH(const QString &key, keys) {
2770 KisAbstractPreferenceSetFactory *preferenceSetFactory = preferenceSetRegistry->value(key);
2771 KisPreferenceSet* preferenceSet = preferenceSetFactory->createPreferenceSet();
2772 vbox = new KoVBox();
2773 page = new KPageWidgetItem(vbox, preferenceSet->name());
2774 page->setHeader(preferenceSet->header());
2775 page->setIcon(preferenceSet->icon());
2776 addPage(page);
2777 preferenceSet->setParent(vbox);
2778 preferenceSet->loadPreferences();
2779
2780 connect(restoreDefaultsButton, SIGNAL(clicked(bool)), preferenceSet, SLOT(loadDefaultPreferences()), Qt::UniqueConnection);
2781 connect(this, SIGNAL(accepted()), preferenceSet, SLOT(savePreferences()), Qt::UniqueConnection);
2782 }
2783
2784 connect(restoreDefaultsButton, SIGNAL(clicked(bool)), this, SLOT(slotDefault()));
2785
2786 KisConfig cfg(true);
2787 QString currentPageName = cfg.readEntry<QString>("KisDlgPreferences/CurrentPage");
2788 Q_FOREACH(KPageWidgetItem *page, m_pages) {
2789 if (page->objectName() == currentPageName) {
2790 setCurrentPage(page);
2791 break;
2792 }
2793 }
2794
2795 // TODO QT6: check what this code actually does?
2796#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2797 {
2798 // HACK ALERT! Remove title widget background, thus making
2799 // it consistent across all systems
2800 const auto *titleWidget = findChild<KTitleWidget*>();
2801 if (titleWidget) {
2802 QLayoutItem *titleFrame = titleWidget->layout()->itemAt(0); // vboxLayout -> titleFrame
2803 if (titleFrame) {
2804 titleFrame->widget()->setBackgroundRole(QPalette::Window);
2805 }
2806 }
2807 }
2808#endif
2809}
2810
2812{
2813 KisConfig cfg(true);
2814 cfg.writeEntry<QString>("KisDlgPreferences/CurrentPage", currentPage()->objectName());
2815}
2816
2817void KisDlgPreferences::showEvent(QShowEvent *event){
2818 KPageDialog::showEvent(event);
2819 button(QDialogButtonBox::Cancel)->setAutoDefault(false);
2820 button(QDialogButtonBox::Ok)->setAutoDefault(false);
2821 button(QDialogButtonBox::RestoreDefaults)->setAutoDefault(false);
2822 button(QDialogButtonBox::Cancel)->setDefault(false);
2823 button(QDialogButtonBox::Ok)->setDefault(false);
2824 button(QDialogButtonBox::RestoreDefaults)->setDefault(false);
2825}
2826
2828{
2829 if (buttonBox()->buttonRole(button) == QDialogButtonBox::RejectRole) {
2830 m_cancelClicked = true;
2831 }
2832}
2833
2835{
2836 if (currentPage()->objectName() == "general") {
2838 }
2839 else if (currentPage()->objectName() == "shortcuts") {
2841 }
2842 else if (currentPage()->objectName() == "display") {
2844 }
2845 else if (currentPage()->objectName() == "colormanagement") {
2847 }
2848 else if (currentPage()->objectName() == "performance") {
2850 }
2851 else if (currentPage()->objectName() == "tablet") {
2853 }
2854 else if (currentPage()->objectName() == "canvasonly") {
2856 }
2857 else if (currentPage()->objectName() == "canvasinput") {
2859 }
2860 else if (currentPage()->objectName() == "popuppalette") {
2862 }
2863}
2864
2865KPageWidgetItem *KisDlgPreferences::getPage(Page page_enum)
2866{
2867 QString name = "";
2868 switch (page_enum) {
2869 case General:
2870 name = "general";
2871 break;
2872 case Shortucts:
2873 name = "shortcuts";
2874 break;
2875 case Color:
2876 name = "colormanagement";
2877 break;
2878 case Performance:
2879 name = "performance";
2880 break;
2881 case Display:
2882 name = "display";
2883 break;
2884 case Tablet:
2885 name = "tablet";
2886 break;
2887 case Fullscreen:
2888 name = "canvasonly";
2889 break;
2890 case Input:
2891 name = "canvasinput";
2892 break;
2893 case PopupPalette:
2894 name = "popuppalette";
2895 break;
2896 }
2897
2898 Q_FOREACH (KPageWidgetItem *page, m_pages) {
2899 if (page->objectName() == name) {
2900 return page;
2901 }
2902 }
2903 return nullptr;
2904}
2905
2907{
2908 switch (page.page) {
2909 case General: {
2910 QWidget *tab = nullptr;
2911 switch (page.tab) {
2912 case File:
2913 tab = m_general->File;
2914 break;
2915 case Pasting:
2916 tab = m_general->Pasting;
2917 break;
2918 case Window:
2919 tab = m_general->Window;
2920 break;
2921 case Cursor:
2922 tab = m_general->Cursor;
2923 break;
2924 case Tools:
2925 tab = m_general->Tools;
2926 break;
2927 case Animation:
2928 tab = m_general->Animation;
2929 break;
2930 case Resources:
2931 tab = m_general->Resources;
2932 break;
2934 tab = m_general->Miscellaneous;
2935 break;
2936 }
2937 m_general->tabWidget->setCurrentWidget(tab);
2938 } break;
2939 case Color: {
2940 QWidget *tab = nullptr;
2941 switch (page.tab) {
2942 case GeneralColor:
2943 tab = m_colorSettings->m_page->General;
2944 break;
2945 case DisplayTab:
2946 tab = m_colorSettings->m_page->Display;
2947 break;
2948 case SoftProofing:
2949 tab = m_colorSettings->m_page->SoftProofing;
2950 break;
2951 }
2952 m_colorSettings->m_page->tabWidget->setCurrentWidget(tab);
2953 } break;
2954 case Performance: {
2955 QWidget *tab = nullptr;
2956 switch (page.tab) {
2957 case GeneralPerformance:
2958 tab = m_performanceSettings->General;
2959 break;
2960 case Advanced:
2961 tab = m_performanceSettings->Advanced;
2962 break;
2963 case AnimationCache:
2964 tab = m_performanceSettings->AnimationCache;
2965 break;
2966 case InstantPreview:
2967 tab = m_performanceSettings->InstantPreview;
2968 break;
2969 }
2970 m_performanceSettings->tabWidget->setCurrentWidget(tab);
2971 } break;
2972 case Display: {
2973 QWidget *tab = nullptr;
2974 switch (page.tab) {
2975 case CanvasAcceleration:
2976 tab = m_displaySettings->CanvasAcceleration;
2977 break;
2978 case HDR:
2979 tab = m_displaySettings->HDR;
2980 break;
2981 case CanvasDecoration:
2982 tab = m_displaySettings->CanvasDecoration;
2983 break;
2985 tab = m_displaySettings->Miscellaneous;
2986 break;
2987 }
2988 m_displaySettings->tabWidget->setCurrentWidget(tab);
2989 } break;
2990
2991 default:
2992 break;
2993 }
2994}
2995
2996bool KisDlgPreferences::editPreferences(std::optional<PageDesc>page)
2997{
2998 connect(this->buttonBox(), SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonClicked(QAbstractButton*)));
2999
3000 if (page.has_value()) {
3001 PageDesc page_val = page.value();
3002 setCurrentPage(getPage(page_val.page));
3003 switchTab(page_val);
3004 }
3005
3006 int retval = exec();
3007 Q_UNUSED(retval);
3008
3009 if (!m_cancelClicked) {
3010 // General settings
3011 KisConfig cfg(false);
3012 KisImageConfig cfgImage(false);
3013
3016 cfg.setSeparateEraserCursor(m_general->m_chkSeparateEraserCursor->isChecked());
3024
3027 cfg.setForceAlwaysFullSizedOutline(!m_general->m_changeBrushOutline->isChecked());
3029 cfg.setForceAlwaysFullSizedEraserOutline(!m_general->m_changeEraserBrushOutline->isChecked());
3032
3033 KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
3034 group.writeEntry("DontUseNativeFileDialog", !m_general->m_chkNativeFileDialog->isChecked());
3035
3036 cfgImage.setMaxBrushSize(m_general->intMaxBrushSize->value());
3037 cfg.setIgnoreHighFunctionKeys(m_general->chkIgnoreHighFunctionKeys->isChecked());
3038
3039 cfg.writeEntry<bool>("use_custom_system_font", m_general->chkUseCustomFont->isChecked());
3040 if (m_general->chkUseCustomFont->isChecked()) {
3041 cfg.writeEntry<QString>("custom_system_font", m_general->cmbCustomFont->currentFont().family());
3042 cfg.writeEntry<int>("custom_font_size", m_general->intFontSize->value());
3043 }
3044 else {
3045 cfg.writeEntry<QString>("custom_system_font", "");
3046 cfg.writeEntry<int>("custom_font_size", -1);
3047 }
3048
3049 cfg.writeEntry<int>("mdi_viewmode", m_general->mdiMode());
3050 cfg.setMDIBackgroundColor(m_general->m_mdiColor->color().toXML());
3051 cfg.setMDIBackgroundImage(m_general->m_backgroundimage->text());
3052 cfg.writeEntry<int>("mdi_rubberband", m_general->m_chkRubberBand->isChecked());
3054 cfg.writeEntry("autosavefileshidden", m_general->chkHideAutosaveFiles->isChecked());
3055
3056 cfg.setBackupFile(m_general->m_backupFileCheckBox->isChecked());
3057 cfg.writeEntry("backupfilelocation", m_general->cmbBackupFileLocation->currentIndex());
3058 cfg.writeEntry("backupfilesuffix", m_general->txtBackupFileSuffix->text());
3059 cfg.writeEntry("numberofbackupfiles", m_general->intNumBackupFiles->value());
3060
3061
3069
3070 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
3071 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
3072 kritarc.setValue("EnableHiDPI", m_general->m_chkHiDPI->isChecked());
3073#if defined(Q_OS_WIN) && defined(HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY)
3074 kritarc.setValue("EnableHiDPIFractionalScaling", m_general->m_chkHiDPIFractionalScaling->isChecked());
3075#endif
3076 kritarc.setValue("LogUsage", m_general->chkUsageLogging->isChecked());
3077
3079
3080 cfg.writeEntry<bool>("useCreamyAlphaDarken", (bool)!m_general->cmbFlowMode->currentIndex());
3081 cfg.writeEntry<bool>("useSubtractiveBlendingForCmykColorSpaces", (bool)!m_general->cmbCmykBlendingMode->currentIndex());
3082
3089
3091
3093 cfg.setTouchPainting(KisConfig::TouchPainting(m_general->cmbTouchPainting->currentIndex()));
3094 cfg.writeEntry("useTouchPressureSensitivity", m_general->chkTouchPressureSensitivity->isChecked());
3095 cfg.setActivateTransformToolAfterPaste(m_general->chkEnableTransformToolAfterPaste->isChecked());
3096 cfg.setZoomHorizontal(m_general->chkZoomHorizontally->isChecked());
3097 cfg.setSelectionActionBar(m_general->chkEnableSelectionActionBar->isChecked());
3100 cfg.setCumulativeUndoRedo(m_general->chkCumulativeUndo->isChecked());
3102
3103 // Animation..
3107
3108#ifdef Q_OS_ANDROID
3109 QFileInfo fi(m_general->m_resourceFolderSelector->currentData(Qt::UserRole).value<QString>());
3110#else
3111 QFileInfo fi(m_general->m_urlResourceFolder->fileName());
3112#endif
3113 if (fi.isWritable()) {
3115 }
3116
3120
3121 // Color settings
3123 cfg.setUseSystemMonitorProfile(m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
3124 for (int i = 0; i < QApplication::screens().count(); ++i) {
3125 if (m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked()) {
3126 int currentIndex = m_colorSettings->m_monitorProfileWidgets[i]->currentIndex();
3127 QString monitorid = m_colorSettings->m_monitorProfileWidgets[i]->itemData(currentIndex).toString();
3128 cfg.setMonitorForScreen(i, monitorid);
3129 } else {
3130 cfg.setMonitorProfile(i,
3131 m_colorSettings->m_monitorProfileWidgets[i]->currentUnsqueezedText(),
3132 m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
3133 }
3134 }
3135 } else {
3139 }
3140 cfg.setUseDefaultColorSpace(m_colorSettings->m_page->useDefColorSpace->isChecked());
3141 if (cfg.useDefaultColorSpace())
3142 {
3143 KoID currentWorkingColorSpace = m_colorSettings->m_page->cmbWorkingColorSpace->currentItem();
3144 cfg.setWorkingColorSpace(currentWorkingColorSpace.id());
3145 cfg.defColorModel(KoColorSpaceRegistry::instance()->colorSpaceColorModelId(currentWorkingColorSpace.id()).id());
3146 cfg.setDefaultColorDepth(KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(currentWorkingColorSpace.id()).id());
3147 }
3148
3149 cfg.writeEntry("ExrDefaultColorProfile", m_colorSettings->m_page->cmbColorProfileForEXR->currentText());
3150
3151 cfgImage.setDefaultProofingConfig(*m_colorSettings->m_page->wdgProofingOptions->currentProofingConfig());
3152 cfg.setUseBlackPointCompensation(m_colorSettings->m_page->chkBlackpoint->isChecked());
3153 cfg.setAllowLCMSOptimization(m_colorSettings->m_page->chkAllowLCMSOptimization->isChecked());
3154 cfg.setForcePaletteColors(m_colorSettings->m_page->chkForcePaletteColor->isChecked());
3156 cfg.setRenderIntent(m_colorSettings->m_page->cmbMonitorIntent->currentIndex());
3157
3158 // Tablet settings
3159 cfg.setPressureTabletCurve( m_tabletSettings->m_page->pressureCurve->curve().toString() );
3161 m_tabletSettings->m_page->chkUseRightMiddleClickWorkaround->isChecked());
3162
3163#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
3164 cfg.setUseWin8PointerInput(m_tabletSettings->m_page->radioWin8PointerInput->isChecked());
3165
3166# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
3167 // Qt6 supports switching the tablet API on the fly
3168 using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
3169 if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) {
3170 nativeWindowsApp->setWinTabEnabled(!cfg.useWin8PointerInput());
3171 }
3172# endif
3173#endif
3174 cfg.writeEntry<bool>("useTimestampsForBrushSpeed", m_tabletSettings->m_page->chkUseTimestampsForBrushSpeed->isChecked());
3175
3176#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_PAGE_UP_DOWN
3177 cfg.setUsePageUpDownMouseButtonEmulationWorkaround(
3178 m_tabletSettings->m_page->chkUsePageUpDownMouseButtonEmulationWorkaround->isChecked());
3179#endif
3180
3181#if KRITA_QT_HAS_ANDROID_EMULATE_MOUSE_BUTTONS_FOR_HIGH_FUNCTION_KEYS
3182 cfg.setUseHighFunctionKeyMouseButtonEmulationWorkaround(
3183 m_tabletSettings->m_page->chkUseHighFunctionKeyMouseButtonEmulationWorkaround->isChecked());
3184#endif
3185
3186#if KRITA_QT_HAS_ANDROID_IGNORE_HISTORIC_TABLET_EVENTS
3187 cfg.setUseIgnoreHistoricTabletEventsWorkaround(
3188 m_tabletSettings->m_page->chkUseIgnoreHistoricTabletEventsWorkaround->isChecked());
3189#endif
3190
3191 cfg.writeEntry<int>("maxAllowedSpeedValue", m_tabletSettings->m_page->intMaxAllowedBrushSpeed->value());
3192 cfg.writeEntry<int>("speedValueSmoothing", m_tabletSettings->m_page->intBrushSpeedSmoothing->value());
3193 // the angle is saved in clockwise direction to be consistent with Drawing Angle, so negate
3194 cfg.writeEntry<int>("tiltDirectionOffset", -m_tabletSettings->m_page->tiltDirectionOffsetAngle->angle());
3195
3197
3198 if (!cfg.useOpenGL() && m_displaySettings->grpOpenGL->isChecked())
3199 cfg.setCanvasState("TRY_OPENGL");
3200
3201 if (m_displaySettings->grpOpenGL->isChecked()) {
3203 m_displaySettings->cmbPreferredRenderer->itemData(
3204 m_displaySettings->cmbPreferredRenderer->currentIndex()).toInt());
3206 } else {
3208 }
3209
3210 if (KisOpenGL::xcbGlProviderProtocol().has_value()) {
3211 cfg.setPreferXcbEglProvider(m_displaySettings->cmbPreferredXcbGlApi->currentData().value<KisOpenGL::XcbGLProviderProtocol>() == KisOpenGL::XCB_EGL);
3212 }
3213
3214 cfg.setUseOpenGLTextureBuffer(m_displaySettings->chkUseTextureBuffer->isChecked());
3215 cfg.setOpenGLFilteringMode(m_displaySettings->cmbFilterMode->currentIndex());
3216 cfg.setRootSurfaceFormat(&kritarc, indexToFormat(m_displaySettings->cmbPreferedRootSurfaceFormat->currentIndex()));
3217 cfg.setAssistantsDrawMode(indexToAssistantDrawMode(m_displaySettings->cmbAssistantsDrawMode->currentIndex()));
3218
3219 cfg.setCheckSize(m_displaySettings->intCheckSize->value());
3220 cfg.setScrollingCheckers(m_displaySettings->chkMoving->isChecked());
3221 cfg.setCheckersColor1(m_displaySettings->colorChecks1->color().toQColor());
3222 cfg.setCheckersColor2(m_displaySettings->colorChecks2->color().toQColor());
3223 cfg.setCanvasBorderColor(m_displaySettings->canvasBorder->color().toQColor());
3224 cfg.setHideScrollbars(m_displaySettings->hideScrollbars->isChecked());
3225 KoColor c = m_displaySettings->btnSelectionOverlayColor->color();
3226 c.setOpacity(m_displaySettings->sldSelectionOverlayOpacity->value());
3228 cfgImage.setSelectionOutlineOpacity(m_displaySettings->sldSelectionOutlineOpacity->value());
3229 cfg.setAntialiasCurves(m_displaySettings->chkCurveAntialiasing->isChecked());
3230 cfg.setAntialiasSelectionOutline(m_displaySettings->chkSelectionOutlineAntialiasing->isChecked());
3231 cfg.setShowSingleChannelAsColor(m_displaySettings->chkChannelsAsColor->isChecked());
3232 cfg.setHidePopups(m_displaySettings->chkHidePopups->isChecked());
3233
3234 cfg.setHideDockersFullscreen(m_fullscreenSettings->chkDockers->checkState());
3235 cfg.setHideMenuFullscreen(m_fullscreenSettings->chkMenu->checkState());
3236 cfg.setHideScrollbarsFullscreen(m_fullscreenSettings->chkScrollbars->checkState());
3237 cfg.setHideStatusbarFullscreen(m_fullscreenSettings->chkStatusbar->checkState());
3238 cfg.setHideTitlebarFullscreen(m_fullscreenSettings->chkTitlebar->checkState());
3239 cfg.setHideToolbarFullscreen(m_fullscreenSettings->chkToolbar->checkState());
3240
3241 cfg.setCursorMainColor(m_general->cursorColorButton->color().toQColor());
3242 cfg.setEraserCursorMainColor(m_general->eraserCursorColorButton->color().toQColor());
3243 cfg.setPixelGridColor(m_displaySettings->pixelGridColorButton->color().toQColor());
3244 cfg.setPixelGridDrawingThreshold(m_displaySettings->pixelGridDrawingThresholdBox->value() / 100);
3245
3248
3250 cfg.writeEntry("forcedDpiForQtFontBugWorkaround", m_general->forcedFontDpi());
3251 }
3252
3253 return !m_cancelClicked;
3254}
qreal length(const QPointF &vec)
Definition Ellipse.cc:82
float value(const T *src, size_t ch)
qreal u
QList< QString > QStringList
const KoID AlphaColorModelID("A", ki18n("Alpha mask"))
const KoID Float16BitsColorDepthID("F16", ki18n("16-bit float/channel"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
Q_GUI_EXPORT int qt_defaultDpi()
void toggleUseDefaultColorSpace(bool useDefColorSpace)
QList< QLabel * > m_monitorProfileLabels
void toggleAllowMonitorProfileSelection(bool useSystemProfile)
QPointer< KisCIETongueWidget > m_preferredSpaceGraphic
QButtonGroup m_pasteBehaviourGroup
QPointer< QCheckBox > m_chkEnableCanvasColorSpaceManagement
QPointer< KisSqueezedComboBox > m_canvasSurfaceBitDepth
QScopedPointer< KisProofingConfigModel > m_proofModel
QPointer< KisSqueezedComboBox > m_canvasSurfaceColorSpace
QList< KisSqueezedComboBox * > m_monitorProfileWidgets
void refillMonitorProfiles(const KoID &s)
QButtonGroup m_preferredSpaceGraphicMode
ColorSettingsTab(QWidget *parent=0, const char *name=0)
WdgColorSettings * m_page
QScopedPointer< KisScreenMigrationTracker > m_screenMigrationTracker
DisplaySettingsTab(QWidget *parent=0, const char *name=0)
void slotUseOpenGLToggled(bool isChecked)
void slotPreferredSurfaceFormatChanged(int index)
FullscreenSettingsTab(QWidget *parent)
KisConfig::SessionOnStartup sessionOnStartup() const
bool kineticScrollingHiddenScrollbars()
bool saveSessionOnQuit() const
void showAdvancedCumulativeUndoSettings()
int colorSamplerPreviewCircleDiameter() const
bool autoZoomTimelineToPlaybackRange()
void colorSamplePreviewThicknessChanged(qreal value)
KisConfig::ColorSamplerPreviewStyle colorSamplerPreviewStyle() const
void colorSamplePreviewOutlineEnabledChanged(int value)
void colorSamplePreviewStyleChanged(int index)
bool colorSamplerPreviewCircleExtraCirclesEnabled() const
bool convertToImageColorspaceOnImport()
QButtonGroup m_pasteFormatGroup
OutlineStyle eraserOutlineStyle()
static KisConfig::ColorSamplerPreviewStyle getColorSamplerPreviewStyleValue(const QComboBox *cmb)
int kineticScrollingSensitivity()
void colorSamplePreviewSizeChanged(int value)
KisCumulativeUndoData m_cumulativeUndoData
QString exportMimeType()
void updateTouchPressureSensitivityEnabled(int)
bool showOutlineWhilePainting()
CursorStyle eraserCursorStyle()
static void setColorSamplerPreviewStyleItems(QComboBox *cmb)
static void setColorSamplerPreviewStyleIndexByValue(QComboBox *cmb, KisConfig::ColorSamplerPreviewStyle style)
void enableSubWindowOptions(int)
bool colorSamplerPreviewCircleOutlineEnabled() const
OutlineStyle outlineStyle()
bool showEraserOutlineWhilePainting()
CursorStyle cursorStyle()
qreal colorSamplerPreviewCircleThickness() const
GeneralTab(QWidget *parent=0, const char *name=0)
virtual KisPreferenceSet * createPreferenceSet()=0
static KisActionRegistry * instance()
The KisActionsSnapshot class.
void connectBackwardInt(QObject *sender, const char *signal, QObject *receiver, const char *method)
void connectForwardInt(QObject *sender, const char *signal, QObject *receiver, const char *method)
@ FlipOptionsMode_MenuButton
The flip options are shown as a menu accessible via a options button.
QStringList devices(DeviceType type=screen) const
Return a list of device id's for the specified type.
static KisColorManager * instance()
static const Colorimetry AdobeRGB
static const Colorimetry DisplayP3
void setCumulativeUndoData(KisCumulativeUndoData value)
bool backupFile(bool defaultValue=false) const
void setAntialiasCurves(bool v) const
void setSwitchSelectionCtrlAlt(bool value)
bool antialiasSelectionOutline(bool defaultValue=false) const
void setZoomSteps(int steps)
@ ASSISTANTS_DRAW_MODE_PIXMAP_CACHE
Definition kis_config.h:806
@ ASSISTANTS_DRAW_MODE_DIRECT
Definition kis_config.h:805
@ ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE
Definition kis_config.h:807
int zoomSteps(bool defaultValue=false) const
void setHideDockersFullscreen(const bool value) const
static CanvasSurfaceBitDepthMode canvasSurfaceBitDepthMode(QSettings *settings, bool defaultValue=false)
void setAdaptivePlaybackRange(bool value)
void setEnableCanvasSurfaceColorSpaceManagement(bool value)
bool colorSamplerPreviewCircleOutlineEnabled(bool defaultValue=false) const
void setPasteFormat(qint32 format)
QColor checkersColor2(bool defaultValue=false) const
void setColorSamplerPreviewCircleOutlineEnabled(bool enabled)
void setUseRightMiddleTabletButtonWorkaround(bool value)
void setCheckersColor1(const QColor &v) const
void setHidePopups(bool hidePopups)
void setMDIBackgroundColor(const QString &v) const
QString pressureTabletCurve(bool defaultValue=false) const
void setUndoStackLimit(int limit) const
bool hideScrollbars(bool defaultValue=false) const
int openGLFilteringMode(bool defaultValue=false) const
void setUseZip64(bool value)
bool showSingleChannelAsColor(bool defaultValue=false) const
void setHideToolbarFullscreen(const bool value) const
void setCanvasState(const QString &state) const
int kineticScrollingSensitivity(bool defaultValue=false) const
bool convertToImageColorspaceOnImport(bool defaultValue=false) const
int zoomMarginSize(bool defaultValue=false) const
void setAutoZoomTimelineToPlaybackRange(bool value)
bool showRootLayer(bool defaultValue=false) const
qint32 pasteFormat(bool defaultValue) const
void setEnableBrushSpeedLogging(bool value) const
void setExportMimeType(const QString &defaultExportMimeType)
void setUseWin8PointerInput(bool value)
qreal getPixelGridDrawingThreshold(bool defaultValue=false) const
bool switchSelectionCtrlAlt(bool defaultValue=false) const
void writeEntry(const QString &name, const T &value)
Definition kis_config.h:825
void setRenamePastedLayers(bool value)
QColor checkersColor1(bool defaultValue=false) const
void setHideScrollbars(bool value) const
bool allowLCMSOptimization(bool defaultValue=false) const
static void setCanvasSurfaceBitDepthMode(QSettings *settings, CanvasSurfaceBitDepthMode value)
void setIgnoreHighFunctionKeys(bool value)
bool activateTransformToolAfterPaste(bool defaultValue=false) const
void setNewCursorStyle(CursorStyle style)
bool hideDockersFullscreen(bool defaultValue=false) const
void setEraserCursorStyle(CursorStyle style)
bool compressKra(bool defaultValue=false) const
static bool preferXcbEglProvider(const QSettings *settings, bool defaultValue=false)
bool disableVectorOptimizations(bool defaultValue=false) const
void setCursorMainColor(const QColor &v) const
void setColorSamplerPreviewCircleThickness(qreal thickness)
void setCanvasSurfaceColorSpaceManagementMode(CanvasSurfaceMode value)
void setCumulativeUndoRedo(bool value)
void setConvertToImageColorspaceOnImport(bool value)
void setPixelGridColor(const QColor &v) const
void setToolOptionsInDocker(bool inDocker)
void setForceAlwaysFullSizedOutline(bool value) const
void setLongPressEnabled(bool value)
SessionOnStartup sessionOnStartup(bool defaultValue=false) const
void setForcePaletteColors(bool forcePaletteColors)
void setHideTitlebarFullscreen(const bool value) const
bool enableOpenGLFramerateLogging(bool defaultValue=false) const
QColor getPixelGridColor(bool defaultValue=false) const
bool useDefaultColorSpace(bool defaultvalue=false) const
bool hideMenuFullscreen(bool defaultValue=false) const
QString getMDIBackgroundColor(bool defaultValue=false) const
void setMonitorProfile(int screen, const QString &monitorProfile, bool override) const
void setUseDefaultColorSpace(bool value) const
void setDefaultColorDepth(const QString &depth) const
bool hideScrollbarsFullscreen(bool defaultValue=false) const
TouchPainting touchPainting(bool defaultValue=false) const
void setSeparateEraserCursor(bool value) const
qint32 monitorRenderIntent(bool defaultValue=false) const
void setActivateTransformToolAfterPaste(bool value)
int kineticScrollingGesture(bool defaultValue=false) const
bool useZip64(bool defaultValue=false) const
bool calculateAnimationCacheInBackground(bool defaultValue=false) const
int favoritePresets(bool defaultValue=false) const
bool zoomHorizontal(bool defaultValue=false) const
QString getMDIBackgroundImage(bool defaultValue=false) const
void setAssistantsDrawMode(AssistantsDrawMode value)
CanvasSurfaceMode canvasSurfaceColorSpaceManagementMode(bool defaultValue=false) const
bool hideToolbarFullscreen(bool defaultValue=false) const
bool showCanvasMessages(bool defaultValue=false) const
void setUseSystemMonitorProfile(bool _useSystemMonitorProfile) const
bool useWin8PointerInput(bool defaultValue=false) const
bool useOpenGLTextureBuffer(bool defaultValue=false) const
void setCalculateAnimationCacheInBackground(bool value)
void setColorSamplerPreviewCircleExtraCirclesEnabled(bool enabled)
void setAutoSaveInterval(int seconds) const
void setShowSingleChannelAsColor(bool asColor)
void setTrimFramesImport(bool trim)
bool forcePaletteColors(bool defaultValue=false) const
void setAllowLCMSOptimization(bool allowLCMSOptimization)
void setColorSamplerPreviewCircleDiameter(int style)
void setRenderIntent(qint32 monitorRenderIntent) const
void setFavoritePresets(const int value)
void setEraserOutlineStyle(OutlineStyle style)
void setShowOutlineWhilePainting(bool showOutlineWhilePainting) const
RootSurfaceFormat rootSurfaceFormat(bool defaultValue=false) const
QColor canvasBorderColor(bool defaultValue=false) const
int colorSamplerPreviewCircleDiameter(bool defaultValue=false) const
QString exportMimeType(bool defaultValue) const
void setScrollingCheckers(bool scrollCheckers) const
const QString getScreenStringIdentfier(int screenNo) const
void setBackupFile(bool backupFile) const
void logImportantSettings() const
Log the most interesting settings to the usage log.
Definition kis_config.cc:77
CursorStyle newCursorStyle(bool defaultValue=false) const
bool useCumulativeUndoRedo(bool defaultValue=false) const
void setCheckSize(qint32 checkSize) const
CursorStyle eraserCursorStyle(bool defaultValue=false) const
void setKineticScrollingGesture(int kineticScroll)
void setPreferXcbEglProvider(bool value)
void setPixelGridDrawingThreshold(qreal v) const
void setMonitorForScreen(int screen, const QString &monitor)
void setCanvasBorderColor(const QColor &color) const
QString monitorProfile(int screen) const
get the profile the user has selected for the given screen
@ TOUCH_PAINTING_DISABLED
Definition kis_config.h:50
void setShowCanvasMessages(bool show)
qint32 checkSize(bool defaultValue=false) const
void setWorkingColorSpace(const QString &workingColorSpace) const
KisCumulativeUndoData cumulativeUndoData(bool defaultValue=false) const
OutlineStyle newOutlineStyle(bool defaultValue=false) const
bool forceAlwaysFullSizedOutline(bool defaultValue=false) const
ColorSamplerPreviewStyle
Definition kis_config.h:138
void setPressureTabletCurve(const QString &curveString) const
qreal colorSamplerPreviewCircleThickness(bool defaultValue=false) const
QString workingColorSpace(bool defaultValue=false) const
void setEnableOpenGLFramerateLogging(bool value) const
bool renamePastedLayers(bool defaultValue=false) const
void setNewOutlineStyle(OutlineStyle style)
void setCheckersColor2(const QColor &v) const
void setShowRootLayer(bool showRootLayer) const
OutlineStyle eraserOutlineStyle(bool defaultValue=false) const
void setUseBlackPointCompensation(bool useBlackPointCompensation) const
bool kineticScrollingEnabled(bool defaultValue=false) const
void setUseOpenGLTextureBuffer(bool useBuffer)
void setTrimKra(bool trim)
bool hideTitlebarFullscreen(bool defaultValue=false) const
bool useRightMiddleTabletButtonWorkaround(bool defaultValue=false) const
bool longPressEnabled(bool defaultValue=false) const
void setColorSamplerPreviewStyle(ColorSamplerPreviewStyle style)
bool hidePopups(bool defaultValue=false) const
bool enableCanvasSurfaceColorSpaceManagement(bool defaultValue=false) const
void setRootSurfaceFormat(RootSurfaceFormat value)
bool autoPinLayersToTimeline(bool defaultValue=false) const
bool toolOptionsInDocker(bool defaultValue=false) const
void setOpenGLFilteringMode(int filteringMode)
void setKineticScrollingHideScrollbars(bool scrollbar)
void setAntialiasSelectionOutline(bool v) const
bool trimKra(bool defaultValue=false) const
bool enableBrushSpeedLogging(bool defaultValue=false) const
bool forceAlwaysFullSizedEraserOutline(bool defaultValue=false) const
T readEntry(const QString &name, const T &defaultValue=T())
Definition kis_config.h:835
int autoSaveInterval(bool defaultValue=false) const
QString defColorModel(bool defaultValue=false) const
void setDisableVectorOptimizations(bool value)
void setHideStatusbarFullscreen(const bool value) const
void setCompressKra(bool compress)
void setTouchPainting(TouchPainting value) const
bool showOutlineWhilePainting(bool defaultValue=false) const
void setShowEraserOutlineWhilePainting(bool showEraserOutlineWhilePainting) const
void setHideMenuFullscreen(const bool value) const
bool useSystemMonitorProfile(bool defaultValue=false) const
bool autoZoomTimelineToPlaybackRange(bool defaultValue=false) const
bool scrollCheckers(bool defaultValue=false) const
CanvasSurfaceBitDepthMode
Definition kis_config.h:189
void setZoomMarginSize(int zoomMarginSize)
bool hideStatusbarFullscreen(bool defaultValue=false) const
bool colorSamplerPreviewCircleExtraCirclesEnabled(bool defaultValue=false) const
void setZoomHorizontal(bool value)
bool kineticScrollingHiddenScrollbars(bool defaultValue=false) const
bool useOpenGL(bool defaultValue=false) const
bool trimFramesImport(bool defaultValue=false) const
void setForceAlwaysFullSizedEraserOutline(bool value) const
bool selectionActionBar(bool defaultValue=false) const
int undoStackLimit(bool defaultValue=false) const
bool useBlackPointCompensation(bool defaultValue=false) const
bool saveSessionOnQuit(bool defaultValue) const
ColorSamplerPreviewStyle colorSamplerPreviewStyle(bool defaultValue=false) const
void setMDIBackgroundImage(const QString &fileName) const
QColor getCursorMainColor(bool defaultValue=false) const
void setSelectionActionBar(bool value)
qint32 pasteBehaviour(bool defaultValue=false) const
AssistantsDrawMode assistantsDrawMode(bool defaultValue=false) const
bool separateEraserCursor(bool defaultValue=false) const
void setEraserCursorMainColor(const QColor &v) const
void setSaveSessionOnQuit(bool value)
bool disableAVXOptimizations(bool defaultValue=false) const
bool showEraserOutlineWhilePainting(bool defaultValue=false) const
void setPasteBehaviour(qint32 behaviour) const
void setSessionOnStartup(SessionOnStartup value)
void setHideScrollbarsFullscreen(const bool value) const
QString monitorForScreen(int screen, const QString &defaultMonitor, bool defaultValue=true) const
void setAutoPinLayersToTimeline(bool value)
QColor getEraserCursorMainColor(bool defaultValue=false) const
bool antialiasCurves(bool defaultValue=false) const
void setKineticScrollingSensitivity(int sensitivity)
bool ignoreHighFunctionKeys(bool defaultValue=false) const
void setDisableAVXOptimizations(bool value)
bool adaptivePlaybackRange(bool defaultValue=false) const
void setKineticScrollingEnabled(bool enabled)
std::pair< KoColorConversionTransformation::Intent, KoColorConversionTransformation::ConversionFlags > Options
KisCumulativeUndoData cumulativeUndoData() const
KoConfigAuthorPage * m_authorPage
PerformanceTab * m_performanceSettings
ColorSettingsTab * m_colorSettings
PopupPaletteTab * m_popupPaletteSettings
KPageWidgetItem * getPage(Page page_enum)
KisInputConfigurationPage * m_inputConfiguration
FullscreenSettingsTab * m_fullscreenSettings
ShortcutSettingsTab * m_shortcutSettings
TabletSettingsTab * m_tabletSettings
bool editPreferences(std::optional< PageDesc > page)
QList< KPageWidgetItem * > m_pages
DisplaySettingsTab * m_displaySettings
void slotButtonClicked(QAbstractButton *button)
KisDlgPreferences(QWidget *parent=0, const char *name=0)
void switchTab(PageDesc tab)
void showEvent(QShowEvent *event) override
void setEnableProgressReporting(bool value)
void setUseAnimationCacheRegionOfInterest(bool value)
bool useAnimationCacheFrameSizeLimit(bool defaultValue=false) const
void setAnimationCacheFrameSizeLimit(int value)
void setFrameRenderingClones(int value)
int animationCacheFrameSizeLimit(bool defaultValue=false) const
KisProofingConfigurationSP defaultProofingconfiguration(bool requestDefault=false)
void setMaxNumberOfThreads(int value)
bool useAnimationCacheRegionOfInterest(bool defaultValue=false) const
int frameRenderingClones(bool defaultValue=false) const
void setDetectFpsLimit(bool value)
void setFpsLimit(int value)
QString swapDir(bool requestDefault=false)
int maxNumberOfThreads(bool defaultValue=false) const
qreal memoryPoolLimitPercent(bool requestDefault=false) const
void setEnablePerfLog(bool value)
bool detectFpsLimit(bool defaultValue=false) const
bool enableProgressReporting(bool requestDefault=false) const
void setUseAnimationCacheFrameSizeLimit(bool value)
int fpsLimit(bool defaultValue=false) const
void setSelectionOutlineOpacity(qreal value)
int maxSwapSize(bool requestDefault=false) const
void setUseOnDiskAnimationCacheSwapping(bool value)
qreal animationCacheRegionOfInterestMargin(bool defaultValue=false) const
void setFrameRenderingTimeout(int value)
void setMaxSwapSize(int value)
qreal memoryHardLimitPercent(bool requestDefault=false) const
void setMemorySoftLimitPercent(qreal value)
void setSwapDir(const QString &swapDir)
void setSelectionOverlayMaskColor(const QColor &color)
qreal selectionOutlineOpacity(bool defaultValue=false) const
void setRenameDuplicatedLayers(bool value)
static int totalRAM()
int frameRenderingTimeout(bool defaultValue=false) const
bool enablePerfLog(bool requestDefault=false) const
void setMaxBrushSize(int value)
void setRenameMergedLayers(bool value)
void setDefaultProofingConfig(const KisProofingConfiguration &config)
QColor selectionOverlayMaskColor(bool defaultValue=false) const
qreal memorySoftLimitPercent(bool requestDefault=false) const
void setMemoryHardLimitPercent(qreal value)
bool useOnDiskAnimationCacheSwapping(bool defaultValue=false) const
void setMemoryPoolLimitPercent(qreal value)
void setAnimationCacheRegionOfInterestMargin(qreal value)
static QStringList supportedMimeTypes(Direction direction)
A Configuration Dialog Page to configure the canvas input.
A container for a set of QAction objects.
Q_INVOKABLE QAction * addAction(const QString &name, QAction *action)
QList< QAction * > actions() const
virtual KisKActionCollection * actionCollection() const
Main window for Krita.
static QString descriptionForMimeType(const QString &mimeType)
Find the user-readable description for the given mimetype.
static KisOpenGLModeProber * instance()
QSurfaceFormat surfaceformatInUse() const
static OpenGLRenderer getCurrentOpenGLRenderer()
static OpenGLRenderers getSupportedOpenGLRenderers()
@ RendererSoftware
Definition kis_opengl.h:45
@ RendererDesktopGL
Definition kis_opengl.h:43
@ RendererOpenGLES
Definition kis_opengl.h:44
static QStringList getOpenGLWarnings()
static bool supportsLoD()
static OpenGLRenderer getUserPreferredOpenGLRendererConfig()
static OpenGLRenderer getQtPreferredOpenGLRenderer()
XcbGLProviderProtocol
Definition kis_opengl.h:63
static std::optional< XcbGLProviderProtocol > xcbGlProviderProtocol()
static void setUserPreferredOpenGLRendererConfig(OpenGLRenderer renderer)
static KisPart * instance()
Definition KisPart.cpp:131
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:459
static KisPlatformPluginInterfaceFactory * instance()
static KisPreferenceSetRegistry * instance()
virtual QIcon icon()=0
virtual QString header()=0
virtual void loadPreferences()=0
virtual QString name()=0
The KisProofingConfigModel class.
static const QString resourceLocationKey
std::optional< KisSurfaceColorimetry::SurfaceDescription > currentSurfaceDescription() const
ScreenInfo infoForScreen(QScreen *screen) const
void sigScreenChanged(QScreen *screen)
void addCollection(KisKActionCollection *, const QString &title=QString())
static KisSurfaceColorSpaceWrapper fromQtColorSpace(const QColorSpace &colorSpace)
static KoColorSpaceEngineRegistry * instance()
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
Definition KoColor.cpp:350
void setColor(const quint8 *data, const KoColorSpace *colorSpace=0)
Definition KoColor.cpp:186
void setOpacity(quint8 alpha)
Definition KoColor.cpp:333
void fromQColor(const QColor &c)
Convenient function for converting from a QColor.
Definition KoColor.cpp:213
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
const T value(const QString &id) const
T get(const QString &id) const
QList< QString > keys() const
Definition KoID.h:30
QString id() const
Definition KoID.cpp:63
static bool tabletInputReceived()
static void getAllUserResourceFoldersLocationsForWindowsStore(QString &standardLocation, QString &privateLocation)
getAllAppDataLocationsForWindowsStore Use this to get both private and general appdata folders which ...
static QString getAppDataLocation()
static QString saveLocation(const QString &type, const QString &suffix=QString(), bool create=true)
void load(bool requestDefault)
PerformanceTab(QWidget *parent=0, const char *name=0)
QScopedPointer< KisFrameRateLimitModel > m_frameRateModel
void slotThreadsLimitChanged(int value)
QVector< SliderAndSpinBoxSync * > m_syncs
void slotFrameClonesLimitChanged(int value)
PopupPaletteTab(QWidget *parent=0, const char *name=0)
void slotSelectorTypeChanged(int index)
WdgShortcutSettings * m_page
QScopedPointer< KisActionsSnapshot > m_snapshot
ShortcutSettingsTab(QWidget *parent=0, const char *name=0)
WdgTabletSettings * m_page
TabletSettingsTab(QWidget *parent=0, const char *name=0)
bool eventFilter(QObject *, QEvent *event) override
UnscrollableComboBox(QObject *parent)
#define KIS_SAFE_ASSERT_RECOVER(cond)
Definition kis_assert.h:126
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
Definition kis_assert.h:128
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130
int getTotalRAM()
QString shortNameOfDisplay(int index)
Q_GUI_EXPORT int qt_defaultDpi()
OutlineStyle
Definition kis_global.h:53
CursorStyle
Definition kis_global.h:62
#define koIcon(name)
Use these macros for icons without any issues.
Definition kis_icon.h:25
QString button(const QWheelEvent &ev)
QIcon loadIcon(const QString &name)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
void install(QSpinBox *spinBox, std::function< QString(int)> messageFn)
void connectControl(KisCompositeOpListWidget *widget, QObject *source, const char *property)
void connectControlState(QSpinBox *spinBox, QObject *source, const char *readStateProperty, const char *writeProperty)
static const QStringList allowedColorHistorySortingValues({"none", "hsv"})
State validate(QString &line, int &) const override
BackupSuffixValidator(QObject *parent)
const QStringList invalidCharacters
void linkActivated(const QString &link)
virtual bool isSuitableForDisplay() const =0
virtual const KoColorProfile * addProfile(const QString &filename)=0
QString colorSpaceId(const QString &colorModelId, const QString &colorDepthId) const
static KoColorSpaceRegistry * instance()
KoID colorSpaceColorDepthId(const QString &_colorSpaceId) const
QString defaultProfileForColorSpace(const QString &colorSpaceId) const
KoID colorSpaceColorModelId(const QString &_colorSpaceId) const
QList< KoID > listKeys() const
State validate(QString &line, int &) const override
WritableLocationValidator(QObject *parent)