Moved some common include files to public headers folder

This commit is contained in:
matlabbe
2015-08-25 10:32:27 -04:00
parent 0ac79d0e8f
commit 0cf1ea8777
39 changed files with 103 additions and 89 deletions

View File

@@ -0,0 +1,181 @@
/*
* utilite is a cross-platform library with
* useful utilities for fast and small developing.
* Copyright (C) 2010 Mathieu Labbe
*
* utilite is free library: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* utilite is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UCV2QT_H_
#define UCV2QT_H_
#include <QtGui/QImage>
#include <opencv2/core/core.hpp>
#include <rtabmap/utilite/UMath.h>
#include <rtabmap/utilite/UThread.h>
#include <stdio.h>
/**
* Convert a cv::Mat image to a QImage. Support
* depth (float32, uint16) image and RGB/BGR 8bits images.
* @param image the cv::Mat image (can be 1 channel [CV_8U, CV_16U or CV_32F] or 3 channels [CV_U8])
* @param isBgr if 3 channels, it is BGR or RGB order.
* @return the QImage
*/
inline QImage uCvMat2QImage(const cv::Mat & image, bool isBgr = true)
{
QImage qtemp;
if(!image.empty() && image.depth() == CV_8U)
{
if(image.channels()==3)
{
const unsigned char * data = image.data;
if(image.channels() == 3)
{
qtemp = QImage(image.cols, image.rows, QImage::Format_RGB32);
for(int y = 0; y < image.rows; ++y, data += image.cols*image.elemSize())
{
for(int x = 0; x < image.cols; ++x)
{
QRgb * p = ((QRgb*)qtemp.scanLine (y)) + x;
if(isBgr)
{
*p = qRgb(data[x * image.channels()+2], data[x * image.channels()+1], data[x * image.channels()]);
}
else
{
*p = qRgb(data[x * image.channels()], data[x * image.channels()+1], data[x * image.channels()+2]);
}
}
}
}
}
else if(image.channels() == 1)
{
// mono grayscale
qtemp = QImage(image.data, image.cols, image.rows, image.cols, QImage::Format_Indexed8).copy();
QVector<QRgb> my_table;
for(int i = 0; i < 256; i++) my_table.push_back(qRgb(i,i,i));
qtemp.setColorTable(my_table);
}
else
{
printf("Wrong image format, must have 1 or 3 channels\n");
}
}
else if(image.depth() == CV_32F && image.channels()==1)
{
// Assume depth image (float in meters)
const float * data = (const float *)image.data;
float min=0, max=0;
uMinMax(data, image.rows*image.cols, min, max);
qtemp = QImage(image.cols, image.rows, QImage::Format_Indexed8);
for(int y = 0; y < image.rows; ++y, data += image.cols)
{
for(int x = 0; x < image.cols; ++x)
{
uchar * p = qtemp.scanLine (y) + x;
if(data[x] < min || data[x] > max || uIsNan(data[x]))
{
*p = 0;
}
else
{
*p = uchar(255.0f - ((data[x]-min)*255.0f)/(max-min));
if(*p == 255)
{
*p = 0;
}
}
}
}
QVector<QRgb> my_table;
for(int i = 0; i < 256; i++) my_table.push_back(qRgb(i,i,i));
qtemp.setColorTable(my_table);
}
else if(image.depth() == CV_16U && image.channels()==1)
{
// Assume depth image (unsigned short in mm)
const unsigned short * data = (const unsigned short *)image.data;
unsigned short min=data[0], max=data[0];
for(unsigned int i=1; i<image.total(); ++i)
{
if(!uIsNan(data[i]) && data[i] > 0)
{
if((uIsNan(min) && data[i] > 0) ||
(data[i] > 0 && data[i]<min))
{
min = data[i];
}
if((uIsNan(max) && data[i] > 0) ||
(data[i] > 0 && data[i]>max))
{
max = data[i];
}
}
}
qtemp = QImage(image.cols, image.rows, QImage::Format_Indexed8);
for(int y = 0; y < image.rows; ++y, data += image.cols)
{
for(int x = 0; x < image.cols; ++x)
{
uchar * p = qtemp.scanLine (y) + x;
if(data[x] < min || data[x] > max || uIsNan(data[x]) || max == min)
{
*p = 0;
}
else
{
*p = uchar(255.0f - (float(data[x]-min)/float(max-min))*255.0f);
if(*p == 255)
{
*p = 0;
}
}
}
}
QVector<QRgb> my_table;
for(int i = 0; i < 256; i++) my_table.push_back(qRgb(i,i,i));
qtemp.setColorTable(my_table);
}
else if(!image.empty() && image.depth() != CV_8U)
{
printf("Wrong image format, must be 8_bits/3channels or (depth) 32bitsFloat/1channel, 16bits/1channel\n");
}
return qtemp;
}
class UCvMat2QImageThread : public UThread
{
public:
UCvMat2QImageThread(const cv::Mat & image, bool isBgr = true) :
image_(image),
isBgr_(isBgr) {}
QImage & getQImage() {return qtImage_;}
protected:
virtual void mainLoop()
{
qtImage_ = uCvMat2QImage(image_, isBgr_);
this->kill();
}
private:
cv::Mat image_;
bool isBgr_;
QImage qtImage_;
};
#endif /* UCV2QT_H_ */

View File

@@ -0,0 +1,98 @@
/*
* ImageView.h
*
* Created on: 2012-06-20
* Author: mathieu
*/
#ifndef IMAGEVIEW_H_
#define IMAGEVIEW_H_
#include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines
#include <QWidget>
#include <QtGui/QPainter>
class RTABMAPGUI_EXP UImageView : public QWidget
{
Q_OBJECT;
public:
UImageView(QWidget * parent = 0) : QWidget(parent) {}
~UImageView() {}
void setBackgroundBrush(const QBrush & brush) {brush_ = brush;}
public slots:
void setImage(const QImage & image)
{
pixmap_ = QPixmap::fromImage(image);
this->update();
}
private:
void computeScaleOffsets(float & scale, float & offsetX, float & offsetY)
{
scale = 1.0f;
offsetX = 0.0f;
offsetY = 0.0f;
if(!pixmap_.isNull())
{
float w = pixmap_.width();
float h = pixmap_.height();
float widthRatio = float(this->rect().width()) / w;
float heightRatio = float(this->rect().height()) / h;
if(widthRatio < heightRatio)
{
scale = widthRatio;
}
else
{
scale = heightRatio;
}
w *= scale;
h *= scale;
if(w < this->rect().width())
{
offsetX = (this->rect().width() - w)/2.0f;
}
if(h < this->rect().height())
{
offsetY = (this->rect().height() - h)/2.0f;
}
}
}
protected:
virtual void paintEvent(QPaintEvent *event)
{
QPainter painter(this);
//Draw background
painter.save();
painter.setBrush(brush_);
painter.drawRect(this->rect());
painter.restore();
if(!pixmap_.isNull())
{
painter.save();
//Scale
float ratio, offsetX, offsetY;
this->computeScaleOffsets(ratio, offsetX, offsetY);
painter.translate(offsetX, offsetY);
painter.scale(ratio, ratio);
painter.drawPixmap(QPoint(0,0), pixmap_);
painter.restore();
}
}
private:
QPixmap pixmap_;
QBrush brush_;
};
#endif /* IMAGEVIEW_H_ */

View File

@@ -0,0 +1,628 @@
/*
* utilite is a cross-platform library with
* useful utilities for fast and small developing.
* Copyright (C) 2010 Mathieu Labbe
*
* utilite is free library: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* utilite is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef UPLOT_H_
#define UPLOT_H_
#include "rtabmap/gui/RtabmapGuiExp.h" // DLL export/import defines
#include <QFrame>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtGui/QPen>
#include <QtGui/QBrush>
#include <QGraphicsEllipseItem>
#include <QtCore/QMutex>
#include <QLabel>
#include <QPushButton>
#include <QtCore/QTime>
class QGraphicsView;
class QGraphicsScene;
class QGraphicsItem;
class QFormLayout;
/**
* UPlotItem is a QGraphicsEllipseItem and can be inherited to do custom behaviors
* on an hoverEnterEvent() for example.
*/
class RTABMAPGUI_EXP UPlotItem : public QGraphicsEllipseItem
{
public:
/**
* Constructor 1.
*/
UPlotItem(qreal dataX, qreal dataY, qreal width=2);
/**
* Constructor 2.
*/
UPlotItem(const QPointF & data, qreal width=2);
virtual ~UPlotItem();
public:
void setNextItem(UPlotItem * nextItem);
void setPreviousItem(UPlotItem * previousItem);
void setData(const QPointF & data);
UPlotItem * nextItem() const {return _nextItem;}
UPlotItem * previousItem() const {return _previousItem;};
const QPointF & data() const {return _data;}
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent * event);
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent * event);
virtual void focusInEvent(QFocusEvent * event);
virtual void focusOutEvent(QFocusEvent * event);
virtual void keyReleaseEvent(QKeyEvent * keyEvent);
virtual void showDescription(bool shown);
private:
void init(qreal dataX, qreal dataY);
private:
QPointF _data;
UPlotItem * _previousItem;
UPlotItem * _nextItem;
QGraphicsTextItem * _text;
QGraphicsRectItem * _textBackground;
};
class UPlot;
/**
* UPlotCurve is a curve used to hold data shown in a UPlot.
*/
class RTABMAPGUI_EXP UPlotCurve : public QObject
{
Q_OBJECT
public:
/**
* Constructor 1
*/
UPlotCurve(const QString & name, QObject * parent = 0);
/**
* Constructor 2
*/
UPlotCurve(const QString & name, const QVector<UPlotItem *> data, QObject * parent = 0);
/**
* Constructor 3
*/
UPlotCurve(const QString & name, const QVector<float> & x, const QVector<float> & y, QObject * parent = 0);
virtual ~UPlotCurve();
/**
* Get pen.
*/
const QPen & pen() const {return _pen;}
/**
* Get brush.
*/
const QBrush & brush() const {return _brush;}
/**
* Set pen.
*/
void setPen(const QPen & pen);
/**
* Set brush.
*/
void setBrush(const QBrush & brush);
void setItemsColor(const QColor & color);
QColor itemsColor() const {return _itemsColor;}
/**
* Get name.
*/
QString name() const {return _name;}
/**
* Get the number of items in the curve (dot + line items).
*/
int itemsSize() const;
QPointF getItemData(int index);
bool isVisible() const {return _visible;}
void setData(QVector<UPlotItem*> & data); // take the ownership
void getData(QVector<float> & x, QVector<float> & y) const; // only call in Qt MainThread
void draw(QPainter * painter, const QRect & limits);
public slots:
/**
*
* Clear curve's values.
*/
virtual void clear();
/**
*
* Show or hide the curve.
*/
void setVisible(bool visible);
/**
*
* Set increment of the x values (when auto-increment is used).
*/
void setXIncrement(float increment);
/**
*
* Set starting x value (when auto-increment is used).
*/
void setXStart(float val);
/**
*
* Add a single value, using a custom UPlotItem.
*/
void addValue(UPlotItem * data); // take the ownership
/**
*
* Add a single value y, x is auto-incremented by the increment set with setXIncrement().
* @see setXStart()
*/
void addValue(float y);
/**
*
* Add a single value y at x.
*/
void addValue(float x, float y);
/**
*
* For convenience...
* Add a single value y, x is auto-incremented by the increment set with setXIncrement().
* @see setXStart()
*/
void addValue(const QString & y);
/**
*
* For convenience...
* Add multiple values, using custom UPlotItem.
*/
void addValues(QVector<UPlotItem *> & data); // take the ownership
/**
*
* Add multiple values y at x. Vectors must have the same size.
*/
void addValues(const QVector<float> & xs, const QVector<float> & ys);
/**
*
* Add multiple values y, x is auto-incremented by the increment set with setXIncrement().
* @see setXStart()
*/
void addValues(const QVector<float> & ys);
void addValues(const QVector<int> & ys); // for convenience
/**
*
* Add multiple values y, x is auto-incremented by the increment set with setXIncrement().
* @see setXStart()
*/
void addValues(const std::vector<float> & ys); // for convenience
void addValues(const std::vector<int> & ys); // for convenience
void setData(const QVector<float> & x, const QVector<float> & y);
void setData(const std::vector<float> & x, const std::vector<float> & y);
void setData(const QVector<float> & y);
void setData(const std::vector<float> & y);
signals:
/**
*
* emitted when data is changed.
*/
void dataChanged(const UPlotCurve *);
protected:
friend class UPlot;
void attach(UPlot * plot);
void detach(UPlot * plot);
void updateMinMax();
const QVector<float> & getMinMax() const {return _minMax;}
int removeItem(int index);
void _addValue(UPlotItem * data);;
virtual bool isMinMaxValid() const {return _minMax.size();}
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept);
QList<QGraphicsItem *> _items;
UPlot * _plot;
private:
void removeItem(UPlotItem * item);
private:
QString _name;
QPen _pen;
QBrush _brush;
float _xIncrement;
float _xStart;
bool _visible;
bool _valuesShown;
QVector<float> _minMax; // minX, maxX, minY, maxY
QGraphicsRectItem * _rootItem;
QColor _itemsColor;
};
/**
* A special UPlotCurve that shows as a line at the specified value, spanning all the UPlot.
*/
class RTABMAPGUI_EXP UPlotCurveThreshold : public UPlotCurve
{
Q_OBJECT
public:
/**
* Constructor.
*/
UPlotCurveThreshold(const QString & name, float thesholdValue, Qt::Orientation orientation = Qt::Horizontal, QObject * parent = 0);
virtual ~UPlotCurveThreshold();
public slots:
/**
* Set threshold value.
*/
void setThreshold(float threshold);
/**
* Set orientation (Qt::Horizontal or Qt::Vertical).
*/
void setOrientation(Qt::Orientation orientation);
protected:
friend class UPlot;
virtual void update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept);
virtual bool isMinMaxValid() const {return false;}
private:
Qt::Orientation _orientation;
};
/**
* The UPlot axis object.
*/
class RTABMAPGUI_EXP UPlotAxis : public QWidget
{
public:
/**
* Constructor.
*/
UPlotAxis(Qt::Orientation orientation = Qt::Horizontal, float min=0, float max=1, QWidget * parent = 0);
virtual ~UPlotAxis();
public:
/**
* Set axis minimum and maximum values, compute the resulting
* intervals depending on the size of the axis.
*/
void setAxis(float & min, float & max);
/**
* Size of the border between the first line and the beginning of the widget.
*/
int border() const {return _border;}
/**
* Interval step value.
*/
int step() const {return _step;}
/**
* Number of intervals.
*/
int count() const {return _count;}
/**
* Reverse the axis (for vertical :bottom->up, for horizontal :right->left)
*/
void setReversed(bool reversed); // Vertical :bottom->up, horizontal :right->left
protected:
virtual void paintEvent(QPaintEvent * event);
private:
Qt::Orientation _orientation;
float _min;
float _max;
int _count;
int _step;
bool _reversed;
int _gradMaxDigits;
int _border;
};
/**
* The UPlot legend item. Used internally by UPlot.
*/
class RTABMAPGUI_EXP UPlotLegendItem : public QPushButton
{
Q_OBJECT
public:
/**
* Constructor.
*/
UPlotLegendItem(UPlotCurve * curve, QWidget * parent = 0);
virtual ~UPlotLegendItem();
const UPlotCurve * curve() const {return _curve;}
QPixmap createSymbol(const QPen & pen, const QBrush & brush);
signals:
void legendItemRemoved(const UPlotCurve *);
void moveUpRequest(UPlotLegendItem *);
void moveDownRequest(UPlotLegendItem *);
private slots:
void updateStdDev();
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
private:
UPlotCurve * _curve;
QMenu * _menu;
QAction * _aChangeText;
QAction * _aResetText;
QAction * _aChangeColor;
QAction * _aCopyToClipboard;
QAction * _aShowStdDev;
QAction * _aRemoveCurve;
QAction * _aMoveUp;
QAction * _aMoveDown;
};
/**
* The UPlot legend. Used internally by UPlot.
*/
class RTABMAPGUI_EXP UPlotLegend : public QWidget
{
Q_OBJECT
public:
/**
* Constructor.
*/
UPlotLegend(QWidget * parent = 0);
virtual ~UPlotLegend();
void setFlat(bool on);
bool isFlat() const {return _flat;}
void addItem(UPlotCurve * curve);
bool remove(const UPlotCurve * curve);
private slots:
void removeLegendItem(const UPlotCurve * curve);
void moveUp(UPlotLegendItem * item);
void moveDown(UPlotLegendItem * item);
signals:
void legendItemRemoved(const UPlotCurve * curve);
void legendItemToggled(const UPlotCurve * curve, bool toggled);
void legendItemMoved(const UPlotCurve * curve, int);
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
private slots:
void redirectToggled(bool);
private:
bool _flat;
QMenu * _menu;
QAction * _aUseFlatButtons;
};
/**
* Orientable QLabel. Inherit QLabel and let you to specify the orientation.
*/
class RTABMAPGUI_EXP UOrientableLabel : public QLabel
{
Q_OBJECT
public:
/**
* Constructor.
*/
UOrientableLabel(const QString & text, Qt::Orientation orientation = Qt::Horizontal, QWidget * parent = 0);
virtual ~UOrientableLabel();
/**
* Get orientation.
*/
Qt::Orientation orientation() const {return _orientation;}
/**
* Set orientation (Qt::Vertical or Qt::Horizontal).
*/
void setOrientation(Qt::Orientation orientation);
QSize sizeHint() const;
QSize minimumSizeHint() const;
protected:
virtual void paintEvent(QPaintEvent* event);
private:
Qt::Orientation _orientation;
};
/**
* UPlot is a QWidget to create a plot like MATLAB, and
* incrementally add new values like a scope using Qt signals/slots.
* Many customizations can be done at runtime with the right-click menu.
* @image html UPlot.gif
* @image html UPlotMenu.png
*
* Example:
* @code
* #include "utilite/UPlot.h"
* #include <QApplication>
*
* int main(int argc, char * argv[])
* {
* QApplication app(argc, argv);
* UPlot plot;
* UPlotCurve * curve = plot.addCurve("My curve");
* float y[10] = {0, 1, 2, 3, -3, -2, -1, 0, 1, 2};
* curve->addValues(std::vector<float>(y, y+10));
* plot.showGrid(true);
* plot.setGraphicsView(true);
* plot.show();
* app.exec();
* return 0;
* }
* @endcode
* @image html SimplePlot.tiff
*
*
*/
class RTABMAPGUI_EXP UPlot : public QWidget
{
Q_OBJECT
public:
/**
* Constructor.
*/
UPlot(QWidget * parent = 0);
virtual ~UPlot();
/**
* Add a curve. The returned curve doesn't need to be deallocated (UPlot keeps the ownership).
*/
UPlotCurve * addCurve(const QString & curveName, const QColor & color = QColor());
/**
* Add a curve. Ownership is transferred to UPlot if ownershipTransferred=true.
*/
bool addCurve(UPlotCurve * curve, bool ownershipTransferred = true);
/**
* Get all curve names.
*/
QStringList curveNames();
bool contains(const QString & curveName);
void removeCurves();
/**
* Add a threshold to the plot.
*/
UPlotCurveThreshold * addThreshold(const QString & name, float value, Qt::Orientation orientation = Qt::Horizontal);
QString title() const {return this->objectName();}
QPen getRandomPenColored();
void showLegend(bool shown);
void showGrid(bool shown);
void showRefreshRate(bool shown);
void trackMouse(bool tracking);
void keepAllData(bool kept);
void showXAxis(bool shown) {_horizontalAxis->setVisible(shown);}
void showYAxis(bool shown) {_verticalAxis->setVisible(shown);}
void setVariableXAxis() {_fixedAxis[0] = false;}
void setVariableYAxis() {_fixedAxis[1] = false;}
void setFixedXAxis(float x1, float x2);
void setFixedYAxis(float y1, float y2);
void setMaxVisibleItems(int maxVisibleItems);
void setTitle(const QString & text);
void setXLabel(const QString & text);
void setYLabel(const QString & text, Qt::Orientation orientation = Qt::Vertical);
void setWorkingDirectory(const QString & workingDirectory);
void setGraphicsView(bool on);
void setBackgroundColor(const QColor & color);
QRectF sceneRect() const;
public slots:
/**
*
* Remove a curve. If UPlot is the parent of the curve, the curve is deleted.
*/
void removeCurve(const UPlotCurve * curve);
void showCurve(const UPlotCurve * curve, bool shown);
void updateAxis(); //reset axis and recompute it with all curves minMax
/**
*
* Clear all curves' data.
*/
void clearData();
private slots:
void captureScreen();
void updateAxis(const UPlotCurve * curve);
void moveCurve(const UPlotCurve *, int index);
protected:
virtual void contextMenuEvent(QContextMenuEvent * event);
virtual void paintEvent(QPaintEvent * event);
virtual void resizeEvent(QResizeEvent * event);
virtual void mousePressEvent(QMouseEvent * event);
virtual void mouseMoveEvent(QMouseEvent * event);
virtual void mouseReleaseEvent(QMouseEvent * event);
virtual void mouseDoubleClickEvent(QMouseEvent * event);
private:
friend class UPlotCurve;
void addItem(QGraphicsItem * item);
private:
void replot(QPainter * painter);
bool updateAxis(float x, float y);
bool updateAxis(float x1, float x2, float y1, float y2);
void setupUi();
void createActions();
void createMenus();
void selectScreenCaptureFormat();
bool mousePosToValue(const QPoint & pos, float & x, float & y);
private:
UPlotLegend * _legend;
QGraphicsView * _view;
QGraphicsItem * _sceneRoot;
QWidget * _graphicsViewHolder;
float _axisMaximums[4]; // {x1->x2, y1->y2}
bool _axisMaximumsSet[4]; // {x1->x2, y1->y2}
bool _fixedAxis[2];
UPlotAxis * _verticalAxis;
UPlotAxis * _horizontalAxis;
int _penStyleCount;
int _maxVisibleItems;
QList<QGraphicsLineItem *> hGridLines;
QList<QGraphicsLineItem *> vGridLines;
QList<UPlotCurve*> _curves;
QLabel * _title;
QLabel * _xLabel;
UOrientableLabel * _yLabel;
QLabel * _refreshRate;
QString _workingDirectory;
QTime _refreshIntervalTime;
int _lowestRefreshRate;
QTime _refreshStartTime;
QString _autoScreenCaptureFormat;
QPoint _mousePressedPos;
QPoint _mouseCurrentPos;
QColor _bgColor;
QMenu * _menu;
QAction * _aShowLegend;
QAction * _aShowGrid;
QAction * _aKeepAllData;
QAction * _aLimit0;
QAction * _aLimit10;
QAction * _aLimit50;
QAction * _aLimit100;
QAction * _aLimit500;
QAction * _aLimit1000;
QAction * _aLimitCustom;
QAction * _aAddVerticalLine;
QAction * _aAddHorizontalLine;
QAction * _aChangeTitle;
QAction * _aChangeXLabel;
QAction * _aChangeYLabel;
QAction * _aChangeBackgroundColor;
QAction * _aYLabelVertical;
QAction * _aShowRefreshRate;
QAction * _aMouseTracking;
QAction * _aSaveFigure;
QAction * _aAutoScreenCapture;
QAction * _aClearData;
QAction * _aGraphicsView;
};
#endif /* UPLOT_H_ */