QGIS API Documentation  3.13.0-Master (740be229cb)
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
double maxHistogramValueRange() const
Returns the maximum expected value for the range of values shown in the histogram.
#define SIP_TRANSFERTHIS
Definition: qgis_sip.h:53
QgsCurveTransform curve() const
Returns a curve representing the current curve from the widget.
A widget for manipulating QgsCurveTransform curves.
QPointF QwtDoublePoint
Calculator for a numeric histogram from a list of values.
Definition: qgshistogram.h:37
double minHistogramValueRange() const
Returns the minimum expected value for the range of values shown in the histogram.
Base class for feedback objects to be used for cancellation of something running in a worker thread...
Definition: qgsfeedback.h:45
#define SIP_SKIP
Definition: qgis_sip.h:126
Handles scaling of input values to output values by using a curve created from smoothly joining a num...
Represents a vector layer which manages a vector based data sets.