1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2006-05-15
7 * Description : a dialog to see preview ICC color correction
8 * before to apply color profile.
9 *
10 * Copyright (C) 2006-2021 by Gilles Caulier <caulier dot gilles at gmail dot com>
11 *
12 * This program is free software; you can redistribute it
13 * and/or modify it under the terms of the GNU General
14 * Public License as published by the Free Software Foundation;
15 * either version 2, or (at your option)
16 * any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * ============================================================ */
24
25 #include "colorcorrectiondlg.h"
26
27 // Qt includes
28
29 #include <QCheckBox>
30 #include <QFrame>
31 #include <QFileInfo>
32 #include <QGridLayout>
33 #include <QGroupBox>
34 #include <QHBoxLayout>
35 #include <QLabel>
36 #include <QRadioButton>
37 #include <QStandardPaths>
38 #include <QIcon>
39 #include <QDialogButtonBox>
40 #include <QVBoxLayout>
41 #include <QPushButton>
42
43 // KDE includes
44
45 #include <klocalizedstring.h>
46
47 // Local includes
48
49 #include "dlayoutbox.h"
50 #include "dimg.h"
51 #include "iccmanager.h"
52 #include "iccsettings.h"
53 #include "icctransform.h"
54 #include "iccprofileinfodlg.h"
55 #include "iccprofilescombobox.h"
56 #include "dxmlguiwindow.h"
57 #include "dexpanderbox.h"
58
59 namespace Digikam
60 {
61
62 class Q_DECL_HIDDEN ColorCorrectionDlg::Private
63 {
64 public:
65
Private()66 explicit Private()
67 : imageProfileTitle (nullptr),
68 imageProfileDesc (nullptr),
69 previewTarget (nullptr),
70 keepProfile (nullptr),
71 convertToWorkingSpace(nullptr),
72 thirdOption (nullptr),
73 thirdCheckBox (nullptr),
74 imageSRGB (nullptr),
75 imageWorkingSpace (nullptr),
76 imageOtherSpace (nullptr),
77 buttons (nullptr),
78 otherProfileBox (nullptr),
79 imageProfileBox (nullptr),
80 mode (ColorCorrectionDlg::ProfileMismatch)
81 {
82 }
83
84 DImg preview;
85 QString filePath;
86
87 QLabel* imageProfileTitle;
88 QLabel* imageProfileDesc;
89 QLabel* previewTarget;
90
91 QRadioButton* keepProfile;
92 QRadioButton* convertToWorkingSpace;
93 QRadioButton* thirdOption;
94 QCheckBox* thirdCheckBox;
95
96 QRadioButton* imageSRGB;
97 QRadioButton* imageWorkingSpace;
98 QRadioButton* imageOtherSpace;
99
100 QDialogButtonBox* buttons;
101
102 IccProfilesComboBox* otherProfileBox;
103 IccProfilesComboBox* imageProfileBox;
104
105 ColorCorrectionDlg::Mode mode;
106
107 IccProfile workspaceProfile;
108 IccProfile imageProfile;
109 IccProfile outputProfile;
110 };
111
ColorCorrectionDlg(Mode mode,const DImg & preview,const QString & file,QWidget * const parent)112 ColorCorrectionDlg::ColorCorrectionDlg(Mode mode,
113 const DImg& preview,
114 const QString& file,
115 QWidget* const parent)
116 : QDialog(parent),
117 d (new Private)
118 {
119 setModal(true);
120
121 d->buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
122 d->buttons->button(QDialogButtonBox::Ok)->setDefault(true);
123 d->buttons->button(QDialogButtonBox::Cancel)->setText(i18n("Do not know"));
124 d->buttons->button(QDialogButtonBox::Cancel)->setToolTip(i18n("Take the safest and most appropriate action"));
125
126 d->mode = mode;
127 d->preview = preview;
128 d->filePath = file;
129 ICCSettingsContainer iccSettings = IccSettings::instance()->settings();
130 d->workspaceProfile = IccProfile(iccSettings.workspaceProfile);
131
132 QString caption;
133
134 if (d->mode == ProfileMismatch)
135 {
136 caption = i18n("Color Profile Mismatch");
137 }
138 else if (d->mode == MissingProfile)
139 {
140 caption = i18n("Missing Color Profile");
141 }
142 else if (d->mode == UncalibratedColor)
143 {
144 caption = i18n("Image with Uncalibrated Color");
145 }
146
147 if (!file.isNull())
148 {
149 QFileInfo fi(file);
150 caption = i18nc("<Problem> - <b>", "%1 - %2", caption, fi.fileName());
151 }
152
153 setWindowTitle(caption);
154
155 QWidget* const page = new QWidget(this);
156 QGridLayout* const grid = new QGridLayout(page);
157
158 if (d->mode == ProfileMismatch)
159 {
160 grid->addLayout(createHeading(), 0, 0, 1, 2);
161 grid->addLayout(createProfilesInfo(), 1, 0);
162 grid->addLayout(createPreviews(), 1, 1, 2, 1);
163 grid->addWidget(createOptions(), 3, 0, 1, 2);
164 }
165 else if (d->mode == MissingProfile)
166 {
167 QVBoxLayout* vbox = new QVBoxLayout;
168 vbox->addWidget(createAssumeOptions());
169 vbox->addLayout(createProfilesInfo());
170 vbox->addStretch(1);
171
172 grid->addLayout(createHeading(), 0, 0, 1, 2);
173 grid->addLayout(vbox, 1, 0);
174 grid->addLayout(createPreviews(), 1, 1, 2, 1);
175 grid->addWidget(createOptions(), 3, 0, 1, 2);
176 grid->setRowStretch(1, 1);
177 grid->setRowStretch(3, 1);
178 }
179 else if (d->mode == UncalibratedColor)
180 {
181 grid->addLayout(createHeading(), 0, 0, 1, 2);
182 grid->addLayout(createProfilesInfo(), 1, 0, Qt::AlignTop);
183 grid->addLayout(createPreviews(), 1, 1, 2, 1);
184 grid->addWidget(createAssumeOptions(), 3, 0, 1, 2);
185 }
186
187 page->setLayout(grid);
188
189 QVBoxLayout* const vbx = new QVBoxLayout(this);
190 vbx->addWidget(page);
191 vbx->addWidget(d->buttons);
192 setLayout(vbx);
193
194 connect(d->buttons->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
195 this, SLOT(slotOk()));
196
197 connect(d->buttons->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
198 this, SLOT(reject()));
199
200 connect(d->buttons->button(QDialogButtonBox::Help), SIGNAL(clicked()),
201 this, SLOT(slotHelp()));
202
203 readSettings();
204 updateImageProfileUI();
205 updateUsedProfileUI();
206 updateInfo();
207 }
208
~ColorCorrectionDlg()209 ColorCorrectionDlg::~ColorCorrectionDlg()
210 {
211 delete d;
212 }
213
slotOk()214 void ColorCorrectionDlg::slotOk()
215 {
216 accept();
217 setSettings();
218 }
219
createHeading() const220 QLayout* ColorCorrectionDlg::createHeading() const
221 {
222 QLabel* const icon = new QLabel;
223 icon->setPixmap(QIcon::fromTheme(QLatin1String("fill-color")).pixmap(32));
224
225 QLabel* const message = new QLabel;
226
227 if (d->mode == ProfileMismatch)
228 {
229 message->setText(i18n("<p>This image has an <b>embedded color profile</b><br/> "
230 "which does not match your working space color profile.<br/>"
231 "How do you want to proceed?</p>"));
232 }
233 else if (d->mode == MissingProfile)
234 {
235 message->setText(i18n("<p>This image has <b>no information about the color space</b><br/>"
236 "that was used when creating the image. <br/>"
237 "How do you want to proceed?</p>"));
238
239 }
240 else if (d->mode == UncalibratedColor)
241 {
242 message->setText(i18n("<p>The color information of this image is uncalibrated.<br/>"
243 "How do you want to proceed?</p>"));
244 }
245
246 message->setWordWrap(true);
247
248 QLabel* const logo = new QLabel;
249 logo->setPixmap(QIcon::fromTheme(QLatin1String("digikam")).pixmap(QSize(48,48)));
250
251 DLineWidget* const line = new DLineWidget(Qt::Horizontal);
252
253 QGridLayout* const grid = new QGridLayout;
254 grid->addWidget(icon, 0, 0);
255 grid->addWidget(message, 0, 1);
256 grid->addWidget(logo, 0, 2);
257 grid->addWidget(line, 1, 0, 1, 3);
258 grid->setColumnStretch(1, 1);
259
260 return grid;
261 }
262
createProfilesInfo() const263 QLayout* ColorCorrectionDlg::createProfilesInfo() const
264 {
265 QVBoxLayout* const vbox = new QVBoxLayout;
266
267 if ((d->mode == ProfileMismatch) || (d->mode == UncalibratedColor))
268 {
269 d->imageProfileTitle = new QLabel;
270
271 if (d->mode == ProfileMismatch)
272 {
273 d->imageProfileTitle->setText(i18n("Embedded Color Profile:"));
274 }
275 /*
276 else if (d->mode == MissingProfile)
277 {
278 d->imageProfileTitle->setText(i18n("Image Color Profile:"));
279 }
280 */
281 else if (d->mode == UncalibratedColor)
282 {
283 d->imageProfileTitle->setText(i18n("Input Color Profile:"));
284 }
285
286 d->imageProfileDesc = new QLabel;
287 QPushButton* const imageProfInfo = new QPushButton(i18n("Info..."));
288 /*
289 d->imageProfileTitle->setWordWrap(true);
290 */
291 d->imageProfileDesc->setWordWrap(true);
292
293 vbox->addWidget(d->imageProfileTitle);
294 vbox->addWidget(d->imageProfileDesc);
295 vbox->addWidget(imageProfInfo, 0, Qt::AlignLeft);
296
297 connect(imageProfInfo, SIGNAL(clicked()),
298 this, SLOT(slotImageProfInfo()));
299 }
300
301 QLabel* const workspaceProfileTitle = new QLabel(i18n("Working Color Space:"));
302 QLabel* const workspaceProfileDesc = new QLabel(QString::fromUtf8("<b>%1</b>").arg(d->workspaceProfile.description()));
303 QPushButton* const workspaceProfInfo = new QPushButton(i18n("Info..."));
304 /*
305 workspaceProfileTitle->setWordWrap(true);
306 */
307 workspaceProfileDesc->setWordWrap(true);
308
309 vbox->addWidget(workspaceProfileTitle);
310 vbox->addWidget(workspaceProfileDesc);
311 vbox->addWidget(workspaceProfInfo, 0, Qt::AlignLeft);
312
313 connect(workspaceProfInfo, SIGNAL(clicked()),
314 this, SLOT(slotWorkspaceProfInfo()));
315
316 return vbox;
317 }
318
createPreviews() const319 QLayout* ColorCorrectionDlg::createPreviews() const
320 {
321 QGridLayout* const grid = new QGridLayout;
322 QLabel* const originalTitle = new QLabel;
323
324 if (d->mode == ProfileMismatch)
325 {
326 originalTitle->setText(i18n("Original Colors:"));
327 }
328 else if (d->mode == MissingProfile)
329 {
330 originalTitle->setText(i18n("Uncorrected Colors:"));
331 }
332 else if (d->mode == UncalibratedColor)
333 {
334 originalTitle->setText(i18n("Raw Colors:"));
335 }
336
337 originalTitle->setWordWrap(true);
338
339 QLabel* const previewOriginal = new QLabel;
340 DImg copyOriginal = d->preview.copy();
341 IccManager manager(copyOriginal);
342 manager.transformForDisplay();
343 previewOriginal->setPixmap(copyOriginal.convertToPixmap());
344
345 QLabel* const targetTitle = new QLabel;
346
347 if (d->mode == ProfileMismatch)
348 {
349 targetTitle->setText(i18n("Resulting Colors:"));
350 }
351 else if (d->mode == MissingProfile)
352 {
353 targetTitle->setText(i18n("Correction Applied:"));
354 }
355 else if (d->mode == UncalibratedColor)
356 {
357 targetTitle->setText(i18n("Corrected Colors:"));
358 }
359
360 targetTitle->setWordWrap(true);
361
362 d->previewTarget = new QLabel;
363
364 if (d->preview.width() > d->preview.height())
365 {
366 grid->addWidget(originalTitle, 0, 0, Qt::AlignTop);
367 grid->addWidget(previewOriginal, 1, 0);
368 grid->addWidget(targetTitle, 2, 0, Qt::AlignTop);
369 grid->addWidget(d->previewTarget, 3, 0);
370 }
371 else
372 {
373 grid->addWidget(originalTitle, 0, 0, Qt::AlignTop);
374 grid->addWidget(previewOriginal, 1, 0);
375 grid->addWidget(targetTitle, 0, 1, Qt::AlignTop);
376 grid->addWidget(d->previewTarget, 1, 1);
377 }
378
379 return grid;
380 }
381
createOptions() const382 QWidget* ColorCorrectionDlg::createOptions() const
383 {
384 QGroupBox* const box = new QGroupBox;
385
386 if (d->mode == ProfileMismatch)
387 {
388 QVBoxLayout* const vbox = new QVBoxLayout(box);
389 d->keepProfile = new QRadioButton(i18n("Keep the embedded profile, do not convert"));
390 d->convertToWorkingSpace = new QRadioButton(i18n("Convert to working color space"));
391 d->thirdOption = new QRadioButton(i18n("Ignore embedded profile, assign this profile:"));
392 d->otherProfileBox = new IccProfilesComboBox;
393 d->otherProfileBox->addProfilesSqueezed(IccSettings::instance()->workspaceProfiles());
394 d->thirdCheckBox = new QCheckBox(i18n("and then convert to working space"));
395
396 d->keepProfile->setChecked(true);
397 d->otherProfileBox->setCurrentProfile(IccProfile::adobeRGB());
398 d->otherProfileBox->setNoProfileIfEmpty(i18n("No Profile Available"));
399
400 if (d->otherProfileBox->count() == 0) // disable if empty
401 {
402 d->thirdOption->setEnabled(false);
403 d->otherProfileBox->setEnabled(false);
404 }
405
406 QHBoxLayout* const hboxAssign = new QHBoxLayout;
407 hboxAssign->addSpacing(10);
408 hboxAssign->addWidget(d->otherProfileBox);
409 hboxAssign->addWidget(d->thirdCheckBox);
410 hboxAssign->setSpacing(0);
411
412 vbox->addWidget(d->keepProfile);
413 vbox->addWidget(d->convertToWorkingSpace);
414 vbox->addWidget(d->thirdOption);
415 vbox->addLayout(hboxAssign);
416
417 connect(d->keepProfile, SIGNAL(toggled(bool)),
418 this, SLOT(imageProfileToggled(bool)));
419
420 connect(d->convertToWorkingSpace, SIGNAL(toggled(bool)),
421 this, SLOT(imageProfileToggled(bool)));
422
423 connect(d->thirdOption, SIGNAL(toggled(bool)),
424 this, SLOT(imageProfileToggled(bool)));
425
426 connect(d->thirdCheckBox, SIGNAL(toggled(bool)),
427 this, SLOT(imageProfileToggled(bool)));
428
429 connect(d->otherProfileBox, SIGNAL(currentIndexChanged(int)),
430 this, SLOT(imageProfileChanged()));
431 }
432 else if (d->mode == MissingProfile)
433 {
434 QVBoxLayout* const vbox = new QVBoxLayout(box);
435 d->convertToWorkingSpace = new QRadioButton(i18n("Assign profile and convert to working color space"));
436 d->keepProfile = new QRadioButton(i18n("Assign and keep color profile"));
437 d->thirdOption = new QRadioButton(i18n("Leave the file untagged, do not color manage"));
438
439 d->convertToWorkingSpace->setChecked(true);
440
441 vbox->addWidget(d->convertToWorkingSpace);
442 vbox->addWidget(d->keepProfile);
443 vbox->addWidget(d->thirdOption);
444
445 connect(d->keepProfile, SIGNAL(toggled(bool)),
446 this, SLOT(missingProfileToggled(bool)));
447
448 connect(d->convertToWorkingSpace, SIGNAL(toggled(bool)),
449 this, SLOT(missingProfileToggled(bool)));
450
451 connect(d->thirdOption, SIGNAL(toggled(bool)),
452 this, SLOT(missingProfileToggled(bool)));
453 }
454 else if (d->mode == UncalibratedColor)
455 {
456 // empty
457 /*
458 QVBoxLayout* const vbox = new QVBoxLayout(box);
459 d->convertToWorkingSpace = new QRadioButton(i18n("Convert to working color space"));
460 d->thirdOption = new QRadioButton(i18n("Convert to this profile:"));
461 d->otherProfileBox = new IccProfilesComboBox;
462 d->otherProfileBox->addProfilesSqueezed(IccSettings::instance()->workspaceProfiles());
463
464 vbox->addWidget(d->convertToWorkingSpace);
465 vbox->addWidget(d->thirdOption);
466 vbox->addWidget(d->otherProfileBox);
467 */
468 }
469
470 return box;
471 }
472
createAssumeOptions() const473 QWidget* ColorCorrectionDlg::createAssumeOptions() const
474 {
475 QGroupBox* const box = new QGroupBox;
476
477 if (d->mode == ProfileMismatch)
478 {
479 // unused
480 }
481 else if (d->mode == MissingProfile)
482 {
483 QGridLayout* const grid = new QGridLayout(box);
484 QLabel* const label = new QLabel(i18n("Which color space shall be used to interpret the colors of this image?"));
485 label->setWordWrap(true);
486
487 d->imageSRGB = new QRadioButton(i18n("sRGB (Internet standard)"));
488 d->imageWorkingSpace = new QRadioButton(i18n("Current working color space"));
489 d->imageOtherSpace = new QRadioButton(i18n("This profile:"));
490 d->imageProfileBox = new IccProfilesComboBox;
491 d->imageProfileBox->addProfilesSqueezed(IccSettings::instance()->workspaceProfiles()
492 << IccSettings::instance()->inputProfiles());
493 QPushButton* const usedProfInfo = new QPushButton(i18n("Info..."));
494
495 d->imageSRGB->setChecked(true);
496 d->imageProfileBox->setCurrentProfile(IccProfile::adobeRGB());
497 d->imageProfileBox->setNoProfileIfEmpty(i18n("No Profile Available"));
498
499 if (d->imageProfileBox->count() == 0) // disable if empty
500 {
501 d->imageOtherSpace->setEnabled(false);
502 d->imageProfileBox->setEnabled(false);
503 }
504
505 grid->addWidget(label, 0, 0, 1, 2);
506 grid->addWidget(d->imageSRGB, 1, 0, 1, 2);
507 grid->addWidget(d->imageWorkingSpace, 2, 0, 1, 2);
508 grid->addWidget(d->imageOtherSpace, 3, 0, 1, 2);
509 grid->addWidget(d->imageProfileBox, 4, 1);
510 grid->addWidget(usedProfInfo, 5, 0, 1, 2, Qt::AlignLeft);
511 grid->setColumnMinimumWidth(0, 10);
512 grid->setColumnStretch(1, 1);
513
514 connect(d->imageProfileBox, SIGNAL(currentIndexChanged(int)),
515 this, SLOT(usedProfileChanged()));
516
517 connect(d->imageSRGB, SIGNAL(toggled(bool)),
518 this, SLOT(usedProfileToggled(bool)));
519
520 connect(d->imageWorkingSpace, SIGNAL(toggled(bool)),
521 this, SLOT(usedProfileToggled(bool)));
522
523 connect(d->imageOtherSpace, SIGNAL(toggled(bool)),
524 this, SLOT(usedProfileToggled(bool)));
525
526 connect(usedProfInfo, SIGNAL(clicked()),
527 this, SLOT(slotImageProfInfo()));
528 }
529 else if (d->mode == UncalibratedColor)
530 {
531 QGridLayout* const grid = new QGridLayout(box);
532 QLabel* const label = new QLabel(i18n("Please select the input color profile of the device (camera) "
533 "used to create this image:"));
534 label->setWordWrap(true);
535
536 d->imageProfileBox = new IccProfilesComboBox;
537 d->imageProfileBox->addProfilesSqueezed(IccSettings::instance()->inputProfiles());
538 d->imageProfileBox->setCurrentProfile(IccProfile(IccSettings::instance()->settings().defaultInputProfile));
539 d->imageProfileBox->setNoProfileIfEmpty(i18n("No Input Profile Available"));
540
541 grid->addWidget(label);
542 grid->addWidget(d->imageProfileBox);
543
544 connect(d->imageProfileBox, SIGNAL(currentIndexChanged(int)),
545 this, SLOT(inputProfileChanged()));
546 }
547
548 return box;
549 }
550
imageProfileToggled(bool on)551 void ColorCorrectionDlg::imageProfileToggled(bool on)
552 {
553 if (!on)
554 {
555 return;
556 }
557
558 imageProfileChanged();
559 }
560
imageProfileChanged()561 void ColorCorrectionDlg::imageProfileChanged()
562 {
563 updateImageProfileUI();
564 updateInfo();
565 }
566
updateImageProfileUI()567 void ColorCorrectionDlg::updateImageProfileUI()
568 {
569 if (d->otherProfileBox)
570 {
571 d->otherProfileBox->setEnabled(d->thirdOption->isChecked());
572 }
573
574 if (d->thirdCheckBox)
575 {
576 d->thirdCheckBox->setEnabled(d->thirdOption->isChecked());
577 }
578 }
579
missingProfileToggled(bool on)580 void ColorCorrectionDlg::missingProfileToggled(bool on)
581 {
582 if (!on)
583 {
584 return;
585 }
586
587 missingProfileChanged();
588 }
589
missingProfileChanged()590 void ColorCorrectionDlg::missingProfileChanged()
591 {
592 updateInfo();
593 }
594
usedProfileToggled(bool on)595 void ColorCorrectionDlg::usedProfileToggled(bool on)
596 {
597 if (!on)
598 {
599 return;
600 }
601
602 usedProfileChanged();
603 }
604
usedProfileChanged()605 void ColorCorrectionDlg::usedProfileChanged()
606 {
607 updateUsedProfileUI();
608 updateInfo();
609 }
610
updateUsedProfileUI()611 void ColorCorrectionDlg::updateUsedProfileUI()
612 {
613 if (d->imageProfileBox && d->imageOtherSpace)
614 {
615 d->imageProfileBox->setEnabled(d->imageOtherSpace->isChecked());
616 }
617 }
618
inputProfileChanged()619 void ColorCorrectionDlg::inputProfileChanged()
620 {
621 updateInfo();
622 }
623
updateInfo()624 void ColorCorrectionDlg::updateInfo()
625 {
626 setCursor(Qt::WaitCursor);
627
628 DImg colorPreview = d->preview.copy();
629 IccManager manager(colorPreview);
630 ICCSettingsContainer::Behavior b = currentBehavior();
631 d->imageProfile = manager.imageProfile(b, specifiedProfile());
632
633 if (d->mode == ProfileMismatch)
634 {
635 if (b & ICCSettingsContainer::UseSpecifiedProfile)
636 {
637 d->imageProfileTitle->setText(i18n("Assigned Color Profile:"));
638 }
639 else
640 {
641 d->imageProfileTitle->setText(i18n("Embedded Color Profile:"));
642 }
643 }
644
645 if ((d->mode == ProfileMismatch) || (d->mode == UncalibratedColor))
646 {
647 QString description = d->imageProfile.description();
648
649 if (description.isEmpty())
650 {
651 d->imageProfileDesc->setText(i18n("<b>No Profile</b>"));
652 }
653 else
654 {
655 d->imageProfileDesc->setText(QString::fromUtf8("<b>%1</b>").arg(description));
656 }
657 }
658
659 manager.transform(currentBehavior(), specifiedProfile());
660 manager.transformForDisplay(this);
661 d->previewTarget->setPixmap(colorPreview.convertToPixmap());
662
663 unsetCursor();
664 }
665
slotWorkspaceProfInfo()666 void ColorCorrectionDlg::slotWorkspaceProfInfo()
667 {
668 ICCProfileInfoDlg infoDlg(parentWidget(), QString(), d->workspaceProfile);
669 infoDlg.exec();
670 }
671
slotImageProfInfo()672 void ColorCorrectionDlg::slotImageProfInfo()
673 {
674 if (d->imageProfile.isNull())
675 {
676 return;
677 }
678
679 ICCProfileInfoDlg infoDlg(parentWidget(), QString(), d->imageProfile);
680 infoDlg.exec();
681 }
682
behavior() const683 ICCSettingsContainer::Behavior ColorCorrectionDlg::behavior() const
684 {
685 if (result() == QDialog::Rejected)
686 {
687 return ICCSettingsContainer::SafestBestAction;
688 }
689
690 return currentBehavior();
691 }
692
currentBehavior() const693 ICCSettingsContainer::Behavior ColorCorrectionDlg::currentBehavior() const
694 {
695 if (d->mode == ProfileMismatch)
696 {
697 if (d->keepProfile->isChecked())
698 {
699 return ICCSettingsContainer::PreserveEmbeddedProfile;
700 }
701 else if (d->convertToWorkingSpace->isChecked())
702 {
703 return ICCSettingsContainer::EmbeddedToWorkspace;
704 }
705 else if (d->thirdOption->isChecked())
706 {
707 if (d->thirdCheckBox->isChecked())
708 {
709 return ICCSettingsContainer::UseSpecifiedProfile | ICCSettingsContainer::ConvertToWorkspace;
710 }
711 else
712 {
713 return ICCSettingsContainer::UseSpecifiedProfile | ICCSettingsContainer::KeepProfile;
714 }
715 }
716 }
717 else if (d->mode == MissingProfile)
718 {
719 if (d->thirdOption->isChecked())
720 {
721 return ICCSettingsContainer::NoColorManagement;
722 }
723
724 ICCSettingsContainer::Behavior behavior;
725
726 if (d->keepProfile->isChecked())
727 {
728 behavior |= ICCSettingsContainer::KeepProfile;
729 }
730 else if (d->convertToWorkingSpace->isChecked())
731 {
732 behavior |= ICCSettingsContainer::ConvertToWorkspace;
733 }
734
735 if (d->imageSRGB->isChecked())
736 {
737 behavior |= ICCSettingsContainer::UseSRGB;
738 }
739 else if (d->imageWorkingSpace->isChecked())
740 {
741 behavior |= ICCSettingsContainer::UseWorkspace;
742 }
743 else if (d->imageOtherSpace->isChecked())
744 {
745 behavior |= ICCSettingsContainer::UseSpecifiedProfile;
746 }
747
748 return behavior;
749 }
750 else if (d->mode == UncalibratedColor)
751 {
752 return (ICCSettingsContainer::ConvertToWorkspace | ICCSettingsContainer::UseSpecifiedProfile);
753 }
754
755 return ICCSettingsContainer::SafestBestAction;
756 }
757
specifiedProfile() const758 IccProfile ColorCorrectionDlg::specifiedProfile() const
759 {
760 if (d->mode == ProfileMismatch)
761 {
762 return d->otherProfileBox->currentProfile();
763 }
764 else if ((d->mode == MissingProfile) || (d->mode == UncalibratedColor))
765 {
766 return d->imageProfileBox->currentProfile();
767 }
768
769 return IccProfile();
770 }
771
readSettings()772 void ColorCorrectionDlg::readSettings()
773 {
774 ICCSettingsContainer settings = IccSettings::instance()->settings();
775
776 if (d->mode == ProfileMismatch)
777 {
778 if ((settings.lastMismatchBehavior & ICCSettingsContainer::UseSpecifiedProfile) &&
779 d->otherProfileBox->count() > 0)
780 {
781 d->thirdOption->setChecked(true);
782 d->thirdCheckBox->setChecked(settings.lastMismatchBehavior & ICCSettingsContainer::ConvertToWorkspace);
783 d->thirdOption->setFocus();
784 }
785 else
786 {
787 if (settings.lastMismatchBehavior & ICCSettingsContainer::KeepProfile)
788 {
789 d->keepProfile->setChecked(true);
790 d->keepProfile->setFocus();
791 }
792 else if (settings.lastMismatchBehavior & ICCSettingsContainer::ConvertToWorkspace)
793 {
794 d->convertToWorkingSpace->setChecked(true);
795 d->convertToWorkingSpace->setFocus();
796 }
797 }
798
799 if (!settings.lastSpecifiedAssignProfile.isEmpty())
800 {
801 d->otherProfileBox->setCurrentProfile(IccProfile(settings.lastSpecifiedAssignProfile));
802 }
803 }
804 else if (d->mode == MissingProfile)
805 {
806 if (settings.lastMissingProfileBehavior == ICCSettingsContainer::NoColorManagement)
807 {
808 d->imageSRGB->setChecked(true); // ?
809 d->thirdOption->setChecked(true);
810 d->thirdOption->setFocus();
811 }
812 else
813 {
814 if (settings.lastMissingProfileBehavior & ICCSettingsContainer::KeepProfile)
815 {
816 d->keepProfile->setChecked(true);
817 d->keepProfile->setFocus();
818 }
819 else if (settings.lastMissingProfileBehavior & ICCSettingsContainer::ConvertToWorkspace)
820 {
821 d->convertToWorkingSpace->setChecked(true);
822 d->convertToWorkingSpace->setFocus();
823 }
824
825 if (settings.lastMissingProfileBehavior & ICCSettingsContainer::UseSRGB)
826 {
827 d->imageSRGB->setChecked(true);
828 }
829
830 if (settings.lastMissingProfileBehavior & ICCSettingsContainer::UseWorkspace)
831 {
832 d->imageWorkingSpace->setChecked(true);
833 }
834
835 if ((settings.lastMissingProfileBehavior & ICCSettingsContainer::UseSpecifiedProfile) &&
836 (d->imageProfileBox->count() > 0))
837 {
838 d->imageOtherSpace->setChecked(true);
839 }
840 }
841
842 if (!settings.lastSpecifiedInputProfile.isEmpty())
843 {
844 d->imageProfileBox->setCurrentProfile(IccProfile(settings.lastSpecifiedInputProfile));
845 }
846 }
847 else if (d->mode == UncalibratedColor)
848 {
849 d->imageProfileBox->setCurrentProfile(IccProfile(settings.lastSpecifiedInputProfile));
850 d->imageProfileBox->setFocus();
851 }
852 }
853
setSettings()854 void ColorCorrectionDlg::setSettings()
855 {
856 ICCSettingsContainer settings = IccSettings::instance()->settings();
857
858 if (d->mode == ProfileMismatch)
859 {
860 settings.lastMismatchBehavior = currentBehavior();
861 settings.lastSpecifiedAssignProfile = specifiedProfile().filePath();
862 }
863 else if (d->mode == MissingProfile)
864 {
865 settings.lastMissingProfileBehavior = currentBehavior();
866 settings.lastSpecifiedInputProfile = specifiedProfile().filePath();
867 }
868 else if (d->mode == UncalibratedColor)
869 {
870 settings.lastUncalibratedBehavior = currentBehavior();
871 settings.lastSpecifiedInputProfile = specifiedProfile().filePath();
872 }
873
874 IccSettings::instance()->setSettings(settings);
875 }
876
slotHelp()877 void ColorCorrectionDlg::slotHelp()
878 {
879 DXmlGuiWindow::openHandbook();
880 }
881
882 } // namespace Digikam
883