202{
204
205
206
207
208 {
209 scrollAreaWidgetContents->setAutoFillBackground(false);
210 scrollAreaWidgetContents->parentWidget()->setAutoFillBackground(false);
211 }
212
213
214
215
216
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
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
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
248 cursorColor.fromQColor(cfg.getCursorMainColor());
249 cursorColorButton->setColor(cursorColor);
250
251
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
268 eraserCursorColor.fromQColor(cfg.getEraserCursorMainColor());
269 eraserCursorColorButton->setColor(eraserCursorColor);
270
271
272
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));
297
298 m_backgroundimage->setText(cfg.getMDIBackgroundImage());
301
302 QString xml = cfg.getMDIBackgroundColor();
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
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(
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)),
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
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
365
366 int autosaveInterval = cfg.autoSaveInterval();
367
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", "~"));
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) {
391 mimeTypeMap.insert(description, mimeType);
392 }
393
394
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
411 const QString defaultMimeType = "image/png";
412 const int defaultIndex = cmbDefaultExportFileType->findData(defaultMimeType);
413 if (defaultIndex >= 0) {
414 cmbDefaultExportFileType->setCurrentIndex(defaultIndex);
415 } else {
416
417 qDebug() << "Default mime type not found in the combo box.";
418 }
419 }
420
421 QString selectedMimeType = cmbDefaultExportFileType->currentData().toString();
422
423
424
425
426 m_chkAutoPin->setChecked(cfg.autoPinLayersToTimeline());
427 m_chkAdaptivePlaybackRange->setChecked(cfg.adaptivePlaybackRange());
428 m_chkAutoZoom->setChecked(cfg.autoZoomTimelineToPlaybackRange());
429
430
431
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());
448
449 chkShowRootLayer->setChecked(cfg.showRootLayer());
450
452 chkRenamePastedLayers->setChecked(cfg.renamePastedLayers());
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
475
476 m_chkNativeFileDialog->setChecked(false);
477 m_chkNativeFileDialog->setEnabled(false);
478 }
479
481 chkIgnoreHighFunctionKeys->setChecked(cfg.ignoreHighFunctionKeys());
482#ifndef Q_OS_WIN
483
484
485 chkIgnoreHighFunctionKeys->setVisible(false);
486#endif
487
488
489
490
492 m_urlResourceFolder->setConfigurationName("resource_directory");
494 if (QFileInfo(resourceLocation).isWritable()) {
495 m_urlResourceFolder->setFileName(resourceLocation);
496 }
497 else {
498 m_urlResourceFolder->setFileName(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation));
499 }
501 txtBackupFileSuffix->setValidator(writableValidator);
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);
520
523
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
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
559 m_resourceFolderSelector->setItemData(m_resourceFolderSelector->count() - 1, it->second, Qt::UserRole);
560 }
561
562
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
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);
580 m_resourceFolderSelector->setCurrentIndex(index);
581 }
582 }
583
584
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
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
597
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
606 m_resourceFolderSelector->insertItem(index, selectedDirectory);
607 m_resourceFolderSelector->setItemData(index, selectedDirectory, Qt::UserRole);
608 m_resourceFolderSelector->setCurrentIndex(index);
609 }
610
611 grpAndroidWarningMessage->setVisible(true);
612 } else {
613 m_resourceFolderSelector->setCurrentIndex(previousIndex);
614 }
615 }
616
617
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;
631
632 if (!folderInPrivateAppData.isEmpty()) {
633 const auto pathToDisplay = [](const QString &path) {
634
635
636
637
638
639
640
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
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
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
690
692
694
697 }
698}
QList< QString > QStringList
Q_GUI_EXPORT int qt_defaultDpi()
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
bool renameDuplicatedLayers()
void showAdvancedCumulativeUndoSettings()
void clearBackgroundImage()
QButtonGroup m_pasteFormatGroup
void getBackgroundImage()
KisCumulativeUndoData m_cumulativeUndoData
void updateTouchPressureSensitivityEnabled(int)
bool renameMergedLayers()
void enableSubWindowOptions(int)
static QStringList supportedMimeTypes(Direction direction)
static QString descriptionForMimeType(const QString &mimeType)
Find the user-readable description for the given mimetype.
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
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()
WdgGeneralSettings(QWidget *parent, const char *name)
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
QString button(const QWheelEvent &ev)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
void linkActivated(const QString &link)
static KoColorSpaceRegistry * instance()