Engauge Digitizer  2
DlgSettingsColorFilter.cpp
1 #include "CmdMediator.h"
2 #include "CmdSettingsColorFilter.h"
3 #include "ColorFilter.h"
4 #include "ColorFilterHistogram.h"
5 #include "ColorConstants.h"
6 #include "DlgFilterThread.h"
7 #include "DlgSettingsColorFilter.h"
8 #include "EngaugeAssert.h"
9 #include "Logger.h"
10 #include "MainWindow.h"
11 #include <QComboBox>
12 #include <QDebug>
13 #include <QGraphicsLineItem>
14 #include <QGraphicsScene>
15 #include <QGridLayout>
16 #include <QImage>
17 #include <QLabel>
18 #include <qmath.h>
19 #include <QPixmap>
20 #include <QRadioButton>
21 #include <QRgb>
22 #include "ViewPreview.h"
23 #include "ViewProfile.h"
24 #include "ViewProfileDivider.h"
25 #include "ViewProfileScale.h"
26 
28  DlgSettingsAbstractBase ("Filter",
29  "DlgSettingsColorFilter",
30  mainWindow),
31  m_scenePreview (0),
32  m_viewPreview (0),
33  m_filterThread (0),
34  m_modelColorFilterBefore (0),
35  m_modelColorFilterAfter (0)
36 {
37  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::DlgSettingsColorFilter";
38 
39  QWidget *subPanel = createSubPanel ();
40  finishPanel (subPanel);
41 }
42 
43 DlgSettingsColorFilter::~DlgSettingsColorFilter()
44 {
45  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::~DlgSettingsColorFilter";
46 }
47 
48 void DlgSettingsColorFilter::createControls (QGridLayout *layout, int &row)
49 {
50  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createControls";
51 
52  QLabel *labelCurve = new QLabel ("Curve Name:");
53  layout->addWidget (labelCurve, row++, 1);
54 
55  m_cmbCurveName = new QComboBox ();
56  m_cmbCurveName->setWhatsThis (tr ("Name of the curve that is currently selected for editing"));
57  connect (m_cmbCurveName, SIGNAL (activated (const QString &)), this, SLOT (slotCurveName (const QString &))); // activated() ignores code changes
58  layout->addWidget (m_cmbCurveName, row++, 1);
59 
60  QLabel *labelProfile = new QLabel ("Filter mode:");
61  layout->addWidget (labelProfile, row++, 1);
62 
63  m_btnIntensity = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_INTENSITY));
64  m_btnIntensity->setWhatsThis (tr ("Filter the original image into black and white pixels using the Intensity parameter, "
65  "to hide unimportant information and emphasize important information.\n\n"
66  "The Intensity value of a pixel is computed from the red, green "
67  "and blue components as I = squareroot (R * R + G * G + B * B)"));
68  connect (m_btnIntensity, SIGNAL (released ()), this, SLOT (slotIntensity ()));
69  layout->addWidget (m_btnIntensity, row++, 1);
70 
71  m_btnForeground = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_FOREGROUND));
72  m_btnForeground->setWhatsThis (tr ("Filter the original image into black and white pixels by isolating the foreground from the background, "
73  "to hide unimportant information and emphasize important information.\n\n"
74  "The background color is shown on the left side of the scale bar.\n\n"
75  "The distance of any color (R, G, B) from the background color (Rb, Gb, Bb) is computed as "
76  "F = squareroot ((R - Rb) * (R - Rb) + (G - Gb) * (G - Gb) + (B - Bb)). On the left end of the "
77  "scale, the foreground distance value is zero, and it increases linearly to the maximum on the far right."));
78  connect (m_btnForeground, SIGNAL (released ()), this, SLOT (slotForeground ()));
79  layout->addWidget (m_btnForeground, row++, 1);
80 
81  m_btnHue = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_HUE));
82  m_btnHue->setWhatsThis (tr ("Filter the original image into black and white pixels using the Hue component of the "
83  "Hue, Saturation and Value (HSV) color components, "
84  "to hide unimportant information and emphasize important information."));
85  connect (m_btnHue, SIGNAL (released ()), this, SLOT (slotHue ()));
86  layout->addWidget (m_btnHue, row++, 1);
87 
88  m_btnSaturation = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_SATURATION));
89  m_btnSaturation->setWhatsThis (tr ("Filter the original image into black and white pixels using the Saturation component of the "
90  "Hue, Saturation and Value (HSV) color components, "
91  "to hide unimportant information and emphasize important information."));
92  connect (m_btnSaturation, SIGNAL (released ()), this, SLOT (slotSaturation ()));
93  layout->addWidget (m_btnSaturation, row++, 1);
94 
95  m_btnValue = new QRadioButton (colorFilterModeToString (COLOR_FILTER_MODE_VALUE));
96  m_btnValue->setWhatsThis (tr ("Filter the original image into black and white pixels using the Value component of the "
97  "Hue, Saturation and Value (HSV) color components, "
98  "to hide unimportant information and emphasize important information.\n\n"
99  "The Value component is also called the Lightness."));
100  connect (m_btnValue, SIGNAL (released ()), this, SLOT (slotValue ()));
101  layout->addWidget (m_btnValue, row++, 1);
102 }
103 
104 void DlgSettingsColorFilter::createOptionalSaveDefault (QHBoxLayout * /* layout */)
105 {
106 }
107 
108 void DlgSettingsColorFilter::createPreview (QGridLayout *layout, int &row)
109 {
110  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createPreview";
111 
112  QLabel *labelPreview = new QLabel ("Preview");
113  layout->addWidget (labelPreview, row++, 0, 1, 5);
114 
115  m_scenePreview = new QGraphicsScene (this);
116  m_viewPreview = new ViewPreview (m_scenePreview,
117  ViewPreview::VIEW_ASPECT_RATIO_VARIABLE,
118  this);
119  m_viewPreview->setWhatsThis (tr ("Preview window that shows how current settings affect the filtering of the original image."));
120  m_viewPreview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
121  m_viewPreview->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
122  m_viewPreview->setMinimumHeight (MINIMUM_PREVIEW_HEIGHT);
123  m_viewPreview->setRenderHint(QPainter::Antialiasing);
124 
125  layout->addWidget (m_viewPreview, row++, 0, 1, 5);
126 }
127 
128 void DlgSettingsColorFilter::createProfileAndScale (QGridLayout *layout, int &row)
129 {
130  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createProfileAndScale";
131 
132  const int MINIMUM_VIEW_PROFILE_WIDTH = 70;
133 
134  QLabel *labelProfile = new QLabel ("Filter Parameter Histogram Profile");
135  layout->addWidget (labelProfile, row++, 3);
136 
137  m_sceneProfile = new QGraphicsScene;
138  m_sceneProfile->setSceneRect(0, 0, PROFILE_SCENE_WIDTH (), PROFILE_SCENE_HEIGHT ());
139 
140  m_viewProfile = new ViewProfile (m_sceneProfile,
141  MINIMUM_VIEW_PROFILE_WIDTH);
142  m_viewProfile->setWhatsThis (tr ("Histogram profile of the selected filter parameter. The two Dividers can be moved back and forth to adjust "
143  "the range of filter parameter values that will be included in the filtered image. The clear portion will "
144  "be included, and the shaded portion will be excluded."));
145  layout->addWidget (m_viewProfile, row, 3, PROFILE_HEIGHT_IN_ROWS (), 1);
146  row += PROFILE_HEIGHT_IN_ROWS ();
147 
148  m_scale = new ViewProfileScale (MINIMUM_VIEW_PROFILE_WIDTH);
149  m_scale->setWhatsThis (tr ("This read-only box displays a graphical representation of the horizontal axis in the histogram profile above."));
150  m_scale->setAutoFillBackground(true);
151  layout->addWidget (m_scale, row++, 3, 1, 1);
152 }
153 
155 {
156  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createSubPanel";
157 
158  const int EMPTY_COLUMN_WIDTH = 40;
159 
160  QWidget *subPanel = new QWidget ();
161  QGridLayout *layout = new QGridLayout (subPanel);
162  subPanel->setLayout (layout);
163 
164  layout->setColumnStretch(0, 0); // Empty column
165  layout->setColumnMinimumWidth(0, EMPTY_COLUMN_WIDTH);
166  layout->setColumnStretch(1, 0); // Radio buttons
167  layout->setColumnMinimumWidth(1, 210);
168  layout->setColumnStretch(2, 0); // Empty column to put some space between previous and next columns, so they are not too close
169  layout->setColumnMinimumWidth(2, 15);
170  layout->setColumnStretch(3, 1); // Profile
171  layout->setColumnMinimumWidth(4, EMPTY_COLUMN_WIDTH); // Empty column
172  layout->setColumnStretch(4, 0);
173 
174  int rowLeft = 0, rowRight = 0;
175  createControls (layout, rowLeft);
176  createProfileAndScale (layout, rowRight);
177 
178  int row = qMax (rowLeft, rowRight);
179  createPreview (layout, row);
180 
181  return subPanel;
182 }
183 
184 QRgb DlgSettingsColorFilter::createThread ()
185 {
186  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::createThread";
187 
188  // Get background color
189  QImage image = cmdMediator().document().pixmap().toImage();
190  ColorFilter filter;
191  QRgb rgbBackground = filter.marginColor(&image);
192 
193  // Only create thread once
194  if (m_filterThread == 0) {
195 
196  m_filterThread = new DlgFilterThread (cmdMediator().document().pixmap(),
197  rgbBackground,
198  *this);
199  m_filterThread->start(); // Now that thread is started, we can use signalApplyFilter
200  }
201 
202  return rgbBackground;
203 }
204 
206 {
207  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::handleOk";
208 
210  cmdMediator ().document(),
211  *m_modelColorFilterBefore,
212  *m_modelColorFilterAfter);
213  cmdMediator ().push (cmd);
214 
215  hide ();
216 }
217 
219 {
220  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::load";
221 
222  setCmdMediator (cmdMediator);
223 
224  // Flush old data
225  if (m_modelColorFilterBefore != 0) {
226  delete m_modelColorFilterBefore;
227  }
228  if (m_modelColorFilterAfter != 0) {
229  delete m_modelColorFilterAfter;
230  }
231 
232  // Save new data
233  m_modelColorFilterBefore = new DocumentModelColorFilter (cmdMediator.document());
234  m_modelColorFilterAfter = new DocumentModelColorFilter (cmdMediator.document());
235 
236  // Populate controls. First load curve name combobox. The curve-specific controls get loaded in slotCurveName
237  m_cmbCurveName->clear ();
238  m_cmbCurveName->addItem (AXIS_CURVE_NAME);
239  QStringList curveNames = cmdMediator.curvesGraphsNames();
240  QStringList::const_iterator itr;
241  for (itr = curveNames.begin (); itr != curveNames.end (); itr++) {
242 
243  QString curveName = *itr;
244  m_cmbCurveName->addItem (curveName);
245  }
246 
247  // This sets the curve name
248  m_cmbCurveName->setCurrentText (mainWindow().selectedGraphCurve());
249  loadForCurveName();
250 
251  enableOk (false); // Disable Ok button since there not yet any changes
252 }
253 
254 void DlgSettingsColorFilter::loadForCurveName()
255 {
256  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::loadForCurveName";
257 
258  // Get curve name from control
259  QString curveName = m_cmbCurveName->currentText();
260 
261  // Skip if everything is not set up yet
262  if (!curveName.isEmpty () && m_modelColorFilterAfter != 0) {
263 
264  // Populate controls
265  ColorFilterMode colorFilterMode = m_modelColorFilterAfter->colorFilterMode(curveName);
266  m_btnIntensity->setChecked (colorFilterMode == COLOR_FILTER_MODE_INTENSITY);
267  m_btnForeground->setChecked (colorFilterMode == COLOR_FILTER_MODE_FOREGROUND);
268  m_btnHue->setChecked (colorFilterMode == COLOR_FILTER_MODE_HUE);
269  m_btnSaturation->setChecked (colorFilterMode == COLOR_FILTER_MODE_SATURATION);
270  m_btnValue->setChecked (colorFilterMode == COLOR_FILTER_MODE_VALUE);
271 
272  m_scenePreview->clear();
273  m_imagePreview = cmdMediator().document().pixmap().toImage();
274  m_scenePreview->addPixmap (QPixmap::fromImage (m_imagePreview));
275 
276  QRgb rgbBackground = createThread ();
277  m_scale->setBackgroundColor (rgbBackground);
278  createThread ();
279  updateHistogram();
280  updatePreview(); // Needs thread initialized
281  }
282 }
283 
284 void DlgSettingsColorFilter::slotCurveName(const QString & /* curveName */)
285 {
286  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotCurveName";
287 
288  loadForCurveName ();
289 }
290 
291 void DlgSettingsColorFilter::slotDividerHigh (double xCenter)
292 {
293  m_modelColorFilterAfter->setHigh (m_cmbCurveName->currentText(),
294  xCenter / (double) PROFILE_SCENE_WIDTH ());
295  updatePreview();
296 }
297 
298 void DlgSettingsColorFilter::slotDividerLow (double xCenter)
299 {
300  m_modelColorFilterAfter->setLow (m_cmbCurveName->currentText(),
301  xCenter / (double) PROFILE_SCENE_WIDTH ());
302  updatePreview();
303 }
304 
305 void DlgSettingsColorFilter::slotForeground ()
306 {
307  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotForeground";
308 
309  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
310  COLOR_FILTER_MODE_FOREGROUND);
311  updateHistogram();
312  updatePreview();
313 }
314 
315 void DlgSettingsColorFilter::slotHue ()
316 {
317  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotHue";
318 
319  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
320  COLOR_FILTER_MODE_HUE);
321  updateHistogram();
322  updatePreview();
323 }
324 
325 void DlgSettingsColorFilter::slotIntensity ()
326 {
327  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotIntensity";
328 
329  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
330  COLOR_FILTER_MODE_INTENSITY);
331  updateHistogram();
332  updatePreview();
333 }
334 
335 void DlgSettingsColorFilter::slotSaturation ()
336 {
337  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotSaturation";
338 
339  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
340  COLOR_FILTER_MODE_SATURATION);
341  updateHistogram();
342  updatePreview();
343 }
344 
346  QImage image)
347 {
348  // Overwrite one piece of the processed image. This approach is a bit slow because the entire QPixmap
349  // in the QGraphicsScene gets exchanged as part of each update, but that seems to be the only possible
350  // approach when using QGraphicsScene. If not fast enough or there is ugly flicker, we may replace
351  // QGraphicsScene by a simple QWidget and override the paint function - but that approach may get
352  // complicated when resizing the QGraphicsView
353  for (int xFrom = 0, xTo = xLeft; xFrom < image.width(); xFrom++, xTo++) {
354  for (int y = 0; y < image.height (); y++) {
355 
356  QColor pixel = image.pixel (xFrom, y);
357  m_imagePreview.setPixel (xTo, y, pixel.rgb());
358  }
359  }
360 
361  // Remove old pixmap
362  QGraphicsItem *itemPixmap = m_scenePreview->items().at(0);
363  m_scenePreview->removeItem (itemPixmap);
364  delete itemPixmap;
365 
366  // Save new pixmap. Only visible change should be the area covered by the pixels in image
367  m_scenePreview->addPixmap (QPixmap::fromImage (m_imagePreview));
368 }
369 
370 void DlgSettingsColorFilter::slotValue ()
371 {
372  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::slotValue";
373 
374  m_modelColorFilterAfter->setColorFilterMode(m_cmbCurveName->currentText(),
375  COLOR_FILTER_MODE_VALUE);
376  updateHistogram();
377  updatePreview();
378 }
379 
380 void DlgSettingsColorFilter::updateHistogram()
381 {
382  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettingsColorFilter::updateHistogram";
383 
384  enableOk (true);
385 
386  const double PEN_WIDTH = 0.0; // Zero value gives one-pixel width at all scales
387 
388  QString curveName = m_cmbCurveName->currentText();
389 
390  m_sceneProfile->clear();
391 
392  m_scale->setColorFilterMode (m_modelColorFilterAfter->colorFilterMode(curveName));
393 
394  // Start with original image
395  QImage image = cmdMediator().document().pixmap().toImage();
396 
397  double *histogramBins = new double [ColorFilterHistogram::HISTOGRAM_BINS ()];
398 
399  ColorFilter filter;
400  ColorFilterHistogram filterHistogram;
401  int maxBinCount;
402  filterHistogram.generate (filter,
403  histogramBins,
404  m_modelColorFilterAfter->colorFilterMode (curveName),
405  image,
406  maxBinCount);
407 
408  // Draw histogram, normalizing so highest peak exactly fills the vertical range. Log scale is used
409  // so smaller peaks do not disappear
410  double logMaxBinCount = qLn (maxBinCount);
411  for (int bin = 1; bin < ColorFilterHistogram::HISTOGRAM_BINS (); bin++) {
412 
413  double x0 = PROFILE_SCENE_WIDTH () * (bin - 1.0) / (ColorFilterHistogram::HISTOGRAM_BINS () - 1.0);
414 
415  // Map logPixelCount through 0 to 0 through PROFILE_SCENE_HEIGHT-1, using log scale
416  double count0 = 1.0 + histogramBins [bin - 1];
417  double y0 = (PROFILE_SCENE_HEIGHT () - 1.0) * (1.0 - qLn (count0) / logMaxBinCount);
418 
419  double x1 = PROFILE_SCENE_WIDTH () * (bin - 0.0) / (ColorFilterHistogram::HISTOGRAM_BINS () - 1.0);
420 
421  // Map logPixelCount through 0 to 0 through PROFILE_SCENE_HEIGHT-1, using log scale
422  double count1 = 1.0 + histogramBins [bin];
423  double y1 = (PROFILE_SCENE_HEIGHT () - 1.0) * (1.0 - qLn (count1) / logMaxBinCount);
424 
425  QGraphicsLineItem *line = new QGraphicsLineItem (x0, y0, x1, y1);
426  line->setPen (QPen (QBrush (Qt::black), PEN_WIDTH));
427  m_sceneProfile->addItem (line);
428  }
429 
430  // Create low and high dividers
431  m_dividerLow = new ViewProfileDivider(*m_sceneProfile,
432  *m_viewProfile,
433  PROFILE_SCENE_WIDTH (),
434  PROFILE_SCENE_HEIGHT (),
435  PROFILE_SCENE_HEIGHT () * 2.0 / 3.0,
436  true);
437  m_dividerHigh = new ViewProfileDivider(*m_sceneProfile,
438  *m_viewProfile,
439  PROFILE_SCENE_HEIGHT (),
440  PROFILE_SCENE_WIDTH (),
441  PROFILE_SCENE_HEIGHT () / 3.0,
442  false);
443 
444  // Connect the dividers to each other since the shaded areas depend on both divides when low divider is
445  // moved to the right of the high divider
446  connect (m_dividerLow, SIGNAL (signalMovedLow (double)), m_dividerHigh, SLOT (slotOtherMoved(double)));
447  connect (m_dividerHigh, SIGNAL (signalMovedHigh (double)), m_dividerLow, SLOT (slotOtherMoved(double)));
448 
449  // Update preview when the dividers move
450  connect (m_dividerLow, SIGNAL (signalMovedLow (double)), this, SLOT (slotDividerLow (double)));
451  connect (m_dividerHigh, SIGNAL(signalMovedHigh (double)), this, SLOT (slotDividerHigh (double)));
452 
453  if (m_btnForeground->isChecked()) {
454 
455  // Foreground
456  m_dividerLow->setX (m_modelColorFilterAfter->foregroundLow(curveName), FOREGROUND_MIN, FOREGROUND_MAX);
457  m_dividerHigh->setX (m_modelColorFilterAfter->foregroundHigh(curveName), FOREGROUND_MIN, FOREGROUND_MAX);
458 
459  } else if (m_btnIntensity->isChecked()) {
460 
461  // Intensity
462  m_dividerLow->setX (m_modelColorFilterAfter->intensityLow(curveName), INTENSITY_MIN, INTENSITY_MAX);
463  m_dividerHigh->setX (m_modelColorFilterAfter->intensityHigh(curveName), INTENSITY_MIN, INTENSITY_MAX);
464 
465  } else if (m_btnHue->isChecked()) {
466 
467  // Hue
468  m_dividerLow->setX (m_modelColorFilterAfter->hueLow(curveName), HUE_MIN, HUE_MAX);
469  m_dividerHigh->setX (m_modelColorFilterAfter->hueHigh(curveName), HUE_MIN, HUE_MAX);
470 
471  } else if (m_btnSaturation->isChecked()) {
472 
473  // Saturation
474  m_dividerLow->setX (m_modelColorFilterAfter->saturationLow(curveName), SATURATION_MIN, SATURATION_MAX);
475  m_dividerHigh->setX (m_modelColorFilterAfter->saturationHigh(curveName), SATURATION_MIN, SATURATION_MAX);
476 
477  } else if (m_btnValue->isChecked()) {
478 
479  // Value
480  m_dividerLow->setX (m_modelColorFilterAfter->valueLow(curveName), VALUE_MIN, VALUE_MAX);
481  m_dividerHigh->setX (m_modelColorFilterAfter->valueHigh(curveName), VALUE_MIN, VALUE_MAX);
482 
483  } else {
484 
485  ENGAUGE_ASSERT (false);
486 
487  }
488 
489  free (histogramBins);
490 }
491 
492 void DlgSettingsColorFilter::updatePreview ()
493 {
494  LOG4CPP_INFO_S ((*mainCat)) << "DlgSettings::updatePreview";
495 
496  enableOk (true);
497 
498  // This (indirectly) updates the preview
499  QString curveName = m_cmbCurveName->currentText();
500  emit signalApplyFilter (m_modelColorFilterAfter->colorFilterMode(curveName),
501  m_modelColorFilterAfter->low(curveName),
502  m_modelColorFilterAfter->high(curveName));
503 }
void setBackgroundColor(QRgb rgbBackground)
Save the background color for foreground calculations.
int valueHigh(const QString &curveName) const
Get method for value high.
void generate(const ColorFilter &filter, double histogramBins[], ColorFilterMode colorFilterMode, const QImage &image, int &maxBinCount) const
Generate the histogram.
void setColorFilterMode(const QString &curveName, ColorFilterMode colorFilterMode)
Set method for filter mode.
int saturationLow(const QString &curveName) const
Get method for saturation lower bound.
void setX(double x, double xLow, double xHigh)
Set the position by specifying the new x coordinate.
void setCmdMediator(CmdMediator &cmdMediator)
Store CmdMediator for easy access by the leaf class.
int valueLow(const QString &curveName) const
Get method for value low.
QPixmap pixmap() const
Return the image that is being digitized.
Definition: Document.cpp:721
Document & document()
Provide the Document to commands, primarily for undo/redo processing.
Definition: CmdMediator.cpp:61
Class for filtering image to remove unimportant information.
Definition: ColorFilter.h:12
void slotTransferPiece(int xLeft, QImage image)
Receive processed piece of preview image, to be inserted at xLeft to xLeft+pixmap.width().
virtual void handleOk()
Process slotOk.
int foregroundLow(const QString &curveName) const
Get method for foreground lower bound.
int intensityLow(const QString &curveName) const
Get method for intensity lower bound.
void signalApplyFilter(ColorFilterMode colorFilterMode, double low, double high)
Send filter parameters to DlgFilterThread and DlgFilterWorker for processing.
double low(const QString &curveName) const
Low value of foreground, hue, intensity, saturation or value according to current filter mode normali...
virtual void load(CmdMediator &cmdMediator)
Load settings from Document.
void setHigh(const QString &curveName, double s0To1)
Set the high value for the current filter mode.
Class that modifies QGraphicsView to automatically expand/shrink the view to fit the window...
Definition: ViewPreview.h:8
Model for DlgSettingsColorFilter and CmdSettingsColorFilter.
int hueLow(const QString &curveName) const
Get method for hue lower bound.
Linear horizontal scale, with the spectrum reflecting the active filter parameter.
double high(const QString &curveName) const
High value of foreground, hue, intensity, saturation or value according to current filter mode...
QRgb marginColor(const QImage *image) const
Identify the margin color of the image, which is defined as the most common color in the four margins...
Definition: ColorFilter.cpp:52
int hueHigh(const QString &curveName) const
Get method for hue higher bound.
void setColorFilterMode(ColorFilterMode colorFilterMode)
Change the gradient type.
int foregroundHigh(const QString &curveName) const
Get method for foreground higher bound.
Divider that can be dragged, in a dialog QGraphicsView.
ColorFilterMode colorFilterMode(const QString &curveName) const
Get method for filter mode.
Class for processing new filter settings. This is based on http://blog.debao.me/2013/08/how-to-use-qt...
void setLow(const QString &curveName, double s0To1)
Set the low value for the current filter mode.
Command for DlgSettingsColorFilter.
void finishPanel(QWidget *subPanel)
Add Ok and Cancel buttons to subpanel to get the whole dialog.
virtual void createOptionalSaveDefault(QHBoxLayout *layout)
Let subclass define an optional Save As Default button.
virtual QWidget * createSubPanel()
Create dialog-specific panel to which base class will add Ok and Cancel buttons.
static int MINIMUM_PREVIEW_HEIGHT
Dialog layout constant that guarantees preview has sufficent room.
void enableOk(bool enable)
Let leaf subclass control the Ok button.
Command queue stack.
Definition: CmdMediator.h:16
DlgSettingsColorFilter(MainWindow &mainWindow)
Single constructor.
Abstract base class for all Settings dialogs.
int intensityHigh(const QString &curveName) const
Get method for intensity higher bound.
Class that generates a histogram according to the current filter.
Class that modifies QGraphicsView to present a two-dimensional profile, with movable dividers for sel...
Definition: ViewProfile.h:9
static int HISTOGRAM_BINS()
Number of histogram bins.
MainWindow & mainWindow()
Get method for MainWindow.
Main window consisting of menu, graphics scene, status bar and optional toolbars as a Single Document...
Definition: MainWindow.h:66
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition: CmdMediator.cpp:51
int saturationHigh(const QString &curveName) const
Get method for saturation higher bound.
CmdMediator & cmdMediator()
Provide access to Document information wrapped inside CmdMediator.