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
43#include <KisApplication.h>
44#include <KisDocument.h>
45#include <kis_icon.h>
46#include <KisPart.h>
49#include <KoColorProfile.h>
50#include <KoColorSpaceEngine.h>
51#include <KoConfigAuthorPage.h>
52#include <KoConfig.h>
53#include <KoPointerEvent.h>
54
55#include <KoFileDialog.h>
56#include "KoID.h"
57#include <KoVBox.h>
58
59#include <KTitleWidget>
60#include <KoResourcePaths.h>
61#include <kformat.h>
62#include <klocalizedstring.h>
63#include <kstandardguiitem.h>
64#include <kundo2stack.h>
65
66#include <KisResourceCacheDb.h>
67#include <KisResourceLocator.h>
68
72#include "kis_action_registry.h"
73#include <kis_image.h>
74#include <KisSqueezedComboBox.h>
75#include "kis_clipboard.h"
77#include "KoColorSpace.h"
80#include "kis_color_manager.h"
81#include "kis_config.h"
82#include "kis_image_config.h"
84#include "KisMainWindow.h"
85#include "KisMimeDatabase.h"
90
92
93// for the performance update
94#include <kis_cubic_curve.h>
95#include <kis_signals_blocker.h>
96
99
101#include <config-qt-patches-present.h>
102
103#ifdef Q_OS_WIN
104#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
105// this include is Qt5-only, the switch to WinTab is embedded in Qt
106# include "config_qt5_has_wintab_switch.h"
107#else
108# include <QtGui/private/qguiapplication_p.h>
109# include <QtGui/qpa/qplatformintegration.h>
110#endif
111#include "config-high-dpi-scale-factor-rounding-policy.h"
113#endif
114
120Q_GUI_EXPORT int qt_defaultDpi();
121
122QString shortNameOfDisplay(int index)
123{
124 if (QGuiApplication::screens().length() <= index) {
125 return QString();
126 }
127 QScreen* screen = QGuiApplication::screens()[index];
128 QString resolution = QString::number(screen->geometry().width()).append("x").append(QString::number(screen->geometry().height()));
129 QString name = screen->name();
130 // 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
131
132 KisConfig cfg(true);
133 QString shortName = resolution + " " + name + " " + cfg.getScreenStringIdentfier(index);
134 return shortName;
135}
136
137
138struct WritableLocationValidator : public QValidator {
140 : QValidator(parent)
141 {
142 }
143
144 State validate(QString &line, int &/*pos*/) const override
145 {
146 QFileInfo fi(line);
147 if (!fi.isWritable()) {
148 return Invalid;
149 }
150 return Acceptable;
151 }
152};
153
154struct BackupSuffixValidator : public QValidator {
155 BackupSuffixValidator(QObject *parent)
156 : QValidator(parent)
158 << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"
159 << "/" << "\\" << ":" << ";" << " ")
160 {}
161
163
165
166 State validate(QString &line, int &/*pos*/) const override
167 {
168 Q_FOREACH(const QString invalidChar, invalidCharacters) {
169 if (line.contains(invalidChar)) {
170 return Invalid;
171 }
172 }
173 return Acceptable;
174 }
175};
176
177/*
178 * We need this because the final item in the ComboBox is a used as an action to launch file selection dialog.
179 * So disabling it makes sure that user doesn't accidentally scroll and select it and get confused why the
180 * file picker launched.
181 */
182class UnscrollableComboBox : public QObject
183{
184public:
185 UnscrollableComboBox(QObject *parent)
186 : QObject(parent)
187 {
188 }
189
190 bool eventFilter(QObject *, QEvent *event) override
191 {
192 if (event->type() == QEvent::Wheel) {
193 event->accept();
194 return true;
195 }
196 return false;
197 }
198};
199
200GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
201 : WdgGeneralSettings(_parent, _name)
202{
203 KisConfig cfg(true);
204
205 // HACK ALERT!
206 // QScrollArea contents are opaque at multiple levels
207 // The contents themselves AND the viewport widget
208 {
209 scrollAreaWidgetContents->setAutoFillBackground(false);
210 scrollAreaWidgetContents->parentWidget()->setAutoFillBackground(false);
211 }
212
213 //
214 // Cursor Tab
215 //
216
217 QStringList cursorItems = QStringList()
218 << i18n("No Cursor")
219 << i18n("Tool Icon")
220 << i18n("Arrow")
221 << i18n("Small Circle")
222 << i18n("Crosshair")
223 << i18n("Triangle Righthanded")
224 << i18n("Triangle Lefthanded")
225 << i18n("Black Pixel")
226 << i18n("White Pixel");
227
228 QStringList outlineItems = QStringList()
229 << i18nc("Display options label to not DISPLAY brush outline", "No Outline")
230 << i18n("Circle Outline")
231 << i18n("Preview Outline")
232 << i18n("Tilt Outline");
233
234 // brush
235
236 m_cmbCursorShape->addItems(cursorItems);
237
238 m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());
239
240 m_cmbOutlineShape->addItems(outlineItems);
241
242 m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());
243
244 m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting());
245 m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline());
246
247 KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
248 cursorColor.fromQColor(cfg.getCursorMainColor());
249 cursorColorButton->setColor(cursorColor);
250
251 // eraser
252
253 m_chkSeparateEraserCursor->setChecked(cfg.separateEraserCursor());
254
255 m_cmbEraserCursorShape->addItems(cursorItems);
256 m_cmbEraserCursorShape->addItem(i18n("Eraser"));
257
258 m_cmbEraserCursorShape->setCurrentIndex(cfg.eraserCursorStyle());
259
260 m_cmbEraserOutlineShape->addItems(outlineItems);
261
262 m_cmbEraserOutlineShape->setCurrentIndex(cfg.eraserOutlineStyle());
263
264 m_showEraserOutlinePainting->setChecked(cfg.showEraserOutlineWhilePainting());
265 m_changeEraserBrushOutline->setChecked(!cfg.forceAlwaysFullSizedEraserOutline());
266
267 KoColor eraserCursorColor(KoColorSpaceRegistry::instance()->rgb8());
268 eraserCursorColor.fromQColor(cfg.getEraserCursorMainColor());
269 eraserCursorColorButton->setColor(eraserCursorColor);
270
271 //
272 // Window Tab
273 //
274 chkUseCustomFont->setChecked(cfg.readEntry<bool>("use_custom_system_font", false));
275 cmbCustomFont->findChild <QComboBox*>("stylesComboBox")->setVisible(false);
276
277 QString fontName = cfg.readEntry<QString>("custom_system_font", "");
278 if (fontName.isEmpty()) {
279 cmbCustomFont->setCurrentFont(qApp->font());
280
281 }
282 else {
283 int pointSize = qApp->font().pointSize();
284 cmbCustomFont->setCurrentFont(QFont(fontName, pointSize));
285 }
286 int fontSize = cfg.readEntry<int>("custom_font_size", -1);
287 if (fontSize < 0) {
288 intFontSize->setValue(qApp->font().pointSize());
289 }
290 else {
291 intFontSize->setValue(fontSize);
292 }
293
294 m_cmbMDIType->setCurrentIndex(cfg.readEntry<int>("mdi_viewmode", (int)QMdiArea::TabbedView));
295 enableSubWindowOptions(m_cmbMDIType->currentIndex());
296 connect(m_cmbMDIType, SIGNAL(currentIndexChanged(int)), SLOT(enableSubWindowOptions(int)));
297
298 m_backgroundimage->setText(cfg.getMDIBackgroundImage());
299 connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
300 connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));
301
302 QString xml = cfg.getMDIBackgroundColor();
303 KoColor mdiColor = KoColor::fromXML(xml);
304 m_mdiColor->setColor(mdiColor);
305
306 m_chkRubberBand->setChecked(cfg.readEntry<int>("mdi_rubberband", cfg.useOpenGL()));
307
308 m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());
309
310 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
311 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
312 m_chkHiDPI->setChecked(kritarc.value("EnableHiDPI", true).toBool());
313#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
314 m_chkHiDPIFractionalScaling->setChecked(kritarc.value("EnableHiDPIFractionalScaling", false).toBool());
315#else
316 m_wdgHiDPIFractionalScaling->setEnabled(false);
317#endif
318 chkUsageLogging->setChecked(kritarc.value("LogUsage", true).toBool());
319
320
321 //
322 // Tools tab
323 //
324 m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
325 cmbFlowMode->setCurrentIndex((int)!cfg.readEntry<bool>("useCreamyAlphaDarken", true));
326 cmbCmykBlendingMode->setCurrentIndex((int)!cfg.readEntry<bool>("useSubtractiveBlendingForCmykColorSpaces", true));
327 m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
328 cmbTouchPainting->addItem(
329 KoPointerEvent::tabletInputReceived() ? i18nc("touch painting", "Auto (Disabled)")
330 : i18nc("touch painting", "Auto (Enabled)"));
331 cmbTouchPainting->addItem(i18nc("touch painting", "Enabled"));
332 cmbTouchPainting->addItem(i18nc("touch painting", "Disabled"));
333 cmbTouchPainting->setCurrentIndex(int(cfg.touchPainting()));
334 chkTouchPressureSensitivity->setChecked(cfg.readEntry("useTouchPressureSensitivity", true));
335 connect(cmbTouchPainting, SIGNAL(currentIndexChanged(int)),
337 updateTouchPressureSensitivityEnabled(cmbTouchPainting->currentIndex());
338
339 chkEnableTransformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste());
340 chkZoomHorizontally->setChecked(cfg.zoomHorizontal());
341
342 chkEnableLongPress->setChecked(cfg.longPressEnabled());
343
344 m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled());
345
346 m_cmbKineticScrollingGesture->addItem(i18n("On Touch Drag"));
347 m_cmbKineticScrollingGesture->addItem(i18n("On Click Drag"));
348 m_cmbKineticScrollingGesture->addItem(i18n("On Middle-Click Drag"));
349 //m_cmbKineticScrollingGesture->addItem(i18n("On Right Click Drag"));
350
351 spnZoomSteps->setValue(cfg.zoomSteps());
352
353
354 m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture());
355 m_kineticScrollingSensitivitySlider->setRange(0, 100);
356 m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity());
357 m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars());
358
359 intZoomMarginSize->setValue(cfg.zoomMarginSize());
360
361 chkEnableSelectionActionBar->setChecked(cfg.selectionActionBar());
362
363 //
364 // File handling
365 //
366 int autosaveInterval = cfg.autoSaveInterval();
367 //convert to minutes
368 m_autosaveSpinBox->setValue(autosaveInterval / 60);
369 m_autosaveCheckBox->setChecked(autosaveInterval > 0);
370 chkHideAutosaveFiles->setChecked(cfg.readEntry<bool>("autosavefileshidden", true));
371
372 m_chkCompressKra->setChecked(cfg.compressKra());
373 chkZip64->setChecked(cfg.useZip64());
374 m_chkTrimKra->setChecked(cfg.trimKra());
375 m_chkTrimFramesImport->setChecked(cfg.trimFramesImport());
376
377 m_backupFileCheckBox->setChecked(cfg.backupFile());
378 cmbBackupFileLocation->setCurrentIndex(cfg.readEntry<int>("backupfilelocation", 0));
379 txtBackupFileSuffix->setText(cfg.readEntry<QString>("backupfilesuffix", "~"));
380 QValidator *validator = new BackupSuffixValidator(txtBackupFileSuffix);
381 txtBackupFileSuffix->setValidator(validator);
382 intNumBackupFiles->setValue(cfg.readEntry<int>("numberofbackupfiles", 1));
383
384 cmbDefaultExportFileType->clear();
386
387 QMap<QString, QString> mimeTypeMap;
388
389 foreach (const QString &mimeType, mimeFilter) {
390 QString description = KisMimeDatabase::descriptionForMimeType(mimeType);
391 mimeTypeMap.insert(description, mimeType);
392 }
393
394 // Sort after we get the description because mimeType values have image, application, etc... in front
395 QStringList sortedDescriptions = mimeTypeMap.keys();
396 sortedDescriptions.sort(Qt::CaseInsensitive);
397
398 cmbDefaultExportFileType->addItem(i18n("All Supported Files"), "all/mime");
399 foreach (const QString &description, sortedDescriptions) {
400 const QString &mimeType = mimeTypeMap.value(description);
401 cmbDefaultExportFileType->addItem(description, mimeType);
402 }
403
404 const QString mimeTypeToFind = cfg.exportMimeType(false).toUtf8();
405 const int index = cmbDefaultExportFileType->findData(mimeTypeToFind);
406
407 if (index >= 0) {
408 cmbDefaultExportFileType->setCurrentIndex(index);
409 } else {
410 // Index can't be found, default set to image/png
411 const QString defaultMimeType = "image/png";
412 const int defaultIndex = cmbDefaultExportFileType->findData(defaultMimeType);
413 if (defaultIndex >= 0) {
414 cmbDefaultExportFileType->setCurrentIndex(defaultIndex);
415 } else {
416 // Case where the default mime type is also not found in the combo box
417 qDebug() << "Default mime type not found in the combo box.";
418 }
419 }
420
421 QString selectedMimeType = cmbDefaultExportFileType->currentData().toString();
422
423 //
424 // Animation tab
425 //
426 m_chkAutoPin->setChecked(cfg.autoPinLayersToTimeline());
427 m_chkAdaptivePlaybackRange->setChecked(cfg.adaptivePlaybackRange());
428 m_chkAutoZoom->setChecked(cfg.autoZoomTimelineToPlaybackRange());
429
430 //
431 // Miscellaneous tab
432 //
433 cmbStartupSession->addItem(i18n("Open default window"));
434 cmbStartupSession->addItem(i18n("Load previous session"));
435 cmbStartupSession->addItem(i18n("Show session manager"));
436 cmbStartupSession->setCurrentIndex(cfg.sessionOnStartup());
437
438 chkSaveSessionOnQuit->setChecked(cfg.saveSessionOnQuit(false));
439
440 m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport());
441
442 m_undoStackSize->setValue(cfg.undoStackLimit());
443 chkCumulativeUndo->setChecked(cfg.useCumulativeUndoRedo());
444 connect(chkCumulativeUndo, SIGNAL(toggled(bool)), btnAdvancedCumulativeUndo, SLOT(setEnabled(bool)));
445 btnAdvancedCumulativeUndo->setEnabled(chkCumulativeUndo->isChecked());
446 connect(btnAdvancedCumulativeUndo, SIGNAL(clicked()), SLOT(showAdvancedCumulativeUndoSettings()));
448
449 chkShowRootLayer->setChecked(cfg.showRootLayer());
450
451 chkRenameMergedLayers->setChecked(KisImageConfig(true).renameMergedLayers());
452 chkRenamePastedLayers->setChecked(cfg.renamePastedLayers());
453 chkRenameDuplicatedLayers->setChecked(KisImageConfig(true).renameDuplicatedLayers());
454
455 KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
456 bool dontUseNative = true;
457#ifdef Q_OS_ANDROID
458 dontUseNative = false;
459#endif
460#ifdef Q_OS_UNIX
461 if (qgetenv("XDG_CURRENT_DESKTOP") == "KDE") {
462 dontUseNative = false;
463 }
464#endif
465#ifdef Q_OS_MACOS
466 dontUseNative = false;
467#endif
468#ifdef Q_OS_WIN
469 dontUseNative = false;
470#endif
471 m_chkNativeFileDialog->setChecked(!group.readEntry("DontUseNativeFileDialog", dontUseNative));
472
473 if (!qEnvironmentVariable("APPIMAGE").isEmpty()) {
474 // AppImages don't have access to platform plugins. BUG: 447805
475 // Setting the checkbox to false is
476 m_chkNativeFileDialog->setChecked(false);
477 m_chkNativeFileDialog->setEnabled(false);
478 }
479
480 intMaxBrushSize->setValue(KisImageConfig(true).maxBrushSize());
481 chkIgnoreHighFunctionKeys->setChecked(cfg.ignoreHighFunctionKeys());
482#ifndef Q_OS_WIN
483 // we properly support ignoring high F-keys on Windows only. To support on other platforms
484 // we should synchronize KisExtendedModifiersMatcher to ignore the keys as well.
485 chkIgnoreHighFunctionKeys->setVisible(false);
486#endif
487
488 //
489 // Resources
490 //
491 m_urlResourceFolder->setMode(KoFileDialog::OpenDirectory);
492 m_urlResourceFolder->setConfigurationName("resource_directory");
493 const QString resourceLocation = KoResourcePaths::getAppDataLocation();
494 if (QFileInfo(resourceLocation).isWritable()) {
495 m_urlResourceFolder->setFileName(resourceLocation);
496 }
497 else {
498 m_urlResourceFolder->setFileName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
499 }
500 QValidator *writableValidator = new WritableLocationValidator(m_urlResourceFolder);
501 txtBackupFileSuffix->setValidator(writableValidator);
502 connect(m_urlResourceFolder, SIGNAL(textChanged(QString)), SLOT(checkResourcePath()));
504
505 grpRestartMessage->setPixmap(
506 grpRestartMessage->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
507 grpRestartMessage->setText(i18n("You will need to Restart Krita for the changes to take an effect."));
508
509 grpAndroidWarningMessage->setVisible(false);
510 grpAndroidWarningMessage->setPixmap(
511 grpAndroidWarningMessage->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
512 grpAndroidWarningMessage->setText(
513 i18n("Saving at a Location picked from the File Picker may slow down the startup!"));
514
515#ifdef Q_OS_ANDROID
516 m_urlResourceFolder->setVisible(false);
517
518 m_resourceFolderSelector->setVisible(true);
519 m_resourceFolderSelector->installEventFilter(new UnscrollableComboBox(this));
520
521 const QList<QPair<QString, QString>> writableLocations = []() {
522 QList<QPair<QString, QString>> writableLocationsAndText;
523 // filters out the duplicates
524 const QList<QString> locations = []() {
525 QStringList filteredLocations;
526 const QStringList locations = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
527 Q_FOREACH(const QString &location, locations) {
528 if (!filteredLocations.contains(location)) {
529 filteredLocations.append(location);
530 }
531 }
532 return filteredLocations;
533 }();
534
535 bool isFirst = true;
536
537 Q_FOREACH (QString location, locations) {
538 QString text;
539 QFileInfo fileLocation(location);
540 // The first one that we get from is the "Default"
541 if (isFirst) {
542 text = i18n("Default");
543 isFirst = false;
544 } else if (location.startsWith("/data")) {
545 text = i18n("Internal Storage");
546 } else {
547 text = i18n("SD-Card");
548 }
549 if (fileLocation.isWritable()) {
550 writableLocationsAndText.append({text, location});
551 }
552 }
553 return writableLocationsAndText;
554 }();
555
556 for (auto it = writableLocations.constBegin(); it != writableLocations.constEnd(); ++it) {
557 m_resourceFolderSelector->addItem(it->first + " - " + it->second);
558 // we need it to extract out the path
559 m_resourceFolderSelector->setItemData(m_resourceFolderSelector->count() - 1, it->second, Qt::UserRole);
560 }
561
562 // if the user has selected a custom location, we add it to the list as well.
563 if (resourceLocation.startsWith("content://")) {
564 m_resourceFolderSelector->addItem(resourceLocation);
565 int index = m_resourceFolderSelector->count() - 1;
566 m_resourceFolderSelector->setItemData(index, resourceLocation, Qt::UserRole);
567 m_resourceFolderSelector->setCurrentIndex(index);
568 grpAndroidWarningMessage->setVisible(true);
569 } else {
570 // find the index of the current resource location in the writableLocation, so we can set our view to that
571 auto iterator = std::find_if(writableLocations.constBegin(),
572 writableLocations.constEnd(),
573 [&resourceLocation](QPair<QString, QString> location) {
574 return location.second == resourceLocation;
575 });
576
577 if (iterator != writableLocations.constEnd()) {
578 int index = writableLocations.indexOf(*iterator);
579 KIS_SAFE_ASSERT_RECOVER_NOOP(index < m_resourceFolderSelector->count());
580 m_resourceFolderSelector->setCurrentIndex(index);
581 }
582 }
583
584 // this should be the last item we add.
585 m_resourceFolderSelector->addItem(i18n("Choose Manually"));
586
587 connect(m_resourceFolderSelector, qOverload<int>(&QComboBox::activated), [this](int index) {
588 const int previousIndex = m_resourceFolderSelector->currentIndex();
589
590 // if it is the last item in the last item, then open file picker and set the name returned as the filename
591 if (m_resourceFolderSelector->count() - 1 == index) {
592 KoFileDialog dialog(this, KoFileDialog::OpenDirectory, "Select Directory");
593 const QString selectedDirectory = dialog.filename();
594
595 if (!selectedDirectory.isEmpty()) {
596 // if the index above "Choose Manually" is a content Uri, then we just modify it, and then set that as
597 // the index.
598 if (m_resourceFolderSelector->itemData(index - 1, Qt::DisplayRole)
599 .value<QString>()
600 .startsWith("content://")) {
601 m_resourceFolderSelector->setItemText(index - 1, selectedDirectory);
602 m_resourceFolderSelector->setItemData(index - 1, selectedDirectory, Qt::UserRole);
603 m_resourceFolderSelector->setCurrentIndex(index - 1);
604 } else {
605 // There isn't any content Uri in the ComboBox list, so just insert one, and set that as the index.
606 m_resourceFolderSelector->insertItem(index, selectedDirectory);
607 m_resourceFolderSelector->setItemData(index, selectedDirectory, Qt::UserRole);
608 m_resourceFolderSelector->setCurrentIndex(index);
609 }
610 // since we have selected the custom location, make the warning visible.
611 grpAndroidWarningMessage->setVisible(true);
612 } else {
613 m_resourceFolderSelector->setCurrentIndex(previousIndex);
614 }
615 }
616
617 // hide-unhide based on the selection of user.
618 grpAndroidWarningMessage->setVisible(
619 m_resourceFolderSelector->currentData(Qt::UserRole).value<QString>().startsWith("content://"));
620 });
621
622#else
623 m_resourceFolderSelector->setVisible(false);
624#endif
625
626 grpWindowsAppData->setVisible(false);
627#ifdef Q_OS_WIN
628 QString folderInStandardAppData;
629 QString folderInPrivateAppData;
630 KoResourcePaths::getAllUserResourceFoldersLocationsForWindowsStore(folderInStandardAppData, folderInPrivateAppData);
631
632 if (!folderInPrivateAppData.isEmpty()) {
633 const auto pathToDisplay = [](const QString &path) {
634 // Due to how Unicode word wrapping works, the string does not
635 // wrap after backslashes in Qt 5.12. We don't want the path to
636 // become too long, so we add a U+200B ZERO WIDTH SPACE to allow
637 // wrapping. The downside is that we cannot let the user select
638 // and copy the path because it now contains invisible unicode
639 // code points.
640 // See: https://bugreports.qt.io/browse/QTBUG-80892
641 return QDir::toNativeSeparators(path).replace(QChar('\\'), QStringLiteral(u"\\\u200B"));
642 };
643
644 const QDir privateResourceDir(folderInPrivateAppData);
645 const QDir appDataDir(folderInStandardAppData);
646 grpWindowsAppData->setPixmap(
647 grpWindowsAppData->style()->standardIcon(QStyle::SP_MessageBoxInformation).pixmap(QSize(32, 32)));
648 // Similar text is also used in KisViewManager.cpp
649 grpWindowsAppData->setText(i18nc("@info resource folder",
650 "<p>You are using the Microsoft Store package version of Krita. "
651 "Even though Krita can be configured to place resources under the "
652 "user AppData location, Windows may actually store the files "
653 "inside a private app location.</p>\n"
654 "<p>You should check both locations to determine where "
655 "the files are located.</p>\n"
656 "<p><b>User AppData</b> (<a href=\"copyuser\">Copy</a>):<br/>\n"
657 "%1</p>\n"
658 "<p><b>Private app location</b> (<a href=\"copyprivate\">Copy</a>):<br/>\n"
659 "%2</p>",
660 pathToDisplay(appDataDir.absolutePath()),
661 pathToDisplay(privateResourceDir.absolutePath())));
662 grpWindowsAppData->setVisible(true);
663
664 connect(grpWindowsAppData,
666 [userPath = appDataDir.absolutePath(),
667 privatePath = privateResourceDir.absolutePath()](const QString &link) {
668 if (link == QStringLiteral("copyuser")) {
669 qApp->clipboard()->setText(QDir::toNativeSeparators(userPath));
670 } else if (link == QStringLiteral("copyprivate")) {
671 qApp->clipboard()->setText(QDir::toNativeSeparators(privatePath));
672 } else {
673 qWarning() << "Unexpected link activated in lblWindowsAppDataNote:" << link;
674 }
675 });
676 }
677#endif
678
679
680 const int forcedFontDPI = cfg.readEntry("forcedDpiForQtFontBugWorkaround", -1);
681 chkForcedFontDPI->setChecked(forcedFontDPI > 0);
682 intForcedFontDPI->setValue(forcedFontDPI > 0 ? forcedFontDPI : qt_defaultDpi());
683 intForcedFontDPI->setEnabled(forcedFontDPI > 0);
684 connect(chkForcedFontDPI, SIGNAL(toggled(bool)), intForcedFontDPI, SLOT(setEnabled(bool)));
685
686 m_pasteFormatGroup.addButton(btnDownload, KisClipboard::PASTE_FORMAT_DOWNLOAD);
687 m_pasteFormatGroup.addButton(btnLocal, KisClipboard::PASTE_FORMAT_LOCAL);
688 m_pasteFormatGroup.addButton(btnBitmap, KisClipboard::PASTE_FORMAT_CLIP);
689 m_pasteFormatGroup.addButton(btnAsk, KisClipboard::PASTE_FORMAT_ASK);
690
691 QAbstractButton *button = m_pasteFormatGroup.button(cfg.pasteFormat(false));
692
693 Q_ASSERT(button);
694
695 if (button) {
696 button->setChecked(true);
697 }
698}
699
701{
702 KisConfig cfg(true);
703
704 m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle(true));
705 m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle(true));
706 m_chkSeparateEraserCursor->setChecked(cfg.readEntry<bool>("separateEraserCursor", false));
707 m_cmbEraserCursorShape->setCurrentIndex(cfg.eraserCursorStyle(true));
708 m_cmbEraserOutlineShape->setCurrentIndex(cfg.eraserOutlineStyle(true));
709
710 chkShowRootLayer->setChecked(cfg.showRootLayer(true));
711 m_autosaveCheckBox->setChecked(cfg.autoSaveInterval(true) > 0);
712 //convert to minutes
713 m_autosaveSpinBox->setValue(cfg.autoSaveInterval(true) / 60);
714 chkHideAutosaveFiles->setChecked(true);
715
716 m_undoStackSize->setValue(cfg.undoStackLimit(true));
717 chkCumulativeUndo->setChecked(cfg.useCumulativeUndoRedo(true));
719
720 m_backupFileCheckBox->setChecked(cfg.backupFile(true));
721 cmbBackupFileLocation->setCurrentIndex(0);
722 txtBackupFileSuffix->setText("~");
723 intNumBackupFiles->setValue(1);
724
725 m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true));
726 m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline(true));
727 m_showEraserOutlinePainting->setChecked(cfg.showEraserOutlineWhilePainting(true));
728 m_changeEraserBrushOutline->setChecked(!cfg.forceAlwaysFullSizedEraserOutline(true));
729
730#if defined Q_OS_ANDROID || defined Q_OS_MACOS || defined Q_OS_WIN
731 m_chkNativeFileDialog->setChecked(true);
732#else
733 m_chkNativeFileDialog->setChecked(false);
734#endif
735
736 intMaxBrushSize->setValue(1000);
737
738 chkIgnoreHighFunctionKeys->setChecked(cfg.ignoreHighFunctionKeys(true));
739
740
741 chkUseCustomFont->setChecked(false);
742 cmbCustomFont->setCurrentFont(qApp->font());
743 intFontSize->setValue(qApp->font().pointSize());
744
745
746 m_cmbMDIType->setCurrentIndex((int)QMdiArea::TabbedView);
747 m_chkRubberBand->setChecked(cfg.useOpenGL(true));
748 KoColor mdiColor;
749 mdiColor.fromXML(cfg.getMDIBackgroundColor(true));
750 m_mdiColor->setColor(mdiColor);
751 m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
752 m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
753 m_chkCompressKra->setChecked(cfg.compressKra(true));
754 m_chkTrimKra->setChecked(cfg.trimKra(true));
755 m_chkTrimFramesImport->setChecked(cfg.trimFramesImport(true));
756 chkZip64->setChecked(cfg.useZip64(true));
757 m_chkHiDPI->setChecked(true);
758#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
759 m_chkHiDPIFractionalScaling->setChecked(true);
760#endif
761 chkUsageLogging->setChecked(true);
762 m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
763 cmbFlowMode->setCurrentIndex(0);
764 chkEnableLongPress->setChecked(cfg.longPressEnabled(true));
765 m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled(true));
766 m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true));
767 spnZoomSteps->setValue(cfg.zoomSteps(true));
768 m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity(true));
769 m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars(true));
770 intZoomMarginSize->setValue(cfg.zoomMarginSize(true));
771 m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
772 cmbTouchPainting->setCurrentIndex(int(cfg.touchPainting(true)));
773 chkTouchPressureSensitivity->setChecked(true);
774 chkEnableTransformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste(true));
775 chkZoomHorizontally->setChecked(cfg.zoomHorizontal(true));
776 m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true));
777
778 KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
779 cursorColor.fromQColor(cfg.getCursorMainColor(true));
780 cursorColorButton->setColor(cursorColor);
781
782 KoColor eraserCursorColor(KoColorSpaceRegistry::instance()->rgb8());
783 eraserCursorColor.fromQColor(cfg.getEraserCursorMainColor(true));
784 eraserCursorColorButton->setColor(eraserCursorColor);
785
786
787 m_chkAutoPin->setChecked(cfg.autoPinLayersToTimeline(true));
788 m_chkAdaptivePlaybackRange->setChecked(cfg.adaptivePlaybackRange(false));
789
790 m_urlResourceFolder->setFileName(KoResourcePaths::getAppDataLocation());
791
792 chkForcedFontDPI->setChecked(false);
793 intForcedFontDPI->setValue(qt_defaultDpi());
794 intForcedFontDPI->setEnabled(false);
795
796 chkRenameMergedLayers->setChecked(KisImageConfig(true).renameMergedLayers(true));
797 chkRenamePastedLayers->setChecked(cfg.renamePastedLayers(true));
798 chkRenameDuplicatedLayers->setChecked(KisImageConfig(true).renameDuplicatedLayers(true));
799
800 QAbstractButton *button = m_pasteFormatGroup.button(cfg.pasteFormat(true));
801 Q_ASSERT(button);
802
803 if (button) {
804 button->setChecked(true);
805 }
806}
807
809{
810 KisDlgConfigureCumulativeUndo dlg(m_cumulativeUndoData, m_undoStackSize->value(), this);
811 if (dlg.exec() == KoDialog::Accepted) {
813 }
814}
815
817{
818 return (CursorStyle)m_cmbCursorShape->currentIndex();
819}
820
822{
823 return (OutlineStyle)m_cmbOutlineShape->currentIndex();
824}
825
827{
828 return (CursorStyle)m_cmbEraserCursorShape->currentIndex();
829}
830
832{
833 return (OutlineStyle)m_cmbEraserOutlineShape->currentIndex();
834}
835
837{
838 return (KisConfig::SessionOnStartup)cmbStartupSession->currentIndex();
839}
840
842{
843 return chkSaveSessionOnQuit->isChecked();
844}
845
847{
848 return chkShowRootLayer->isChecked();
849}
850
852{
853 //convert to seconds
854 return m_autosaveCheckBox->isChecked() ? m_autosaveSpinBox->value() * 60 : 0;
855}
856
858{
859 return m_undoStackSize->value();
860}
861
863{
864 return m_showOutlinePainting->isChecked();
865}
866
868{
869 return m_showEraserOutlinePainting->isChecked();
870}
871
873{
874 return m_cmbMDIType->currentIndex();
875}
876
878{
879 return m_chkCanvasMessages->isChecked();
880}
881
883{
884 return m_chkCompressKra->isChecked();
885}
886
888{
889 return m_chkTrimKra->isChecked();
890}
891
893{
894 return m_chkTrimFramesImport->isChecked();
895}
896
898{
899 return cmbDefaultExportFileType->currentData().toString();
900}
901
903{
904 return chkZip64->isChecked();
905}
906
908{
909 return m_radioToolOptionsInDocker->isChecked();
910}
911
913{
914 return spnZoomSteps->value();
915}
916
918{
919 return chkEnableLongPress->isChecked();
920}
921
923{
924 return m_groupBoxKineticScrollingSettings->isChecked();
925}
926
928{
929 return m_cmbKineticScrollingGesture->currentIndex();
930}
931
933{
934 return m_kineticScrollingSensitivitySlider->value();
935}
936
938{
939 return m_chkKineticScrollingHideScrollbars->isChecked();
940}
941
943{
944 return intZoomMarginSize->value();
945}
946
948{
949 return m_chkSwitchSelectionCtrlAlt->isChecked();
950}
951
953{
954 return m_chkConvertOnImport->isChecked();
955}
956
958{
959 return m_chkAutoPin->isChecked();
960}
961
963{
964 return m_chkAdaptivePlaybackRange->isChecked();
965}
966
968{
969 return m_chkAutoZoom->isChecked();
970}
971
973{
974 return chkForcedFontDPI->isChecked() ? intForcedFontDPI->value() : -1;
975}
976
978{
979 return chkRenameMergedLayers->isChecked();
980}
981
983{
984 return chkRenamePastedLayers->isChecked();
985}
986
988{
989 return chkRenameDuplicatedLayers->isChecked();
990}
991
993{
994 KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
995 dialog.setCaption(i18n("Select a Background Image"));
996 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
997 dialog.setImageFilters();
998
999 QString fn = dialog.filename();
1000 // dialog box was canceled or somehow no file was selected
1001 if (fn.isEmpty()) {
1002 return;
1003 }
1004
1005 QImage image(fn);
1006 if (image.isNull()) {
1007 QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("%1 is not a valid image file!", fn));
1008 }
1009 else {
1010 m_backgroundimage->setText(fn);
1011 }
1012}
1013
1015{
1016 // clearing the background image text will implicitly make the background color be used
1017 m_backgroundimage->setText("");
1018}
1019
1021{
1022 const QFileInfo fi(m_urlResourceFolder->fileName());
1023 if (!fi.isWritable()) {
1024 grpNonWritableLocation->setPixmap(
1025 grpNonWritableLocation->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
1026 grpNonWritableLocation->setText(
1027 i18nc("@info resource folder", "<b>Warning:</b> this location is not writable."));
1028 grpNonWritableLocation->setVisible(true);
1029 } else {
1030 grpNonWritableLocation->setVisible(false);
1031 }
1032}
1033
1035{
1036 group_subWinMode->setEnabled(mdi_mode == QMdiArea::SubWindowView);
1037}
1038
1040{
1041 chkTouchPressureSensitivity->setEnabled(touchPainting != int(KisConfig::TOUCH_PAINTING_DISABLED));
1042}
1043
1044
1045#include "kactioncollection.h"
1046#include "KisActionsSnapshot.h"
1047
1048ShortcutSettingsTab::ShortcutSettingsTab(QWidget *parent, const char *name)
1049 : QWidget(parent)
1050{
1051 setObjectName(name);
1052
1053 QGridLayout * l = new QGridLayout(this);
1054 l->setContentsMargins(0, 0, 0, 0);
1055 m_page = new WdgShortcutSettings(this);
1056 l->addWidget(m_page, 0, 0);
1057
1058
1059 m_snapshot.reset(new KisActionsSnapshot);
1060
1061 KisKActionCollection *collection =
1063
1064 Q_FOREACH (QAction *action, collection->actions()) {
1065 m_snapshot->addAction(action->objectName(), action);
1066 }
1067
1068 QMap<QString, KisKActionCollection*> sortedCollections =
1069 m_snapshot->actionCollections();
1070
1071 for (auto it = sortedCollections.constBegin(); it != sortedCollections.constEnd(); ++it) {
1072 m_page->addCollection(it.value(), it.key());
1073 }
1074}
1075
1079
1084
1090
1095
1096ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
1097 : QWidget(parent)
1098 , m_proofModel(new KisProofingConfigModel())
1099{
1100 setObjectName(name);
1101
1102 // XXX: Make sure only profiles that fit the specified color model
1103 // are shown in the profile combos
1104
1105 QGridLayout * l = new QGridLayout(this);
1106 l->setContentsMargins(0, 0, 0, 0);
1107 m_page = new WdgColorSettings(this);
1108 l->addWidget(m_page, 0, 0);
1109
1110 KisConfig cfg(true);
1111
1113
1114 if (!m_colorManagedByOS) {
1115 m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile());
1116 connect(m_page->chkUseSystemMonitorProfile, SIGNAL(toggled(bool)), this, SLOT(toggleAllowMonitorProfileSelection(bool)));
1117 }
1118 m_page->chkUseSystemMonitorProfile->setVisible(!m_colorManagedByOS);
1119
1120 m_page->useDefColorSpace->setChecked(cfg.useDefaultColorSpace());
1121 connect(m_page->useDefColorSpace, SIGNAL(toggled(bool)), this, SLOT(toggleUseDefaultColorSpace(bool)));
1123 for (QList<KoID>::iterator id = colorSpaces.begin(); id != colorSpaces.end(); /* nop */) {
1125 id = colorSpaces.erase(id);
1126 } else {
1127 ++id;
1128 }
1129 }
1130 m_page->cmbWorkingColorSpace->setIDList(colorSpaces);
1131 m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
1132 m_page->cmbWorkingColorSpace->setEnabled(cfg.useDefaultColorSpace());
1133
1134 if (!m_colorManagedByOS) {
1135 m_page->bnAddColorProfile->setIcon(koIcon("document-import-16"));
1136 connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));
1137 }
1138 m_page->bnAddColorProfile->setVisible(!m_colorManagedByOS);
1139
1140 {
1141 QStringList profiles;
1142 QMap<QString, const KoColorProfile *> profileList;
1143 Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(RGBAColorModelID.id())) {
1144 profileList[profile->name()] = profile;
1145 profiles.append(profile->name());
1146 }
1147
1148 std::sort(profiles.begin(), profiles.end());
1149 Q_FOREACH (const QString profile, profiles) {
1150 m_page->cmbColorProfileForEXR->addSqueezedItem(profile);
1151 }
1152
1154 const QString defaultProfile = KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId);
1155 const QString userProfile = cfg.readEntry("ExrDefaultColorProfile", defaultProfile);
1156
1157 m_page->cmbColorProfileForEXR->setCurrent(profiles.contains(userProfile) ? userProfile : defaultProfile);
1158 }
1159
1160
1161 if (!m_colorManagedByOS) {
1162 QFormLayout *monitorProfileGrid = new QFormLayout(m_page->monitorprofileholder);
1163 monitorProfileGrid->setContentsMargins(0, 0, 0, 0);
1164 for(int i = 0; i < QGuiApplication::screens().count(); ++i) {
1165 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)));
1166 lbl->setWordWrap(true);
1169 cmb->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1170 monitorProfileGrid->addRow(lbl, cmb);
1172 }
1173
1174 // disable if not Linux as KisColorManager is not yet implemented outside Linux
1175#ifndef Q_OS_LINUX
1176 m_page->chkUseSystemMonitorProfile->setChecked(false);
1177 m_page->chkUseSystemMonitorProfile->setDisabled(true);
1178 m_page->chkUseSystemMonitorProfile->setHidden(true);
1179#endif
1180
1181 refillMonitorProfiles(KoID("RGBA"));
1182
1183 for(int i = 0; i < QApplication::screens().count(); ++i) {
1184 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1185 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1186 }
1187 }
1188 } else {
1189 QVBoxLayout *vboxLayout = new QVBoxLayout(m_page->monitorprofileholder);
1190 vboxLayout->setContentsMargins(0, 0, 0, 0);
1191 vboxLayout->addItem(new QSpacerItem(20,20));
1192
1193 QGroupBox *groupBox = new QGroupBox(i18n("Display's color space is managed by the operating system"));
1194 vboxLayout->addWidget(groupBox);
1195
1196 QFormLayout *monitorProfileGrid = new QFormLayout(groupBox);
1197 monitorProfileGrid->setContentsMargins(0, 0, 0, 0);
1198
1200 new QCheckBox(i18n("Enable canvas color management"), this);
1201
1203 i18n("<p>Enabling canvas color management automatically creates "
1204 "a separate native surface for the canvas. It might cause "
1205 "performance issues on some systems.</p>"
1206 ""
1207 "<p>If color management is disabled, Krita will render "
1208 "the canvas into the surface of the main window, which "
1209 "is considered sRGB. It will cause two limitations:"
1210 ""
1211 "<ol>"
1212 " <li>the color gamut will be limited to sRGB</li>"
1213 " <li>color proofing mode will be limited to \"use global display settings\", "
1214 " i.e. paper white proofing will become impossible</li>"
1215 "</ol>"
1216 "</p>"));
1217
1218 monitorProfileGrid->addRow(m_chkEnableCanvasColorSpaceManagement);
1219
1220 // surface color space
1222 m_canvasSurfaceColorSpace->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1223 QLabel *canvasSurfaceColorSpaceLbl = new QLabel(i18n("Canvas surface color space:"), this);
1224 monitorProfileGrid->addRow(canvasSurfaceColorSpaceLbl, m_canvasSurfaceColorSpace);
1225
1226 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Preferred by operating system"), QVariant::fromValue(CanvasSurfaceMode::Preferred));
1227 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Rec 709 Gamma 2.2"), QVariant::fromValue(CanvasSurfaceMode::Rec709g22));
1228 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Rec 709 Linear"), QVariant::fromValue(CanvasSurfaceMode::Rec709g10));
1229 m_canvasSurfaceColorSpace->addSqueezedItem(i18n("Unmanaged (testing only)"), QVariant::fromValue(CanvasSurfaceMode::Unmanaged));
1230
1231 m_canvasSurfaceColorSpace->setToolTip(
1232 i18n("<p>Color space of the pixels that are transferred to the "
1233 "window compositor. Use \"preferred\" space unless you know "
1234 "what you are doing</p>"));
1235
1236 // surface bit depth
1238 m_canvasSurfaceBitDepth->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
1239 QLabel *canvasSurfaceBitDepthLbl = new QLabel(i18n("Canvas surface bit depth (needs restart):"), this);
1240 monitorProfileGrid->addRow(canvasSurfaceBitDepthLbl, m_canvasSurfaceBitDepth);
1241
1242 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("Auto"), QVariant::fromValue(CanvasSurfaceBitDepthMode::DepthAuto));
1243 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("8-bit"), QVariant::fromValue(CanvasSurfaceBitDepthMode::Depth8Bit));
1244 m_canvasSurfaceBitDepth->addSqueezedItem(i18n("10-bit"), QVariant::fromValue(CanvasSurfaceBitDepthMode::Depth10Bit));
1245
1246 m_canvasSurfaceBitDepth->setToolTip(
1247 i18n("<p>The bit depth of the color that is passed to the window "
1248 "compositor. You should switch into 10-bit mode if you want to use "
1249 "HDR capabilities of your display</p>"));
1250
1251 const QString currentBitBepthString = QSurfaceFormat::defaultFormat().redBufferSize() == 10 ? i18n("10-bit") : i18n("8-bit");
1252 QLabel *currentCanvasSurfaceBitDepthLbl = new QLabel(i18n("Current canvas surface bit depth:"), this);
1253 QLabel *currentCanvasSurfaceBitDepth = new QLabel(currentBitBepthString, this);
1254 monitorProfileGrid->addRow(currentCanvasSurfaceBitDepthLbl, currentCanvasSurfaceBitDepth);
1255
1256 vboxLayout->addItem(new QSpacerItem(20,20));
1257
1259 QLabel *preferredLbl = new QLabel(i18n("Color space preferred by the operating system:\n%1", KisPlatformPluginInterfaceFactory::instance()->osPreferredColorSpaceReport(mainWindow)), this);
1260 vboxLayout->addWidget(preferredLbl);
1261
1263
1264 {
1265 auto mode = cfg.canvasSurfaceColorSpaceManagementMode();
1266 int index = m_canvasSurfaceColorSpace->findData(QVariant::fromValue(mode));
1267 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1268 index = 0;
1269 }
1270 m_canvasSurfaceColorSpace->setCurrentIndex(index);
1271 }
1272
1273 {
1274 auto mode = cfg.canvasSurfaceBitDepthMode();
1275 int index = m_canvasSurfaceBitDepth->findData(QVariant::fromValue(mode));
1276 KIS_SAFE_ASSERT_RECOVER(index >= 0) {
1277 index = 0;
1278 }
1279 m_canvasSurfaceBitDepth->setCurrentIndex(index);
1280 }
1281
1282 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, m_canvasSurfaceColorSpace, &QWidget::setEnabled);
1284
1285 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, canvasSurfaceColorSpaceLbl, &QWidget::setEnabled);
1286 canvasSurfaceColorSpaceLbl->setEnabled(m_chkEnableCanvasColorSpaceManagement->isChecked());
1287
1288 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, m_canvasSurfaceBitDepth, &QWidget::setEnabled);
1290
1291 connect(m_chkEnableCanvasColorSpaceManagement, &QCheckBox::toggled, canvasSurfaceBitDepthLbl, &QWidget::setEnabled);
1292 canvasSurfaceBitDepthLbl->setEnabled(m_chkEnableCanvasColorSpaceManagement->isChecked());
1293 }
1294
1295 m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
1296 m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
1297 m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors());
1298 m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent());
1299 KisImageConfig cfgImage(true);
1300
1304 KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration();
1305
1306 m_page->wdgProofingOptions->setProofingConfig(proofingConfig);
1307
1308 m_proofModel->data.set(*proofingConfig.data());
1309
1310 connect(m_page->chkBlackpoint, SIGNAL(toggled(bool)), this, SLOT(updateProofingDisplayInfo()));
1311 connect(m_page->cmbMonitorIntent, SIGNAL(currentIndexChanged(int)), this, SLOT(updateProofingDisplayInfo()));
1313
1316 m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, KisClipboard::PASTE_ASK);
1317
1318 QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour());
1319 Q_ASSERT(button);
1320
1321 if (button) {
1322 button->setChecked(true);
1323 }
1324
1325 if (!m_colorManagedByOS) {
1327 }
1328}
1329
1331{
1333
1334 KoFileDialog dialog(this, KoFileDialog::OpenFiles, "OpenDocumentICC");
1335 dialog.setCaption(i18n("Install Color Profiles"));
1336 dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
1337 dialog.setMimeTypeFilters(QStringList() << "application/vnd.iccprofile", "application/vnd.iccprofile");
1338 QStringList profileNames = dialog.filenames();
1339
1341 Q_ASSERT(iccEngine);
1342
1343 QString saveLocation = KoResourcePaths::saveLocation("icc_profiles");
1344
1345 Q_FOREACH (const QString &profileName, profileNames) {
1346 if (!QFile::copy(profileName, saveLocation + QFileInfo(profileName).fileName())) {
1347 qWarning() << "Could not install profile!" << saveLocation + QFileInfo(profileName).fileName();
1348 continue;
1349 }
1350 iccEngine->addProfile(saveLocation + QFileInfo(profileName).fileName());
1351 }
1352
1353 KisConfig cfg(true);
1354 refillMonitorProfiles(KoID("RGBA"));
1355
1356 for(int i = 0; i < QApplication::screens().count(); ++i) {
1357 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1358 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1359 }
1360 }
1361
1362}
1363
1365{
1367
1368 KisConfig cfg(true);
1369
1370 if (useSystemProfile) {
1372 if (devices.size() == QApplication::screens().count()) {
1373 for(int i = 0; i < QApplication::screens().count(); ++i) {
1374 m_monitorProfileWidgets[i]->clear();
1375 QString monitorForScreen = cfg.monitorForScreen(i, devices[i]);
1376 Q_FOREACH (const QString &device, devices) {
1377 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)));
1378 m_monitorProfileWidgets[i]->addSqueezedItem(KisColorManager::instance()->deviceName(device), device);
1379 if (devices[i] == monitorForScreen) {
1380 m_monitorProfileWidgets[i]->setCurrentIndex(i);
1381 }
1382 }
1383 }
1384 }
1385 }
1386 else {
1387 refillMonitorProfiles(KoID("RGBA"));
1388
1389 for(int i = 0; i < QApplication::screens().count(); ++i) {
1390 if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
1391 m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
1392 }
1393 }
1394 }
1395}
1396
1398{
1399 m_page->cmbWorkingColorSpace->setEnabled(useDefColorSpace);
1400}
1401
1403{
1404 m_page->cmbWorkingColorSpace->setCurrent("RGBA");
1405
1407 const QString defaultProfile = KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId);
1408 m_page->cmbColorProfileForEXR->setCurrent(defaultProfile);
1409
1410 KisConfig cfg(true);
1411
1412 if (!m_colorManagedByOS) {
1413 refillMonitorProfiles(KoID("RGBA"));
1414 } else {
1416
1417 {
1418 auto mode = cfg.canvasSurfaceColorSpaceManagementMode(true);
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(true);
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
1436 KisImageConfig cfgImage(true);
1437 KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration(true);
1438 m_page->wdgProofingOptions->setProofingConfig(proofingConfig);
1439
1440 m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
1441 m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
1442 m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors(true));
1443 m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent(true));
1444 if (!m_colorManagedByOS) {
1445 m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile(true));
1446 }
1447 QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour(true));
1448 Q_ASSERT(button);
1449 if (button) {
1450 button->setChecked(true);
1451 }
1452}
1453
1454
1456{
1458
1459 for (int i = 0; i < QApplication::screens().count(); ++i) {
1460 m_monitorProfileWidgets[i]->clear();
1461 }
1462
1463 QMap<QString, const KoColorProfile *> profileList;
1464 Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(colorSpaceId.id())) {
1465 profileList[profile->name()] = profile;
1466 }
1467
1468 Q_FOREACH (const KoColorProfile *profile, profileList.values()) {
1469 //qDebug() << "Profile" << profile->name() << profile->isSuitableForDisplay() << csf->defaultProfile();
1470 if (profile->isSuitableForDisplay()) {
1471 for (int i = 0; i < QApplication::screens().count(); ++i) {
1472 m_monitorProfileWidgets[i]->addSqueezedItem(profile->name());
1473 }
1474 }
1475 }
1476
1477 for (int i = 0; i < QApplication::screens().count(); ++i) {
1478 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)));
1480 }
1481}
1482
1485 options.first = KoColorConversionTransformation::Intent(m_page->cmbMonitorIntent->currentIndex());
1487 options.second.setFlag(KoColorConversionTransformation::BlackpointCompensation, m_page->chkBlackpoint->isChecked());
1488 m_page->wdgProofingOptions->setDisplayConfigOptions(options);
1489}
1490
1491//---------------------------------------------------------------------------------------------------
1492
1494{
1495 KisConfig cfg(true);
1497 m_page->pressureCurve->setCurve(curve);
1498
1499 m_page->chkUseRightMiddleClickWorkaround->setChecked(
1500 KisConfig(true).useRightMiddleTabletButtonWorkaround(true));
1501
1502#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1503 m_page->radioWintab->setChecked(!cfg.useWin8PointerInput(true));
1504 m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput(true));
1505#else
1506 m_page->grpTabletApi->setVisible(false);
1507#endif
1508
1509 m_page->chkUseTimestampsForBrushSpeed->setChecked(false);
1510 m_page->intMaxAllowedBrushSpeed->setValue(30);
1511 m_page->intBrushSpeedSmoothing->setValue(3);
1512 m_page->tiltDirectionOffsetAngle->setAngle(0);
1513}
1514
1515TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget(parent)
1516{
1517 setObjectName(name);
1518
1519 QGridLayout * l = new QGridLayout(this);
1520 l->setContentsMargins(0, 0, 0, 0);
1521 m_page = new WdgTabletSettings(this);
1522 l->addWidget(m_page, 0, 0);
1523
1524 KisConfig cfg(true);
1525 const KisCubicCurve curve(cfg.pressureTabletCurve());
1526 m_page->pressureCurve->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
1527 m_page->pressureCurve->setCurve(curve);
1528
1529 m_page->chkUseRightMiddleClickWorkaround->setChecked(
1531
1532#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1533# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1534 QString actualTabletProtocol = "<unknown>";
1535 using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
1536 if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) {
1537 actualTabletProtocol = nativeWindowsApp->isWinTabEnabled() ? "WinTab" : "Windows Ink";
1538 }
1539 m_page->grpTabletApi->setTitle(i18n("Tablet Input API (currently active API: \"%1\")", actualTabletProtocol));
1540# endif
1541 m_page->radioWintab->setChecked(!cfg.useWin8PointerInput());
1542 m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput());
1543
1544 connect(m_page->btnResolutionSettings, SIGNAL(clicked()), SLOT(slotResolutionSettings()));
1545 connect(m_page->radioWintab, SIGNAL(toggled(bool)), m_page->btnResolutionSettings, SLOT(setEnabled(bool)));
1546 m_page->btnResolutionSettings->setEnabled(m_page->radioWintab->isChecked());
1547#else
1548 m_page->grpTabletApi->setVisible(false);
1549#endif
1550 connect(m_page->btnTabletTest, SIGNAL(clicked()), SLOT(slotTabletTest()));
1551
1552#ifdef Q_OS_WIN
1553 m_page->chkUseTimestampsForBrushSpeed->setText(i18n("Use tablet driver timestamps for brush speed (may cause severe artifacts when using WinTab tablet API)"));
1554#else
1555 m_page->chkUseTimestampsForBrushSpeed->setText(i18n("Use tablet driver timestamps for brush speed"));
1556#endif
1557 m_page->chkUseTimestampsForBrushSpeed->setChecked(cfg.readEntry("useTimestampsForBrushSpeed", false));
1558
1559 m_page->intMaxAllowedBrushSpeed->setRange(1, 100);
1560 m_page->intMaxAllowedBrushSpeed->setValue(cfg.readEntry("maxAllowedSpeedValue", 30));
1561 KisSpinBoxI18nHelper::install(m_page->intMaxAllowedBrushSpeed, [](int value) {
1562 // i18n: This is meant to be used in a spinbox so keep the {n} in the text
1563 // and it will be substituted by the number. The text before will be
1564 // used as the prefix and the text after as the suffix
1565 return i18np("Maximum brush speed: {n} px/ms", "Maximum brush speed: {n} px/ms", value);
1566 });
1567
1568 m_page->intBrushSpeedSmoothing->setRange(3, 100);
1569 m_page->intBrushSpeedSmoothing->setValue(cfg.readEntry("speedValueSmoothing", 3));
1570 KisSpinBoxI18nHelper::install(m_page->intBrushSpeedSmoothing, [](int value) {
1571 // i18n: This is meant to be used in a spinbox so keep the {n} in the text
1572 // and it will be substituted by the number. The text before will be
1573 // used as the prefix and the text after as the suffix
1574 return i18np("Brush speed smoothing: {n} sample", "Brush speed smoothing: {n} samples", value);
1575 });
1576
1577 m_page->tiltDirectionOffsetAngle->setDecimals(0);
1578 m_page->tiltDirectionOffsetAngle->setRange(-180, 180);
1579 // the angle is saved in clockwise direction to be consistent with Drawing Angle, so negate
1580 m_page->tiltDirectionOffsetAngle->setAngle(-cfg.readEntry("tiltDirectionOffset", 0.0));
1581 m_page->tiltDirectionOffsetAngle->setPrefix(i18n("Pen tilt direction offset: "));
1582 m_page->tiltDirectionOffsetAngle->setFlipOptionsMode(KisAngleSelector::FlipOptionsMode_MenuButton);
1583}
1584
1586{
1587 TabletTestDialog tabletTestDialog(this);
1588 tabletTestDialog.exec();
1589}
1590
1591#ifdef Q_OS_WIN
1593#endif
1594
1596{
1597#ifdef Q_OS_WIN
1599 dlg.exec();
1600#endif
1601}
1602
1603
1604//---------------------------------------------------------------------------------------------------
1606
1608{
1609 return KisImageConfig(true).totalRAM();
1610}
1611
1613{
1614 return intMemoryLimit->value() - intPoolLimit->value();
1615}
1616
1617PerformanceTab::PerformanceTab(QWidget *parent, const char *name)
1618 : WdgPerformanceSettings(parent, name)
1619 , m_frameRateModel(new KisFrameRateLimitModel())
1620{
1621 KisImageConfig cfg(true);
1622 const double totalRAM = cfg.totalRAM();
1623 lblTotalMemory->setText(KFormat().formatByteSize(totalRAM * 1024 * 1024, 0, KFormat::IECBinaryDialect, KFormat::UnitMegaByte));
1624
1625 KisSpinBoxI18nHelper::setText(sliderMemoryLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1626 sliderMemoryLimit->setRange(1, 100, 2);
1627 sliderMemoryLimit->setSingleStep(0.01);
1628
1629 KisSpinBoxI18nHelper::setText(sliderPoolLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1630 sliderPoolLimit->setRange(0, 20, 2);
1631 sliderPoolLimit->setSingleStep(0.01);
1632
1633 KisSpinBoxI18nHelper::setText(sliderUndoLimit, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1634 sliderUndoLimit->setRange(0, 50, 2);
1635 sliderUndoLimit->setSingleStep(0.01);
1636
1637 intMemoryLimit->setMinimumWidth(80);
1638 intPoolLimit->setMinimumWidth(80);
1639 intUndoLimit->setMinimumWidth(80);
1640
1641 {
1642 formLayout->takeRow(2);
1643 label_5->setVisible(false);
1644 intPoolLimit->setVisible(false);
1645 sliderPoolLimit->setVisible(false);
1646 }
1647
1648 SliderAndSpinBoxSync *sync1 =
1649 new SliderAndSpinBoxSync(sliderMemoryLimit,
1650 intMemoryLimit,
1651 getTotalRAM);
1652
1653 sync1->slotParentValueChanged();
1654 m_syncs << sync1;
1655
1656 SliderAndSpinBoxSync *sync2 =
1657 new SliderAndSpinBoxSync(sliderPoolLimit,
1658 intPoolLimit,
1659 std::bind(&KisIntParseSpinBox::value,
1660 intMemoryLimit));
1661
1662
1663 connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync2, SLOT(slotParentValueChanged()));
1664 sync2->slotParentValueChanged();
1665 m_syncs << sync2;
1666
1667 SliderAndSpinBoxSync *sync3 =
1668 new SliderAndSpinBoxSync(sliderUndoLimit,
1669 intUndoLimit,
1671 this));
1672
1673
1674 connect(intPoolLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
1675 connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
1676 sync3->slotParentValueChanged();
1677 m_syncs << sync3;
1678
1679 sliderSwapSize->setSuffix(i18n(" GiB"));
1680 sliderSwapSize->setRange(1, 64);
1681 intSwapSize->setRange(1, 64);
1682
1683
1684 KisAcyclicSignalConnector *swapSizeConnector = new KisAcyclicSignalConnector(this);
1685
1686 swapSizeConnector->connectForwardInt(sliderSwapSize, SIGNAL(valueChanged(int)),
1687 intSwapSize, SLOT(setValue(int)));
1688
1689 swapSizeConnector->connectBackwardInt(intSwapSize, SIGNAL(valueChanged(int)),
1690 sliderSwapSize, SLOT(setValue(int)));
1691
1692 swapFileLocation->setMode(KoFileDialog::OpenDirectory);
1693 swapFileLocation->setConfigurationName("swapfile_location");
1694 swapFileLocation->setFileName(cfg.swapDir());
1695
1696 sliderThreadsLimit->setRange(1, QThread::idealThreadCount());
1697 sliderFrameClonesLimit->setRange(1, QThread::idealThreadCount());
1698
1699 sliderFrameTimeout->setRange(5, 600);
1700 sliderFrameTimeout->setSuffix(i18nc("suffix for \"seconds\"", " sec"));
1701 sliderFrameTimeout->setValue(cfg.frameRenderingTimeout() / 1000);
1702
1703 sliderFpsLimit->setSuffix(i18n(" fps"));
1704
1705 KisWidgetConnectionUtils::connectControlState(sliderFpsLimit, m_frameRateModel.data(), "frameRateState", "frameRate");
1706 KisWidgetConnectionUtils::connectControl(chkDetectFps, m_frameRateModel.data(), "detectFrameRate");
1707
1708 connect(sliderThreadsLimit, SIGNAL(valueChanged(int)), SLOT(slotThreadsLimitChanged(int)));
1709 connect(sliderFrameClonesLimit, SIGNAL(valueChanged(int)), SLOT(slotFrameClonesLimitChanged(int)));
1710
1711 intCachedFramesSizeLimit->setRange(256, 10000);
1712 intCachedFramesSizeLimit->setSuffix(i18n(" px"));
1713 intCachedFramesSizeLimit->setSingleStep(1);
1714 intCachedFramesSizeLimit->setPageStep(1000);
1715
1716 intRegionOfInterestMargin->setRange(1, 100);
1717 KisSpinBoxI18nHelper::setText(intRegionOfInterestMargin,
1718 i18nc("{n} is the number value, % is the percent sign", "{n}%"));
1719 intRegionOfInterestMargin->setSingleStep(1);
1720 intRegionOfInterestMargin->setPageStep(10);
1721
1722 connect(chkCachedFramesSizeLimit, SIGNAL(toggled(bool)), intCachedFramesSizeLimit, SLOT(setEnabled(bool)));
1723 connect(chkUseRegionOfInterest, SIGNAL(toggled(bool)), intRegionOfInterestMargin, SLOT(setEnabled(bool)));
1724
1725 connect(chkTransformToolUseInStackPreview, SIGNAL(toggled(bool)), chkTransformToolForceLodMode, SLOT(setEnabled(bool)));
1726
1727#ifndef Q_OS_WIN
1728 // AVX workaround is needed on Windows+GCC only
1729 chkDisableAVXOptimizations->setVisible(false);
1730#endif
1731
1732 load(false);
1733}
1734
1736{
1737 qDeleteAll(m_syncs);
1738}
1739
1740void PerformanceTab::load(bool requestDefault)
1741{
1742 KisImageConfig cfg(true);
1743
1744 sliderMemoryLimit->setValue(cfg.memoryHardLimitPercent(requestDefault));
1745 sliderPoolLimit->setValue(cfg.memoryPoolLimitPercent(requestDefault));
1746 sliderUndoLimit->setValue(cfg.memorySoftLimitPercent(requestDefault));
1747
1748 chkPerformanceLogging->setChecked(cfg.enablePerfLog(requestDefault));
1749 chkProgressReporting->setChecked(cfg.enableProgressReporting(requestDefault));
1750
1751 sliderSwapSize->setValue(cfg.maxSwapSize(requestDefault) / 1024);
1752 swapFileLocation->setFileName(cfg.swapDir(requestDefault));
1753
1754 m_lastUsedThreadsLimit = cfg.maxNumberOfThreads(requestDefault);
1755 m_lastUsedClonesLimit = cfg.frameRenderingClones(requestDefault);
1756
1757 sliderThreadsLimit->setValue(m_lastUsedThreadsLimit);
1758 sliderFrameClonesLimit->setValue(m_lastUsedClonesLimit);
1759
1760#if KRITA_QT_HAS_UPDATE_COMPRESSION_PATCH
1761 m_frameRateModel->data.set(std::make_tuple(cfg.detectFpsLimit(requestDefault), cfg.fpsLimit(requestDefault)));
1762#else
1763 m_frameRateModel->data.set(std::make_tuple(false, cfg.fpsLimit(requestDefault)));
1764 chkDetectFps->setVisible(false);
1765#endif
1766 {
1767 KisConfig cfg2(true);
1768 chkOpenGLFramerateLogging->setChecked(cfg2.enableOpenGLFramerateLogging(requestDefault));
1769 chkBrushSpeedLogging->setChecked(cfg2.enableBrushSpeedLogging(requestDefault));
1770 chkDisableVectorOptimizations->setChecked(cfg2.disableVectorOptimizations(requestDefault));
1771#ifdef Q_OS_WIN
1772 chkDisableAVXOptimizations->setChecked(cfg2.disableAVXOptimizations(requestDefault));
1773#endif
1774 chkBackgroundCacheGeneration->setChecked(cfg2.calculateAnimationCacheInBackground(requestDefault));
1775 }
1776
1777 if (cfg.useOnDiskAnimationCacheSwapping(requestDefault)) {
1778 optOnDisk->setChecked(true);
1779 } else {
1780 optInMemory->setChecked(true);
1781 }
1782
1783 chkCachedFramesSizeLimit->setChecked(cfg.useAnimationCacheFrameSizeLimit(requestDefault));
1784 intCachedFramesSizeLimit->setValue(cfg.animationCacheFrameSizeLimit(requestDefault));
1785 intCachedFramesSizeLimit->setEnabled(chkCachedFramesSizeLimit->isChecked());
1786
1787 chkUseRegionOfInterest->setChecked(cfg.useAnimationCacheRegionOfInterest(requestDefault));
1788 intRegionOfInterestMargin->setValue(cfg.animationCacheRegionOfInterestMargin(requestDefault) * 100.0);
1789 intRegionOfInterestMargin->setEnabled(chkUseRegionOfInterest->isChecked());
1790
1791 {
1792 KConfigGroup group = KSharedConfig::openConfig()->group("KisToolTransform");
1793 chkTransformToolUseInStackPreview->setChecked(!group.readEntry("useOverlayPreviewStyle", false));
1794 chkTransformToolForceLodMode->setChecked(group.readEntry("forceLodMode", true));
1795 chkTransformToolForceLodMode->setEnabled(chkTransformToolUseInStackPreview->isChecked());
1796 }
1797
1798 {
1799 KConfigGroup group = KSharedConfig::openConfig()->group("KritaTransform/KisToolMove");
1800 chkMoveToolForceLodMode->setChecked(group.readEntry("forceLodMode", false));
1801 }
1802
1803 {
1804 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
1805 chkFiltersForceLodMode->setChecked(group.readEntry("forceLodMode", true));
1806 }
1807}
1808
1810{
1811 KisImageConfig cfg(false);
1812
1813 cfg.setMemoryHardLimitPercent(sliderMemoryLimit->value());
1814 cfg.setMemorySoftLimitPercent(sliderUndoLimit->value());
1815 cfg.setMemoryPoolLimitPercent(sliderPoolLimit->value());
1816
1817 cfg.setEnablePerfLog(chkPerformanceLogging->isChecked());
1818 cfg.setEnableProgressReporting(chkProgressReporting->isChecked());
1819
1820 cfg.setMaxSwapSize(sliderSwapSize->value() * 1024);
1821
1822 cfg.setSwapDir(swapFileLocation->fileName());
1823
1824 cfg.setMaxNumberOfThreads(sliderThreadsLimit->value());
1825 cfg.setFrameRenderingClones(sliderFrameClonesLimit->value());
1826 cfg.setFrameRenderingTimeout(sliderFrameTimeout->value() * 1000);
1827 cfg.setFpsLimit(std::get<int>(*m_frameRateModel->data));
1828#if KRITA_QT_HAS_UPDATE_COMPRESSION_PATCH
1829 cfg.setDetectFpsLimit(std::get<bool>(*m_frameRateModel->data));
1830#endif
1831
1832 {
1833 KisConfig cfg2(true);
1834 cfg2.setEnableOpenGLFramerateLogging(chkOpenGLFramerateLogging->isChecked());
1835 cfg2.setEnableBrushSpeedLogging(chkBrushSpeedLogging->isChecked());
1836 cfg2.setDisableVectorOptimizations(chkDisableVectorOptimizations->isChecked());
1837#ifdef Q_OS_WIN
1838 cfg2.setDisableAVXOptimizations(chkDisableAVXOptimizations->isChecked());
1839#endif
1840 cfg2.setCalculateAnimationCacheInBackground(chkBackgroundCacheGeneration->isChecked());
1841 }
1842
1843 cfg.setUseOnDiskAnimationCacheSwapping(optOnDisk->isChecked());
1844
1845 cfg.setUseAnimationCacheFrameSizeLimit(chkCachedFramesSizeLimit->isChecked());
1846 cfg.setAnimationCacheFrameSizeLimit(intCachedFramesSizeLimit->value());
1847
1848 cfg.setUseAnimationCacheRegionOfInterest(chkUseRegionOfInterest->isChecked());
1849 cfg.setAnimationCacheRegionOfInterestMargin(intRegionOfInterestMargin->value() / 100.0);
1850
1851 {
1852 KConfigGroup group = KSharedConfig::openConfig()->group("KisToolTransform");
1853 group.writeEntry("useOverlayPreviewStyle", !chkTransformToolUseInStackPreview->isChecked());
1854 group.writeEntry("forceLodMode", chkTransformToolForceLodMode->isChecked());
1855 }
1856
1857 {
1858 KConfigGroup group = KSharedConfig::openConfig()->group("KritaTransform/KisToolMove");
1859 group.writeEntry("forceLodMode", chkMoveToolForceLodMode->isChecked());
1860 }
1861
1862 {
1863 KConfigGroup group( KSharedConfig::openConfig(), "filterdialog");
1864 group.writeEntry("forceLodMode", chkFiltersForceLodMode->isChecked());
1865 }
1866
1867}
1868
1870{
1871 KisSignalsBlocker b(sliderFrameClonesLimit);
1872 sliderFrameClonesLimit->setValue(qMin(m_lastUsedClonesLimit, value));
1874}
1875
1877{
1878 KisSignalsBlocker b(sliderThreadsLimit);
1879 sliderThreadsLimit->setValue(qMax(m_lastUsedThreadsLimit, value));
1881}
1882
1883//---------------------------------------------------------------------------------------------------
1884
1885#include "KoColor.h"
1888#include <QOpenGLContext>
1889#include <QScreen>
1890
1891namespace {
1892
1893QString colorSpaceString(const KisSurfaceColorSpaceWrapper &cs, int depth)
1894{
1895 const QString csString =
1896#ifdef HAVE_HDR
1898 cs == KisSurfaceColorSpaceWrapper::scRGBColorSpace ? "Rec. 709 Linear" :
1899#endif
1902 "Unknown Color Space";
1903
1904 return QString("%1 (%2 bit)").arg(csString).arg(depth);
1905}
1906
1907int formatToIndex(KisConfig::RootSurfaceFormat fmt)
1908{
1909 return fmt == KisConfig::BT2020_PQ ? 1 :
1910 fmt == KisConfig::BT709_G10 ? 2 :
1911 0;
1912}
1913
1914KisConfig::RootSurfaceFormat indexToFormat(int value)
1915{
1916 return value == 1 ? KisConfig::BT2020_PQ :
1919}
1920
1921int assistantDrawModeToIndex(KisConfig::AssistantsDrawMode mode)
1922{
1925 0;
1926}
1927
1928KisConfig::AssistantsDrawMode indexToAssistantDrawMode(int value)
1929{
1933}
1934
1935} // anonymous namespace
1936
1937DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
1938 : WdgDisplaySettings(parent, name)
1939{
1940 KisConfig cfg(true);
1941
1942 const QString rendererOpenGLText = i18nc("canvas renderer", "OpenGL");
1943 const QString rendererSoftwareText = i18nc("canvas renderer", "Software Renderer (very slow)");
1944#ifdef Q_OS_WIN
1945 const QString rendererOpenGLESText =
1946 qEnvironmentVariable("QT_ANGLE_PLATFORM") != "opengl"
1947 ? i18nc("canvas renderer", "Direct3D 11 via ANGLE")
1948 : i18nc("canvas renderer", "OpenGL via ANGLE");
1949#else
1950 const QString rendererOpenGLESText = i18nc("canvas renderer", "OpenGL ES");
1951#endif
1952
1954 lblCurrentRenderer->setText(renderer == KisOpenGL::RendererOpenGLES ? rendererOpenGLESText :
1955 renderer == KisOpenGL::RendererDesktopGL ? rendererOpenGLText :
1956 renderer == KisOpenGL::RendererSoftware ? rendererSoftwareText :
1957 i18nc("canvas renderer", "Unknown"));
1958
1959 cmbPreferredRenderer->clear();
1960
1961 const KisOpenGL::OpenGLRenderers supportedRenderers = KisOpenGL::getSupportedOpenGLRenderers();
1962 const bool onlyOneRendererSupported =
1963 supportedRenderers == KisOpenGL::RendererDesktopGL ||
1964 supportedRenderers == KisOpenGL::RendererOpenGLES ||
1965 supportedRenderers == KisOpenGL::RendererSoftware;
1966
1967
1968 if (!onlyOneRendererSupported) {
1969 QString qtPreferredRendererText;
1971 qtPreferredRendererText = rendererOpenGLESText;
1973 qtPreferredRendererText = rendererSoftwareText;
1974 } else {
1975 qtPreferredRendererText = rendererOpenGLText;
1976 }
1977 cmbPreferredRenderer->addItem(i18nc("canvas renderer", "Auto (%1)", qtPreferredRendererText), KisOpenGL::RendererAuto);
1978 cmbPreferredRenderer->setCurrentIndex(0);
1979 } else {
1980 cmbPreferredRenderer->setEnabled(false);
1981 }
1982
1983 if (supportedRenderers & KisOpenGL::RendererDesktopGL) {
1984 cmbPreferredRenderer->addItem(rendererOpenGLText, KisOpenGL::RendererDesktopGL);
1986 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
1987 }
1988 }
1989
1990 if (supportedRenderers & KisOpenGL::RendererOpenGLES) {
1991 cmbPreferredRenderer->addItem(rendererOpenGLESText, KisOpenGL::RendererOpenGLES);
1993 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
1994 }
1995 }
1996
1997 if (supportedRenderers & KisOpenGL::RendererSoftware) {
1998 cmbPreferredRenderer->addItem(rendererSoftwareText, KisOpenGL::RendererSoftware);
2000 cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
2001 }
2002 }
2003
2004 if (!(supportedRenderers &
2008
2009 grpOpenGL->setEnabled(false);
2010 grpOpenGL->setChecked(false);
2011 chkUseTextureBuffer->setEnabled(false);
2012 cmbAssistantsDrawMode->setEnabled(false);
2013 cmbFilterMode->setEnabled(false);
2014 } else {
2015 grpOpenGL->setEnabled(true);
2016 grpOpenGL->setChecked(cfg.useOpenGL());
2017 chkUseTextureBuffer->setEnabled(cfg.useOpenGL());
2018 chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer());
2019 cmbAssistantsDrawMode->setEnabled(cfg.useOpenGL());
2020 cmbAssistantsDrawMode->setCurrentIndex(assistantDrawModeToIndex(cfg.assistantsDrawMode()));
2021 cmbFilterMode->setEnabled(cfg.useOpenGL());
2022 cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode());
2023 // Don't show the high quality filtering mode if it's not available
2024 if (!KisOpenGL::supportsLoD()) {
2025 cmbFilterMode->removeItem(3);
2026 }
2027 }
2028
2029 lblCurrentDisplayFormat->setText("");
2030 lblCurrentRootSurfaceFormat->setText("");
2031 grpHDRWarning->setVisible(false);
2032 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::sRGBColorSpace, 8));
2033#ifdef HAVE_HDR
2034 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::bt2020PQColorSpace, 10));
2035 cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpaceWrapper::scRGBColorSpace, 16));
2036#endif
2037 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
2038 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2039
2040 QOpenGLContext *context = QOpenGLContext::currentContext();
2041
2042 if (!context) {
2043 context = QOpenGLContext::globalShareContext();
2044 }
2045
2046 if (context) {
2047 QScreen *screen = KisPart::instance()->currentMainwindow()->screen();
2048 KisScreenInformationAdapter adapter(context);
2049 if (screen && adapter.isValid()) {
2051 if (info.isValid()) {
2052 QStringList toolTip;
2053
2054 toolTip << i18n("Display Id: %1", info.screen->name());
2055 toolTip << i18n("Display Name: %1 %2", info.screen->manufacturer(), info.screen->model());
2056 toolTip << i18n("Min Luminance: %1", info.minLuminance);
2057 toolTip << i18n("Max Luminance: %1", info.maxLuminance);
2058 toolTip << i18n("Max Full Frame Luminance: %1", info.maxFullFrameLuminance);
2059 toolTip << i18n("Red Primary: %1, %2", info.redPrimary[0], info.redPrimary[1]);
2060 toolTip << i18n("Green Primary: %1, %2", info.greenPrimary[0], info.greenPrimary[1]);
2061 toolTip << i18n("Blue Primary: %1, %2", info.bluePrimary[0], info.bluePrimary[1]);
2062 toolTip << i18n("White Point: %1, %2", info.whitePoint[0], info.whitePoint[1]);
2063
2064 lblCurrentDisplayFormat->setToolTip(toolTip.join('\n'));
2065 lblCurrentDisplayFormat->setText(colorSpaceString(info.colorSpace, info.bitsPerColor));
2066 } else {
2067 lblCurrentDisplayFormat->setToolTip("");
2068 lblCurrentDisplayFormat->setText(i18n("Unknown"));
2069 }
2070 } else {
2071 lblCurrentDisplayFormat->setToolTip("");
2072 lblCurrentDisplayFormat->setText(i18n("Unknown"));
2073 qWarning() << "Failed to fetch display info:" << adapter.errorString();
2074 }
2075
2076 const QSurfaceFormat currentFormat = KisOpenGLModeProber::instance()->surfaceformatInUse();
2077 const auto colorSpace = KisSurfaceColorSpaceWrapper::fromQtColorSpace(currentFormat.colorSpace());
2078 lblCurrentRootSurfaceFormat->setText(colorSpaceString(colorSpace, currentFormat.redBufferSize()));
2079 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(cfg.rootSurfaceFormat()));
2080 connect(cmbPreferedRootSurfaceFormat, SIGNAL(currentIndexChanged(int)), SLOT(slotPreferredSurfaceFormatChanged(int)));
2081 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2082 }
2083
2084#ifndef HAVE_HDR
2085 tabHDR->setEnabled(false);
2086
2092 if (KisPlatformPluginInterfaceFactory::instance()->surfaceColorManagedByOS()) {
2093 const int hdrTabIndex = tabWidget->indexOf(tabHDR);
2094 KIS_SAFE_ASSERT_RECOVER_NOOP(hdrTabIndex >= 0);
2095 if (hdrTabIndex >= 0) {
2096 tabWidget->setTabVisible(hdrTabIndex, false);
2097 }
2098 }
2099#endif
2100
2101 const QStringList openglWarnings = KisOpenGL::getOpenGLWarnings();
2102 if (openglWarnings.isEmpty()) {
2103 grpOpenGLWarnings->setVisible(false);
2104 } else {
2105 QString text = QString("<p><b>%1</b>").arg(i18n("Warning(s):"));
2106 text.append("<ul>");
2107 Q_FOREACH (const QString &warning, openglWarnings) {
2108 text.append("<li>");
2109 text.append(warning.toHtmlEscaped());
2110 text.append("</li>");
2111 }
2112 text.append("</ul></p>");
2113 grpOpenGLWarnings->setText(text);
2114 grpOpenGLWarnings->setPixmap(
2115 grpOpenGLWarnings->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
2116 grpOpenGLWarnings->setVisible(true);
2117 }
2118
2119 KisImageConfig imageCfg(false);
2120
2121 KoColor c;
2123 c.setOpacity(1.0);
2124 btnSelectionOverlayColor->setColor(c);
2125 sldSelectionOverlayOpacity->setRange(0.0, 1.0, 2);
2126 sldSelectionOverlayOpacity->setSingleStep(0.05);
2127 sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor().alphaF());
2128
2129 sldSelectionOutlineOpacity->setRange(0.0, 1.0, 2);
2130 sldSelectionOutlineOpacity->setSingleStep(0.05);
2131 sldSelectionOutlineOpacity->setValue(imageCfg.selectionOutlineOpacity());
2132
2133 intCheckSize->setValue(cfg.checkSize());
2134 chkMoving->setChecked(cfg.scrollCheckers());
2136 ck1.fromQColor(cfg.checkersColor1());
2137 colorChecks1->setColor(ck1);
2139 ck2.fromQColor(cfg.checkersColor2());
2140 colorChecks2->setColor(ck2);
2142 cb.fromQColor(cfg.canvasBorderColor());
2143 canvasBorder->setColor(cb);
2144 hideScrollbars->setChecked(cfg.hideScrollbars());
2145 chkCurveAntialiasing->setChecked(cfg.antialiasCurves());
2146 chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline());
2147 chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor());
2148 chkHidePopups->setChecked(cfg.hidePopups());
2149
2150 connect(grpOpenGL, SIGNAL(toggled(bool)), SLOT(slotUseOpenGLToggled(bool)));
2151
2152 KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
2153 gridColor.fromQColor(cfg.getPixelGridColor());
2154 pixelGridColorButton->setColor(gridColor);
2155 pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold() * 100);
2156 KisSpinBoxI18nHelper::setText(pixelGridDrawingThresholdBox, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
2157}
2158
2160{
2161 KisConfig cfg(true);
2162 cmbPreferredRenderer->setCurrentIndex(0);
2165 grpOpenGL->setEnabled(false);
2166 grpOpenGL->setChecked(false);
2167 chkUseTextureBuffer->setEnabled(false);
2168 cmbAssistantsDrawMode->setEnabled(false);
2169 cmbFilterMode->setEnabled(false);
2170 }
2171 else {
2172 grpOpenGL->setEnabled(true);
2173 grpOpenGL->setChecked(cfg.useOpenGL(true));
2174 chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer(true));
2175 chkUseTextureBuffer->setEnabled(true);
2176 cmbAssistantsDrawMode->setEnabled(true);
2177 cmbAssistantsDrawMode->setCurrentIndex(assistantDrawModeToIndex(cfg.assistantsDrawMode(true)));
2178 cmbFilterMode->setEnabled(true);
2179 cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode(true));
2180 }
2181
2182 chkMoving->setChecked(cfg.scrollCheckers(true));
2183
2184 KisImageConfig imageCfg(false);
2185
2186 KoColor c;
2187 c.fromQColor(imageCfg.selectionOverlayMaskColor(true));
2188 c.setOpacity(1.0);
2189 btnSelectionOverlayColor->setColor(c);
2190 sldSelectionOverlayOpacity->setValue(imageCfg.selectionOverlayMaskColor(true).alphaF());
2191
2192 sldSelectionOutlineOpacity->setValue(imageCfg.selectionOutlineOpacity(true));
2193
2194 intCheckSize->setValue(cfg.checkSize(true));
2196 ck1.fromQColor(cfg.checkersColor1(true));
2197 colorChecks1->setColor(ck1);
2199 ck2.fromQColor(cfg.checkersColor2(true));
2200 colorChecks2->setColor(ck2);
2202 cvb.fromQColor(cfg.canvasBorderColor(true));
2203 canvasBorder->setColor(cvb);
2204 hideScrollbars->setChecked(cfg.hideScrollbars(true));
2205 chkCurveAntialiasing->setChecked(cfg.antialiasCurves(true));
2206 chkSelectionOutlineAntialiasing->setChecked(cfg.antialiasSelectionOutline(true));
2207 chkChannelsAsColor->setChecked(cfg.showSingleChannelAsColor(true));
2208 chkHidePopups->setChecked(cfg.hidePopups(true));
2209
2210 KoColor gridColor(KoColorSpaceRegistry::instance()->rgb8());
2211 gridColor.fromQColor(cfg.getPixelGridColor(true));
2212 pixelGridColorButton->setColor(gridColor);
2213 pixelGridDrawingThresholdBox->setValue(cfg.getPixelGridDrawingThreshold(true) * 100);
2214 KisSpinBoxI18nHelper::setText(pixelGridDrawingThresholdBox, i18nc("{n} is the number value, % is the percent sign", "{n}%"));
2215
2216 cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
2217 slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
2218}
2219
2221{
2222 chkUseTextureBuffer->setEnabled(isChecked);
2223 cmbFilterMode->setEnabled(isChecked);
2224 cmbAssistantsDrawMode->setEnabled(isChecked);
2225}
2226
2228{
2229 Q_UNUSED(index);
2230
2231 QOpenGLContext *context = QOpenGLContext::currentContext();
2232 if (context) {
2233 QScreen *screen = KisPart::instance()->currentMainwindow()->screen();
2234 KisScreenInformationAdapter adapter(context);
2235 if (adapter.isValid()) {
2237 if (info.isValid()) {
2238 if (cmbPreferedRootSurfaceFormat->currentIndex() != formatToIndex(KisConfig::BT709_G22) &&
2240 grpHDRWarning->setVisible(true);
2241 grpHDRWarning->setPixmap(
2242 grpHDRWarning->style()->standardIcon(QStyle::SP_MessageBoxWarning).pixmap(QSize(32, 32)));
2243 grpHDRWarning->setText(i18n("<b>Warning:</b> current display doesn't support HDR rendering"));
2244 } else {
2245 grpHDRWarning->setVisible(false);
2246 }
2247 }
2248 }
2249 }
2250}
2251
2252//---------------------------------------------------------------------------------------------------
2254{
2255 KisConfig cfg(true);
2256
2257 chkDockers->setChecked(cfg.hideDockersFullscreen());
2258 chkMenu->setChecked(cfg.hideMenuFullscreen());
2259 chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen());
2260 chkStatusbar->setChecked(cfg.hideStatusbarFullscreen());
2261 chkTitlebar->setChecked(cfg.hideTitlebarFullscreen());
2262 chkToolbar->setChecked(cfg.hideToolbarFullscreen());
2263
2264}
2265
2267{
2268 KisConfig cfg(true);
2269 chkDockers->setChecked(cfg.hideDockersFullscreen(true));
2270 chkMenu->setChecked(cfg.hideMenuFullscreen(true));
2271 chkScrollbars->setChecked(cfg.hideScrollbarsFullscreen(true));
2272 chkStatusbar->setChecked(cfg.hideStatusbarFullscreen(true));
2273 chkTitlebar->setChecked(cfg.hideTitlebarFullscreen(true));
2274 chkToolbar->setChecked(cfg.hideToolbarFullscreen(true));
2275}
2276
2277
2278//---------------------------------------------------------------------------------------------------
2279
2281static const QStringList allowedColorHistorySortingValues({"none", "hsv"});
2282}
2283
2284PopupPaletteTab::PopupPaletteTab(QWidget *parent, const char *name)
2285 : WdgPopupPaletteSettingsBase(parent, name)
2286{
2287 using namespace PopupPaletteTabPrivate;
2288
2289 load();
2290
2291 connect(chkShowColorHistory, SIGNAL(toggled(bool)), cmbColorHistorySorting, SLOT(setEnabled(bool)));
2292 connect(chkShowColorHistory, SIGNAL(toggled(bool)), lblColorHistorySorting, SLOT(setEnabled(bool)));
2293 KIS_SAFE_ASSERT_RECOVER_NOOP(cmbColorHistorySorting->count() == allowedColorHistorySortingValues.size());
2294}
2295
2297{
2298 using namespace PopupPaletteTabPrivate;
2299
2300 KisConfig config(true);
2301 sbNumPresets->setValue(config.favoritePresets());
2302 sbPaletteSize->setValue(config.readEntry("popuppalette/size", 385));
2303 sbSelectorSize->setValue(config.readEntry("popuppalette/selectorSize", 140));
2304 cmbSelectorType->setCurrentIndex(config.readEntry<bool>("popuppalette/usevisualcolorselector", false) ? 1 : 0);
2305 chkShowColorHistory->setChecked(config.readEntry("popuppalette/showColorHistory", true));
2306 chkShowRotationTrack->setChecked(config.readEntry("popuppalette/showRotationTrack", true));
2307 chkUseDynamicSlotCount->setChecked(config.readEntry("popuppalette/useDynamicSlotCount", true));
2308
2309 QString currentSorting = config.readEntry("popuppalette/colorHistorySorting", QString("hsv"));
2310 if (!allowedColorHistorySortingValues.contains(currentSorting)) {
2311 currentSorting = "hsv";
2312 }
2313 cmbColorHistorySorting->setCurrentIndex(allowedColorHistorySortingValues.indexOf(currentSorting));
2314 cmbColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2315 lblColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2316}
2317
2319{
2320 using namespace PopupPaletteTabPrivate;
2321
2322 KisConfig config(true);
2323 config.setFavoritePresets(sbNumPresets->value());
2324 config.writeEntry("popuppalette/size", sbPaletteSize->value());
2325 config.writeEntry("popuppalette/selectorSize", sbSelectorSize->value());
2326 config.writeEntry<bool>("popuppalette/usevisualcolorselector", cmbSelectorType->currentIndex() > 0);
2327 config.writeEntry<bool>("popuppalette/showColorHistory", chkShowColorHistory->isChecked());
2328 config.writeEntry<bool>("popuppalette/showRotationTrack", chkShowRotationTrack->isChecked());
2329 config.writeEntry<bool>("popuppalette/useDynamicSlotCount", chkUseDynamicSlotCount->isChecked());
2330 config.writeEntry("popuppalette/colorHistorySorting",
2331 allowedColorHistorySortingValues[cmbColorHistorySorting->currentIndex()]);
2332}
2333
2335{
2336 KisConfig config(true);
2337 sbNumPresets->setValue(config.favoritePresets(true));
2338 sbPaletteSize->setValue(385);
2339 sbSelectorSize->setValue(140);
2340 cmbSelectorType->setCurrentIndex(0);
2341 chkShowColorHistory->setChecked(true);
2342 chkShowRotationTrack->setChecked(true);
2343 chkUseDynamicSlotCount->setChecked(true);
2344 cmbColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2345 lblColorHistorySorting->setEnabled(chkShowColorHistory->isChecked());
2346}
2347
2348//---------------------------------------------------------------------------------------------------
2349
2350KisDlgPreferences::KisDlgPreferences(QWidget* parent, const char* name)
2351 : KPageDialog(parent)
2352{
2353 Q_UNUSED(name);
2354 setWindowTitle(i18n("Configure Krita"));
2355 setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::RestoreDefaults);
2356
2357 setFaceType(KPageDialog::List);
2358
2359 // General
2360 KoVBox *vbox = new KoVBox();
2361 KPageWidgetItem *page = new KPageWidgetItem(vbox, i18n("General"));
2362 page->setObjectName("general");
2363 page->setHeader(i18n("General"));
2364 page->setIcon(KisIconUtils::loadIcon("config-general"));
2365 m_pages << page;
2366 addPage(page);
2367 m_general = new GeneralTab(vbox);
2368
2369 // Shortcuts
2370 vbox = new KoVBox();
2371 page = new KPageWidgetItem(vbox, i18n("Keyboard Shortcuts"));
2372 page->setObjectName("shortcuts");
2373 page->setHeader(i18n("Shortcuts"));
2374 page->setIcon(KisIconUtils::loadIcon("config-keyboard"));
2375 m_pages << page;
2376 addPage(page);
2378 connect(this, SIGNAL(accepted()), m_shortcutSettings, SLOT(saveChanges()));
2379 connect(this, SIGNAL(rejected()), m_shortcutSettings, SLOT(cancelChanges()));
2380
2381 // Canvas input settings
2383 page = addPage(m_inputConfiguration, i18n("Canvas Input Settings"));
2384 page->setHeader(i18n("Canvas Input"));
2385 page->setObjectName("canvasinput");
2386 page->setIcon(KisIconUtils::loadIcon("config-canvas-input"));
2387 m_pages << page;
2388
2389 // Display
2390 vbox = new KoVBox();
2391 page = new KPageWidgetItem(vbox, i18n("Display"));
2392 page->setObjectName("display");
2393 page->setHeader(i18n("Display"));
2394 page->setIcon(KisIconUtils::loadIcon("config-display"));
2395 m_pages << page;
2396 addPage(page);
2398
2399 // Color
2400 vbox = new KoVBox();
2401 page = new KPageWidgetItem(vbox, i18n("Color Management"));
2402 page->setObjectName("colormanagement");
2403 page->setHeader(i18nc("Label of color as in Color Management", "Color"));
2404 page->setIcon(KisIconUtils::loadIcon("config-color-manage"));
2405 m_pages << page;
2406 addPage(page);
2408
2409 // Performance
2410 vbox = new KoVBox();
2411 page = new KPageWidgetItem(vbox, i18n("Performance"));
2412 page->setObjectName("performance");
2413 page->setHeader(i18n("Performance"));
2414 page->setIcon(KisIconUtils::loadIcon("config-performance"));
2415 m_pages << page;
2416 addPage(page);
2418
2419 // Tablet
2420 vbox = new KoVBox();
2421 page = new KPageWidgetItem(vbox, i18n("Tablet settings"));
2422 page->setObjectName("tablet");
2423 page->setHeader(i18n("Tablet"));
2424 page->setIcon(KisIconUtils::loadIcon("config-tablet"));
2425 m_pages << page;
2426 addPage(page);
2428
2429 // full-screen mode
2430 vbox = new KoVBox();
2431 page = new KPageWidgetItem(vbox, i18n("Canvas-only settings"));
2432 page->setObjectName("canvasonly");
2433 page->setHeader(i18n("Canvas-only"));
2434 page->setIcon(KisIconUtils::loadIcon("config-canvas-only"));
2435 m_pages << page;
2436 addPage(page);
2438
2439 // Pop-up Palette
2440 vbox = new KoVBox();
2441 page = new KPageWidgetItem(vbox, i18n("Pop-up Palette"));
2442 page->setObjectName("popuppalette");
2443 page->setHeader(i18n("Pop-up Palette"));
2444 page->setIcon(KisIconUtils::loadIcon("config-popup-palette"));
2445 m_pages << page;
2446 addPage(page);
2448
2449 // Author profiles
2451 page = addPage(m_authorPage, i18nc("@title:tab Author page", "Author" ));
2452 page->setObjectName("author");
2453 page->setHeader(i18n("Author"));
2454 page->setIcon(KisIconUtils::loadIcon("user-identity"));
2455 m_pages << page;
2456
2457 KGuiItem::assign(button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
2458 KGuiItem::assign(button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
2459 QPushButton *restoreDefaultsButton = button(QDialogButtonBox::RestoreDefaults);
2460 restoreDefaultsButton->setText(i18nc("@action:button", "Restore Defaults"));
2461
2462 connect(this, SIGNAL(accepted()), m_inputConfiguration, SLOT(saveChanges()));
2463 connect(this, SIGNAL(rejected()), m_inputConfiguration, SLOT(revertChanges()));
2464
2466 QStringList keys = preferenceSetRegistry->keys();
2467 keys.sort();
2468 Q_FOREACH(const QString &key, keys) {
2469 KisAbstractPreferenceSetFactory *preferenceSetFactory = preferenceSetRegistry->value(key);
2470 KisPreferenceSet* preferenceSet = preferenceSetFactory->createPreferenceSet();
2471 vbox = new KoVBox();
2472 page = new KPageWidgetItem(vbox, preferenceSet->name());
2473 page->setHeader(preferenceSet->header());
2474 page->setIcon(preferenceSet->icon());
2475 addPage(page);
2476 preferenceSet->setParent(vbox);
2477 preferenceSet->loadPreferences();
2478
2479 connect(restoreDefaultsButton, SIGNAL(clicked(bool)), preferenceSet, SLOT(loadDefaultPreferences()), Qt::UniqueConnection);
2480 connect(this, SIGNAL(accepted()), preferenceSet, SLOT(savePreferences()), Qt::UniqueConnection);
2481 }
2482
2483 connect(restoreDefaultsButton, SIGNAL(clicked(bool)), this, SLOT(slotDefault()));
2484
2485 KisConfig cfg(true);
2486 QString currentPageName = cfg.readEntry<QString>("KisDlgPreferences/CurrentPage");
2487 Q_FOREACH(KPageWidgetItem *page, m_pages) {
2488 if (page->objectName() == currentPageName) {
2489 setCurrentPage(page);
2490 break;
2491 }
2492 }
2493
2494 // TODO QT6: check what this code actually does?
2495#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
2496 {
2497 // HACK ALERT! Remove title widget background, thus making
2498 // it consistent across all systems
2499 const auto *titleWidget = findChild<KTitleWidget*>();
2500 if (titleWidget) {
2501 QLayoutItem *titleFrame = titleWidget->layout()->itemAt(0); // vboxLayout -> titleFrame
2502 if (titleFrame) {
2503 titleFrame->widget()->setBackgroundRole(QPalette::Window);
2504 }
2505 }
2506 }
2507#endif
2508}
2509
2511{
2512 KisConfig cfg(true);
2513 cfg.writeEntry<QString>("KisDlgPreferences/CurrentPage", currentPage()->objectName());
2514}
2515
2516void KisDlgPreferences::showEvent(QShowEvent *event){
2517 KPageDialog::showEvent(event);
2518 button(QDialogButtonBox::Cancel)->setAutoDefault(false);
2519 button(QDialogButtonBox::Ok)->setAutoDefault(false);
2520 button(QDialogButtonBox::RestoreDefaults)->setAutoDefault(false);
2521 button(QDialogButtonBox::Cancel)->setDefault(false);
2522 button(QDialogButtonBox::Ok)->setDefault(false);
2523 button(QDialogButtonBox::RestoreDefaults)->setDefault(false);
2524}
2525
2527{
2528 if (buttonBox()->buttonRole(button) == QDialogButtonBox::RejectRole) {
2529 m_cancelClicked = true;
2530 }
2531}
2532
2534{
2535 if (currentPage()->objectName() == "general") {
2537 }
2538 else if (currentPage()->objectName() == "shortcuts") {
2540 }
2541 else if (currentPage()->objectName() == "display") {
2543 }
2544 else if (currentPage()->objectName() == "colormanagement") {
2546 }
2547 else if (currentPage()->objectName() == "performance") {
2549 }
2550 else if (currentPage()->objectName() == "tablet") {
2552 }
2553 else if (currentPage()->objectName() == "canvasonly") {
2555 }
2556 else if (currentPage()->objectName() == "canvasinput") {
2558 }
2559 else if (currentPage()->objectName() == "popuppalette") {
2561 }
2562}
2563
2565{
2566 connect(this->buttonBox(), SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotButtonClicked(QAbstractButton*)));
2567
2568 int retval = exec();
2569 Q_UNUSED(retval);
2570
2571 if (!m_cancelClicked) {
2572 // General settings
2573 KisConfig cfg(false);
2574 KisImageConfig cfgImage(false);
2575
2578 cfg.setSeparateEraserCursor(m_general->m_chkSeparateEraserCursor->isChecked());
2583 cfg.setForceAlwaysFullSizedOutline(!m_general->m_changeBrushOutline->isChecked());
2585 cfg.setForceAlwaysFullSizedEraserOutline(!m_general->m_changeEraserBrushOutline->isChecked());
2588
2589 KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
2590 group.writeEntry("DontUseNativeFileDialog", !m_general->m_chkNativeFileDialog->isChecked());
2591
2592 cfgImage.setMaxBrushSize(m_general->intMaxBrushSize->value());
2593 cfg.setIgnoreHighFunctionKeys(m_general->chkIgnoreHighFunctionKeys->isChecked());
2594
2595 cfg.writeEntry<bool>("use_custom_system_font", m_general->chkUseCustomFont->isChecked());
2596 if (m_general->chkUseCustomFont->isChecked()) {
2597 cfg.writeEntry<QString>("custom_system_font", m_general->cmbCustomFont->currentFont().family());
2598 cfg.writeEntry<int>("custom_font_size", m_general->intFontSize->value());
2599 }
2600 else {
2601 cfg.writeEntry<QString>("custom_system_font", "");
2602 cfg.writeEntry<int>("custom_font_size", -1);
2603 }
2604
2605 cfg.writeEntry<int>("mdi_viewmode", m_general->mdiMode());
2606 cfg.setMDIBackgroundColor(m_general->m_mdiColor->color().toXML());
2607 cfg.setMDIBackgroundImage(m_general->m_backgroundimage->text());
2608 cfg.writeEntry<int>("mdi_rubberband", m_general->m_chkRubberBand->isChecked());
2610 cfg.writeEntry("autosavefileshidden", m_general->chkHideAutosaveFiles->isChecked());
2611
2612 cfg.setBackupFile(m_general->m_backupFileCheckBox->isChecked());
2613 cfg.writeEntry("backupfilelocation", m_general->cmbBackupFileLocation->currentIndex());
2614 cfg.writeEntry("backupfilesuffix", m_general->txtBackupFileSuffix->text());
2615 cfg.writeEntry("numberofbackupfiles", m_general->intNumBackupFiles->value());
2616
2617
2625
2626 const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
2627 QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
2628 kritarc.setValue("EnableHiDPI", m_general->m_chkHiDPI->isChecked());
2629#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
2630 kritarc.setValue("EnableHiDPIFractionalScaling", m_general->m_chkHiDPIFractionalScaling->isChecked());
2631#endif
2632 kritarc.setValue("LogUsage", m_general->chkUsageLogging->isChecked());
2633
2635
2636 cfg.writeEntry<bool>("useCreamyAlphaDarken", (bool)!m_general->cmbFlowMode->currentIndex());
2637 cfg.writeEntry<bool>("useSubtractiveBlendingForCmykColorSpaces", (bool)!m_general->cmbCmykBlendingMode->currentIndex());
2638
2645
2647
2649 cfg.setTouchPainting(KisConfig::TouchPainting(m_general->cmbTouchPainting->currentIndex()));
2650 cfg.writeEntry("useTouchPressureSensitivity", m_general->chkTouchPressureSensitivity->isChecked());
2651 cfg.setActivateTransformToolAfterPaste(m_general->chkEnableTransformToolAfterPaste->isChecked());
2652 cfg.setZoomHorizontal(m_general->chkZoomHorizontally->isChecked());
2653 cfg.setSelectionActionBar(m_general->chkEnableSelectionActionBar->isChecked());
2656 cfg.setCumulativeUndoRedo(m_general->chkCumulativeUndo->isChecked());
2658
2659 // Animation..
2663
2664#ifdef Q_OS_ANDROID
2665 QFileInfo fi(m_general->m_resourceFolderSelector->currentData(Qt::UserRole).value<QString>());
2666#else
2667 QFileInfo fi(m_general->m_urlResourceFolder->fileName());
2668#endif
2669 if (fi.isWritable()) {
2671 }
2672
2676
2677 // Color settings
2679 cfg.setUseSystemMonitorProfile(m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
2680 for (int i = 0; i < QApplication::screens().count(); ++i) {
2681 if (m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked()) {
2682 int currentIndex = m_colorSettings->m_monitorProfileWidgets[i]->currentIndex();
2683 QString monitorid = m_colorSettings->m_monitorProfileWidgets[i]->itemData(currentIndex).toString();
2684 cfg.setMonitorForScreen(i, monitorid);
2685 } else {
2686 cfg.setMonitorProfile(i,
2687 m_colorSettings->m_monitorProfileWidgets[i]->currentUnsqueezedText(),
2688 m_colorSettings->m_page->chkUseSystemMonitorProfile->isChecked());
2689 }
2690 }
2691 } else {
2695 }
2696 cfg.setUseDefaultColorSpace(m_colorSettings->m_page->useDefColorSpace->isChecked());
2697 if (cfg.useDefaultColorSpace())
2698 {
2699 KoID currentWorkingColorSpace = m_colorSettings->m_page->cmbWorkingColorSpace->currentItem();
2700 cfg.setWorkingColorSpace(currentWorkingColorSpace.id());
2701 cfg.defColorModel(KoColorSpaceRegistry::instance()->colorSpaceColorModelId(currentWorkingColorSpace.id()).id());
2702 cfg.setDefaultColorDepth(KoColorSpaceRegistry::instance()->colorSpaceColorDepthId(currentWorkingColorSpace.id()).id());
2703 }
2704
2705 cfg.writeEntry("ExrDefaultColorProfile", m_colorSettings->m_page->cmbColorProfileForEXR->currentText());
2706
2707 cfgImage.setDefaultProofingConfig(*m_colorSettings->m_page->wdgProofingOptions->currentProofingConfig());
2708 cfg.setUseBlackPointCompensation(m_colorSettings->m_page->chkBlackpoint->isChecked());
2709 cfg.setAllowLCMSOptimization(m_colorSettings->m_page->chkAllowLCMSOptimization->isChecked());
2710 cfg.setForcePaletteColors(m_colorSettings->m_page->chkForcePaletteColor->isChecked());
2712 cfg.setRenderIntent(m_colorSettings->m_page->cmbMonitorIntent->currentIndex());
2713
2714 // Tablet settings
2715 cfg.setPressureTabletCurve( m_tabletSettings->m_page->pressureCurve->curve().toString() );
2717 m_tabletSettings->m_page->chkUseRightMiddleClickWorkaround->isChecked());
2718
2719#if defined Q_OS_WIN && (defined QT5_HAS_WINTAB_SWITCH || QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
2720 cfg.setUseWin8PointerInput(m_tabletSettings->m_page->radioWin8PointerInput->isChecked());
2721
2722# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
2723 // Qt6 supports switching the tablet API on the fly
2724 using QWindowsApplication = QNativeInterface::Private::QWindowsApplication;
2725 if (auto nativeWindowsApp = dynamic_cast<QWindowsApplication *>(QGuiApplicationPrivate::platformIntegration())) {
2726 nativeWindowsApp->setWinTabEnabled(!cfg.useWin8PointerInput());
2727 }
2728# endif
2729#endif
2730 cfg.writeEntry<bool>("useTimestampsForBrushSpeed", m_tabletSettings->m_page->chkUseTimestampsForBrushSpeed->isChecked());
2731 cfg.writeEntry<int>("maxAllowedSpeedValue", m_tabletSettings->m_page->intMaxAllowedBrushSpeed->value());
2732 cfg.writeEntry<int>("speedValueSmoothing", m_tabletSettings->m_page->intBrushSpeedSmoothing->value());
2733 // the angle is saved in clockwise direction to be consistent with Drawing Angle, so negate
2734 cfg.writeEntry<int>("tiltDirectionOffset", -m_tabletSettings->m_page->tiltDirectionOffsetAngle->angle());
2735
2737
2738 if (!cfg.useOpenGL() && m_displaySettings->grpOpenGL->isChecked())
2739 cfg.setCanvasState("TRY_OPENGL");
2740
2741 if (m_displaySettings->grpOpenGL->isChecked()) {
2743 m_displaySettings->cmbPreferredRenderer->itemData(
2744 m_displaySettings->cmbPreferredRenderer->currentIndex()).toInt());
2746 } else {
2748 }
2749
2750 cfg.setUseOpenGLTextureBuffer(m_displaySettings->chkUseTextureBuffer->isChecked());
2751 cfg.setOpenGLFilteringMode(m_displaySettings->cmbFilterMode->currentIndex());
2752 cfg.setRootSurfaceFormat(&kritarc, indexToFormat(m_displaySettings->cmbPreferedRootSurfaceFormat->currentIndex()));
2753 cfg.setAssistantsDrawMode(indexToAssistantDrawMode(m_displaySettings->cmbAssistantsDrawMode->currentIndex()));
2754
2755 cfg.setCheckSize(m_displaySettings->intCheckSize->value());
2756 cfg.setScrollingCheckers(m_displaySettings->chkMoving->isChecked());
2757 cfg.setCheckersColor1(m_displaySettings->colorChecks1->color().toQColor());
2758 cfg.setCheckersColor2(m_displaySettings->colorChecks2->color().toQColor());
2759 cfg.setCanvasBorderColor(m_displaySettings->canvasBorder->color().toQColor());
2760 cfg.setHideScrollbars(m_displaySettings->hideScrollbars->isChecked());
2761 KoColor c = m_displaySettings->btnSelectionOverlayColor->color();
2762 c.setOpacity(m_displaySettings->sldSelectionOverlayOpacity->value());
2764 cfgImage.setSelectionOutlineOpacity(m_displaySettings->sldSelectionOutlineOpacity->value());
2765 cfg.setAntialiasCurves(m_displaySettings->chkCurveAntialiasing->isChecked());
2766 cfg.setAntialiasSelectionOutline(m_displaySettings->chkSelectionOutlineAntialiasing->isChecked());
2767 cfg.setShowSingleChannelAsColor(m_displaySettings->chkChannelsAsColor->isChecked());
2768 cfg.setHidePopups(m_displaySettings->chkHidePopups->isChecked());
2769
2770 cfg.setHideDockersFullscreen(m_fullscreenSettings->chkDockers->checkState());
2771 cfg.setHideMenuFullscreen(m_fullscreenSettings->chkMenu->checkState());
2772 cfg.setHideScrollbarsFullscreen(m_fullscreenSettings->chkScrollbars->checkState());
2773 cfg.setHideStatusbarFullscreen(m_fullscreenSettings->chkStatusbar->checkState());
2774 cfg.setHideTitlebarFullscreen(m_fullscreenSettings->chkTitlebar->checkState());
2775 cfg.setHideToolbarFullscreen(m_fullscreenSettings->chkToolbar->checkState());
2776
2777 cfg.setCursorMainColor(m_general->cursorColorButton->color().toQColor());
2778 cfg.setEraserCursorMainColor(m_general->eraserCursorColorButton->color().toQColor());
2779 cfg.setPixelGridColor(m_displaySettings->pixelGridColorButton->color().toQColor());
2780 cfg.setPixelGridDrawingThreshold(m_displaySettings->pixelGridDrawingThresholdBox->value() / 100);
2781
2784
2786 cfg.writeEntry("forcedDpiForQtFontBugWorkaround", m_general->forcedFontDpi());
2787 }
2788
2789 return !m_cancelClicked;
2790}
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()
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
void toggleUseDefaultColorSpace(bool useDefColorSpace)
QList< QLabel * > m_monitorProfileLabels
void toggleAllowMonitorProfileSelection(bool useSystemProfile)
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)
ColorSettingsTab(QWidget *parent=0, const char *name=0)
WdgColorSettings * m_page
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 renameDuplicatedLayers()
bool saveSessionOnQuit() const
void showAdvancedCumulativeUndoSettings()
bool autoZoomTimelineToPlaybackRange()
bool kineticScrollingEnabled()
bool convertToImageColorspaceOnImport()
QButtonGroup m_pasteFormatGroup
OutlineStyle eraserOutlineStyle()
bool switchSelectionCtrlAlt()
int kineticScrollingSensitivity()
KisCumulativeUndoData m_cumulativeUndoData
QString exportMimeType()
void updateTouchPressureSensitivityEnabled(int)
bool showOutlineWhilePainting()
CursorStyle eraserCursorStyle()
void enableSubWindowOptions(int)
OutlineStyle outlineStyle()
bool autopinLayersToTimeline()
bool showEraserOutlineWhilePainting()
CursorStyle cursorStyle()
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()
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:769
@ ASSISTANTS_DRAW_MODE_DIRECT
Definition kis_config.h:768
@ ASSISTANTS_DRAW_MODE_LARGE_PIXMAP_CACHE
Definition kis_config.h:770
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)
void setPasteFormat(qint32 format)
QColor checkersColor2(bool defaultValue=false) const
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:779
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
bool disableVectorOptimizations(bool defaultValue=false) const
void setCursorMainColor(const QColor &v) const
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 setAutoSaveInterval(int seconds) const
void setShowSingleChannelAsColor(bool asColor)
void setTrimFramesImport(bool trim)
bool forcePaletteColors(bool defaultValue=false) const
void setAllowLCMSOptimization(bool allowLCMSOptimization)
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
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:73
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 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
void setPressureTabletCurve(const QString &curveString) 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
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:789
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:167
void setZoomMarginSize(int zoomMarginSize)
bool hideStatusbarFullscreen(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
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
KisInputConfigurationPage * m_inputConfiguration
FullscreenSettingsTab * m_fullscreenSettings
ShortcutSettingsTab * m_shortcutSettings
TabletSettingsTab * m_tabletSettings
QList< KPageWidgetItem * > m_pages
DisplaySettingsTab * m_displaySettings
void slotButtonClicked(QAbstractButton *button)
KisDlgPreferences(QWidget *parent=0, const char *name=0)
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()
static void setUserPreferredOpenGLRendererConfig(OpenGLRenderer renderer)
static KisPart * instance()
Definition KisPart.cpp:131
KisMainWindow * currentMainwindow() const
Definition KisPart.cpp:483
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
ScreenInfo infoForScreen(QScreen *screen) const
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)
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
const QString DEFAULT_CURVE_STRING
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)