kis_dlg_preferences.cc 67.5 KB
Newer Older
1 2 3 4
/*
 *  preferencesdlg.cc - part of KImageShop
 *
 *  Copyright (c) 1999 Michael Koch <koch@kde.org>
5
 *  Copyright (c) 2003-2011 Boudewijn Rempt <boud@valdyas.org>
6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 21
 */

Boudewijn Rempt's avatar
Boudewijn Rempt committed
22 23
#include "kis_dlg_preferences.h"

24
#include <config-hdr.h>
25
#include <opengl/kis_opengl.h>
26

27
#include <QBitmap>
28
#include <QCheckBox>
29
#include <QCursor>
30 31 32 33
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QPushButton>
34 35
#include <QSlider>
#include <QToolButton>
36
#include <QThread>
37
#include <QStandardPaths>
38
#include <QGroupBox>
39
#include <QGridLayout>
40 41
#include <QRadioButton>
#include <QGroupBox>
42
#include <QMdiArea>
43
#include <QMessageBox>
44
#include <QDesktopWidget>
45
#include <QFileDialog>
46
#include <QFormLayout>
47
#include <QSettings>
48

49
#include <KisDocument.h>
50
#include <KoColorProfile.h>
51
#include <KisApplication.h>
Yue Liu's avatar
Yue Liu committed
52
#include <KoFileDialog.h>
53
#include <KisPart.h>
54
#include <KoColorSpaceEngine.h>
55
#include <kis_icon.h>
56
#include <KoConfig.h>
57
#include "KoID.h"
58
#include <KoConfigAuthorPage.h>
59
#include <KoVBox.h>
60

61
#include <klocalizedstring.h>
62
#include <kformat.h>
63
#include <kundo2stack.h>
64
#include <KoResourcePaths.h>
65
#include "kis_action_registry.h"
Boudewijn Rempt's avatar
Boudewijn Rempt committed
66
#include <kis_image.h>
67
#include <KisSqueezedComboBox.h>
68
#include "kis_clipboard.h"
69
#include "widgets/kis_cmb_idlist.h"
70
#include "KoColorSpace.h"
71
#include "KoColorSpaceRegistry.h"
72
#include "KoColorConversionTransformation.h"
73 74
#include "kis_cursor.h"
#include "kis_config.h"
75
#include "kis_canvas_resource_provider.h"
76
#include "kis_preference_set_registry.h"
77
#include "kis_color_manager.h"
78 79
#include "KisProofingConfiguration.h"
#include "kis_image_config.h"
80

81 82
#include "slider_and_spin_box_sync.h"

83
// for the performance update
84
#include <kis_cubic_curve.h>
85
#include <kis_signals_blocker.h>
86

87
#include "input/config/kis_input_configuration_page.h"
88
#include "input/wintab/drawpile_tablettester/tablettester.h"
89

90
#ifdef Q_OS_WIN
91 92 93 94
#include "config_use_qt_tablet_windows.h"
#   ifndef USE_QT_TABLET_WINDOWS
#       include <kis_tablet_support_win8.h>
#   endif
95
#include "config-high-dpi-scale-factor-rounding-policy.h"
96 97
#endif

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
struct BackupSuffixValidator : public QValidator {
    BackupSuffixValidator(QObject *parent)
        : QValidator(parent)
        , invalidCharacters(QStringList()
                            << "0" << "1" << "2" << "3" << "4" << "5" << "6" << "7" << "8" << "9"
                            << "/" << "\\" << ":" << ";" << " ")
    {}

    ~BackupSuffixValidator() override {}

    const QStringList invalidCharacters;

    State validate(QString &line, int &/*pos*/) const override
    {
        Q_FOREACH(const QString invalidChar, invalidCharacters) {
            if (line.contains(invalidChar)) {
                return Invalid;
            }
        }
        return Acceptable;
    }
};

121

Boudewijn Rempt's avatar
Boudewijn Rempt committed
122
GeneralTab::GeneralTab(QWidget *_parent, const char *_name)
123
    : WdgGeneralSettings(_parent, _name)
124
{
125
    KisConfig cfg(true);
126

127 128 129
    //
    // Cursor Tab
    //
130
    m_cmbCursorShape->addItem(i18n("No Cursor"));
Boudewijn Rempt's avatar
Boudewijn Rempt committed
131 132
    m_cmbCursorShape->addItem(i18n("Tool Icon"));
    m_cmbCursorShape->addItem(i18n("Arrow"));
133
    m_cmbCursorShape->addItem(i18n("Small Circle"));
134
    m_cmbCursorShape->addItem(i18n("Crosshair"));
135 136
    m_cmbCursorShape->addItem(i18n("Triangle Righthanded"));
    m_cmbCursorShape->addItem(i18n("Triangle Lefthanded"));
137 138
    m_cmbCursorShape->addItem(i18n("Black Pixel"));
    m_cmbCursorShape->addItem(i18n("White Pixel"));
139

140 141
    m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle());

142 143 144
    m_cmbOutlineShape->addItem(i18n("No Outline"));
    m_cmbOutlineShape->addItem(i18n("Circle Outline"));
    m_cmbOutlineShape->addItem(i18n("Preview Outline"));
145
    m_cmbOutlineShape->addItem(i18n("Tilt Outline"));
146

147 148 149
    m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle());

    m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting());
150
    m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline());
151 152 153 154 155 156 157 158 159 160 161 162 163 164

    KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
    cursorColor.fromQColor(cfg.getCursorMainColor());
    cursorColorBtutton->setColor(cursorColor);

    //
    // Window Tab
    //
    m_cmbMDIType->setCurrentIndex(cfg.readEntry<int>("mdi_viewmode", (int)QMdiArea::TabbedView));

    m_backgroundimage->setText(cfg.getMDIBackgroundImage());
    connect(m_bnFileName, SIGNAL(clicked()), SLOT(getBackgroundImage()));
    connect(clearBgImageButton, SIGNAL(clicked()), SLOT(clearBackgroundImage()));

165 166
    QString xml = cfg.getMDIBackgroundColor();
    KoColor mdiColor = KoColor::fromXML(xml);
167 168 169 170 171 172 173 174
    m_mdiColor->setColor(mdiColor);

    m_chkRubberBand->setChecked(cfg.readEntry<int>("mdi_rubberband", cfg.useOpenGL()));

    m_chkCanvasMessages->setChecked(cfg.showCanvasMessages());

    const QString configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation);
    QSettings kritarc(configPath + QStringLiteral("/kritadisplayrc"), QSettings::IniFormat);
175
    m_chkHiDPI->setChecked(kritarc.value("EnableHiDPI", true).toBool());
176 177 178 179 180
#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
    m_chkHiDPIFractionalScaling->setChecked(kritarc.value("EnableHiDPIFractionalScaling", true).toBool());
#else
    m_chkHiDPIFractionalScaling->setVisible(false);
#endif
181
    chkUsageLogging->setChecked(kritarc.value("LogUsage", true).toBool());
182 183 184 185 186 187
    m_chkSingleApplication->setChecked(kritarc.value("EnableSingleApplication", true).toBool());

    //
    // Tools tab
    //
    m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker());
188
    cmbFlowMode->setCurrentIndex((int)!cfg.readEntry<bool>("useCreamyAlphaDarken", true));
189 190
    m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt());
    chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas());
191
    chkEnableTouchRotation->setChecked(!cfg.disableTouchRotation());
192
    chkEnableTranformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste());
193

194 195
    m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled());

196 197
    m_cmbKineticScrollingGesture->addItem(i18n("On Touch Drag"));
    m_cmbKineticScrollingGesture->addItem(i18n("On Click Drag"));
198 199
    m_cmbKineticScrollingGesture->addItem(i18n("On Middle-Click Drag"));
    //m_cmbKineticScrollingGesture->addItem(i18n("On Right Click Drag"));
200

201
    m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture());
202 203 204 205
    m_kineticScrollingSensitivitySlider->setRange(0, 100);
    m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity());
    m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars());

206
    //
207
    // File handling
208
    //
209
    int autosaveInterval = cfg.autoSaveInterval();
210
    //convert to minutes
211 212
    m_autosaveSpinBox->setValue(autosaveInterval / 60);
    m_autosaveCheckBox->setChecked(autosaveInterval > 0);
213
    chkHideAutosaveFiles->setChecked(cfg.readEntry<bool>("autosavefileshidden", true));
214 215

    m_chkCompressKra->setChecked(cfg.compressKra());
216
    chkZip64->setChecked(cfg.useZip64());
217

218
    m_backupFileCheckBox->setChecked(cfg.backupFile());
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233
    cmbBackupFileLocation->setCurrentIndex(cfg.readEntry<int>("backupfilelocation", 0));
    txtBackupFileSuffix->setText(cfg.readEntry<QString>("backupfilesuffix", "~"));
    QValidator *validator = new BackupSuffixValidator(txtBackupFileSuffix);
    txtBackupFileSuffix->setValidator(validator);
    intNumBackupFiles->setValue(cfg.readEntry<int>("numberofbackupfiles", 1));

    //
    // Miscellaneous
    //
    cmbStartupSession->addItem(i18n("Open default window"));
    cmbStartupSession->addItem(i18n("Load previous session"));
    cmbStartupSession->addItem(i18n("Show session manager"));
    cmbStartupSession->setCurrentIndex(cfg.sessionOnStartup());

    chkSaveSessionOnQuit->setChecked(cfg.saveSessionOnQuit(false));
234 235 236 237 238 239 240 241 242

    m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport());

    m_undoStackSize->setValue(cfg.undoStackLimit());

    m_favoritePresetsSpinBox->setValue(cfg.favoritePresets());

    chkShowRootLayer->setChecked(cfg.showRootLayer());

243
    KConfigGroup group = KSharedConfig::openConfig()->group("File Dialogs");
244 245 246 247 248
    bool dontUseNative = true;
#ifdef Q_OS_UNIX
    if (qgetenv("XDG_CURRENT_DESKTOP") == "KDE") {
        dontUseNative = false;
    }
249 250 251
#endif
#ifdef Q_OS_WIN
    dontUseNative = false;
252 253
#endif
    m_chkNativeFileDialog->setChecked(!group.readEntry("DontUseNativeFileDialog", dontUseNative));
254

255
    intMaxBrushSize->setValue(cfg.readEntry("maximumBrushSize", 1000));
256 257
}

258 259
void GeneralTab::setDefault()
{
260
    KisConfig cfg(true);
261

262 263
    m_cmbCursorShape->setCurrentIndex(cfg.newCursorStyle(true));
    m_cmbOutlineShape->setCurrentIndex(cfg.newOutlineStyle(true));
264 265
    chkShowRootLayer->setChecked(cfg.showRootLayer(true));
    m_autosaveCheckBox->setChecked(cfg.autoSaveInterval(true) > 0);
266
    //convert to minutes
267
    m_autosaveSpinBox->setValue(cfg.autoSaveInterval(true) / 60);
268 269
    chkHideAutosaveFiles->setChecked(true);

270
    m_undoStackSize->setValue(cfg.undoStackLimit(true));
271

272
    m_backupFileCheckBox->setChecked(cfg.backupFile(true));
273 274 275 276
    cmbBackupFileLocation->setCurrentIndex(0);
    txtBackupFileSuffix->setText("~");
    intNumBackupFiles->setValue(1);

277
    m_showOutlinePainting->setChecked(cfg.showOutlineWhilePainting(true));
278
    m_changeBrushOutline->setChecked(!cfg.forceAlwaysFullSizedOutline(true));
279

280
    m_chkNativeFileDialog->setChecked(false);
281
    intMaxBrushSize->setValue(1000);
282

283 284 285
    m_cmbMDIType->setCurrentIndex((int)QMdiArea::TabbedView);
    m_chkRubberBand->setChecked(cfg.useOpenGL(true));
    m_favoritePresetsSpinBox->setValue(cfg.favoritePresets(true));
286
    KoColor mdiColor;
287
    mdiColor.fromXML(cfg.getMDIBackgroundColor(true));
288
    m_mdiColor->setColor(mdiColor);
289 290 291
    m_backgroundimage->setText(cfg.getMDIBackgroundImage(true));
    m_chkCanvasMessages->setChecked(cfg.showCanvasMessages(true));
    m_chkCompressKra->setChecked(cfg.compressKra(true));
292
    chkZip64->setChecked(cfg.useZip64(true));
293 294 295
    m_chkHiDPI->setChecked(false);
    m_chkSingleApplication->setChecked(true);

296
    m_chkHiDPI->setChecked(true);
297 298 299
#ifdef HAVE_HIGH_DPI_SCALE_FACTOR_ROUNDING_POLICY
    m_chkHiDPIFractionalScaling->setChecked(true);
#endif
300
    chkUsageLogging->setChecked(true);
301
    m_radioToolOptionsInDocker->setChecked(cfg.toolOptionsInDocker(true));
302
    cmbFlowMode->setCurrentIndex(0);
303
    m_groupBoxKineticScrollingSettings->setChecked(cfg.kineticScrollingEnabled(true));
304
    m_cmbKineticScrollingGesture->setCurrentIndex(cfg.kineticScrollingGesture(true));
305 306
    m_kineticScrollingSensitivitySlider->setValue(cfg.kineticScrollingSensitivity(true));
    m_chkKineticScrollingHideScrollbars->setChecked(cfg.kineticScrollingHiddenScrollbars(true));
307
    m_chkSwitchSelectionCtrlAlt->setChecked(cfg.switchSelectionCtrlAlt(true));
308
    chkEnableTouch->setChecked(!cfg.disableTouchOnCanvas(true));
309
    chkEnableTouchRotation->setChecked(!cfg.disableTouchRotation(true));
310
    chkEnableTranformToolAfterPaste->setChecked(cfg.activateTransformToolAfterPaste(true));
311
    m_chkConvertOnImport->setChecked(cfg.convertToImageColorspaceOnImport(true));
312

313 314 315
    KoColor cursorColor(KoColorSpaceRegistry::instance()->rgb8());
    cursorColor.fromQColor(cfg.getCursorMainColor(true));
    cursorColorBtutton->setColor(cursorColor);
316 317 318



319 320
}

321 322 323 324 325 326
CursorStyle GeneralTab::cursorStyle()
{
    return (CursorStyle)m_cmbCursorShape->currentIndex();
}

OutlineStyle GeneralTab::outlineStyle()
327
{
328
    return (OutlineStyle)m_cmbOutlineShape->currentIndex();
329
}
330

331 332 333 334 335
KisConfig::SessionOnStartup GeneralTab::sessionOnStartup() const
{
    return (KisConfig::SessionOnStartup)cmbStartupSession->currentIndex();
}

336 337 338 339 340
bool GeneralTab::saveSessionOnQuit() const
{
    return chkSaveSessionOnQuit->isChecked();
}

341 342 343 344
bool GeneralTab::showRootLayer()
{
    return chkShowRootLayer->isChecked();
}
345

346 347
int GeneralTab::autoSaveInterval()
{
348
    //convert to seconds
349
    return m_autosaveCheckBox->isChecked() ? m_autosaveSpinBox->value() * 60 : 0;
350 351
}

352 353 354 355 356
int GeneralTab::undoStackSize()
{
    return m_undoStackSize->value();
}

357 358 359 360 361
bool GeneralTab::showOutlineWhilePainting()
{
    return m_showOutlinePainting->isChecked();
}

362 363 364 365 366
int GeneralTab::mdiMode()
{
    return m_cmbMDIType->currentIndex();
}

367 368 369 370 371
int GeneralTab::favoritePresets()
{
    return m_favoritePresetsSpinBox->value();
}

372 373 374 375 376
bool GeneralTab::showCanvasMessages()
{
    return m_chkCanvasMessages->isChecked();
}

377 378 379 380 381
bool GeneralTab::compressKra()
{
    return m_chkCompressKra->isChecked();
}

382 383 384 385 386
bool GeneralTab::useZip64()
{
    return chkZip64->isChecked();
}

387 388 389 390 391
bool GeneralTab::toolOptionsInDocker()
{
    return m_radioToolOptionsInDocker->isChecked();
}

392 393 394 395 396
bool GeneralTab::kineticScrollingEnabled()
{
    return m_groupBoxKineticScrollingSettings->isChecked();
}

397 398 399 400 401 402 403
int GeneralTab::kineticScrollingGesture()
{
    return m_cmbKineticScrollingGesture->currentIndex();
}

int GeneralTab::kineticScrollingSensitivity()
{
404
    return m_kineticScrollingSensitivitySlider->value();
405 406
}

407
bool GeneralTab::kineticScrollingHiddenScrollbars()
408
{
409
    return m_chkKineticScrollingHideScrollbars->isChecked();
410 411
}

412 413 414 415 416 417
bool GeneralTab::switchSelectionCtrlAlt()
{
    return m_chkSwitchSelectionCtrlAlt->isChecked();

}

418 419 420 421 422
bool GeneralTab::convertToImageColorspaceOnImport()
{
    return m_chkConvertOnImport->isChecked();
}

423 424 425 426
void GeneralTab::getBackgroundImage()
{
    KoFileDialog dialog(this, KoFileDialog::OpenFile, "BackgroundImages");
    dialog.setCaption(i18n("Select a Background Image"));
427
    dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::PicturesLocation));
428
    dialog.setImageFilters();
429

430
    QString fn = dialog.filename();
431 432 433 434 435
    // dialog box was canceled or somehow no file was selected
    if (fn.isEmpty()) {
        return;
    }

436 437 438 439 440 441 442 443 444
    QImage image(fn);
    if (image.isNull()) {
        QMessageBox::warning(this, i18nc("@title:window", "Krita"), i18n("%1 is not a valid image file!", fn));
    }
    else {
        m_backgroundimage->setText(fn);
    }
}

445 446 447 448 449
void GeneralTab::clearBackgroundImage()
{
    // clearing the background image text will implicitly make the background color be used
    m_backgroundimage->setText("");
}
450

451 452 453
#include "kactioncollection.h"
#include "KisActionsSnapshot.h"

454 455 456 457 458 459 460 461 462 463
ShortcutSettingsTab::ShortcutSettingsTab(QWidget *parent, const char *name)
    : QWidget(parent)
{
    setObjectName(name);

    QGridLayout * l = new QGridLayout(this);
    l->setMargin(0);
    m_page = new WdgShortcutSettings(this);
    l->addWidget(m_page, 0, 0);

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483

    m_snapshot.reset(new KisActionsSnapshot);

    KActionCollection *collection =
        KisPart::instance()->currentMainwindow()->actionCollection();

    Q_FOREACH (QAction *action, collection->actions()) {
        m_snapshot->addAction(action->objectName(), action);
    }

    QMap<QString, KActionCollection*> sortedCollections =
        m_snapshot->actionCollections();

    for (auto it = sortedCollections.constBegin(); it != sortedCollections.constEnd(); ++it) {
        m_page->addCollection(it.value(), it.key());
    }
}

ShortcutSettingsTab::~ShortcutSettingsTab()
{
484 485 486 487 488 489 490 491 492
}

void ShortcutSettingsTab::setDefault()
{
    m_page->allDefault();
}

void ShortcutSettingsTab::saveChanges()
{
493
    m_page->save();
494 495 496
    KisActionRegistry::instance()->settingsPageSaved();
}

497
void ShortcutSettingsTab::cancelChanges()
498
{
499
    m_page->undo();
500 501
}

Boudewijn Rempt's avatar
Boudewijn Rempt committed
502
ColorSettingsTab::ColorSettingsTab(QWidget *parent, const char *name)
503
    : QWidget(parent)
504
{
505 506
    setObjectName(name);

507 508
    // XXX: Make sure only profiles that fit the specified color model
    // are shown in the profile combos
509

510
    QGridLayout * l = new QGridLayout(this);
511
    l->setMargin(0);
512
    m_page = new WdgColorSettings(this);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
513
    l->addWidget(m_page, 0, 0);
514

515
    KisConfig cfg(true);
Laurent Montel's avatar
Laurent Montel committed
516

517
    m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile());
518
    connect(m_page->chkUseSystemMonitorProfile, SIGNAL(toggled(bool)), this, SLOT(toggleAllowMonitorProfileSelection(bool)));
519

520
    m_page->cmbWorkingColorSpace->setIDList(KoColorSpaceRegistry::instance()->listKeys());
521
    m_page->cmbWorkingColorSpace->setCurrent(cfg.workingColorSpace());
522

Timothée Giet's avatar
Timothée Giet committed
523
    m_page->bnAddColorProfile->setIcon(KisIconUtils::loadIcon("document-open"));
524 525 526
    m_page->bnAddColorProfile->setToolTip( i18n("Open Color Profile") );
    connect(m_page->bnAddColorProfile, SIGNAL(clicked()), SLOT(installProfile()));

527
    QFormLayout *monitorProfileGrid = new QFormLayout(m_page->monitorprofileholder);
528
    for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
529
        QLabel *lbl = new QLabel(i18nc("The number of the screen", "Screen %1:", i + 1));
530
        m_monitorProfileLabels << lbl;
531
        KisSqueezedComboBox *cmb = new KisSqueezedComboBox();
532 533
        cmb->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
        monitorProfileGrid->addRow(lbl, cmb);
534 535 536
        m_monitorProfileWidgets << cmb;
    }

537 538 539 540 541 542 543
// disable if not Linux as KisColorManager is not yet implemented outside Linux
#ifndef Q_OS_LINUX
    m_page->chkUseSystemMonitorProfile->setChecked(false);
    m_page->chkUseSystemMonitorProfile->setDisabled(true);
    m_page->chkUseSystemMonitorProfile->setHidden(true);
#endif

544
    refillMonitorProfiles(KoID("RGBA"));
545 546 547 548 549 550 551

    for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
        if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
            m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
        }
    }

552
    m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation());
553
    m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization());
554
    m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors());
555
    KisImageConfig cfgImage(true);
556

557
    KisProofingConfigurationSP proofingConfig = cfgImage.defaultProofingconfiguration();
558 559 560 561
    m_page->sldAdaptationState->setMaximum(20);
    m_page->sldAdaptationState->setMinimum(0);
    m_page->sldAdaptationState->setValue((int)proofingConfig->adaptationState*20);

562 563 564 565 566 567 568 569
    //probably this should become the screenprofile?
    KoColor ga(KoColorSpaceRegistry::instance()->rgb8());
    ga.fromKoColor(proofingConfig->warningColor);
    m_page->gamutAlarm->setColor(ga);

    const KoColorSpace *proofingSpace =  KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,
                                                                                      proofingConfig->proofingDepth,
                                                                                      proofingConfig->proofingProfile);
570 571 572
    if (proofingSpace) {
        m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
    }
573 574 575 576

    m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
    m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));

577 578 579 580 581 582 583 584 585 586 587
    m_pasteBehaviourGroup.addButton(m_page->radioPasteWeb, PASTE_ASSUME_WEB);
    m_pasteBehaviourGroup.addButton(m_page->radioPasteMonitor, PASTE_ASSUME_MONITOR);
    m_pasteBehaviourGroup.addButton(m_page->radioPasteAsk, PASTE_ASK);

    QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour());
    Q_ASSERT(button);

    if (button) {
        button->setChecked(true);
    }

588
    m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent());
589

590
    toggleAllowMonitorProfileSelection(cfg.useSystemMonitorProfile());
591

592 593
}

594 595
void ColorSettingsTab::installProfile()
{
596 597
    KoFileDialog dialog(this, KoFileDialog::OpenFiles, "OpenDocumentICC");
    dialog.setCaption(i18n("Install Color Profiles"));
598
    dialog.setDefaultDir(QStandardPaths::writableLocation(QStandardPaths::HomeLocation));
599
    dialog.setMimeTypeFilters(QStringList() << "application/vnd.iccprofile", "application/vnd.iccprofile");
600
    QStringList profileNames = dialog.filenames();
601 602 603 604

    KoColorSpaceEngine *iccEngine = KoColorSpaceEngineRegistry::instance()->get("icc");
    Q_ASSERT(iccEngine);

605
    QString saveLocation = KoResourcePaths::saveLocation("icc_profiles");
606

607
    Q_FOREACH (const QString &profileName, profileNames) {
608 609 610
        if (!QFile::copy(profileName, saveLocation + QFileInfo(profileName).fileName())) {
            qWarning() << "Could not install profile!" << saveLocation + QFileInfo(profileName).fileName();
            continue;
611
        }
612
        iccEngine->addProfile(saveLocation + QFileInfo(profileName).fileName());
613 614
    }

615
    KisConfig cfg(true);
616
    refillMonitorProfiles(KoID("RGBA"));
617

618 619 620 621 622 623
    for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
        if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
            m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
        }
    }

624 625 626 627
}

void ColorSettingsTab::toggleAllowMonitorProfileSelection(bool useSystemProfile)
{
628 629
    KisConfig cfg(true);

630
    if (useSystemProfile) {
631 632 633 634 635
        QStringList devices = KisColorManager::instance()->devices();
        if (devices.size() == QApplication::desktop()->screenCount()) {
            for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
                m_monitorProfileWidgets[i]->clear();
                QString monitorForScreen = cfg.monitorForScreen(i, devices[i]);
636
                Q_FOREACH (const QString &device, devices) {
637 638 639 640 641 642 643
                    m_monitorProfileLabels[i]->setText(i18nc("The display/screen we got from Qt", "Screen %1:", i + 1));
                    m_monitorProfileWidgets[i]->addSqueezedItem(KisColorManager::instance()->deviceName(device), device);
                    if (devices[i] == monitorForScreen) {
                        m_monitorProfileWidgets[i]->setCurrentIndex(i);
                    }
                }
            }
644 645 646
        }
    }
    else {
647
        refillMonitorProfiles(KoID("RGBA"));
648 649 650 651 652 653

        for(int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
            if (m_monitorProfileWidgets[i]->contains(cfg.monitorProfile(i))) {
                m_monitorProfileWidgets[i]->setCurrent(cfg.monitorProfile(i));
            }
        }
654 655 656
    }
}

657 658
void ColorSettingsTab::setDefault()
{
659
    m_page->cmbWorkingColorSpace->setCurrent("RGBA");
660

661
    refillMonitorProfiles(KoID("RGBA"));
662

663 664
    KisConfig cfg(true);
    KisImageConfig cfgImage(true);
665
    KisProofingConfigurationSP proofingConfig =  cfgImage.defaultProofingconfiguration();
666
    const KoColorSpace *proofingSpace =  KoColorSpaceRegistry::instance()->colorSpace(proofingConfig->proofingModel,proofingConfig->proofingDepth,proofingConfig->proofingProfile);
667 668 669
    if (proofingSpace) {
        m_page->proofingSpaceSelector->setCurrentColorSpace(proofingSpace);
    }
670 671 672 673
    m_page->cmbProofingIntent->setCurrentIndex((int)proofingConfig->intent);
    m_page->ckbProofBlackPoint->setChecked(proofingConfig->conversionFlags.testFlag(KoColorConversionTransformation::BlackpointCompensation));
    m_page->sldAdaptationState->setValue(0);

674 675 676 677
    //probably this should become the screenprofile?
    KoColor ga(KoColorSpaceRegistry::instance()->rgb8());
    ga.fromKoColor(proofingConfig->warningColor);
    m_page->gamutAlarm->setColor(ga);
678

679 680
    m_page->chkBlackpoint->setChecked(cfg.useBlackPointCompensation(true));
    m_page->chkAllowLCMSOptimization->setChecked(cfg.allowLCMSOptimization(true));
681
    m_page->chkForcePaletteColor->setChecked(cfg.forcePaletteColors(true));
682 683 684 685
    m_page->cmbMonitorIntent->setCurrentIndex(cfg.monitorRenderIntent(true));
    m_page->chkUseSystemMonitorProfile->setChecked(cfg.useSystemMonitorProfile(true));
    QAbstractButton *button = m_pasteBehaviourGroup.button(cfg.pasteBehaviour(true));
    Q_ASSERT(button);
686 687 688
    if (button) {
        button->setChecked(true);
    }
689 690
}

691

692
void ColorSettingsTab::refillMonitorProfiles(const KoID & colorSpaceId)
693
{
694 695 696
    for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
        m_monitorProfileWidgets[i]->clear();
    }
697

698
    QMap<QString, const KoColorProfile *>  profileList;
699
    Q_FOREACH(const KoColorProfile *profile, KoColorSpaceRegistry::instance()->profilesFor(colorSpaceId.id())) {
700 701
        profileList[profile->name()] = profile;
    }
702

703 704
    Q_FOREACH (const KoColorProfile *profile, profileList.values()) {
        //qDebug() << "Profile" << profile->name() << profile->isSuitableForDisplay() << csf->defaultProfile();
705 706 707 708 709
        if (profile->isSuitableForDisplay()) {
            for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
                m_monitorProfileWidgets[i]->addSqueezedItem(profile->name());
            }
        }
710
    }
711

712
    for (int i = 0; i < QApplication::desktop()->screenCount(); ++i) {
713
        m_monitorProfileLabels[i]->setText(i18nc("The number of the screen", "Screen %1:", i + 1));
714
        m_monitorProfileWidgets[i]->setCurrent(KoColorSpaceRegistry::instance()->defaultProfileForColorSpace(colorSpaceId.id()));
715
    }
716 717
}

718

719 720
//---------------------------------------------------------------------------------------------------

721 722 723 724 725
void TabletSettingsTab::setDefault()
{
    KisCubicCurve curve;
    curve.fromString(DEFAULT_CURVE_STRING);
    m_page->pressureCurve->setCurve(curve);
726

727 728 729
    m_page->chkUseRightMiddleClickWorkaround->setChecked(
        KisConfig(true).useRightMiddleTabletButtonWorkaround(true));

730 731 732 733 734 735 736 737 738
#if defined Q_OS_WIN && (!defined USE_QT_TABLET_WINDOWS || defined QT_HAS_WINTAB_SWITCH)

#ifdef USE_QT_TABLET_WINDOWS
    // ask Qt if WinInk is actually available
    const bool isWinInkAvailable = true;
#else
    const bool isWinInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
    if (isWinInkAvailable) {
739
        KisConfig cfg(true);
740 741 742 743 744 745
        m_page->radioWintab->setChecked(!cfg.useWin8PointerInput(true));
        m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput(true));
    } else {
        m_page->radioWintab->setChecked(true);
        m_page->radioWin8PointerInput->setChecked(false);
    }
746 747 748
#else
        m_page->grpTabletApi->setVisible(false);
#endif
749 750 751 752 753
}

TabletSettingsTab::TabletSettingsTab(QWidget* parent, const char* name): QWidget(parent)
{
    setObjectName(name);
754 755 756

    QGridLayout * l = new QGridLayout(this);
    l->setMargin(0);
757
    m_page = new WdgTabletSettings(this);
758
    l->addWidget(m_page, 0, 0);
759

760
    KisConfig cfg(true);
761 762
    KisCubicCurve curve;
    curve.fromString( cfg.pressureTabletCurve() );
763

764
    m_page->pressureCurve->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
765
    m_page->pressureCurve->setCurve(curve);
766

767 768 769
    m_page->chkUseRightMiddleClickWorkaround->setChecked(
         cfg.useRightMiddleTabletButtonWorkaround());

770 771 772 773 774 775 776 777
#if defined Q_OS_WIN && (!defined USE_QT_TABLET_WINDOWS || defined QT_HAS_WINTAB_SWITCH)
#ifdef USE_QT_TABLET_WINDOWS
    // ask Qt if WinInk is actually available
    const bool isWinInkAvailable = true;
#else
    const bool isWinInkAvailable = KisTabletSupportWin8::isAvailable();
#endif
    if (isWinInkAvailable) {
778 779 780 781 782 783 784
        m_page->radioWintab->setChecked(!cfg.useWin8PointerInput());
        m_page->radioWin8PointerInput->setChecked(cfg.useWin8PointerInput());
    } else {
        m_page->radioWintab->setChecked(true);
        m_page->radioWin8PointerInput->setChecked(false);
        m_page->grpTabletApi->setVisible(false);
    }
785 786 787 788 789 790 791 792 793

#ifdef USE_QT_TABLET_WINDOWS
    connect(m_page->btnResolutionSettings, SIGNAL(clicked()), SLOT(slotResolutionSettings()));
    connect(m_page->radioWintab, SIGNAL(toggled(bool)), m_page->btnResolutionSettings, SLOT(setEnabled(bool)));
    m_page->btnResolutionSettings->setEnabled(m_page->radioWintab->isChecked());
#else
    m_page->btnResolutionSettings->setVisible(false);
#endif

794 795 796
#else
    m_page->grpTabletApi->setVisible(false);
#endif
797 798 799 800 801 802 803
    connect(m_page->btnTabletTest, SIGNAL(clicked()), SLOT(slotTabletTest()));
}

void TabletSettingsTab::slotTabletTest()
{
    TabletTestDialog tabletTestDialog(this);
    tabletTestDialog.exec();
804 805
}

806 807 808 809 810 811 812 813 814 815 816 817
#if defined Q_OS_WIN && defined USE_QT_TABLET_WINDOWS
#include "KisDlgCustomTabletResolution.h"
#endif

void TabletSettingsTab::slotResolutionSettings()
{
#if defined Q_OS_WIN && defined USE_QT_TABLET_WINDOWS
    KisDlgCustomTabletResolution dlg(this);
    dlg.exec();
#endif
}

818 819

//---------------------------------------------------------------------------------------------------
820 821
#include "kis_acyclic_signal_connector.h"

822 823 824
int getTotalRAM()
{
    return KisImageConfig(true).totalRAM();
825 826 827 828 829 830 831
}

int PerformanceTab::realTilesRAM()
{
    return intMemoryLimit->value() - intPoolLimit->value();
}

Boudewijn Rempt's avatar
Boudewijn Rempt committed
832
PerformanceTab::PerformanceTab(QWidget *parent, const char *name)
833
    : WdgPerformanceSettings(parent, name)
834
{
835
    KisImageConfig cfg(true);
836 837
    const double totalRAM = cfg.totalRAM();
    lblTotalMemory->setText(KFormat().formatByteSize(totalRAM * 1024 * 1024, 0, KFormat::IECBinaryDialect, KFormat::UnitMegaByte));
838

839
    sliderMemoryLimit->setSuffix(i18n(" %"));
840 841 842
    sliderMemoryLimit->setRange(1, 100, 2);
    sliderMemoryLimit->setSingleStep(0.01);

843
    sliderPoolLimit->setSuffix(i18n(" %"));
844 845 846
    sliderPoolLimit->setRange(0, 20, 2);
    sliderMemoryLimit->setSingleStep(0.01);

847
    sliderUndoLimit->setSuffix(i18n(" %"));
848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866
    sliderUndoLimit->setRange(0, 50, 2);
    sliderMemoryLimit->setSingleStep(0.01);

    intMemoryLimit->setMinimumWidth(80);
    intPoolLimit->setMinimumWidth(80);
    intUndoLimit->setMinimumWidth(80);


    SliderAndSpinBoxSync *sync1 =
        new SliderAndSpinBoxSync(sliderMemoryLimit,
                                 intMemoryLimit,
                                 getTotalRAM);

    sync1->slotParentValueChanged();
    m_syncs << sync1;

    SliderAndSpinBoxSync *sync2 =
        new SliderAndSpinBoxSync(sliderPoolLimit,
                                 intPoolLimit,
867
                                 std::bind(&KisIntParseSpinBox::value,
868 869 870 871 872 873 874 875 876 877
                                             intMemoryLimit));


    connect(intMemoryLimit, SIGNAL(valueChanged(int)), sync2, SLOT(slotParentValueChanged()));
    sync2->slotParentValueChanged();
    m_syncs << sync2;

    SliderAndSpinBoxSync *sync3 =
        new SliderAndSpinBoxSync(sliderUndoLimit,
                                 intUndoLimit,
878
                                 std::bind(&PerformanceTab::realTilesRAM,
879
                                             this));
880 881


882 883 884 885 886 887 888 889
    connect(intPoolLimit, SIGNAL(valueChanged(int)), sync3, SLOT(slotParentValueChanged()));
    sync3->slotParentValueChanged();
    m_syncs << sync3;

    sliderSwapSize->setSuffix(i18n(" GiB"));
    sliderSwapSize->setRange(1, 64);
    intSwapSize->setRange(1, 64);

890 891

    KisAcyclicSignalConnector *swapSizeConnector = new KisAcyclicSignalConnector(this);
892 893 894 895 896 897

    swapSizeConnector->connectForwardInt(sliderSwapSize, SIGNAL(valueChanged(int)),
                                         intSwapSize, SLOT(setValue(int)));

    swapSizeConnector->connectBackwardInt(intSwapSize, SIGNAL(valueChanged(int)),
                                          sliderSwapSize, SLOT(setValue(int)));
898

899 900
    lblSwapFileLocation->setText(cfg.swapDir());
    connect(bnSwapFile, SIGNAL(clicked()), SLOT(selectSwapDir()));
901

902 903
    sliderThreadsLimit->setRange(1, QThread::idealThreadCount());
    sliderFrameClonesLimit->setRange(1, QThread::idealThreadCount());
904
    sliderFpsLimit->setRange(20, 100);
905
    sliderFpsLimit->setSuffix(i18n(" fps"));
906 907 908 909

    connect(sliderThreadsLimit, SIGNAL(valueChanged(int)), SLOT(slotThreadsLimitChanged(int)));
    connect(sliderFrameClonesLimit, SIGNAL(valueChanged(int)), SLOT(slotFrameClonesLimitChanged(int)));

910 911 912 913 914 915 916 917 918 919 920 921 922
    intCachedFramesSizeLimit->setRange(1, 10000);
    intCachedFramesSizeLimit->setSuffix(i18n(" px"));
    intCachedFramesSizeLimit->setSingleStep(1);
    intCachedFramesSizeLimit->setPageStep(1000);

    intRegionOfInterestMargin->setRange(1, 100);
    intRegionOfInterestMargin->setSuffix(i18n(" %"));
    intRegionOfInterestMargin->setSingleStep(1);
    intRegionOfInterestMargin->setPageStep(10);

    connect(chkCachedFramesSizeLimit, SIGNAL(toggled(bool)), intCachedFramesSizeLimit, SLOT(setEnabled(bool)));
    connect(chkUseRegionOfInterest, SIGNAL(toggled(bool)), intRegionOfInterestMargin, SLOT(setEnabled(bool)));

923 924 925 926 927
#ifndef Q_OS_WIN
    // AVX workaround is needed on Windows+GCC only
    chkDisableAVXOptimizations->setVisible(false);
#endif

928
    load(false);
929 930
}

931
PerformanceTab::~PerformanceTab()
932
{
933 934 935 936 937
    qDeleteAll(m_syncs);
}

void PerformanceTab::load(bool requestDefault)
{
938
    KisImageConfig cfg(true);
939 940 941 942 943 944

    sliderMemoryLimit->setValue(cfg.memoryHardLimitPercent(requestDefault));
    sliderPoolLimit->setValue(cfg.memoryPoolLimitPercent(requestDefault));
    sliderUndoLimit->setValue(cfg.memorySoftLimitPercent(requestDefault));

    chkPerformanceLogging->setChecked(cfg.enablePerfLog(requestDefault));
945
    chkProgressReporting->setChecked(cfg.enableProgressReporting(requestDefault));
946 947

    sliderSwapSize->setValue(cfg.maxSwapSize(requestDefault) / 1024);
948
    lblSwapFileLocation->setText(cfg.swapDir(requestDefault));
949

950 951 952 953 954
    m_lastUsedThreadsLimit = cfg.maxNumberOfThreads(requestDefault);
    m_lastUsedClonesLimit = cfg.frameRenderingClones(requestDefault);

    sliderThreadsLimit->setValue(m_lastUsedThreadsLimit);
    sliderFrameClonesLimit->setValue(m_lastUsedClonesLimit);
955 956

    sliderFpsLimit->setValue(cfg.fpsLimit(requestDefault));
957

958
    {
959
        KisConfig cfg2(true);
960
        chkOpenGLFramerateLogging->setChecked(cfg2.enableOpenGLFramerateLogging(requestDefault));
961
        chkBrushSpeedLogging->setChecked(cfg2.enableBrushSpeedLogging(requestDefault));
962
        chkDisableVectorOptimizations->setChecked(cfg2.enableAmdVectorizationWorkaround(requestDefault));
963 964 965
#ifdef Q_OS_WIN
        chkDisableAVXOptimizations->setChecked(cfg2.disableAVXOptimizations(requestDefault));
#endif
966 967 968 969 970 971 972
        chkBackgroundCacheGeneration->setChecked(cfg2.calculateAnimationCacheInBackground(requestDefault));
    }

    if (cfg.useOnDiskAnimationCacheSwapping(requestDefault)) {
        optOnDisk->setChecked(true);
    } else {
        optInMemory->setChecked(true);
973
    }
974 975 976 977 978 979 980 981

    chkCachedFramesSizeLimit->setChecked(cfg.useAnimationCacheFrameSizeLimit(requestDefault));
    intCachedFramesSizeLimit->setValue(cfg.animationCacheFrameSizeLimit(requestDefault));
    intCachedFramesSizeLimit->setEnabled(chkCachedFramesSizeLimit->isChecked());

    chkUseRegionOfInterest->setChecked(cfg.useAnimationCacheRegionOfInterest(requestDefault));
    intRegionOfInterestMargin->setValue(cfg.animationCacheRegionOfInterestMargin(requestDefault) * 100.0);
    intRegionOfInterestMargin->setEnabled(chkUseRegionOfInterest->isChecked());
982 983 984 985
}

void PerformanceTab::save()
{
986
    KisImageConfig cfg(false);
987 988 989 990 991 992

    cfg.setMemoryHardLimitPercent(sliderMemoryLimit->value());
    cfg.setMemorySoftLimitPercent(sliderUndoLimit->value());
    cfg.setMemoryPoolLimitPercent(sliderPoolLimit->value());

    cfg.setEnablePerfLog(chkPerformanceLogging->isChecked());
993
    cfg.setEnableProgressReporting(chkProgressReporting->isChecked());
994 995

    cfg.setMaxSwapSize(sliderSwapSize->value() * 1024);
996 997

    cfg.setSwapDir(lblSwapFileLocation->text());
998

999 1000
    cfg.setMaxNumberOfThreads(sliderThreadsLimit->value());
    cfg.setFrameRenderingClones(sliderFrameClonesLimit->value());
1001
    cfg.setFpsLimit(sliderFpsLimit->value());
1002

1003
    {
1004
        KisConfig cfg2(true);
1005
        cfg2.setEnableOpenGLFramerateLogging(chkOpenGLFramerateLogging->isChecked());
1006
        cfg2.setEnableBrushSpeedLogging(chkBrushSpeedLogging->isChecked());
1007
        cfg2.setEnableAmdVectorizationWorkaround(chkDisableVectorOptimizations->isChecked());
1008 1009 1010
#ifdef Q_OS_WIN
        cfg2.setDisableAVXOptimizations(chkDisableAVXOptimizations->isChecked());
#endif
1011
        cfg2.setCalculateAnimationCacheInBackground(chkBackgroundCacheGeneration->isChecked());
1012
    }
1013 1014 1015 1016 1017 1018 1019 1020 1021

    cfg.setUseOnDiskAnimationCacheSwapping(optOnDisk->isChecked());

    cfg.setUseAnimationCacheFrameSizeLimit(chkCachedFramesSizeLimit->isChecked());
    cfg.setAnimationCacheFrameSizeLimit(intCachedFramesSizeLimit->value());

    cfg.setUseAnimationCacheRegionOfInterest(chkUseRegionOfInterest->isChecked());
    cfg.setAnimationCacheRegionOfInterestMargin(intRegionOfInterestMargin->value() / 100.0);

1022 1023 1024 1025
}

void PerformanceTab::selectSwapDir()
{
1026
    KisImageConfig cfg(true);
1027 1028
    QString swapDir = cfg.swapDir();
    swapDir = QFileDialog::getExistingDirectory(0, i18nc("@title:window", "Select a swap directory"), swapDir);
1029 1030 1031
    if (swapDir.isEmpty()) {
        return;
    }
1032
    lblSwapFileLocation->setText(swapDir);
1033 1034
}

1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
void PerformanceTab::slotThreadsLimitChanged(int value)
{
    KisSignalsBlocker b(sliderFrameClonesLimit);
    sliderFrameClonesLimit->setValue(qMin(m_lastUsedClonesLimit, value));
    m_lastUsedThreadsLimit = value;
}

void PerformanceTab::slotFrameClonesLimitChanged(int value)
{
    KisSignalsBlocker b(sliderThreadsLimit);
    sliderThreadsLimit->setValue(qMax(m_lastUsedThreadsLimit, value));
    m_lastUsedClonesLimit = value;
}

1049
//---------------------------------------------------------------------------------------------------
1050

1051
#include "KoColor.h"
1052 1053 1054 1055 1056
#include "opengl/KisOpenGLModeProber.h"
#include "opengl/KisScreenInformationAdapter.h"
#include <QOpenGLContext>
#include <QScreen>

1057
QString colorSpaceString(KisSurfaceColorSpace cs, int depth)
1058 1059
{
    const QString csString =
1060
#ifdef HAVE_HDR
1061 1062
        cs == KisSurfaceColorSpace::bt2020PQColorSpace ? "Rec. 2020 PQ" :
        cs == KisSurfaceColorSpace::scRGBColorSpace ? "Rec. 709 Linear" :
1063
#endif
1064 1065
        cs == KisSurfaceColorSpace::sRGBColorSpace ? "sRGB" :
        cs == KisSurfaceColorSpace::DefaultColorSpace ? "sRGB" :
1066 1067 1068 1069 1070 1071 1072
        "Unknown Color Space";

    return QString("%1 (%2 bit)").arg(csString).arg(depth);
}

int formatToIndex(KisConfig::RootSurfaceFormat fmt)
{
1073 1074
    return fmt == KisConfig::BT2020_PQ ? 1 :
           fmt == KisConfig::BT709_G10 ? 2 :
1075 1076 1077 1078 1079
           0;
}

KisConfig::RootSurfaceFormat indexToFormat(int value)
{
1080 1081
    return value == 1 ? KisConfig::BT2020_PQ :
           value == 2 ? KisConfig::BT709_G10 :
1082 1083
           KisConfig::BT709_G22;
}
1084

Boudewijn Rempt's avatar
Boudewijn Rempt committed
1085
DisplaySettingsTab::DisplaySettingsTab(QWidget *parent, const char *name)
1086
    : WdgDisplaySettings(parent, name)
1087
{
1088
    KisConfig cfg(true);
1089

1090
    const QString rendererOpenGLText = i18nc("canvas renderer", "OpenGL");
1091
    const QString rendererSoftwareText = i18nc("canvas renderer", "Software Renderer (very slow)");
1092
#ifdef Q_OS_WIN
1093 1094 1095 1096
    const QString rendererOpenGLESText = i18nc("canvas renderer", "Direct3D 11 via ANGLE");
#else
    const QString rendererOpenGLESText = i18nc("canvas renderer", "OpenGL ES");
#endif
1097 1098 1099 1100 1101 1102

    const KisOpenGL::OpenGLRenderer renderer = KisOpenGL::getCurrentOpenGLRenderer();
    lblCurrentRenderer->setText(renderer == KisOpenGL::RendererOpenGLES ? rendererOpenGLESText :
                                renderer == KisOpenGL::RendererDesktopGL ? rendererOpenGLText :
                                renderer == KisOpenGL::RendererSoftware ? rendererSoftwareText :
                                i18nc("canvas renderer", "Unknown"));
1103 1104

    cmbPreferredRenderer->clear();
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123

    const KisOpenGL::OpenGLRenderers supportedRenderers = KisOpenGL::getSupportedOpenGLRenderers();
    const bool onlyOneRendererSupported =
        supportedRenderers == KisOpenGL::RendererDesktopGL ||
        supportedRenderers == KisOpenGL::RendererOpenGLES ||
        supportedRenderers == KisOpenGL::RendererSoftware;


    if (!onlyOneRendererSupported) {
        QString qtPreferredRendererText;
        if (KisOpenGL::getQtPreferredOpenGLRenderer() == KisOpenGL::RendererOpenGLES) {
            qtPreferredRendererText = rendererOpenGLESText;
        } else if (KisOpenGL::getQtPreferredOpenGLRenderer() == KisOpenGL::RendererSoftware) {
            qtPreferredRendererText = rendererSoftwareText;
        } else {
            qtPreferredRendererText = rendererOpenGLText;
        }
        cmbPreferredRenderer->addItem(i18nc("canvas renderer", "Auto (%1)", qtPreferredRendererText), KisOpenGL::RendererAuto);
        cmbPreferredRenderer->setCurrentIndex(0);
1124
    } else {
1125
        cmbPreferredRenderer->setEnabled(false);
1126
    }
1127

1128
    if (supportedRenderers & KisOpenGL::RendererDesktopGL) {
1129 1130 1131
        cmbPreferredRenderer->addItem(rendererOpenGLText, KisOpenGL::RendererDesktopGL);
        if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererDesktopGL) {
            cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
1132 1133
        }
    }
1134 1135

#ifdef Q_OS_WIN
1136
    if (supportedRenderers & KisOpenGL::RendererOpenGLES) {
1137
        cmbPreferredRenderer->addItem(rendererOpenGLESText, KisOpenGL::RendererOpenGLES);
1138 1139
        if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererOpenGLES) {
            cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
1140 1141
        }
    }
1142
    if (supportedRenderers & KisOpenGL::RendererSoftware) {
1143 1144 1145 1146 1147
        cmbPreferredRenderer->addItem(rendererSoftwareText, KisOpenGL::RendererSoftware);
        if (KisOpenGL::getUserPreferredOpenGLRendererConfig() == KisOpenGL::RendererSoftware) {
            cmbPreferredRenderer->setCurrentIndex(cmbPreferredRenderer->count() - 1);
        }
    }
1148 1149
#endif

1150
    if (!(supportedRenderers &
1151 1152 1153 1154
          (KisOpenGL::RendererDesktopGL |
           KisOpenGL::RendererOpenGLES |
           KisOpenGL::RendererSoftware))) {

1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169
        grpOpenGL->setEnabled(false);
        grpOpenGL->setChecked(false);
        chkUseTextureBuffer->setEnabled(false);
        chkDisableVsync->setEnabled(false);
        cmbFilterMode->setEnabled(false);
    } else {
        grpOpenGL->setEnabled(true);
        grpOpenGL->setChecked(cfg.useOpenGL());
        chkUseTextureBuffer->setEnabled(cfg.useOpenGL());
        chkUseTextureBuffer->setChecked(cfg.useOpenGLTextureBuffer());
        chkDisableVsync->setVisible(cfg.showAdvancedOpenGLSettings());
        chkDisableVsync->setEnabled(cfg.useOpenGL());
        chkDisableVsync->setChecked(cfg.disableVSync());
        cmbFilterMode->setEnabled(cfg.useOpenGL());
        cmbFilterMode->setCurrentIndex(cfg.openGLFilteringMode());
1170
        // Don't show the high quality filtering mode if it's not available
1171
        if (!KisOpenGL::supportsLoD()) {
1172 1173
            cmbFilterMode->removeItem(3);
        }
1174
    }
1175

1176 1177 1178
    lblCurrentDisplayFormat->setText("");
    lblCurrentRootSurfaceFormat->setText("");
    lblHDRWarning->setText("");
1179
    cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::sRGBColorSpace, 8));
1180
#ifdef HAVE_HDR
1181 1182
    cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::bt2020PQColorSpace, 10));
    cmbPreferedRootSurfaceFormat->addItem(colorSpaceString(KisSurfaceColorSpace::scRGBColorSpace, 16));
1183
#endif
1184 1185 1186 1187
    cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(KisConfig::BT709_G22));
    slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());

    QOpenGLContext *context = QOpenGLContext::currentContext();
1188 1189 1190 1191 1192

    if (!context) {
        context = QOpenGLContext::globalShareContext();
    }

1193
    if (context) {
1194
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
1195
        QScreen *screen = QGuiApplication::screenAt(rect().center());
1196 1197 1198
#else
        QScreen *screen = 0;
#endif
1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221
        KisScreenInformationAdapter adapter(context);
        if (screen && adapter.isValid()) {
            KisScreenInformationAdapter::ScreenInfo info = adapter.infoForScreen(screen);
            if (info.isValid()) {
                QStringList toolTip;

                toolTip << i18n("Display Id: %1", info.screen->name());
                toolTip << i18n("Display Name: %1 %2", info.screen->manufacturer(), info.screen->model());
                toolTip << i18n("Min Luminance: %1", info.minLuminance);
                toolTip << i18n("Max Luminance: %1", info.maxLuminance);
                toolTip << i18n("Max Full Frame Luminance: %1", info.maxFullFrameLuminance);
                toolTip << i18n("Red Primary: %1, %2", info.redPrimary[0], info.redPrimary[1]);
                toolTip << i18n("Green Primary: %1, %2", info.greenPrimary[0], info.greenPrimary[1]);
                toolTip << i18n("Blue Primary: %1, %2", info.bluePrimary[0], info.bluePrimary[1]);
                toolTip << i18n("White Point: %1, %2", info.whitePoint[0], info.whitePoint[1]);

                lblCurrentDisplayFormat->setToolTip(toolTip.join('\n'));
                lblCurrentDisplayFormat->setText(colorSpaceString(info.colorSpace, info.bitsPerColor));
            } else {
                lblCurrentDisplayFormat->setToolTip("");
                lblCurrentDisplayFormat->setText(i18n("Unknown"));
            }
        } else {
1222 1223
            lblCurrentDisplayFormat->setToolTip("");
            lblCurrentDisplayFormat->setText(i18n("Unknown"));
1224
            qWarning() << "Failed to fetch display info:" << adapter.errorString();
1225
        }
1226 1227

        const QSurfaceFormat currentFormat = KisOpenGLModeProber::instance()->surfaceformatInUse();
1228 1229 1230 1231 1232 1233
#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
        KisSurfaceColorSpace colorSpace = currentFormat.colorSpace();
#else
        KisSurfaceColorSpace colorSpace = KisSurfaceColorSpace::DefaultColorSpace;
#endif
        lblCurrentRootSurfaceFormat->setText(colorSpaceString(colorSpace, currentFormat.redBufferSize()));
1234 1235 1236
        cmbPreferedRootSurfaceFormat->setCurrentIndex(formatToIndex(cfg.rootSurfaceFormat()));
        connect(cmbPreferedRootSurfaceFormat, SIGNAL(currentIndexChanged(int)), SLOT(slotPreferredSurfaceFormatChanged(int)));
        slotPreferredSurfaceFormatChanged(cmbPreferedRootSurfaceFormat->currentIndex());
1237 1238
    }

1239 1240 1241 1242
#ifndef HAVE_HDR
    grpHDRSettings->setVisible(false);
#endif

1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259
    const QStringList openglWarnings = KisOpenGL::getOpenGLWarnings();
    if (openglWarnings.isEmpty()) {
        lblOpenGLWarnings->setVisible(false);
    } else {
        QString text("<span style=\"color: yellow;\">&#x26A0;</span> ");
        text.append(i18n("Warning(s):"));
        text.append("<ul>");
        Q_FOREACH (const QString &warning, openglWarnings) {
            text.append("<li>");
            text.append(warning.toHtmlEscaped());
            text.append("</li>");
        }
        text.append("</ul>");
        lblOpenGLWarnings->setText(text);
        lblOpenGLWarnings->setVisible(true);
    }

1260
    if (qApp->applicationName() == "kritasketch" || qApp->applicationName() == "kritagemini") {