QGIS API Documentation  3.16.0-Hannover (43b64b13f3)
qgscurveeditorwidget.h
Go to the documentation of this file.
1 /***************************************************************************
2  qgscurveeditorwidget.h
3  ----------------------
4  begin : February 2017
5  copyright : (C) 2017 by Nyall Dawson
6  email : nyall dot dawson at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #ifndef QGSCURVEEDITORWIDGET_H
17 #define QGSCURVEEDITORWIDGET_H
18 
19 #include <QWidget>
20 #include "qgis_sip.h"
21 #include <QThread>
22 #include <QMutex>
23 #include <QPen>
24 #include <QPointer>
25 #include <qwt_global.h>
26 #include "qgis_gui.h"
27 #include "qgspropertytransformer.h"
28 #include "qgshistogram.h"
29 #include "qgsvectorlayer.h"
30 
31 class QwtPlot;
32 class QwtPlotCurve;
33 class QwtPlotMarker;
34 class QwtPlotHistogram;
35 class HistogramItem;
36 class QgsCurveEditorPlotEventFilter;
37 
38 // fix for qwt5/qwt6 QwtDoublePoint vs. QPointF
39 typedef QPointF QwtDoublePoint SIP_SKIP;
40 
41 #ifndef SIP_RUN
42 
43 // just internal guff - definitely not for exposing to public API!
45 
51 class QgsHistogramValuesGatherer: public QThread
52 {
53  Q_OBJECT
54 
55  public:
56  QgsHistogramValuesGatherer() = default;
57 
58  void run() override
59  {
60  mWasCanceled = false;
61  if ( mExpression.isEmpty() || !mLayer )
62  {
63  mHistogram.setValues( QList<double>() );
64  return;
65  }
66 
67  // allow responsive cancellation
68  mFeedback = new QgsFeedback();
69 
70  mHistogram.setValues( mLayer, mExpression, mFeedback );
71 
72  // be overly cautious - it's *possible* stop() might be called between deleting mFeedback and nulling it
73  mFeedbackMutex.lock();
74  delete mFeedback;
75  mFeedback = nullptr;
76  mFeedbackMutex.unlock();
77 
78  emit calculatedHistogram();
79  }
80 
82  void stop()
83  {
84  // be cautious, in case gatherer stops naturally just as we are canceling it and mFeedback gets deleted
85  mFeedbackMutex.lock();
86  if ( mFeedback )
87  mFeedback->cancel();
88  mFeedbackMutex.unlock();
89 
90  mWasCanceled = true;
91  }
92 
94  bool wasCanceled() const { return mWasCanceled; }
95 
96  const QgsHistogram &histogram() const { return mHistogram; }
97 
98  const QgsVectorLayer *layer() const
99  {
100  return mLayer;
101  }
102  void setLayer( const QgsVectorLayer *layer )
103  {
104  mLayer = const_cast< QgsVectorLayer * >( layer );
105  }
106 
107  QString expression() const
108  {
109  return mExpression;
110  }
111  void setExpression( const QString &expression )
112  {
113  mExpression = expression;
114  }
115 
116  signals:
117 
121  void calculatedHistogram();
122 
123  private:
124 
125  QPointer< const QgsVectorLayer > mLayer = nullptr;
126  QString mExpression;
127  QgsHistogram mHistogram;
128  QgsFeedback *mFeedback = nullptr;
129  QMutex mFeedbackMutex;
130  bool mWasCanceled = false;
131 };
132 
134 
135 #endif
136 
143 class GUI_EXPORT QgsCurveEditorWidget : public QWidget
144 {
145  Q_OBJECT
146 
147  public:
148 
152  QgsCurveEditorWidget( QWidget *parent SIP_TRANSFERTHIS = nullptr, const QgsCurveTransform &curve = QgsCurveTransform() );
153 
154  ~QgsCurveEditorWidget() override;
155 
160  QgsCurveTransform curve() const { return mCurve; }
161 
166  void setCurve( const QgsCurveTransform &curve );
167 
175  void setHistogramSource( const QgsVectorLayer *layer, const QString &expression );
176 
182  double minHistogramValueRange() const { return mMinValueRange; }
183 
189  double maxHistogramValueRange() const { return mMaxValueRange; }
190 
191  public slots:
192 
198  void setMinHistogramValueRange( double minValueRange );
199 
205  void setMaxHistogramValueRange( double maxValueRange );
206 
207  signals:
208 
210  void changed();
211 
212  protected:
213 
214  void keyPressEvent( QKeyEvent *event ) override;
215 
216  private slots:
217 
218  void plotMousePress( QPointF point );
219  void plotMouseRelease( QPointF point );
220  void plotMouseMove( QPointF point );
221 
222  private:
223 
224  QgsCurveTransform mCurve;
225 
226  QwtPlot *mPlot = nullptr;
227 
228  QwtPlotCurve *mPlotCurve = nullptr;
229 
230  QList< QwtPlotMarker * > mMarkers;
231  QgsCurveEditorPlotEventFilter *mPlotFilter = nullptr;
232  int mCurrentPlotMarkerIndex = -1;
234  std::unique_ptr< QgsHistogramValuesGatherer > mGatherer;
235  std::unique_ptr< QgsHistogram > mHistogram;
236  double mMinValueRange = 0.0;
237  double mMaxValueRange = 1.0;
238 
239  QwtPlotHistogram *mPlotHistogram = nullptr;
240 
241  void updatePlot();
242  void addPlotMarker( double x, double y, bool isSelected = false );
243  void updateHistogram();
244 
245  int findNearestControlPoint( QPointF point ) const;
246 
247  QwtPlotHistogram *createPlotHistogram( const QBrush &brush, const QPen &pen = Qt::NoPen ) const;
248 
249 };
250 
251 
252 
253 
254 #ifndef SIP_RUN
255 //
256 // NOTE:
257 // For private only, not part of stable api or exposed to Python bindings
258 //
260 class GUI_EXPORT QgsCurveEditorPlotEventFilter: public QObject
261 {
262  Q_OBJECT
263 
264  public:
265 
266  QgsCurveEditorPlotEventFilter( QwtPlot *plot );
267 
268  bool eventFilter( QObject *object, QEvent *event ) override;
269 
270  signals:
271 
272  void mousePress( QPointF );
273  void mouseRelease( QPointF );
274  void mouseMove( QPointF );
275 
276  private:
277 
278  QwtPlot *mPlot = nullptr;
279  QPointF mapPoint( QPointF point ) const;
280 };
282 #endif
283 
284 #endif // QGSCURVEEDITORWIDGET_H
QgsCurveEditorWidget::minHistogramValueRange
double minHistogramValueRange() const
Returns the minimum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.h:182
qgspropertytransformer.h
qgshistogram.h
QwtDoublePoint
QPointF QwtDoublePoint
Definition: qgscurveeditorwidget.h:36
SIP_SKIP
#define SIP_SKIP
Definition: qgis_sip.h:126
QgsCurveEditorWidget::changed
void changed()
Emitted when the widget curve changes.
QgsCurveEditorWidget::curve
QgsCurveTransform curve() const
Returns a curve representing the current curve from the widget.
Definition: qgscurveeditorwidget.h:160
QgsFeedback
Base class for feedback objects to be used for cancellation of something running in a worker thread.
Definition: qgsfeedback.h:44
qgis_sip.h
QgsCurveEditorWidget::maxHistogramValueRange
double maxHistogramValueRange() const
Returns the maximum expected value for the range of values shown in the histogram.
Definition: qgscurveeditorwidget.h:189
QgsCurveEditorWidget
A widget for manipulating QgsCurveTransform curves.
Definition: qgscurveeditorwidget.h:144
QgsCurveTransform
Handles scaling of input values to output values by using a curve created from smoothly joining a num...
Definition: qgspropertytransformer.h:57
qgsvectorlayer.h
QgsHistogram
Calculator for a numeric histogram from a list of values.
Definition: qgshistogram.h:38
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:387
SIP_TRANSFERTHIS
#define SIP_TRANSFERTHIS
Definition: qgis_sip.h:53