~ubuntu-branches/ubuntu/saucy/digikam/saucy

« back to all changes in this revision

Viewing changes to imageplugins/color/adjustlevelstool.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Christian Mangold
  • Date: 2010-04-09 21:30:01 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100409213001-4bfyibrd359rn7o3
Tags: 2:1.2.0-0ubuntu1
* New upstream release (LP: #560576)
* Remove all patches, fixed upstream
  - Remove quilt build-depend

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ============================================================
 
2
 *
 
3
 * This file is a part of digiKam project
 
4
 * http://www.digikam.org
 
5
 *
 
6
 * Date        : 2004-07-20
 
7
 * Description : image histogram adjust levels.
 
8
 *
 
9
 * Copyright (C) 2004-2010 by Gilles Caulier <caulier dot gilles at gmail dot com>
 
10
 *
 
11
 * This program is free software; you can redistribute it
 
12
 * and/or modify it under the terms of the GNU General
 
13
 * Public License as published by the Free Software Foundation;
 
14
 * either version 2, or (at your option)
 
15
 * any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * ============================================================ */
 
23
 
 
24
#include "adjustlevelstool.moc"
 
25
 
 
26
// C++ includes
 
27
 
 
28
#include <cmath>
 
29
 
 
30
// Qt includes
 
31
 
 
32
#include <QButtonGroup>
 
33
#include <QColor>
 
34
#include <QGridLayout>
 
35
#include <QGroupBox>
 
36
#include <QHBoxLayout>
 
37
#include <QLabel>
 
38
#include <QPushButton>
 
39
#include <QTimer>
 
40
#include <QToolButton>
 
41
 
 
42
// KDE includes
 
43
 
 
44
#include <kapplication.h>
 
45
#include <kconfig.h>
 
46
#include <kcursor.h>
 
47
#include <kfiledialog.h>
 
48
#include <kglobal.h>
 
49
#include <kglobalsettings.h>
 
50
#include <kicon.h>
 
51
#include <kiconloader.h>
 
52
#include <klocale.h>
 
53
#include <kmessagebox.h>
 
54
#include <kstandarddirs.h>
 
55
 
 
56
// LibKDcraw includes
 
57
 
 
58
#include <libkdcraw/rnuminput.h>
 
59
 
 
60
// Local includes
 
61
 
 
62
#include "dgradientslider.h"
 
63
#include "dimg.h"
 
64
#include "editortoolsettings.h"
 
65
#include "histogrambox.h"
 
66
#include "histogramwidget.h"
 
67
#include "imagehistogram.h"
 
68
#include "imageiface.h"
 
69
#include "levelsfilter.h"
 
70
#include "imagelevels.h"
 
71
#include "imageregionwidget.h"
 
72
 
 
73
using namespace KDcrawIface;
 
74
 
 
75
namespace DigikamColorImagePlugin
 
76
{
 
77
 
 
78
class AdjustLevelsToolPriv
 
79
{
 
80
 
 
81
public:
 
82
 
 
83
    enum ColorPicker
 
84
    {
 
85
        NoPicker   = -1,
 
86
        BlackTonal = 0,
 
87
        GrayTonal,
 
88
        WhiteTonal
 
89
    };
 
90
 
 
91
public:
 
92
 
 
93
    AdjustLevelsToolPriv() :
 
94
        configGroupName("adjustlevels Tool"),
 
95
        configGammaChannelEntry("GammaChannel%1"),
 
96
        configLowInputChannelEntry("LowInputChannel%1"),
 
97
        configLowOutputChannelEntry("LowOutputChannel%1"),
 
98
        configHighInputChannelEntry("HighInputChannel%1"),
 
99
        configHighOutputChannelEntry("HighOutputChannel%1"),
 
100
        configHistogramChannelEntry("Histogram Channel"),
 
101
        configHistogramScaleEntry("Histogram Scale"),
 
102
 
 
103
        destinationPreviewData(0),
 
104
        histoSegments(0),
 
105
        pickerBox(0),
 
106
        resetButton(0),
 
107
        autoButton(0),
 
108
        pickBlack(0),
 
109
        pickGray(0),
 
110
        pickWhite(0),
 
111
        pickerColorButtonGroup(0),
 
112
        minInput(0),
 
113
        maxInput(0),
 
114
        minOutput(0),
 
115
        maxOutput(0),
 
116
        gammaInput(0),
 
117
        levelsHistogramWidget(0),
 
118
        inputLevels(0),
 
119
        outputLevels(0),
 
120
        previewWidget(0),
 
121
        levels(0),
 
122
        originalImage(0),
 
123
        gboxSettings(0)
 
124
        {}
 
125
 
 
126
    const QString       configGroupName;
 
127
    const QString       configGammaChannelEntry;
 
128
    const QString       configLowInputChannelEntry;
 
129
    const QString       configLowOutputChannelEntry;
 
130
    const QString       configHighInputChannelEntry;
 
131
    const QString       configHighOutputChannelEntry;
 
132
    const QString       configHistogramChannelEntry;
 
133
    const QString       configHistogramScaleEntry;
 
134
 
 
135
    uchar*              destinationPreviewData;
 
136
 
 
137
    int                 histoSegments;
 
138
 
 
139
    QWidget*            pickerBox;
 
140
 
 
141
    QPushButton*        resetButton;
 
142
    QToolButton*        autoButton;
 
143
    QToolButton*        pickBlack;
 
144
    QToolButton*        pickGray;
 
145
    QToolButton*        pickWhite;
 
146
 
 
147
    QButtonGroup*       pickerColorButtonGroup;
 
148
 
 
149
    RIntNumInput*       minInput;
 
150
    RIntNumInput*       maxInput;
 
151
    RIntNumInput*       minOutput;
 
152
    RIntNumInput*       maxOutput;
 
153
 
 
154
    RDoubleNumInput*    gammaInput;
 
155
 
 
156
    HistogramWidget*    levelsHistogramWidget;
 
157
 
 
158
    DGradientSlider*    inputLevels;
 
159
    DGradientSlider*    outputLevels;
 
160
 
 
161
    ImageRegionWidget*  previewWidget;
 
162
 
 
163
    ImageLevels*        levels;
 
164
 
 
165
    DImg*               originalImage;
 
166
 
 
167
    EditorToolSettings* gboxSettings;
 
168
};
 
169
 
 
170
AdjustLevelsTool::AdjustLevelsTool(QObject* parent)
 
171
                : EditorToolThreaded(parent),
 
172
                  d(new AdjustLevelsToolPriv)
 
173
{
 
174
    setObjectName("adjustlevels");
 
175
    setToolName(i18n("Adjust Levels"));
 
176
    setToolIcon(SmallIcon("adjustlevels"));
 
177
 
 
178
    ImageIface iface(0, 0);
 
179
    d->originalImage = iface.getOriginalImg();
 
180
 
 
181
    d->histoSegments = d->originalImage->sixteenBit() ? 65535 : 255;
 
182
    d->levels        = new ImageLevels(d->originalImage->sixteenBit());
 
183
 
 
184
    // -------------------------------------------------------------
 
185
 
 
186
    d->previewWidget = new ImageRegionWidget;
 
187
    setToolView(d->previewWidget);
 
188
    setPreviewModeMask(PreviewToolBar::AllPreviewModes);
 
189
 
 
190
    // -------------------------------------------------------------
 
191
 
 
192
    d->gboxSettings = new EditorToolSettings;
 
193
    d->gboxSettings->setButtons(EditorToolSettings::Default|
 
194
                                EditorToolSettings::Load|
 
195
                                EditorToolSettings::SaveAs|
 
196
                                EditorToolSettings::Ok|
 
197
                                EditorToolSettings::Cancel);
 
198
//                                EditorToolSettings::Try);
 
199
 
 
200
    d->gboxSettings->setTools(EditorToolSettings::Histogram);
 
201
    d->gboxSettings->setHistogramType(Digikam::LRGBA);
 
202
 
 
203
    // we don't need to use the Gradient widget in this tool
 
204
    d->gboxSettings->histogramBox()->setGradientVisible(false);
 
205
 
 
206
    // -------------------------------------------------------------
 
207
 
 
208
    d->levelsHistogramWidget = new HistogramWidget(256, 140, d->originalImage->bits(),
 
209
                                                             d->originalImage->width(),
 
210
                                                             d->originalImage->height(),
 
211
                                                             d->originalImage->sixteenBit(),
 
212
                                                             d->gboxSettings->plainPage(), false);
 
213
    d->levelsHistogramWidget->setWhatsThis(i18n("This is the histogram drawing of the selected channel "
 
214
                                                "from the original image."));
 
215
    QHBoxLayout* inputLevelsLayout = new QHBoxLayout;
 
216
    inputLevelsLayout->addWidget(d->levelsHistogramWidget);
 
217
 
 
218
    // -------------------------------------------------------------
 
219
 
 
220
    d->inputLevels = new DGradientSlider();
 
221
    d->inputLevels->setWhatsThis( i18n("Select the input intensity of the histogram here."));
 
222
    d->inputLevels->setToolTip( i18n( "Input intensity." ) );
 
223
    d->inputLevels->installEventFilter(this);
 
224
    d->gboxSettings->histogramBox()->setHistogramMargin(d->inputLevels->gradientOffset());
 
225
    inputLevelsLayout->setContentsMargins(d->inputLevels->gradientOffset(), 0,
 
226
                                          d->inputLevels->gradientOffset(), 0);
 
227
 
 
228
    d->outputLevels = new DGradientSlider();
 
229
    d->outputLevels->setWhatsThis( i18n("Select the output intensity of the histogram here."));
 
230
    d->outputLevels->setToolTip( i18n( "Output intensity." ) );
 
231
    d->outputLevels->installEventFilter(this);
 
232
 
 
233
    d->minInput = new RIntNumInput();
 
234
    d->minInput->setRange(0, d->histoSegments, 1);
 
235
    d->minInput->setSliderEnabled(false);
 
236
    d->minInput->setDefaultValue(0);
 
237
    d->minInput->setWhatsThis( i18n("Select the minimal input intensity value of the histogram here."));
 
238
    d->minInput->setToolTip( i18n( "Minimal input intensity." ) );
 
239
 
 
240
    d->gammaInput = new RDoubleNumInput();
 
241
    d->gammaInput->setDecimals(2);
 
242
    d->gammaInput->setRange(0.1, 3.0, 0.01);
 
243
    d->gammaInput->setDefaultValue(1.0);
 
244
    d->gammaInput->setToolTip( i18n( "Gamma input value." ) );
 
245
    d->gammaInput->setWhatsThis( i18n("Select the gamma input value here."));
 
246
 
 
247
    d->maxInput = new RIntNumInput();
 
248
    d->maxInput->setRange(0, d->histoSegments, 1);
 
249
    d->maxInput->setSliderEnabled(false);
 
250
    d->maxInput->setDefaultValue(d->histoSegments);
 
251
    d->maxInput->setToolTip( i18n( "Maximal input intensity." ) );
 
252
    d->maxInput->setWhatsThis( i18n("Select the maximal input intensity value of the histogram here."));
 
253
 
 
254
    d->minOutput = new RIntNumInput();
 
255
    d->minOutput->setRange(0, d->histoSegments, 1);
 
256
    d->minOutput->setSliderEnabled(false);
 
257
    d->minOutput->setDefaultValue(0);
 
258
    d->minOutput->setToolTip( i18n( "Minimal output intensity." ) );
 
259
    d->minOutput->setWhatsThis( i18n("Select the minimal output intensity value of the histogram here."));
 
260
 
 
261
    d->maxOutput = new RIntNumInput();
 
262
    d->maxOutput->setRange(0, d->histoSegments, 1);
 
263
    d->maxOutput->setSliderEnabled(false);
 
264
    d->maxOutput->setDefaultValue(d->histoSegments);
 
265
    d->maxOutput->setToolTip( i18n( "Maximal output intensity." ) );
 
266
    d->maxOutput->setWhatsThis( i18n("Select the maximal output intensity value of the histogram here."));
 
267
 
 
268
    // -------------------------------------------------------------
 
269
 
 
270
    d->pickerBox = new QWidget();
 
271
 
 
272
    d->pickBlack = new QToolButton();
 
273
    d->pickBlack->setIcon(KIcon("color-picker-black"));
 
274
    d->pickBlack->setCheckable(true);
 
275
    d->pickBlack->setToolTip( i18n( "All channels shadow tone color picker" ) );
 
276
    d->pickBlack->setWhatsThis(i18n("With this button, you can pick the color from the original "
 
277
                                    "image used to set <b>Shadow Tone</b> "
 
278
                                    "input levels on the Red, Green, Blue, and Luminosity channels."));
 
279
 
 
280
    d->pickGray  = new QToolButton();
 
281
    d->pickGray->setIcon(KIcon("color-picker-grey"));
 
282
    d->pickGray->setCheckable(true);
 
283
    d->pickGray->setToolTip( i18n( "All channels middle tone color picker" ) );
 
284
    d->pickGray->setWhatsThis(i18n("With this button, you can pick the color from the original "
 
285
                                   "image used to set <b>Middle Tone</b> "
 
286
                                   "input levels on the Red, Green, Blue, and Luminosity channels."));
 
287
 
 
288
    d->pickWhite = new QToolButton();
 
289
    d->pickWhite->setIcon(KIcon("color-picker-white"));
 
290
    d->pickWhite->setCheckable(true);
 
291
    d->pickWhite->setToolTip( i18n( "All channels highlight tone color picker" ) );
 
292
    d->pickWhite->setWhatsThis(i18n("With this button, you can pick the color from the original "
 
293
                                    "image used to set <b>Highlight Tone</b> "
 
294
                                    "input levels on the Red, Green, Blue, and Luminosity channels."));
 
295
 
 
296
    d->pickerColorButtonGroup = new QButtonGroup(d->pickerBox);
 
297
    d->pickerColorButtonGroup->addButton(d->pickBlack, AdjustLevelsToolPriv::BlackTonal);
 
298
    d->pickerColorButtonGroup->addButton(d->pickGray,  AdjustLevelsToolPriv::GrayTonal);
 
299
    d->pickerColorButtonGroup->addButton(d->pickWhite, AdjustLevelsToolPriv::WhiteTonal);
 
300
 
 
301
    QHBoxLayout* pickerBoxLayout = new QHBoxLayout;
 
302
    pickerBoxLayout->setMargin(0);
 
303
    pickerBoxLayout->setSpacing(0);
 
304
    pickerBoxLayout->addWidget(d->pickBlack);
 
305
    pickerBoxLayout->addWidget(d->pickGray);
 
306
    pickerBoxLayout->addWidget(d->pickWhite);
 
307
    d->pickerBox->setLayout(pickerBoxLayout);
 
308
 
 
309
    d->pickerColorButtonGroup->setExclusive(true);
 
310
 
 
311
    // -------------------------------------------------------------
 
312
 
 
313
    d->autoButton = new QToolButton();
 
314
    d->autoButton->setIcon(KIconLoader::global()->loadIcon("system-run", KIconLoader::Toolbar));
 
315
    d->autoButton->setToolTip( i18n( "Adjust all levels automatically." ) );
 
316
    d->autoButton->setWhatsThis(i18n("If you press this button, all channel levels will be adjusted "
 
317
                                     "automatically."));
 
318
 
 
319
    d->resetButton = new QPushButton(i18n("&Reset"));
 
320
    d->resetButton->setIcon(KIconLoader::global()->loadIcon("document-revert", KIconLoader::Toolbar));
 
321
    d->resetButton->setToolTip( i18n( "Reset current channel levels' values." ) );
 
322
    d->resetButton->setWhatsThis(i18n("If you press this button, all levels' values "
 
323
                                      "from the currently selected channel "
 
324
                                      "will be reset to the default values."));
 
325
 
 
326
    QLabel* space = new QLabel();
 
327
    space->setFixedWidth(d->gboxSettings->spacingHint());
 
328
 
 
329
    QHBoxLayout* l3 = new QHBoxLayout();
 
330
    l3->addWidget(d->pickerBox);
 
331
    l3->addWidget(d->autoButton);
 
332
    l3->addWidget(space);
 
333
    l3->addWidget(d->resetButton);
 
334
    l3->addStretch(10);
 
335
 
 
336
    // -------------------------------------------------------------
 
337
 
 
338
    QGridLayout* grid = new QGridLayout();
 
339
    grid->addLayout(inputLevelsLayout,        0, 0, 1, 7);
 
340
    grid->addWidget(d->inputLevels,           1, 0, 1, 7);
 
341
    grid->addWidget(d->minInput,              2, 1, 1, 1);
 
342
    grid->addWidget(d->maxInput,              2, 5, 1, 1);
 
343
    grid->addWidget(d->gammaInput,            3, 0, 1, 7);
 
344
    grid->addWidget(d->outputLevels,          4, 0, 1, 7);
 
345
    grid->addWidget(d->minOutput,             5, 1, 1, 1);
 
346
    grid->addWidget(d->maxOutput,             5, 5, 1, 1);
 
347
    grid->addLayout(l3,                       6, 0, 1, 7);
 
348
    grid->setRowStretch(7, 10);
 
349
    grid->setColumnStretch(2, 10);
 
350
    grid->setColumnStretch(4, 10);
 
351
    grid->setMargin(0);
 
352
    grid->setSpacing(d->gboxSettings->spacingHint());
 
353
    d->gboxSettings->plainPage()->setLayout(grid);
 
354
 
 
355
    // -------------------------------------------------------------
 
356
 
 
357
    setToolSettings(d->gboxSettings);
 
358
    init();
 
359
 
 
360
    // -------------------------------------------------------------
 
361
    // Channels and scale selection slots.
 
362
 
 
363
    connect(d->previewWidget, SIGNAL(signalResized()),
 
364
            this, SLOT(slotEffect()));
 
365
 
 
366
    connect(d->previewWidget, SIGNAL(signalCapturedPointFromOriginal(const Digikam::DColor&, const QPoint&)),
 
367
            this, SLOT(slotSpotColorChanged(const Digikam::DColor&)));
 
368
/*
 
369
    connect(d->previewWidget, SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const QPoint&)),
 
370
            this, SLOT(slotColorSelectedFromTarget(const Digikam::DColor&)));
 
371
*/
 
372
 
 
373
    // -------------------------------------------------------------
 
374
    // Color sliders and spinbox slots.
 
375
 
 
376
    connect(d->inputLevels, SIGNAL(leftValueChanged(double)),
 
377
            this, SLOT(slotAdjustMinInputSpinBox(double)));
 
378
 
 
379
    connect(d->inputLevels, SIGNAL(rightValueChanged(double)),
 
380
            this, SLOT(slotAdjustMaxInputSpinBox(double)));
 
381
 
 
382
    connect(d->outputLevels, SIGNAL(leftValueChanged(double)),
 
383
            this, SLOT(slotAdjustMinOutputSpinBox(double)));
 
384
 
 
385
    connect(d->outputLevels, SIGNAL(rightValueChanged(double)),
 
386
            this, SLOT(slotAdjustMaxOutputSpinBox(double)));
 
387
 
 
388
    connect(d->minInput, SIGNAL(valueChanged(int)),
 
389
            this, SLOT(slotAdjustSliders()));
 
390
 
 
391
    connect(d->maxInput, SIGNAL(valueChanged(int)),
 
392
            this, SLOT(slotAdjustSliders()));
 
393
 
 
394
    connect(d->minOutput, SIGNAL(valueChanged(int)),
 
395
            this, SLOT(slotAdjustSliders()));
 
396
 
 
397
    connect(d->maxOutput, SIGNAL(valueChanged(int)),
 
398
            this, SLOT(slotAdjustSliders()));
 
399
 
 
400
    connect(d->gammaInput, SIGNAL(valueChanged(double)),
 
401
            this, SLOT(slotGammaInputchanged(double)));
 
402
 
 
403
    // -------------------------------------------------------------
 
404
    // Buttons slots.
 
405
 
 
406
    connect(d->autoButton, SIGNAL(clicked()),
 
407
            this, SLOT(slotAutoLevels()));
 
408
 
 
409
    connect(d->resetButton, SIGNAL(clicked()),
 
410
            this, SLOT(slotResetCurrentChannel()));
 
411
 
 
412
    connect(d->pickerColorButtonGroup, SIGNAL(buttonReleased(int)),
 
413
            this, SLOT(slotPickerColorButtonActived(int)));
 
414
 
 
415
    slotTimer();
 
416
}
 
417
 
 
418
AdjustLevelsTool::~AdjustLevelsTool()
 
419
{
 
420
    if (d->destinationPreviewData)
 
421
       delete [] d->destinationPreviewData;
 
422
 
 
423
    delete d->levels;
 
424
    delete d;
 
425
}
 
426
 
 
427
// See B.K.O #146636: use event filter with all level slider to display a
 
428
// guide over level histogram.
 
429
bool AdjustLevelsTool::eventFilter(QObject *obj, QEvent *ev)
 
430
{
 
431
    if ( obj == d->inputLevels )
 
432
    {
 
433
        if ( ev->type() == QEvent::MouseButtonPress)
 
434
        {
 
435
            connect(d->inputLevels, SIGNAL(leftValueChanged(double)),
 
436
                    this, SLOT(slotShowInputHistogramGuide(double)));
 
437
 
 
438
            connect(d->inputLevels, SIGNAL(rightValueChanged(double)),
 
439
                    this, SLOT(slotShowInputHistogramGuide(double)));
 
440
 
 
441
            return false;
 
442
        }
 
443
        if ( ev->type() == QEvent::MouseButtonRelease)
 
444
        {
 
445
            disconnect(d->inputLevels, SIGNAL(leftValueChanged(double)),
 
446
                       this, SLOT(slotShowInputHistogramGuide(double)));
 
447
 
 
448
            disconnect(d->inputLevels, SIGNAL(rightValueChanged(double)),
 
449
                       this, SLOT(slotShowInputHistogramGuide(double)));
 
450
 
 
451
            d->levelsHistogramWidget->reset();
 
452
            return false;
 
453
        }
 
454
        else
 
455
        {
 
456
            return false;
 
457
        }
 
458
    }
 
459
    if ( obj == d->outputLevels )
 
460
    {
 
461
        if ( ev->type() == QEvent::MouseButtonPress)
 
462
        {
 
463
            connect(d->outputLevels, SIGNAL(leftValueChanged(double)),
 
464
                    this, SLOT(slotShowOutputHistogramGuide(double)));
 
465
 
 
466
            connect(d->outputLevels, SIGNAL(rightValueChanged(double)),
 
467
                    this, SLOT(slotShowOutputHistogramGuide(double)));
 
468
 
 
469
            return false;
 
470
        }
 
471
        if ( ev->type() == QEvent::MouseButtonRelease)
 
472
        {
 
473
            disconnect(d->outputLevels, SIGNAL(leftValueChanged(double)),
 
474
                       this, SLOT(slotShowOutputHistogramGuide(double)));
 
475
 
 
476
            disconnect(d->outputLevels, SIGNAL(rightValueChanged(double)),
 
477
                       this, SLOT(slotShowOutputHistogramGuide(double)));
 
478
 
 
479
            d->gboxSettings->histogramBox()->histogram()->reset();
 
480
            return false;
 
481
        }
 
482
        else
 
483
        {
 
484
            return false;
 
485
        }
 
486
    }
 
487
    else
 
488
    {
 
489
        // pass the event on to the parent class
 
490
        return EditorToolThreaded::eventFilter(obj, ev);
 
491
    }
 
492
}
 
493
 
 
494
void AdjustLevelsTool::slotShowInputHistogramGuide(double v)
 
495
{
 
496
    int val = (int)(v * d->histoSegments);
 
497
    DColor color(val, val, val, val, d->originalImage->sixteenBit());
 
498
    d->levelsHistogramWidget->setHistogramGuideByColor(color);
 
499
}
 
500
 
 
501
void AdjustLevelsTool::slotShowOutputHistogramGuide(double v)
 
502
{
 
503
    int val = (int)(v * d->histoSegments);
 
504
    DColor color(val, val, val, val, d->originalImage->sixteenBit());
 
505
    d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
 
506
}
 
507
 
 
508
void AdjustLevelsTool::slotPickerColorButtonActived(int type)
 
509
{
 
510
    if (type == AdjustLevelsToolPriv::NoPicker) return;
 
511
 
 
512
    d->previewWidget->setCapturePointMode(true);
 
513
}
 
514
 
 
515
void AdjustLevelsTool::slotSpotColorChanged(const DColor& color)
 
516
{
 
517
    if ( d->pickBlack->isChecked() )
 
518
    {
 
519
       // Black tonal levels point.
 
520
       d->levels->levelsBlackToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
 
521
       d->pickBlack->setChecked(false);
 
522
    }
 
523
    else if ( d->pickGray->isChecked() )
 
524
    {
 
525
       // Gray tonal levels point.
 
526
       d->levels->levelsGrayToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
 
527
       d->pickGray->setChecked(false);
 
528
    }
 
529
    else if ( d->pickWhite->isChecked() )
 
530
    {
 
531
       // White tonal levels point.
 
532
       d->levels->levelsWhiteToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
 
533
       d->pickWhite->setChecked(false);
 
534
    }
 
535
    else
 
536
    {
 
537
       d->levelsHistogramWidget->setHistogramGuideByColor(color);
 
538
       return;
 
539
    }
 
540
 
 
541
    // Refresh the current levels config.
 
542
    slotChannelChanged();
 
543
 
 
544
    d->previewWidget->setCapturePointMode(false);
 
545
    slotEffect();
 
546
}
 
547
 
 
548
void AdjustLevelsTool::slotColorSelectedFromTarget(const DColor& color)
 
549
{
 
550
    d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
 
551
}
 
552
 
 
553
void AdjustLevelsTool::slotGammaInputchanged(double val)
 
554
{
 
555
    blockSignals(true);
 
556
    d->levels->setLevelGammaValue(d->gboxSettings->histogramBox()->channel(), val);
 
557
    blockSignals(false);
 
558
    slotTimer();
 
559
}
 
560
 
 
561
void AdjustLevelsTool::slotAdjustMinInputSpinBox(double val)
 
562
{
 
563
    d->minInput->blockSignals(true);
 
564
    int newVal = (int)(val*d->histoSegments);
 
565
    d->minInput->setValue(newVal);
 
566
    d->minInput->blockSignals(false);
 
567
    slotAdjustSliders();
 
568
}
 
569
 
 
570
void AdjustLevelsTool::slotAdjustMaxInputSpinBox(double val)
 
571
{
 
572
    d->maxInput->blockSignals(true);
 
573
    int newVal = (int)(val*d->histoSegments);
 
574
    d->maxInput->setValue(newVal);
 
575
    d->maxInput->blockSignals(false);
 
576
    slotAdjustSliders();
 
577
}
 
578
 
 
579
void AdjustLevelsTool::slotAdjustMinOutputSpinBox(double val)
 
580
{
 
581
    d->minOutput->blockSignals(true);
 
582
    int newVal = (int)(val*d->histoSegments);
 
583
    d->minOutput->setValue(newVal);
 
584
    d->minOutput->blockSignals(false);
 
585
    slotAdjustSliders();
 
586
}
 
587
 
 
588
void AdjustLevelsTool::slotAdjustMaxOutputSpinBox(double val)
 
589
{
 
590
    d->maxOutput->blockSignals(true);
 
591
    int newVal = (int)(val*d->histoSegments);
 
592
    d->maxOutput->setValue(newVal);
 
593
    d->maxOutput->blockSignals(false);
 
594
    slotAdjustSliders();
 
595
}
 
596
 
 
597
void AdjustLevelsTool::slotAdjustSliders()
 
598
{
 
599
    adjustSliders(d->minInput->value(), d->gammaInput->value(),
 
600
                  d->maxInput->value(), d->minOutput->value(),
 
601
                  d->maxOutput->value());
 
602
 
 
603
    slotTimer();
 
604
}
 
605
 
 
606
void AdjustLevelsTool::adjustSlidersAndSpinboxes(int minIn, double gamIn, int maxIn, int minOut, int maxOut)
 
607
{
 
608
    d->minInput->blockSignals(true);
 
609
    d->maxInput->blockSignals(true);
 
610
    d->minOutput->blockSignals(true);
 
611
    d->maxOutput->blockSignals(true);
 
612
 
 
613
    d->minInput->setValue(minIn);
 
614
    d->maxInput->setValue(maxIn);
 
615
    d->minOutput->setValue(minOut);
 
616
    d->maxOutput->setValue(maxOut);
 
617
 
 
618
    d->minInput->blockSignals(false);
 
619
    d->maxInput->blockSignals(false);
 
620
    d->minOutput->blockSignals(false);
 
621
    d->maxOutput->blockSignals(false);
 
622
 
 
623
    adjustSliders(minIn, gamIn, maxIn, minOut, maxOut);
 
624
}
 
625
 
 
626
void AdjustLevelsTool::adjustSliders(int minIn, double gamIn, int maxIn, int minOut, int maxOut)
 
627
{
 
628
    d->inputLevels->blockSignals(true);
 
629
    d->gammaInput->blockSignals(true);
 
630
    d->outputLevels->blockSignals(true);
 
631
 
 
632
    d->inputLevels->setLeftValue((double)minIn/(double)d->histoSegments);
 
633
    d->inputLevels->setRightValue((double)maxIn/(double)d->histoSegments);
 
634
    d->gammaInput->setValue(gamIn);
 
635
    d->outputLevels->setLeftValue((double)minOut/(double)d->histoSegments);
 
636
    d->outputLevels->setRightValue((double)maxOut/(double)d->histoSegments);
 
637
 
 
638
    d->levels->setLevelLowInputValue(d->gboxSettings->histogramBox()->channel(), minIn);
 
639
    d->levels->setLevelHighInputValue(d->gboxSettings->histogramBox()->channel(), maxIn);
 
640
    d->levels->setLevelLowOutputValue(d->gboxSettings->histogramBox()->channel(), minOut);
 
641
    d->levels->setLevelHighOutputValue(d->gboxSettings->histogramBox()->channel(), maxOut);
 
642
 
 
643
    d->inputLevels->blockSignals(false);
 
644
    d->gammaInput->blockSignals(false);
 
645
    d->outputLevels->blockSignals(false);
 
646
}
 
647
 
 
648
void AdjustLevelsTool::slotResetCurrentChannel()
 
649
{
 
650
    d->levels->levelsChannelReset(d->gboxSettings->histogramBox()->channel());
 
651
 
 
652
    // Refresh the current levels config.
 
653
    slotChannelChanged();
 
654
    d->levelsHistogramWidget->reset();
 
655
 
 
656
    slotEffect();
 
657
}
 
658
 
 
659
void AdjustLevelsTool::slotAutoLevels()
 
660
{
 
661
    // Calculate Auto levels.
 
662
    d->levels->levelsAuto(d->levelsHistogramWidget->currentHistogram());
 
663
 
 
664
    // Refresh the current levels config.
 
665
    slotChannelChanged();
 
666
 
 
667
    slotEffect();
 
668
}
 
669
 
 
670
void AdjustLevelsTool::slotChannelChanged()
 
671
{
 
672
    ChannelType channel = d->gboxSettings->histogramBox()->channel();
 
673
    d->levelsHistogramWidget->setChannelType(channel);
 
674
    switch (channel)
 
675
    {
 
676
        case RedChannel:
 
677
            d->inputLevels->setColors(QColor("black"), QColor("red"));
 
678
            d->outputLevels->setColors(QColor("black"), QColor("red"));
 
679
            break;
 
680
 
 
681
        case GreenChannel:
 
682
            d->inputLevels->setColors(QColor("black"), QColor("green"));
 
683
            d->outputLevels->setColors(QColor("black"), QColor("green"));
 
684
            break;
 
685
 
 
686
        case BlueChannel:
 
687
            d->inputLevels->setColors(QColor("black"), QColor("blue"));
 
688
            d->outputLevels->setColors(QColor("black"), QColor("blue"));
 
689
            break;
 
690
 
 
691
        default:
 
692
            d->inputLevels->setColors(QColor("black"), QColor("white"));
 
693
            d->outputLevels->setColors(QColor("black"), QColor("white"));
 
694
            break;
 
695
    }
 
696
 
 
697
    adjustSlidersAndSpinboxes(d->levels->getLevelLowInputValue(channel),
 
698
                              d->levels->getLevelGammaValue(channel),
 
699
                              d->levels->getLevelHighInputValue(channel),
 
700
                              d->levels->getLevelLowOutputValue(channel),
 
701
                              d->levels->getLevelHighOutputValue(channel));
 
702
 
 
703
}
 
704
 
 
705
void AdjustLevelsTool::slotScaleChanged()
 
706
{
 
707
    d->levelsHistogramWidget->setScaleType(d->gboxSettings->histogramBox()->scale());
 
708
}
 
709
 
 
710
void AdjustLevelsTool::readSettings()
 
711
{
 
712
    KSharedConfig::Ptr config = KGlobal::config();
 
713
    KConfigGroup group        = config->group(d->configGroupName);
 
714
 
 
715
    {
 
716
        bool sb        = d->originalImage->sixteenBit();
 
717
        int max        = sb ? 65535 : 255;
 
718
        double gamma   = 0.0;
 
719
        int lowInput   = 0;
 
720
        int lowOutput  = 0;
 
721
        int highInput  = 0;
 
722
        int highOutput = 0;
 
723
 
 
724
        for (int i = 0 ; i < 5 ; ++i)
 
725
        {
 
726
            gamma      = group.readEntry(d->configGammaChannelEntry.arg(i), 1.0);
 
727
            lowInput   = group.readEntry(d->configLowInputChannelEntry.arg(i), 0);
 
728
            lowOutput  = group.readEntry(d->configLowOutputChannelEntry.arg(i), 0);
 
729
            highInput  = group.readEntry(d->configHighInputChannelEntry.arg(i), max);
 
730
            highOutput = group.readEntry(d->configHighOutputChannelEntry.arg(i), max);
 
731
 
 
732
            d->levels->setLevelGammaValue(i, gamma);
 
733
            d->levels->setLevelLowInputValue(i, sb ? lowInput*255 : lowInput);
 
734
            d->levels->setLevelHighInputValue(i, sb ? highInput*255 : highInput);
 
735
            d->levels->setLevelLowOutputValue(i, sb ? lowOutput*255 : lowOutput);
 
736
            d->levels->setLevelHighOutputValue(i, sb ? highOutput*255 : highOutput);
 
737
        }
 
738
    }
 
739
 
 
740
    d->levelsHistogramWidget->reset();
 
741
    d->gboxSettings->histogramBox()->histogram()->reset();
 
742
 
 
743
    d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry,
 
744
                    (int)LuminosityChannel));
 
745
    d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry,
 
746
                    (int)LogScaleHistogram));
 
747
 
 
748
    // This is mandatory here to set spinbox values because slot connections
 
749
    // can be not set completely at plugin startup.
 
750
    d->minInput->setValue(d->levels->getLevelLowInputValue(d->gboxSettings->histogramBox()->channel()));
 
751
    d->minOutput->setValue(d->levels->getLevelLowOutputValue(d->gboxSettings->histogramBox()->channel()));
 
752
    d->maxInput->setValue(d->levels->getLevelHighInputValue(d->gboxSettings->histogramBox()->channel()));
 
753
    d->maxOutput->setValue(d->levels->getLevelHighOutputValue(d->gboxSettings->histogramBox()->channel()));
 
754
    slotChannelChanged();
 
755
    slotScaleChanged();
 
756
}
 
757
 
 
758
void AdjustLevelsTool::writeSettings()
 
759
{
 
760
    KSharedConfig::Ptr config = KGlobal::config();
 
761
    KConfigGroup group        = config->group(d->configGroupName);
 
762
    group.writeEntry(d->configHistogramChannelEntry, (int)d->gboxSettings->histogramBox()->channel());
 
763
    group.writeEntry(d->configHistogramScaleEntry,   (int)d->gboxSettings->histogramBox()->scale());
 
764
 
 
765
    {
 
766
        bool sb        = d->originalImage->sixteenBit();
 
767
        double gamma   = 0.0;
 
768
        int lowInput   = 0;
 
769
        int lowOutput  = 0;
 
770
        int highInput  = 0;
 
771
        int highOutput = 0;
 
772
 
 
773
        for (int i = 0 ; i < 5 ; ++i)
 
774
        {
 
775
            gamma      = d->levels->getLevelGammaValue(i);
 
776
            lowInput   = d->levels->getLevelLowInputValue(i);
 
777
            lowOutput  = d->levels->getLevelLowOutputValue(i);
 
778
            highInput  = d->levels->getLevelHighInputValue(i);
 
779
            highOutput = d->levels->getLevelHighOutputValue(i);
 
780
 
 
781
            group.writeEntry(d->configGammaChannelEntry.arg(i), gamma);
 
782
            group.writeEntry(d->configLowInputChannelEntry.arg(i), sb ? lowInput/255 : lowInput);
 
783
            group.writeEntry(d->configLowOutputChannelEntry.arg(i), sb ? lowOutput/255 : lowOutput);
 
784
            group.writeEntry(d->configHighInputChannelEntry.arg(i), sb ? highInput/255 : highInput);
 
785
            group.writeEntry(d->configHighOutputChannelEntry.arg(i), sb ? highOutput/255 : highOutput);
 
786
        }
 
787
    }
 
788
 
 
789
    config->sync();
 
790
}
 
791
 
 
792
void AdjustLevelsTool::slotResetSettings()
 
793
{
 
794
    for (int channel = 0 ; channel < 5 ; ++channel)
 
795
        d->levels->levelsChannelReset(channel);
 
796
 
 
797
    // Refresh the current levels config.
 
798
    slotChannelChanged();
 
799
    d->levelsHistogramWidget->reset();
 
800
 
 
801
    slotEffect();
 
802
}
 
803
 
 
804
void AdjustLevelsTool::prepareEffect()
 
805
{
 
806
    kapp->setOverrideCursor(Qt::WaitCursor);
 
807
    toolSettings()->setEnabled(false);
 
808
    toolView()->setEnabled(false);
 
809
 
 
810
    LevelsContainer settings;
 
811
    for (int i=0 ; i<5 ; ++i)
 
812
    {
 
813
        settings.lInput[i]  = d->levels->getLevelLowInputValue(i);
 
814
        settings.hInput[i]  = d->levels->getLevelHighInputValue(i);
 
815
        settings.lOutput[i] = d->levels->getLevelLowOutputValue(i);
 
816
        settings.hOutput[i] = d->levels->getLevelHighOutputValue(i);
 
817
        settings.gamma[i]   = d->levels->getLevelGammaValue(i);
 
818
    }
 
819
 
 
820
    d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation();
 
821
 
 
822
    DImg preview = d->previewWidget->getOriginalRegionImage(true);
 
823
    setFilter(new LevelsFilter(&preview, this, settings));
 
824
}
 
825
 
 
826
void AdjustLevelsTool::putPreviewData()
 
827
{
 
828
    DImg preview = filter()->getTargetImage();
 
829
    d->previewWidget->setPreviewImage(preview);
 
830
 
 
831
    // Update histogram.
 
832
 
 
833
    if (d->destinationPreviewData)
 
834
       delete [] d->destinationPreviewData;
 
835
 
 
836
    d->destinationPreviewData = preview.copyBits();
 
837
    d->gboxSettings->histogramBox()->histogram()->updateData(d->destinationPreviewData,
 
838
                                                             preview.width(), preview.height(), preview.sixteenBit(),
 
839
                                                             0, 0, 0, false);
 
840
}
 
841
 
 
842
void AdjustLevelsTool::prepareFinal()
 
843
{
 
844
    toolSettings()->setEnabled(false);
 
845
    toolView()->setEnabled(false);
 
846
 
 
847
    LevelsContainer settings;
 
848
    for (int i=0 ; i<5 ; ++i)
 
849
    {
 
850
        settings.lInput[i]  = d->levels->getLevelLowInputValue(i);
 
851
        settings.hInput[i]  = d->levels->getLevelHighInputValue(i);
 
852
        settings.lOutput[i] = d->levels->getLevelLowOutputValue(i);
 
853
        settings.hOutput[i] = d->levels->getLevelHighOutputValue(i);
 
854
        settings.gamma[i]   = d->levels->getLevelGammaValue(i);
 
855
    }
 
856
 
 
857
    ImageIface iface(0, 0);
 
858
    setFilter(new LevelsFilter(iface.getOriginalImg(), this, settings));
 
859
}
 
860
 
 
861
void AdjustLevelsTool::putFinalData()
 
862
{
 
863
    ImageIface iface(0, 0);
 
864
    iface.putOriginalImage(i18n("Adjust Levels"), filter()->getTargetImage().bits());
 
865
}
 
866
 
 
867
void AdjustLevelsTool::renderingFinished()
 
868
{
 
869
    kapp->restoreOverrideCursor();
 
870
    toolSettings()->setEnabled(true);
 
871
    toolView()->setEnabled(true);
 
872
}
 
873
 
 
874
void AdjustLevelsTool::slotLoadSettings()
 
875
{
 
876
    KUrl loadLevelsFile;
 
877
 
 
878
    loadLevelsFile = KFileDialog::getOpenUrl(KGlobalSettings::documentPath(),
 
879
                                             QString( "*" ), kapp->activeWindow(),
 
880
                                             QString( i18n("Select Gimp Levels File to Load")) );
 
881
    if ( loadLevelsFile.isEmpty() )
 
882
       return;
 
883
 
 
884
    if ( d->levels->loadLevelsFromGimpLevelsFile( loadLevelsFile ) == false )
 
885
    {
 
886
       KMessageBox::error(kapp->activeWindow(),
 
887
                          i18n("Cannot load from the Gimp levels text file."));
 
888
       return;
 
889
    }
 
890
 
 
891
    // Refresh the current levels config.
 
892
    slotChannelChanged();
 
893
 
 
894
    slotEffect();
 
895
}
 
896
 
 
897
void AdjustLevelsTool::slotSaveAsSettings()
 
898
{
 
899
    KUrl saveLevelsFile;
 
900
 
 
901
    saveLevelsFile = KFileDialog::getSaveUrl(KGlobalSettings::documentPath(),
 
902
                                             QString( "*" ), kapp->activeWindow(),
 
903
                                             QString( i18n("Gimp Levels File to Save")) );
 
904
    if ( saveLevelsFile.isEmpty() )
 
905
       return;
 
906
 
 
907
    if ( d->levels->saveLevelsToGimpLevelsFile( saveLevelsFile ) == false )
 
908
    {
 
909
       KMessageBox::error(kapp->activeWindow(),
 
910
                          i18n("Cannot save to the Gimp levels text file."));
 
911
       return;
 
912
    }
 
913
 
 
914
    // Refresh the current levels config.
 
915
    slotChannelChanged();
 
916
}
 
917
 
 
918
}  // namespace DigikamColorImagePlugin