diff --git a/guilib/include/rtabmap/gui/qtipl.h b/guilib/include/rtabmap/gui/RtabmapGuiExp.h
similarity index 71%
rename from guilib/include/rtabmap/gui/qtipl.h
rename to guilib/include/rtabmap/gui/RtabmapGuiExp.h
index 285d9f02..9b0c129f 100644
--- a/guilib/include/rtabmap/gui/qtipl.h
+++ b/guilib/include/rtabmap/gui/RtabmapGuiExp.h
@@ -17,18 +17,17 @@
* along with RTAB-Map. If not, see .
*/
-#ifndef QTIPL_H
-#define QTIPL_H
-
-#include "rtabmap/core/RtabmapExp.h" // DLL export/import defines
-
-#include
-#include
-
-namespace rtabmap {
-
-QImage RTABMAP_EXP Ipl2QImage(const IplImage *newImage, int alpha = 255);
-
-}
-
+#ifndef RTABMAPGUIEXP_H
+#define RTABMAPGUIEXP_H
+
+#if defined(_WIN32)
+ #if defined(rtabmap_gui_EXPORTS)
+ #define RTABMAPGUI_EXP __declspec( dllexport )
+ #else
+ #define RTABMAPGUI_EXP __declspec( dllimport )
+ #endif
+#else
+ #define RTABMAPGUI_EXP
#endif
+
+#endif // RTABMAPGUIEXP_H
diff --git a/utilite/include/rtabmap/utilite/UConversion.h b/utilite/include/rtabmap/utilite/UConversion.h
index 3c2be140..bec2c9ad 100644
--- a/utilite/include/rtabmap/utilite/UConversion.h
+++ b/utilite/include/rtabmap/utilite/UConversion.h
@@ -50,7 +50,6 @@
*/
std::string UTILITE_EXP uReplaceChar(const std::string & str, char before, char after);
-
/**
* Replace old characters in a string with the specified string.
* Example :
@@ -67,7 +66,6 @@ std::string UTILITE_EXP uReplaceChar(const std::string & str, char before, char
*/
std::string UTILITE_EXP uReplaceChar(const std::string & str, char before, const std::string & after);
-
/**
* Transform characters from a string to upper case.
* Example :
@@ -243,13 +241,13 @@ std::string UTILITE_EXP uFormat (const char *fmt, ...);
* Convert multi-byte string to unicode (wide-char) string.
* Note that returned whar_t * must be deleted : delete [] wText;
*/
-wchar_t * UTILITE_EXP createWCharFromChar(const char * text);
+UTILITE_EXP wchar_t * createWCharFromChar(const char * text);
/**
* Convert unicode (wide-char) string to multi-byte string.
* Note that returned char * must be deleted : delete [] text;
*/
-char * UTILITE_EXP createCharFromWChar(const wchar_t * wText);
+UTILITE_EXP char * createCharFromWChar(const wchar_t * wText);
#endif
#endif /* UCONVERSION_H */
diff --git a/utilite/include/rtabmap/utilite/ULogger.h b/utilite/include/rtabmap/utilite/ULogger.h
index 66038ec5..e002dd57 100644
--- a/utilite/include/rtabmap/utilite/ULogger.h
+++ b/utilite/include/rtabmap/utilite/ULogger.h
@@ -43,7 +43,7 @@
*/
/*
- * Convenient macros for logging...
+ * Convenient macros for logging...
*/
#define ULOGGER_LOG(level, ...) ULogger::write(level, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
@@ -243,7 +243,7 @@ public:
* Logger levels, from lowest severity to highest:
* @code
* kDebug, kInfo, kWarning, kError, kFatal
- * @endcode
+ * @endcode
*/
enum Level{kDebug, kInfo, kWarning, kError, kFatal};
@@ -347,7 +347,7 @@ public:
static ULogger::Level eventLevel() {return eventLevel_;}
/**
- * Reset to default parameters.
+ * Reset to default parameters.
*/
static void reset();
@@ -456,6 +456,7 @@ private:
* @param arg the variable arguments
*/
virtual void _write(const char* msg, va_list arg) {} // Do nothing by default
+ virtual void _writeStr(const char* msg) {} // Do nothing by default
private:
/*
diff --git a/utilite/include/rtabmap/utilite/UStl.h b/utilite/include/rtabmap/utilite/UStl.h
index 391e72ff..3b04dfb0 100644
--- a/utilite/include/rtabmap/utilite/UStl.h
+++ b/utilite/include/rtabmap/utilite/UStl.h
@@ -67,7 +67,7 @@ inline std::vector uKeys(const std::multimap & mm)
{
std::vector v(mm.size());
int i=0;
- for(typename std::map::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
+ for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
{
v[i++] = iter->first;
}
@@ -83,7 +83,7 @@ template
inline std::list uKeysList(const std::multimap & mm)
{
std::list l;
- for(typename std::map::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
+ for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
{
l.push_back(iter->first);
}
@@ -100,7 +100,7 @@ inline std::vector uValues(const std::multimap & mm)
{
std::vector v(mm.size());
int i=0;
- for(typename std::map::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
+ for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
{
v[i++] = iter->second;
}
@@ -116,7 +116,7 @@ template
inline std::list uValuesList(const std::multimap & mm)
{
std::list l;
- for(typename std::map::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
+ for(typename std::multimap::const_iterator iter = mm.begin(); iter!=mm.end(); ++iter)
{
l.push_back(iter->second);
}
diff --git a/utilite/include/rtabmap/utilite/UTimer.h b/utilite/include/rtabmap/utilite/UTimer.h
index 4bf6601e..ee70039a 100644
--- a/utilite/include/rtabmap/utilite/UTimer.h
+++ b/utilite/include/rtabmap/utilite/UTimer.h
@@ -20,7 +20,7 @@
#ifndef UTIMER_H
#define UTIMER_H
-#include "UtiLiteExp.h" // DLL export/import defines
+#include "rtabmap/utilite/UtiLiteExp.h" // DLL export/import defines
#ifdef WIN32
#include
diff --git a/utilite/include/rtabmap/utilite/UtiLiteExp.h b/utilite/include/rtabmap/utilite/UtiLiteExp.h
index 4cac6fa7..333f5014 100644
--- a/utilite/include/rtabmap/utilite/UtiLiteExp.h
+++ b/utilite/include/rtabmap/utilite/UtiLiteExp.h
@@ -21,14 +21,14 @@
#define UTILITEEXP_H
/**
- * Used mainly on Windows for dynamic linked libraries (dll).
- */
+ * Used mainly on Windows for dynamic linked libraries (dll).
+ */
#if defined(_WIN32)
- #if defined(utilite_EXPORTS) || defined(utilite_qt_EXPORTS) || defined(utilite_audio_EXPORTS) || defined(utilite_cv_EXPORTS) || defined(utilite_cvqt_EXPORTS)
+ #if defined(rtabmap_utilite_EXPORTS)
#define UTILITE_EXP __declspec( dllexport )
#else
#define UTILITE_EXP __declspec( dllimport )
- #endif
+ #endif
#else
#define UTILITE_EXP
#endif
@@ -44,4 +44,3 @@
#endif
-
diff --git a/utilite/src/UPlot.cpp b/utilite/src/UPlot.cpp
deleted file mode 100644
index 8273795f..00000000
--- a/utilite/src/UPlot.cpp
+++ /dev/null
@@ -1,2979 +0,0 @@
-/*
-* 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 .
-*/
-
-#include "rtabmap/utilite/UPlot.h"
-#include "rtabmap/utilite/ULogger.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#ifdef QT_SVG_LIB
-#include
-#endif
-#include
-
-#define PRINT_DEBUG 0
-
-UPlotItem::UPlotItem(qreal dataX, qreal dataY, qreal width) :
- QGraphicsEllipseItem(0, 0, width, width, 0),
- _previousItem(0),
- _nextItem(0),
- _text(0),
- _textBackground(0)
-{
- this->init(dataX, dataY);
-}
-
-UPlotItem::UPlotItem(const QPointF & data, qreal width) :
- QGraphicsEllipseItem(0, 0, width, width, 0),
- _previousItem(0),
- _nextItem(0),
- _text(0),
- _textBackground(0)
-{
- this->init(data.x(), data.y());
-}
-
-void UPlotItem::init(qreal dataX, qreal dataY)
-{
- _data.setX(dataX);
- _data.setY(dataY);
- this->setAcceptsHoverEvents(true);
- this->setFlag(QGraphicsItem::ItemIsFocusable, true);
-}
-
-UPlotItem::~UPlotItem()
-{
- if(_previousItem && _nextItem)
- {
- _previousItem->setNextItem(_nextItem);
- _nextItem->setPreviousItem(_previousItem);
- }
- else if(_previousItem)
- {
- _previousItem->setNextItem(0);
- }
- else if(_nextItem)
- {
- _nextItem->setPreviousItem(0);
- }
-}
-
-void UPlotItem::setData(const QPointF & data)
-{
- _data = data;
-}
-
-void UPlotItem::setNextItem(UPlotItem * nextItem)
-{
- if(_nextItem != nextItem)
- {
- _nextItem = nextItem;
- if(nextItem)
- {
- nextItem->setPreviousItem(this);
- }
- }
-}
-
-void UPlotItem::setPreviousItem(UPlotItem * previousItem)
-{
- if(_previousItem != previousItem)
- {
- _previousItem = previousItem;
- if(previousItem)
- {
- previousItem->setNextItem(this);
- }
- }
-}
-
-void UPlotItem::showDescription(bool shown)
-{
- if(!_textBackground)
- {
- _textBackground = new QGraphicsRectItem(this);
- _textBackground->setBrush(QBrush(QColor(255, 255, 255, 200)));
- _textBackground->setPen(Qt::NoPen);
- _textBackground->setZValue(this->zValue()+1);
- _textBackground->setVisible(false);
-
- _text = new QGraphicsTextItem(_textBackground);
- }
-
- if(this->parentItem() && this->parentItem() != _textBackground->parentItem())
- {
- _textBackground->setParentItem(this->parentItem());
- _textBackground->setZValue(this->zValue()+1);
- }
-
- if(this->scene() && shown)
- {
- _textBackground->setVisible(true);
- _text->setPlainText(QString("(%1,%2)").arg(_data.x()).arg(_data.y()));
-
- this->setPen(QPen(this->pen().color(), 2));
-
- QRectF rect = this->scene()->sceneRect();
- QPointF p = this->pos();
- QRectF br = _text->boundingRect();
- _textBackground->setRect(QRectF(0,0,br.width(), br.height()));
-
- // Make sure the text is always in the scene
- if(p.x() - br.width() < 0)
- {
- p.setX(0);
- }
- else if(p.x() > rect.width())
- {
- p.setX(rect.width() - br.width());
- }
- else
- {
- p.setX(p.x() - br.width());
- }
-
- if(p.y() - br.height() < 0)
- {
- p.setY(0);
- }
- else
- {
- p.setY(p.y() - br.height());
- }
-
- _textBackground->setPos(p);
- }
- else
- {
- this->setPen(QPen(this->pen().color(), 1));
- _textBackground->setVisible(false);
- }
-}
-
-void UPlotItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
-{
- this->showDescription(true);
- QGraphicsEllipseItem::hoverEnterEvent(event);
-}
-
-void UPlotItem::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
-{
- if(!this->hasFocus())
- {
- this->showDescription(false);
- }
- QGraphicsEllipseItem::hoverLeaveEvent(event);
-}
-
-void UPlotItem::focusInEvent(QFocusEvent * event)
-{
- this->showDescription(true);
- QGraphicsEllipseItem::focusInEvent(event);
-}
-
-void UPlotItem::focusOutEvent(QFocusEvent * event)
-{
- this->showDescription(false);
- QGraphicsEllipseItem::focusOutEvent(event);
-}
-
-void UPlotItem::keyReleaseEvent(QKeyEvent * keyEvent)
-{
- //Get the next/previous visible item
- if(keyEvent->key() == Qt::Key_Right)
- {
- UPlotItem * next = _nextItem;
- while(next && !next->isVisible())
- {
- next = next->nextItem();
- }
- if(next && next->isVisible())
- {
- this->clearFocus();
- next->setFocus();
- }
- }
- else if(keyEvent->key() == Qt::Key_Left)
- {
- UPlotItem * previous = _previousItem;
- while(previous && !previous->isVisible())
- {
- previous = previous->previousItem();
- }
- if(previous && previous->isVisible())
- {
- this->clearFocus();
- previous->setFocus();
- }
- }
- QGraphicsEllipseItem::keyReleaseEvent(keyEvent);
-}
-
-
-
-
-
-UPlotCurve::UPlotCurve(const QString & name, QObject * parent) :
- QObject(parent),
- _plot(0),
- _name(name),
- _xIncrement(1),
- _xStart(0),
- _visible(true),
- _valuesShown(false),
- _itemsColor(0,0,0,150)
-{
- _rootItem = new QGraphicsRectItem();
-}
-
-UPlotCurve::UPlotCurve(const QString & name, QVector data, QObject * parent) :
- QObject(parent),
- _plot(0),
- _name(name),
- _xIncrement(1),
- _xStart(0),
- _visible(true),
- _valuesShown(false),
- _itemsColor(0,0,0,150)
-{
- _rootItem = new QGraphicsRectItem();
- this->setData(data);
-}
-
-UPlotCurve::UPlotCurve(const QString & name, const QVector & x, const QVector & y, QObject * parent) :
- QObject(parent),
- _plot(0),
- _name(name),
- _xIncrement(1),
- _xStart(0),
- _visible(true),
- _valuesShown(false),
- _itemsColor(0,0,0,150)
-{
- _rootItem = new QGraphicsRectItem();
- this->setData(x, y);
-}
-
-UPlotCurve::~UPlotCurve()
-{
- if(_plot)
- {
- _plot->removeCurve(this);
- }
-#if PRINT_DEBUG
- ULOGGER_DEBUG("%s", this->name().toStdString().c_str());
-#endif
- this->clear();
- delete _rootItem;
-}
-
-void UPlotCurve::attach(UPlot * plot)
-{
- if(!plot || plot == _plot)
- {
- return;
- }
- if(_plot)
- {
- _plot->removeCurve(this);
- }
- _plot = plot;
- _plot->addItem(_rootItem);
-}
-
-void UPlotCurve::detach(UPlot * plot)
-{
-#if PRINT_DEBUG
- ULOGGER_DEBUG("curve=\"%s\" from plot=\"%s\"", this->objectName().toStdString().c_str(), plot?plot->objectName().toStdString().c_str():"");
-#endif
- if(plot && _plot == plot)
- {
- _plot = 0;
- if(_rootItem->scene())
- {
- _rootItem->scene()->removeItem(_rootItem);
- }
- }
-}
-
-void UPlotCurve::updateMinMax()
-{
- float x,y;
- const UPlotItem * item;
- if(!_items.size())
- {
- _minMax = QVector();
- }
- else
- {
- _minMax = QVector(4);
- }
- for(int i=0; i<_items.size(); ++i)
- {
- item = qgraphicsitem_cast(_items.at(i));
- if(item)
- {
- x = item->data().x();
- y = item->data().y();
- if(i==0)
- {
- _minMax[0] = x;
- _minMax[1] = x;
- _minMax[2] = y;
- _minMax[3] = y;
- }
- else
- {
- if(x<_minMax[0]) _minMax[0] = x;
- if(x>_minMax[1]) _minMax[1] = x;
- if(y<_minMax[2]) _minMax[2] = y;
- if(y>_minMax[3]) _minMax[3] = y;
- }
- }
- }
-}
-
-void UPlotCurve::_addValue(UPlotItem * data)
-{
- // add item
- if(data)
- {
- float x = data->data().x();
- float y = data->data().y();
- if(_minMax.size() != 4)
- {
- _minMax = QVector(4);
- }
- if(_items.size())
- {
- data->setPreviousItem((UPlotItem *)_items.last());
- QGraphicsLineItem * line = new QGraphicsLineItem(_rootItem);
- line->setPen(_pen);
- line->setVisible(false);
- _items.append(line);
- //Update min/max
- if(x<_minMax[0]) _minMax[0] = x;
- if(x>_minMax[1]) _minMax[1] = x;
- if(y<_minMax[2]) _minMax[2] = y;
- if(y>_minMax[3]) _minMax[3] = y;
- }
- else
- {
- _minMax[0] = x;
- _minMax[1] = x;
- _minMax[2] = y;
- _minMax[3] = y;
- }
- data->setParentItem(_rootItem);
- data->setZValue(1);
- _items.append(data);
- data->setVisible(false);
- QPen pen = data->pen();
- pen.setColor(_itemsColor);
- data->setPen(pen);
- }
- else
- {
- ULOGGER_ERROR("Data is null ?!?");
- }
-}
-
-void UPlotCurve::addValue(UPlotItem * data)
-{
- // add item
- if(data)
- {
- this->_addValue(data);
- emit dataChanged(this);
- }
-}
-
-void UPlotCurve::addValue(float x, float y)
-{
- float width = 2; // TODO warn : hard coded value!
- this->addValue(new UPlotItem(x,y,width));
-}
-
-void UPlotCurve::addValue(float y)
-{
- float x = 0;
- if(_items.size())
- {
- UPlotItem * lastItem = (UPlotItem *)_items.last();
- x = lastItem->data().x() + _xIncrement;
- }
- else
- {
- x = _xStart;
- }
- this->addValue(x,y);
-}
-
-void UPlotCurve::addValue(const QString & value)
-{
- bool ok;
- float v = value.toFloat(&ok);
- if(ok)
- {
- this->addValue(v);
- }
- else
- {
- ULOGGER_ERROR("Value not valid, must be a number, received %s", value.toStdString().c_str());
- }
-}
-
-void UPlotCurve::addValues(QVector & data)
-{
- for(int i=0; i_addValue(data.at(i));
- }
- emit dataChanged(this);
-}
-
-void UPlotCurve::addValues(const QVector & xs, const QVector & ys)
-{
- float width = 2; // TODO warn : hard coded value!
- for(int i=0; i_addValue(new UPlotItem(xs.at(i),ys.at(i),width));
- }
- emit dataChanged(this);
-}
-
-void UPlotCurve::addValues(const QVector & ys)
-{
- float x = 0;
- float width = 2; // TODO warn : hard coded value!
- for(int i=0; idata().x() + _xIncrement;
- }
- else
- {
- x = _xStart;
- }
- this->_addValue(new UPlotItem(x,ys.at(i),width));
- }
- emit dataChanged(this);
-}
-
-void UPlotCurve::addValues(const QVector & ys)
-{
- float x = 0;
- float width = 2; // TODO warn : hard coded value!
- for(int i=0; idata().x() + _xIncrement;
- }
- else
- {
- x = _xStart;
- }
- this->_addValue(new UPlotItem(x,ys.at(i),width));
- }
- emit dataChanged(this);
-}
-
-void UPlotCurve::addValues(const std::vector & ys)
-{
- float x = 0;
- float width = 2; // TODO warn : hard coded value!
- for(unsigned int i=0; idata().x() + _xIncrement;
- }
- else
- {
- x = _xStart;
- }
- this->_addValue(new UPlotItem(x,ys.at(i),width));
- }
- emit dataChanged(this);
-}
-
-void UPlotCurve::addValues(const std::vector & ys)
-{
- float x = 0;
- float width = 2; // TODO warn : hard coded value!
- for(unsigned int i=0; idata().x() + _xIncrement;
- }
- else
- {
- x = _xStart;
- }
- this->_addValue(new UPlotItem(x,ys.at(i),width));
- }
- emit dataChanged(this);
-}
-
-int UPlotCurve::removeItem(int index)
-{
- if(index >= 0 && index < _items.size())
- {
- if(index!=0)
- {
- index-=1;
- delete _items.takeAt(index); // the line
- }
- else if(_items.size()>1)
- {
- delete _items.takeAt(index+1); // the line
- }
- UPlotItem * item = (UPlotItem *)_items.takeAt(index); // the plot item
- //Update min/max
- if(_minMax.size() == 4)
- {
- if(item->data().x() == _minMax[0] || item->data().x() == _minMax[1] ||
- item->data().y() == _minMax[2] || item->data().y() == _minMax[3])
- {
- if(_items.size())
- {
- UPlotItem * tmp = (UPlotItem *)_items.at(0);
- float x = tmp->data().x();
- float y = tmp->data().y();
- _minMax[0]=x;
- _minMax[1]=x;
- _minMax[2]=y;
- _minMax[3]=y;
- for(int i = 2; i<_items.size(); i+=2)
- {
- tmp = (UPlotItem*)_items.at(i);
- x = tmp->data().x();
- y = tmp->data().y();
- if(x<_minMax[0]) _minMax[0] = x;
- if(x>_minMax[1]) _minMax[1] = x;
- if(y<_minMax[2]) _minMax[2] = y;
- if(y>_minMax[3]) _minMax[3] = y;
- }
- }
- else
- {
- _minMax = QVector();
- }
- }
- }
- delete item;
- }
-
- return index;
-}
-
-void UPlotCurve::removeItem(UPlotItem * item) // ownership is transfered to the caller
-{
- for(int i=0; i<_items.size(); ++i)
- {
- if(_items.at(i) == item)
- {
- if(i!=0)
- {
- i-=1;
- delete _items[i];
- _items.removeAt(i);
- }
- else if(_items.size()>1)
- {
- delete _items[i+1];
- _items.removeAt(i+1);
- }
- item->scene()->removeItem(item);
- _items.removeAt(i);
- break;
- }
- }
-}
-
-void UPlotCurve::clear()
-{
-#if PRINT_DEBUG
- ULOGGER_DEBUG("%s", this->name().toStdString().c_str());
-#endif
- qDeleteAll(_rootItem->childItems());
- _items.clear();
-}
-
-void UPlotCurve::setPen(const QPen & pen)
-{
- _pen = pen;
- for(int i=1; i<_items.size(); i+=2)
- {
- ((QGraphicsLineItem*) _items.at(i))->setPen(_pen);
- }
-}
-
-void UPlotCurve::setBrush(const QBrush & brush)
-{
- _brush = brush;
- ULOGGER_WARN("Not used...");
-}
-
-void UPlotCurve::setItemsColor(const QColor & color)
-{
- if(color.isValid())
- {
- _itemsColor.setRgb(color.red(), color.green(), color.blue(), _itemsColor.alpha());
- for(int i=0; i<_items.size(); i+=2)
- {
- QPen pen = ((UPlotItem*) _items.at(i))->pen();
- pen.setColor(_itemsColor);
- ((UPlotItem*) _items.at(i))->setPen(pen);
- }
- }
-}
-
-void UPlotCurve::update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept)
-{
- //ULOGGER_DEBUG("scaleX=%f, scaleY=%f, offsetX=%f, offsetY=%f, xDir=%d, yDir=%d, _plot->scene()->width()=%f, _plot->scene()->height=%f", scaleX, scaleY, offsetX, offsetY, xDir, yDir,_plot->scene()->width(),_plot->scene()->height());
- //make sure direction values are 1 or -1
- xDir<0?xDir=-1:xDir=1;
- yDir<0?yDir=-1:yDir=1;
-
- bool hide = false;
- int j=0;
- for(int i=_items.size()-1; i>=0; --i)
- {
- if(i%2 == 0)
- {
- UPlotItem * item = (UPlotItem *)_items.at(i);
- if(hide)
- {
- if(maxItemsKept == 0 || j <= maxItemsKept)
- {
- // if not visible, stop looping... all other items are normally already hidden
- if(!item->isVisible())
- {
- break;
- }
- item->setVisible(false);
- }
- else
- {
- //remove the item with his line
- i = this->removeItem(i);
- }
- }
- else
- {
- QPointF newPos(((xDir*item->data().x()+offsetX)*scaleX-item->rect().width()/2.0f),
- ((yDir*item->data().y()+offsetY)*scaleY-item->rect().width()/2.0f));
- if(!item->isVisible())
- {
- item->setVisible(true);
- }
- item->setPos(newPos);
- }
- ++j;
- }
- else
- {
- if(hide)
- {
- _items.at(i)->setVisible(false);
- }
- else
- {
- UPlotItem * from = (UPlotItem *)_items.at(i-1);
- UPlotItem * to = (UPlotItem *)_items.at(i+1);
- QGraphicsLineItem * lineItem = (QGraphicsLineItem *)_items.at(i);
- lineItem->setLine((xDir*from->data().x()+offsetX)*scaleX,
- (yDir*from->data().y()+offsetY)*scaleY,
- (xDir*to->data().x()+offsetX)*scaleX,
- (yDir*to->data().y()+offsetY)*scaleY);
- if(!lineItem->isVisible())
- {
- lineItem->setVisible(true);
- }
- //Don't update not visible items
- // (Detect also if the curve goes forward or backward)
- QLineF line = lineItem->line();
- if((line.x1() <= line.x2() && line.x2() < 0-((line.x2() - line.x1()))) ||
- (line.x1() > line.x2() && line.x2() > lineItem->scene()->sceneRect().width() + ((line.x1() - line.x2()))))
- {
- hide = true;
- }
-
- }
- }
- }
-
-}
-
-void UPlotCurve::draw(QPainter * painter, const QRect & limits)
-{
- if(painter)
- {
- for(int i=_items.size()-1; i>=0 && _items.at(i)->isVisible(); i-=2)
- {
- //plotItem
- const UPlotItem * item = (const UPlotItem *)_items.at(i);
- int x = (int)item->x();
- if(x<0)
- {
- break;
- }
-
- // draw line in first
- if(i-1>=0)
- {
- //lineItem
- const QGraphicsLineItem * lineItem = (const QGraphicsLineItem *)_items.at(i-1);
- QLine line = lineItem->line().toLine();
- if(limits.contains(line.p1()) || limits.contains(line.p2()))
- {
- QPointF intersection;
- QLineF::IntersectType type;
- type = lineItem->line().intersect(QLineF(limits.topLeft(), limits.bottomLeft()), &intersection);
- if(type == QLineF::BoundedIntersection)
- {
- !limits.contains(line.p1())?line.setP1(intersection.toPoint()):line.setP2(intersection.toPoint());
- }
- else
- {
- type = lineItem->line().intersect(QLineF(limits.topLeft(), limits.topRight()), &intersection);
- if(type == QLineF::BoundedIntersection)
- {
- !limits.contains(line.p1())?line.setP1(intersection.toPoint()):line.setP2(intersection.toPoint());
- }
- else
- {
- type = lineItem->line().intersect(QLineF(limits.bottomLeft(), limits.bottomRight()), &intersection);
- if(type == QLineF::BoundedIntersection)
- {
- !limits.contains(line.p1())?line.setP1(intersection.toPoint()):line.setP2(intersection.toPoint());
- }
- else
- {
- type = lineItem->line().intersect(QLineF(limits.topRight(), limits.bottomRight()), &intersection);
- if(type == QLineF::BoundedIntersection)
- {
- !limits.contains(line.p1())?line.setP1(intersection.toPoint()):line.setP2(intersection.toPoint());
- }
- }
- }
- }
- painter->save();
- painter->setPen(this->pen());
- painter->setBrush(this->brush());
- painter->drawLine(line);
- painter->restore();
- }
- }
-
- if(limits.contains(item->pos().toPoint()) && limits.contains((item->pos() + QPointF(item->rect().width(), item->rect().height())).toPoint()))
- {
- painter->save();
- painter->setPen(QPen(_itemsColor));
- painter->drawEllipse(item->pos()+QPointF(item->rect().width()/2, item->rect().height()/2), (int)item->rect().width()/2, (int)item->rect().height()/2);
- painter->restore();
- }
- }
- }
-}
-
-int UPlotCurve::itemsSize() const
-{
- return _items.size();
-}
-
-QPointF UPlotCurve::getItemData(int index)
-{
- QPointF data;
- //make sure the index point to a PlotItem {PlotItem, line, PlotItem, line...}
- if(index>=0 && index < _items.size() && index % 2 == 0 )
- {
- data = ((UPlotItem*)_items.at(index))->data();
- }
- else
- {
- ULOGGER_ERROR("Wrong index, not pointing on a PlotItem");
- }
- return data;
-}
-
-void UPlotCurve::setVisible(bool visible)
-{
- _visible = visible;
- for(int i=0; i<_items.size(); ++i)
- {
- _items.at(i)->setVisible(visible);
- }
-}
-
-void UPlotCurve::setXIncrement(float increment)
-{
- _xIncrement = increment;
-}
-
-void UPlotCurve::setXStart(float val)
-{
- _xStart = val;
-}
-
-void UPlotCurve::setData(QVector & data)
-{
- this->clear();
- for(int i = 0; iaddValue(data[i]);
- }
-}
-
-void UPlotCurve::setData(const QVector & x, const QVector & y)
-{
- if(x.size() == y.size())
- {
- //match the size of the current data
- int margin = int((_items.size()+1)/2) - x.size();
- while(margin < 0)
- {
- UPlotItem * newItem = new UPlotItem(0, 0, 2);
- this->_addValue(newItem);
- ++margin;
- }
- while(margin > 0)
- {
- this->removeItem(0);
- --margin;
- }
-
- // update values
- int index = 0;
- QVector::const_iterator i=x.begin();
- QVector::const_iterator j=y.begin();
- for(; i!=x.end() && j!=y.end(); ++i, ++j, index+=2)
- {
- ((UPlotItem*)_items[index])->setData(QPointF(*i, *j));
- }
-
- //reset minMax, this will force the plot to update the axes
- this->updateMinMax();
- emit dataChanged(this);
- }
- else if(y.size()>0 && x.size()==0)
- {
- this->setData(y);
- }
- else
- {
- ULOGGER_ERROR("Data vectors have not the same size.");
- }
-}
-
-void UPlotCurve::setData(const std::vector & x, const std::vector & y)
-{
- if(x.size() == y.size())
- {
- //match the size of the current data
- int margin = int((_items.size()+1)/2) - int(x.size());
- while(margin < 0)
- {
- UPlotItem * newItem = new UPlotItem(0, 0, 2);
- this->_addValue(newItem);
- ++margin;
- }
- while(margin > 0)
- {
- this->removeItem(0);
- --margin;
- }
-
- // update values
- int index = 0;
- std::vector::const_iterator i=x.begin();
- std::vector::const_iterator j=y.begin();
- for(; i!=x.end() && j!=y.end(); ++i, ++j, index+=2)
- {
- ((UPlotItem*)_items[index])->setData(QPointF(*i, *j));
- }
-
- //reset minMax, this will force the plot to update the axes
- this->updateMinMax();
- emit dataChanged(this);
- }
- else if(y.size()>0 && x.size()==0)
- {
- this->setData(y);
- }
- else
- {
- ULOGGER_ERROR("Data vectors have not the same size.");
- }
-}
-
-void UPlotCurve::setData(const QVector & y)
-{
- this->setData(y.toStdVector());
-}
-
-void UPlotCurve::setData(const std::vector & y)
-{
- //match the size of the current data
- int margin = int((_items.size()+1)/2) - int(y.size());
- while(margin < 0)
- {
- UPlotItem * newItem = new UPlotItem(0, 0, 2);
- this->_addValue(newItem);
- ++margin;
- }
- while(margin > 0)
- {
- this->removeItem(0);
- --margin;
- }
-
- // update values
- int index = 0;
- float x = 0;
- std::vector::const_iterator j=y.begin();
- for(; j!=y.end(); ++j, index+=2)
- {
- ((UPlotItem*)_items[index])->setData(QPointF(x++, *j));
- }
-
- //reset minMax, this will force the plot to update the axes
- this->updateMinMax();
- emit dataChanged(this);
-}
-
-void UPlotCurve::getData(QVector & x, QVector & y) const
-{
- x.clear();
- y.clear();
- if(_items.size())
- {
- x.resize((_items.size()-1)/2+1);
- y.resize(x.size());
- int j=0;
- for(int i=0; i<_items.size(); i+=2)
- {
- x[j] = ((UPlotItem*)_items.at(i))->data().x();
- y[j++] = ((UPlotItem*)_items.at(i))->data().y();
- }
- }
-}
-
-
-
-
-
-UPlotCurveThreshold::UPlotCurveThreshold(const QString & name, float thesholdValue, Qt::Orientation orientation, QObject * parent) :
- UPlotCurve(name, parent),
- _orientation(orientation)
-{
- if(_orientation == Qt::Horizontal)
- {
- this->addValue(0, thesholdValue);
- this->addValue(1, thesholdValue);
- }
- else
- {
- this->addValue(thesholdValue, 0);
- this->addValue(thesholdValue, 1);
- }
-}
-
-UPlotCurveThreshold::~UPlotCurveThreshold()
-{
-
-}
-
-void UPlotCurveThreshold::setThreshold(float threshold)
-{
-#if PRINT_DEBUG
- ULOGGER_DEBUG("%f", threshold);
-#endif
- if(_items.size() == 3)
- {
- UPlotItem * item = 0;
- if(_orientation == Qt::Horizontal)
- {
- item = (UPlotItem*)_items.at(0);
- item->setData(QPointF(item->data().x(), threshold));
- item = (UPlotItem*)_items.at(2);
- item->setData(QPointF(item->data().x(), threshold));
- }
- else
- {
- item = (UPlotItem*)_items.at(0);
- item->setData(QPointF(threshold, item->data().y()));
- item = (UPlotItem*)_items.at(2);
- item->setData(QPointF(threshold, item->data().y()));
- }
- }
- else
- {
- ULOGGER_ERROR("A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
- }
-}
-
-void UPlotCurveThreshold::setOrientation(Qt::Orientation orientation)
-{
- if(_orientation != orientation)
- {
- _orientation = orientation;
- if(_items.size() == 3)
- {
- UPlotItem * item = 0;
- item = (UPlotItem*)_items.at(0);
- item->setData(QPointF(item->data().y(), item->data().x()));
- item = (UPlotItem*)_items.at(2);
- item->setData(QPointF(item->data().y(), item->data().x()));
- }
- else
- {
- ULOGGER_ERROR("A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
- }
- }
-}
-
-void UPlotCurveThreshold::update(float scaleX, float scaleY, float offsetX, float offsetY, float xDir, float yDir, int maxItemsKept)
-{
- if(_items.size() == 3)
- {
- if(_plot)
- {
- UPlotItem * item = 0;
- if(_orientation == Qt::Horizontal)
- {
- //(xDir*item->data().x()+offsetX)*scaleX
- item = (UPlotItem*)_items.at(0);
- item->setData(QPointF(-(offsetX-item->rect().width()/scaleX)/xDir, item->data().y()));
- item = (UPlotItem*)_items.at(2);
- item->setData(QPointF( (_plot->sceneRect().width()/scaleX-(offsetX+item->rect().width()/scaleX))/xDir, item->data().y()));
- }
- else
- {
- item = (UPlotItem*)_items.at(0);
- item->setData(QPointF(item->data().x(), -(offsetY-item->rect().height()/scaleY)/yDir));
- item = (UPlotItem*)_items.at(2);
- item->setData(QPointF(item->data().x(), (_plot->sceneRect().height()/scaleY-(offsetY+item->rect().height()/scaleY))/yDir));
- }
- this->updateMinMax();
- }
- }
- else
- {
- ULOGGER_ERROR("A threshold must has only 3 items (1 PlotItem + 1 QGraphicsLineItem + 1 PlotItem)");
- }
- UPlotCurve::update(scaleX, scaleY, offsetX, offsetY, xDir, yDir, maxItemsKept);
-}
-
-
-
-
-
-
-
-UPlotAxis::UPlotAxis(Qt::Orientation orientation, float min, float max, QWidget * parent) :
- QWidget(parent),
- _orientation(orientation),
- _reversed(false),
- _gradMaxDigits(4),
- _border(0)
-{
- if(_orientation == Qt::Vertical)
- {
- _reversed = true; // default bottom->up
- }
-#ifdef WIN32
- this->setMinimumSize(15, 25);
-#else
- this->setMinimumSize(15, 25);
-#endif
- this->setAxis(min, max); // this initialize all attributes
-}
-
-UPlotAxis::~UPlotAxis()
-{
-#if PRINT_DEBUG
- ULOGGER_DEBUG("");
-#endif
-}
-
-// Vertical :bottom->up, horizontal :right->left
-void UPlotAxis::setReversed(bool reversed)
-{
- if(_reversed != reversed)
- {
- float min = _min;
- _min = _max;
- _max = min;
- }
- _reversed = reversed;
-}
-
-void UPlotAxis::setAxis(float & min, float & max)
-{
- int borderMin = 0;
- int borderMax = 0;
- if(_orientation == Qt::Vertical)
- {
- borderMin = borderMax = this->fontMetrics().height()/2;
- }
- else
- {
- borderMin = this->fontMetrics().width(QString::number(_min,'g',_gradMaxDigits))/2;
- borderMax = this->fontMetrics().width(QString::number(_max,'g',_gradMaxDigits))/2;
- }
- int border = borderMin>borderMax?borderMin:borderMax;
- int borderDelta;
- int length;
- if(_orientation == Qt::Vertical)
- {
- length = (this->height()-border*2);
- }
- else
- {
- length = (this->width()-border*2);
- }
-
- if(length <= 70)
- {
- _count = 5;
- }
- else if(length <= 175)
- {
- _count = 10;
- }
- else if(length <= 350)
- {
- _count = 20;
- }
- else if(length <= 700)
- {
- _count = 40;
- }
- else if(length <= 1000)
- {
- _count = 60;
- }
- else if(length <= 1300)
- {
- _count = 80;
- }
- else
- {
- _count = 100;
- }
-
- // Rounding min and max
- if(min != max)
- {
- float mul = 1;
- float rangef = max - min;
- int countStep = _count/5;
- float val;
- for(int i=0; i<6; ++i)
- {
- val = (rangef/float(countStep)) * mul;
- if( val >= 1.0f && val < 10.0f)
- {
- break;
- }
- else if(val<1)
- {
- mul *= 10.0f;
- }
- else
- {
- mul /= 10.0f;
- }
- }
- //ULOGGER_DEBUG("min=%f, max=%f", min, max);
- int minR = min*mul-0.9;
- int maxR = max*mul+0.9;
- min = float(minR)/mul;
- max = float(maxR)/mul;
- //ULOGGER_DEBUG("mul=%f, minR=%d, maxR=%d,countStep=%d", mul, minR, maxR, countStep);
- }
-
- _min = min;
- _max = max;
-
- if(_reversed)
- {
- _min = _max;
- _max = min;
- }
-
- if(_orientation == Qt::Vertical)
- {
- _step = length/_count;
- borderDelta = length - (_step*_count);
- }
- else
- {
- _step = length/_count;
- borderDelta = length - (_step*_count);
- }
-
- if(borderDelta%2 != 0)
- {
- borderDelta+=1;
- }
-
- _border = border + borderDelta/2;
-
- //Resize estimation
- if(_orientation == Qt::Vertical)
- {
- int minWidth = 0;
- for (int i = 0; i <= _count; i+=5)
- {
- QString n(QString::number(_min + (i/5)*((_max-_min)/(_count/5)),'g',_gradMaxDigits));
- if(this->fontMetrics().width(n) > minWidth)
- {
- minWidth = this->fontMetrics().width(n);
- }
- }
- this->setMinimumWidth(15+minWidth);
- }
-}
-
-void UPlotAxis::paintEvent(QPaintEvent * event)
-{
- QPainter painter(this);
- if(_orientation == Qt::Vertical)
- {
- painter.translate(0, _border);
- for (int i = 0; i <= _count; ++i)
- {
- if(i%5 == 0)
- {
- painter.drawLine(this->width(), 0, this->width()-10, 0);
- QLabel n(QString::number(_min + (i/5)*((_max-_min)/(_count/5)),'g',_gradMaxDigits));
- painter.drawText(this->width()-(12+n.sizeHint().width()), n.sizeHint().height()/2-2, n.text());
- }
- else
- {
- painter.drawLine(this->width(), 0, this->width()-5, 0);
- }
- painter.translate(0, _step);
- }
- }
- else
- {
- painter.translate(_border, 0);
- for (int i = 0; i <= _count; ++i)
- {
- if(i%5 == 0)
- {
- painter.drawLine(0, 0, 0, 10);
- QLabel n(QString::number(_min + (i/5)*((_max-_min)/(_count/5)),'g',_gradMaxDigits));
- painter.drawText(-(n.sizeHint().width()/2)+1, 22, n.text());
- }
- else
- {
- painter.drawLine(0, 0, 0, 5);
- }
- painter.translate(_step, 0);
- }
- }
-}
-
-
-
-
-UPlotLegendItem::UPlotLegendItem(UPlotCurve * curve, QWidget * parent) :
- QPushButton(parent),
- _curve(curve)
-{
- QString nameSpaced = curve->name();
- nameSpaced.replace('_', ' ');
- this->setText(nameSpaced);
-
- this->setIcon(QIcon(this->createSymbol(curve->pen(), curve->brush())));
- this->setIconSize(QSize(25,20));
-
- _aChangeText = new QAction(tr("Change text..."), this);
- _aResetText = new QAction(tr("Reset text..."), this);
- _aChangeColor = new QAction(tr("Change color..."), this);
- _aCopyToClipboard = new QAction(tr("Copy curve data to the clipboard"), this);
- _aMoveUp = new QAction(tr("Move up"), this);
- _aMoveDown = new QAction(tr("Move down"), this);
- _aRemoveCurve = new QAction(tr("Remove this curve"), this);
- _menu = new QMenu(tr("Curve"), this);
- _menu->addAction(_aChangeText);
- _menu->addAction(_aResetText);
- _menu->addAction(_aChangeColor);
- _menu->addAction(_aCopyToClipboard);
- _menu->addSeparator();
- _menu->addAction(_aMoveUp);
- _menu->addAction(_aMoveDown);
- _menu->addSeparator();
- _menu->addAction(_aRemoveCurve);
-}
-
-UPlotLegendItem::~UPlotLegendItem()
-{
-
-}
-void UPlotLegendItem::contextMenuEvent(QContextMenuEvent * event)
-{
- QAction * action = _menu->exec(event->globalPos());
- if(action == _aChangeText)
- {
- bool ok;
- QString text = QInputDialog::getText(this, _aChangeText->text(), tr("Name :"), QLineEdit::Normal, this->text(), &ok);
- if(ok && !text.isEmpty())
- {
- this->setText(text);
- }
- }
- else if(action == _aResetText)
- {
- if(_curve)
- {
- this->setText(_curve->name());
- }
- }
- else if(action == _aChangeColor)
- {
- if(_curve)
- {
- QPen pen = _curve->pen();
- QColor color = QColorDialog::getColor(pen.color(), this);
- if(color.isValid())
- {
- pen.setColor(color);
- _curve->setPen(pen);
- this->setIcon(QIcon(this->createSymbol(_curve->pen(), _curve->brush())));
- }
- }
- }
- else if (action == _aCopyToClipboard)
- {
- if(_curve)
- {
- QVector x;
- QVector y;
- _curve->getData(x, y);
- QString textX;
- QString textY;
- for(int i=0; isetText((textX+"\n")+textY);
- }
- }
- else if(action == _aRemoveCurve)
- {
- emit legendItemRemoved(_curve);
- }
- else if(action == _aMoveUp)
- {
- emit moveUpRequest(this);
- }
- else if(action == _aMoveDown)
- {
- emit moveDownRequest(this);
- }
-}
-
-QPixmap UPlotLegendItem::createSymbol(const QPen & pen, const QBrush & brush)
-{
- QPixmap pixmap(50, 50);
- pixmap.fill(Qt::transparent);
- QPainter painter(&pixmap);
- QPen p = pen;
- p.setWidthF(4.0);
- painter.setPen(p);
- painter.drawLine(0.0, 25.0, 50.0, 25.0);
- return pixmap;
-}
-
-
-
-
-
-
-UPlotLegend::UPlotLegend(QWidget * parent) :
- QWidget(parent),
- _flat(true)
-{
- //menu
- _aUseFlatButtons = new QAction(tr("Use flat buttons"), this);
- _aUseFlatButtons->setCheckable(true);
- _aUseFlatButtons->setChecked(_flat);
- _menu = new QMenu(tr("Legend"), this);
- _menu->addAction(_aUseFlatButtons);
-
- QVBoxLayout * vLayout = new QVBoxLayout(this);
- vLayout->setContentsMargins(0,0,0,0);
- this->setLayout(vLayout);
- vLayout->addStretch(0);
- vLayout->setSpacing(0);
-}
-
-UPlotLegend::~UPlotLegend()
-{
-#if PRINT_DEBUG
- ULOGGER_DEBUG("");
-#endif
-}
-
-void UPlotLegend::setFlat(bool on)
-{
- if(_flat != on)
- {
- _flat = on;
- QList items = this->findChildren();
- for(int i=0; isetFlat(_flat);
- items.at(i)->setChecked(!items.at(i)->isChecked());
- }
- _aUseFlatButtons->setChecked(_flat);
- }
-}
-
-void UPlotLegend::addItem(UPlotCurve * curve)
-{
- if(curve)
- {
- UPlotLegendItem * legendItem = new UPlotLegendItem(curve, this);
- legendItem->setAutoDefault(false);
- legendItem->setFlat(_flat);
- legendItem->setCheckable(true);
- legendItem->setChecked(false);
- connect(legendItem, SIGNAL(toggled(bool)), this, SLOT(redirectToggled(bool)));
- connect(legendItem, SIGNAL(legendItemRemoved(const UPlotCurve *)), this, SLOT(removeLegendItem(const UPlotCurve *)));
- connect(legendItem, SIGNAL(moveUpRequest(UPlotLegendItem *)), this, SLOT(moveUp(UPlotLegendItem *)));
- connect(legendItem, SIGNAL(moveDownRequest(UPlotLegendItem *)), this, SLOT(moveDown(UPlotLegendItem *)));
-
- // layout
- QHBoxLayout * hLayout = new QHBoxLayout();
- hLayout->addWidget(legendItem);
- hLayout->addStretch(0);
- hLayout->setMargin(0);
-
- // add to the legend
- ((QVBoxLayout*)this->layout())->insertLayout(this->layout()->count()-1, hLayout);
- }
-}
-
-bool UPlotLegend::remove(const UPlotCurve * curve)
-{
- QList items = this->findChildren();
- for(int i=0; icurve() == curve)
- {
- delete items.at(i);
- return true;
- }
- }
- return false;
-}
-
-void UPlotLegend::removeLegendItem(const UPlotCurve * curve)
-{
- if(this->remove(curve))
- {
- emit legendItemRemoved(curve);
- }
-}
-
-void UPlotLegend::moveUp(UPlotLegendItem * item)
-{
- int index = -1;
- QLayoutItem * layoutItem = 0;
- for(int i=0; ilayout()->count(); ++i)
- {
- if(this->layout()->itemAt(i)->layout() &&
- this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
- {
- layoutItem = this->layout()->itemAt(i);
- index = i;
- break;
- }
- }
- if(index > 0 && layoutItem)
- {
- this->layout()->removeItem(layoutItem);
- QHBoxLayout * hLayout = new QHBoxLayout();
- hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
- hLayout->addStretch(0);
- hLayout->setMargin(0);
- ((QVBoxLayout*)this->layout())->insertLayout(index-1, hLayout);
- delete layoutItem;
- emit legendItemMoved(item->curve(), index-1);
- }
-}
-
-void UPlotLegend::moveDown(UPlotLegendItem * item)
-{
- int index = -1;
- QLayoutItem * layoutItem = 0;
- for(int i=0; ilayout()->count(); ++i)
- {
- if(this->layout()->itemAt(i)->layout() &&
- this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
- {
- layoutItem = this->layout()->itemAt(i);
- index = i;
- break;
- }
- }
- if(index < this->layout()->count()-2 && layoutItem)
- {
- this->layout()->removeItem(layoutItem);
- QHBoxLayout * hLayout = new QHBoxLayout();
- hLayout->addWidget(layoutItem->layout()->itemAt(0)->widget());
- hLayout->addStretch(0);
- hLayout->setMargin(0);
- ((QVBoxLayout*)this->layout())->insertLayout(index+1, hLayout);
- delete layoutItem;
- emit legendItemMoved(item->curve(), index+1);
- }
-}
-
-void UPlotLegend::contextMenuEvent(QContextMenuEvent * event)
-{
- QAction * action = _menu->exec(event->globalPos());
- if(action == _aUseFlatButtons)
- {
- this->setFlat(_aUseFlatButtons->isChecked());
- }
-}
-
-void UPlotLegend::redirectToggled(bool toggled)
-{
- if(sender())
- {
- UPlotLegendItem * item = qobject_cast(sender());
- if(item)
- {
- emit legendItemToggled(item->curve(), _flat?!toggled:toggled);
- }
- }
-}
-
-
-
-
-
-
-
-UOrientableLabel::UOrientableLabel(const QString & text, Qt::Orientation orientation, QWidget * parent) :
- QLabel(text, parent),
- _orientation(orientation)
-{
-}
-
-UOrientableLabel::~UOrientableLabel()
-{
-}
-
-QSize UOrientableLabel::sizeHint() const
-{
- QSize size = QLabel::sizeHint();
- if (_orientation == Qt::Vertical)
- size.transpose();
- return size;
-
-}
-
-QSize UOrientableLabel::minimumSizeHint() const
-{
- QSize size = QLabel::minimumSizeHint();
- if (_orientation == Qt::Vertical)
- size.transpose();
- return size;
-}
-
-void UOrientableLabel::setOrientation(Qt::Orientation orientation)
-{
- _orientation = orientation;
- switch(orientation)
- {
- case Qt::Horizontal:
- setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
- break;
-
- case Qt::Vertical:
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
- break;
- }
-}
-
-void UOrientableLabel::paintEvent(QPaintEvent* event)
-{
- QPainter p(this);
- QRect r = rect();
- switch (_orientation)
- {
- case Qt::Horizontal:
- break;
- case Qt::Vertical:
- p.rotate(-90);
- p.translate(-height(), 0);
- QSize size = r.size();
- size.transpose();
- r.setSize(size);
- break;
- }
- p.drawText(r, this->alignment() | (this->wordWrap()?Qt::TextWordWrap:0), this->text());
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-UPlot::UPlot(QWidget *parent) :
- QWidget(parent),
- _maxVisibleItems(-1),
- _autoScreenCaptureFormat("png"),
- _bgColor(Qt::white)
-{
- this->setupUi();
- this->createActions();
- this->createMenus();
-
- // This will update actions
- this->showLegend(true);
- this->setGraphicsView(false);
- this->setMaxVisibleItems(0);
- this->showGrid(false);
- this->showRefreshRate(false);
- this->keepAllData(false);
-
- for(int i=0; i<4; ++i)
- {
- _axisMaximums[i] = 0;
- _axisMaximumsSet[i] = false;
- if(i<2)
- {
- _fixedAxis[i] = false;
- }
- }
-
- _mouseCurrentPos = _mousePressedPos; // for zooming
-
- _refreshIntervalTime.start();
- _lowestRefreshRate = 99;
- _refreshStartTime.start();
-
- _penStyleCount = rand() % 10 + 1; // rand 1->10
- _workingDirectory = QDir::homePath();
-}
-
-UPlot::~UPlot()
-{
- _aAutoScreenCapture->setChecked(false);
-#if PRINT_DEBUG
- ULOGGER_DEBUG("%s", this->title().toStdString().c_str());
-#endif
- this->removeCurves();
-}
-
-void UPlot::setupUi()
-{
- _legend = new UPlotLegend(this);
- _view = new QGraphicsView(this);
- _view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- _view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- _view->setScene(new QGraphicsScene(0,0,0,0,this));
- _view->setStyleSheet( "QGraphicsView { border-style: none; }" );
- _sceneRoot = _view->scene()->addText("");
- _sceneRoot->translate(0,0);
- _graphicsViewHolder = new QWidget(this);
- _graphicsViewHolder->setMinimumSize(100,100);
- _graphicsViewHolder->setMouseTracking(true);
- _verticalAxis = new UPlotAxis(Qt::Vertical, 0, 1, this);
- _horizontalAxis = new UPlotAxis(Qt::Horizontal, 0, 1, this);
- _title = new QLabel("");
- _xLabel = new QLabel("");
- _refreshRate = new QLabel("");
- _yLabel = new UOrientableLabel("");
- _yLabel->setOrientation(Qt::Vertical);
- _title->setAlignment(Qt::AlignCenter);
- _xLabel->setAlignment(Qt::AlignCenter);
- _yLabel->setAlignment(Qt::AlignCenter);
- _refreshRate->setAlignment(Qt::AlignCenter);
- _title->setWordWrap(true);
- _xLabel->setWordWrap(true);
- _yLabel->setWordWrap(true);
- _title->setVisible(false);
- _xLabel->setVisible(false);
- _yLabel->setVisible(false);
- _refreshRate->setVisible(false);
-
- //layouts
- QVBoxLayout * vLayout = new QVBoxLayout(_graphicsViewHolder);
- vLayout->setContentsMargins(0,0,0,0);
- vLayout->addWidget(_view);
-
- QGridLayout * grid = new QGridLayout(this);
- grid->setContentsMargins(0,0,0,0);
- grid->addWidget(_title, 0, 2);
- grid->addWidget(_yLabel, 1, 0);
- grid->addWidget(_verticalAxis, 1, 1);
- grid->addWidget(_refreshRate, 2, 1);
- grid->addWidget(_graphicsViewHolder, 1, 2);
- grid->setColumnStretch(2, 1);
- grid->setRowStretch(1, 1);
- grid->addWidget(_horizontalAxis, 2, 2);
- grid->addWidget(_xLabel, 3, 2);
- grid->addWidget(_legend, 1, 3);
-
- connect(_legend, SIGNAL(legendItemToggled(const UPlotCurve *, bool)), this, SLOT(showCurve(const UPlotCurve *, bool)));
- connect(_legend, SIGNAL(legendItemRemoved(const UPlotCurve *)), this, SLOT(removeCurve(const UPlotCurve *)));
- connect(_legend, SIGNAL(legendItemMoved(const UPlotCurve *, int)), this, SLOT(moveCurve(const UPlotCurve *, int)));
-}
-
-void UPlot::createActions()
-{
- _aShowLegend = new QAction(tr("Show legend"), this);
- _aShowLegend->setCheckable(true);
- _aShowGrid = new QAction(tr("Show grid"), this);
- _aShowGrid->setCheckable(true);
- _aShowRefreshRate = new QAction(tr("Show refresh rate"), this);
- _aShowRefreshRate->setCheckable(true);
- _aMouseTracking = new QAction(tr("Mouse tracking"), this);
- _aMouseTracking->setCheckable(true);
- _aGraphicsView = new QAction(tr("Graphics view"), this);
- _aGraphicsView->setCheckable(true);
- _aKeepAllData = new QAction(tr("Keep all data"), this);
- _aKeepAllData->setCheckable(true);
- _aLimit0 = new QAction(tr("No maximum items shown"), this);
- _aLimit10 = new QAction(tr("10"), this);
- _aLimit50 = new QAction(tr("50"), this);
- _aLimit100 = new QAction(tr("100"), this);
- _aLimit500 = new QAction(tr("500"), this);
- _aLimit1000 = new QAction(tr("1000"), this);
- _aLimitCustom = new QAction(tr(""), this);
- _aLimit0->setCheckable(true);
- _aLimit10->setCheckable(true);
- _aLimit50->setCheckable(true);
- _aLimit100->setCheckable(true);
- _aLimit500->setCheckable(true);
- _aLimit1000->setCheckable(true);
- _aLimitCustom->setCheckable(true);
- _aLimitCustom->setVisible(false);
- _aAddVerticalLine = new QAction(tr("Vertical line..."), this);
- _aAddHorizontalLine = new QAction(tr("Horizontal line..."), this);
- _aChangeTitle = new QAction(tr("Change title"), this);
- _aChangeXLabel = new QAction(tr("Change X label..."), this);
- _aChangeYLabel = new QAction(tr("Change Y label..."), this);
- _aChangeBackgroundColor = new QAction(tr("Change bg color..."), this);
- _aYLabelVertical = new QAction(tr("Vertical orientation"), this);
- _aYLabelVertical->setCheckable(true);
- _aYLabelVertical->setChecked(true);
- _aSaveFigure = new QAction(tr("Save figure..."), this);
- _aAutoScreenCapture = new QAction(tr("Auto screen capture..."), this);
- _aAutoScreenCapture->setCheckable(true);
- _aClearData = new QAction(tr("Clear data"), this);
-
- QActionGroup * grpLimit = new QActionGroup(this);
- grpLimit->addAction(_aLimit0);
- grpLimit->addAction(_aLimit10);
- grpLimit->addAction(_aLimit50);
- grpLimit->addAction(_aLimit100);
- grpLimit->addAction(_aLimit500);
- grpLimit->addAction(_aLimit1000);
- grpLimit->addAction(_aLimitCustom);
- _aLimit0->setChecked(true);
-}
-
-void UPlot::createMenus()
-{
- _menu = new QMenu(tr("Plot"), this);
- _menu->addAction(_aShowLegend);
- _menu->addAction(_aShowGrid);
- _menu->addAction(_aShowRefreshRate);
- _menu->addAction(_aMouseTracking);
- _menu->addAction(_aGraphicsView);
- _menu->addAction(_aKeepAllData);
- _menu->addSeparator()->setStatusTip(tr("Maximum items shown"));
- _menu->addAction(_aLimit0);
- _menu->addAction(_aLimit10);
- _menu->addAction(_aLimit50);
- _menu->addAction(_aLimit100);
- _menu->addAction(_aLimit500);
- _menu->addAction(_aLimit1000);
- _menu->addAction(_aLimitCustom);
- _menu->addSeparator();
- QMenu * addLineMenu = _menu->addMenu(tr("Add line"));
- addLineMenu->addAction(_aAddHorizontalLine);
- addLineMenu->addAction(_aAddVerticalLine);
- _menu->addSeparator();
- _menu->addAction(_aChangeTitle);
- _menu->addAction(_aChangeXLabel);
- QMenu * yLabelMenu = _menu->addMenu(tr("Y label"));
- yLabelMenu->addAction(_aChangeYLabel);
- yLabelMenu->addAction(_aYLabelVertical);
- _menu->addAction(_aChangeBackgroundColor);
- _menu->addAction(_aSaveFigure);
- _menu->addAction(_aAutoScreenCapture);
- _menu->addSeparator();
- _menu->addAction(_aClearData);
-
-}
-
-UPlotCurve * UPlot::addCurve(const QString & curveName, const QColor & color)
-{
- // add curve
- UPlotCurve * curve = new UPlotCurve(curveName, this);
- if(color.isValid())
- {
- curve->setPen(color);
- }
- else
- {
- curve->setPen(this->getRandomPenColored());
- }
- this->addCurve(curve);
- return curve;
-}
-
-bool UPlot::addCurve(UPlotCurve * curve, bool ownershipTransferred)
-{
- if(curve)
- {
-#if PRINT_DEBUG
- ULOGGER_DEBUG("Adding curve \"%s\" to plot \"%s\"...", curve->name().toStdString().c_str(), this->title().toStdString().c_str());
-#endif
- // only last curve can trigger an update, so disable previous connections
- if(!qobject_cast(curve))
- {
- for(int i=_curves.size()-1; i>=0; --i)
- {
- if(!qobject_cast(_curves.at(i)))
- {
- disconnect(_curves.at(i), SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateAxis()));
- break;
- }
- }
- }
-
- // add curve
- _curves.append(curve);
- curve->attach(this);
- curve->setItemsColor(QColor(255-_bgColor.red(), 255-_bgColor.green(), 255-_bgColor.red(), _bgColor.alpha()));
- if(ownershipTransferred)
- {
- curve->setParent(this);
- }
- this->updateAxis(curve);
- curve->setXStart(_axisMaximums[1]);
-
- connect(curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateAxis()));
-
- _legend->addItem(curve);
-
-#if PRINT_DEBUG
- ULOGGER_DEBUG("Curve \"%s\" added to plot \"%s\"", curve->name().toStdString().c_str(), this->title().toStdString().c_str());
-#endif
-
- return true;
- }
- else
- {
- ULOGGER_ERROR("The curve is null!");
- }
- return false;
-}
-
-QStringList UPlot::curveNames()
-{
- QStringList names;
- for(QList::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
- {
- if(*iter)
- {
- names.append((*iter)->name());
- }
- }
- return names;
-}
-
-bool UPlot::contains(const QString & curveName)
-{
- for(QList::iterator iter = _curves.begin(); iter!=_curves.end(); ++iter)
- {
- if(*iter && (*iter)->name().compare(curveName) == 0)
- {
- return true;
- }
- }
- return false;
-}
-
-QPen UPlot::getRandomPenColored()
-{
- return QPen((Qt::GlobalColor)(_penStyleCount++ % 12 + 7 ));
-}
-
-void UPlot::replot(QPainter * painter)
-{
- if(_maxVisibleItems>0)
- {
- UPlotCurve * c = 0;
- int maxItem = 0;
- // find the curve with the most items
- for(QList::iterator i=_curves.begin(); i!=_curves.end(); ++i)
- {
- if((*i)->isVisible() && ((UPlotCurve *)(*i))->itemsSize() > maxItem)
- {
- c = *i;
- maxItem = c->itemsSize();
- }
- }
- if(c && (maxItem-1)/2+1 > _maxVisibleItems && _axisMaximums[0] < c->getItemData((c->itemsSize()-1) -_maxVisibleItems*2).x())
- {
- _axisMaximums[0] = c->getItemData((c->itemsSize()-1) -_maxVisibleItems*2).x();
- }
- }
-
- float axis[4] = {0};
- for(int i=0; i<4; ++i)
- {
- axis[i] = _axisMaximums[i];
- }
-
- _verticalAxis->setAxis(axis[2], axis[3]);
- _horizontalAxis->setAxis(axis[0], axis[1]);
- if(_aGraphicsView->isChecked() && !painter)
- {
- _verticalAxis->update();
- _horizontalAxis->update();
- }
-
- //ULOGGER_DEBUG("x1=%f, x2=%f, y1=%f, y2=%f", _axisMaximums[0], _axisMaximums[1], _axisMaximums[2], _axisMaximums[3]);
-
- QRectF newRect(0,0, _graphicsViewHolder->size().width(), _graphicsViewHolder->size().height());
- _view->scene()->setSceneRect(newRect);
- float borderHor = (float)_horizontalAxis->border();
- float borderVer = (float)_verticalAxis->border();
-
- //grid
- qDeleteAll(hGridLines);
- hGridLines.clear();
- qDeleteAll(vGridLines);
- vGridLines.clear();
- if(_aShowGrid->isChecked())
- {
- // TODO make a PlotGrid class ?
- float w = newRect.width()-(borderHor*2);
- float h = newRect.height()-(borderVer*2);
- float stepH = w / float(_horizontalAxis->count());
- float stepV = h / float(_verticalAxis->count());
- QPen dashPen(Qt::DashLine);
- dashPen.setColor(QColor(255-_bgColor.red(), 255-_bgColor.green(), 255-_bgColor.blue(), 100));
- QPen pen(dashPen.color());
- for(float i=0.0f; i*stepV <= h+stepV; i+=5.0f)
- {
- //horizontal lines
- if(!_aGraphicsView->isChecked())
- {
- if(painter)
- {
- painter->save();
- painter->setPen(pen);
- painter->drawLine(0, stepV*i+borderVer+0.5f, borderHor, stepV*i+borderVer+0.5f);
-
- painter->setPen(dashPen);
- painter->drawLine(borderHor, stepV*i+borderVer+0.5f, w+borderHor, stepV*i+borderVer+0.5f);
-
- painter->setPen(pen);
- painter->drawLine(w+borderHor, stepV*i+borderVer+0.5f, w+borderHor*2, stepV*i+borderVer+0.5f);
- painter->restore();
- }
- }
- else
- {
- hGridLines.append(new QGraphicsLineItem(0, stepV*i+borderVer, borderHor, stepV*i+borderVer, _sceneRoot));
- hGridLines.last()->setPen(pen);
- hGridLines.append(new QGraphicsLineItem(borderHor, stepV*i+borderVer, w+borderHor, stepV*i+borderVer, _sceneRoot));
- hGridLines.last()->setPen(dashPen);
- hGridLines.append(new QGraphicsLineItem(w+borderHor, stepV*i+borderVer, w+borderHor*2, stepV*i+borderVer, _sceneRoot));
- hGridLines.last()->setPen(pen);
- }
- }
- for(float i=0; i*stepH < w+stepH; i+=5.0f)
- {
- //vertical lines
- if(!_aGraphicsView->isChecked())
- {
- if(painter)
- {
- painter->save();
- painter->setPen(pen);
- painter->drawLine(stepH*i+borderHor+0.5f, 0, stepH*i+borderHor+0.5f, borderVer);
-
- painter->setPen(dashPen);
- painter->drawLine(stepH*i+borderHor+0.5f, borderVer, stepH*i+borderHor+0.5f, h+borderVer);
-
- painter->setPen(pen);
- painter->drawLine(stepH*i+borderHor+0.5f, h+borderVer, stepH*i+borderHor+0.5f, h+borderVer*2);
- painter->restore();
- }
- }
- else
- {
- vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, 0, stepH*i+borderHor, borderVer, _sceneRoot));
- vGridLines.last()->setPen(pen);
- vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, borderVer, stepH*i+borderHor, h+borderVer, _sceneRoot));
- vGridLines.last()->setPen(dashPen);
- vGridLines.append(new QGraphicsLineItem(stepH*i+borderHor, h+borderVer, stepH*i+borderHor, h+borderVer*2, _sceneRoot));
- vGridLines.last()->setPen(pen);
- }
- }
- }
-
- // curves
- float scaleX = 1;
- float scaleY = 1;
- float den = 0;
- den = axis[1] - axis[0];
- if(den != 0)
- {
- scaleX = (newRect.width()-(borderHor*2)) / den;
- }
- den = axis[3] - axis[2];
- if(den != 0)
- {
- scaleY = (newRect.height()-(borderVer*2)) / den;
- }
- for(QList::iterator i=_curves.begin(); i!=_curves.end(); ++i)
- {
- if((*i)->isVisible())
- {
- float xDir = 1.0f;
- float yDir = -1.0f;
- (*i)->update(scaleX,
- scaleY,
- xDir<0?axis[1]+borderHor/scaleX:-(axis[0]-borderHor/scaleX),
- yDir<0?axis[3]+borderVer/scaleY:-(axis[2]-borderVer/scaleY),
- xDir,
- yDir,
- _aKeepAllData->isChecked()?0:_maxVisibleItems);
- if(painter)
- {
- (*i)->draw(painter, QRect(0,0,_graphicsViewHolder->rect().width(), _graphicsViewHolder->rect().height()));
- }
- }
- }
-
- // Update refresh rate
- if(_aShowRefreshRate->isChecked())
- {
- int refreshRate = qRound(1000.0f/float(_refreshIntervalTime.restart()));
- if(refreshRate > 0 && refreshRate < _lowestRefreshRate)
- {
- _lowestRefreshRate = refreshRate;
- }
- // Refresh the label only after each 1000 ms
- if(_refreshStartTime.elapsed() > 1000)
- {
- _refreshRate->setText(QString::number(_lowestRefreshRate));
- _lowestRefreshRate = 99;
- _refreshStartTime.start();
- }
- }
-}
-
-void UPlot::setFixedXAxis(float x1, float x2)
-{
- _fixedAxis[0] = true;
- _axisMaximums[0] = x1;
- _axisMaximums[1] = x2;
-}
-
-void UPlot::setFixedYAxis(float y1, float y2)
-{
- _fixedAxis[1] = true;
- _axisMaximums[2] = y1;
- _axisMaximums[3] = y2;
-}
-
-void UPlot::updateAxis(const UPlotCurve * curve)
-{
- if(curve && curve->isVisible() && curve->itemsSize() && curve->isMinMaxValid())
- {
- const QVector & minMax = curve->getMinMax();
- //ULOGGER_DEBUG("x1=%f, x2=%f, y1=%f, y2=%f", minMax[0], minMax[1], minMax[2], minMax[3]);
- if(minMax.size() != 4)
- {
- ULOGGER_ERROR("minMax size != 4 ?!?");
- return;
- }
- this->updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
- _aGraphicsView->isChecked()?this->replot(0):this->update();
- }
-}
-
-bool UPlot::updateAxis(float x1, float x2, float y1, float y2)
-{
- bool modified = false;
- modified = updateAxis(x1,y1);
- if(!modified)
- {
- modified = updateAxis(x2,y2);
- }
- else
- {
- updateAxis(x2,y2);
- }
- return modified;
-}
-
-bool UPlot::updateAxis(float x, float y)
-{
- //ULOGGER_DEBUG("x=%f, y=%f", x,y);
- bool modified = false;
- if(!_fixedAxis[0] && (!_axisMaximumsSet[0] || x < _axisMaximums[0]))
- {
- _axisMaximums[0] = x;
- _axisMaximumsSet[0] = true;
- modified = true;
- }
-
- if(!_fixedAxis[0] && (!_axisMaximumsSet[1] || x > _axisMaximums[1]))
- {
- _axisMaximums[1] = x;
- _axisMaximumsSet[1] = true;
- modified = true;
- }
-
- if(!_fixedAxis[1] && (!_axisMaximumsSet[2] || y < _axisMaximums[2]))
- {
- _axisMaximums[2] = y;
- _axisMaximumsSet[2] = true;
- modified = true;
- }
-
- if(!_fixedAxis[1] && (!_axisMaximumsSet[3] || y > _axisMaximums[3]))
- {
- _axisMaximums[3] = y;
- _axisMaximumsSet[3] = true;
- modified = true;
- }
-
- return modified;
-}
-
-void UPlot::updateAxis()
-{
- //Reset the axis
- for(int i=0; i<4; ++i)
- {
- if((!_fixedAxis[0] && i<2) || (!_fixedAxis[1] && i>=2))
- {
- _axisMaximums[i] = 0;
- _axisMaximumsSet[i] = false;
- }
- }
-
- for(int i=0; i<_curves.size(); ++i)
- {
- if(_curves.at(i)->isVisible() && _curves.at(i)->isMinMaxValid())
- {
- const QVector & minMax = _curves.at(i)->getMinMax();
- this->updateAxis(minMax[0], minMax[1], minMax[2], minMax[3]);
- }
- }
-
- _aGraphicsView->isChecked()?this->replot(0):this->update();
-
- this->captureScreen();
-}
-
-void UPlot::paintEvent(QPaintEvent * event)
-{
-#if PRINT_DEBUG
- UDEBUG("");
-#endif
- if(!_aGraphicsView->isChecked())
- {
- QPainter painter(this);
- painter.translate(_graphicsViewHolder->pos());
- painter.save();
- painter.setBrush(_bgColor);
- painter.setPen(QPen(Qt::NoPen));
- painter.drawRect(_graphicsViewHolder->rect());
- painter.restore();
-
- this->replot(&painter);
-
- if(_mouseCurrentPos != _mousePressedPos)
- {
- painter.save();
- int left, top, right, bottom;
- left = _mousePressedPos.x() < _mouseCurrentPos.x() ? _mousePressedPos.x()-_graphicsViewHolder->x():_mouseCurrentPos.x()-_graphicsViewHolder->x();
- top = _mousePressedPos.y() < _mouseCurrentPos.y() ? _mousePressedPos.y()-1-_graphicsViewHolder->y():_mouseCurrentPos.y()-1-_graphicsViewHolder->y();
- right = _mousePressedPos.x() > _mouseCurrentPos.x() ? _mousePressedPos.x()-_graphicsViewHolder->x():_mouseCurrentPos.x()-_graphicsViewHolder->x();
- bottom = _mousePressedPos.y() > _mouseCurrentPos.y() ? _mousePressedPos.y()-_graphicsViewHolder->y():_mouseCurrentPos.y()-_graphicsViewHolder->y();
- if(left <= 0)
- {
- left = 1;
- }
- if(right >= _graphicsViewHolder->width())
- {
- right = _graphicsViewHolder->width()-1;
- }
- if(top <= 0)
- {
- top = 1;
- }
- if(bottom >= _graphicsViewHolder->height())
- {
- bottom = _graphicsViewHolder->height()-1;
- }
- painter.setPen(Qt::NoPen);
- painter.setBrush(QBrush(QColor(255-_bgColor.red(),255-_bgColor.green(),255-_bgColor.blue(),100)));
- painter.drawRect(0, 0, _graphicsViewHolder->width(), top);
- painter.drawRect(0, top, left, bottom-top);
- painter.drawRect(right, top, _graphicsViewHolder->width()-right, bottom-top);
- painter.drawRect(0, bottom, _graphicsViewHolder->width(), _graphicsViewHolder->height()-bottom);
- painter.restore();
- }
- }
- else
- {
- QWidget::paintEvent(event);
- }
-}
-
-void UPlot::resizeEvent(QResizeEvent * event)
-{
- if(_aGraphicsView->isChecked())
- {
- this->replot(0);
- }
- QWidget::resizeEvent(event);
-}
-
-void UPlot::mousePressEvent(QMouseEvent * event)
-{
- _mousePressedPos = event->pos();
- _mouseCurrentPos = _mousePressedPos;
- QWidget::mousePressEvent(event);
-}
-
-void UPlot::mouseMoveEvent(QMouseEvent * event)
-{
- if(!_aGraphicsView->isChecked())
- {
- if(!(QApplication::mouseButtons() & Qt::LeftButton))
- {
- _mousePressedPos = _mouseCurrentPos;
- }
-
- float x,y;
- if(mousePosToValue(event->pos(), x ,y))
- {
- if(QApplication::mouseButtons() & Qt::LeftButton)
- {
- _mouseCurrentPos = event->pos();
- this->update();
- }
-
- int xPos = event->pos().x() - _graphicsViewHolder->pos().x();
- int yPos = event->pos().y() - _graphicsViewHolder->pos().y();
- if((QApplication::mouseButtons() & Qt::LeftButton) ||
- (_aMouseTracking->isChecked() && xPos>=0 && yPos>=0 && xPos<_graphicsViewHolder->width() && yPos<_graphicsViewHolder->height()))
- {
- QToolTip::showText(event->globalPos(), QString("%1,%2").arg(x).arg(y));
- }
- else
- {
- QToolTip::hideText();
- }
- }
- else
- {
- QToolTip::hideText();
- }
- }
- QWidget::mouseMoveEvent(event);
-}
-
-void UPlot::mouseReleaseEvent(QMouseEvent * event)
-{
- if(_mousePressedPos != _mouseCurrentPos)
- {
- int left,top,bottom,right;
-
- left = _mousePressedPos.x() < _mouseCurrentPos.x() ? _mousePressedPos.x():_mouseCurrentPos.x();
- top = _mousePressedPos.y() < _mouseCurrentPos.y() ? _mousePressedPos.y():_mouseCurrentPos.y();
- right = _mousePressedPos.x() > _mouseCurrentPos.x() ? _mousePressedPos.x():_mouseCurrentPos.x();
- bottom = _mousePressedPos.y() > _mouseCurrentPos.y() ? _mousePressedPos.y():_mouseCurrentPos.y();
-
- if(right - left > 5 || bottom - top > 5)
- {
- float axis[4];
- if(mousePosToValue(QPoint(left, top), axis[0], axis[3]) && mousePosToValue(QPoint(right, bottom), axis[1], axis[2]))
- {
-#if PRINT_DEBUG
- UDEBUG("resize! new axis = [%f, %f, %f, %f]", axis[0], axis[1], axis[2], axis[3]);
-#endif
- //update axis (only if not fixed)
- for(int i=0; i<4; ++i)
- {
- if((!_fixedAxis[0] && i<2) || (!_fixedAxis[1] && i>=2))
- {
- _axisMaximums[i] = axis[i];
- }
- }
- _aGraphicsView->isChecked()?this->replot(0):this->update();
- }
- }
- _mousePressedPos = _mouseCurrentPos;
- }
- QWidget::mouseReleaseEvent(event);
-}
-
-void UPlot::mouseDoubleClickEvent(QMouseEvent * event)
-{
- this->updateAxis();
- QWidget::mouseDoubleClickEvent(event);
-}
-
-bool UPlot::mousePosToValue(const QPoint & pos, float & x, float & y)
-{
- int xPos = pos.x() - _graphicsViewHolder->pos().x() - _horizontalAxis->border();
- int yPos = pos.y() - _graphicsViewHolder->pos().y() - _verticalAxis->border();
- int maxX = _graphicsViewHolder->width() - _horizontalAxis->border()*2;
- int maxY = _graphicsViewHolder->height() - _verticalAxis->border()*2;
- if(maxX == 0 || maxY == 0)
- {
- return false;
- }
-
- if(xPos < 0)
- {
- xPos = 0;
- }
- else if(xPos > maxX)
- {
- xPos = maxX;
- }
-
- if(yPos < 0)
- {
- yPos = 0;
- }
- else if(yPos > maxY)
- {
- yPos = maxY;
- }
-
- //UDEBUG("IN");
- //UDEBUG("x1=%f, x2=%f, y1=%f, y2=%f", _axisMaximums[0], _axisMaximums[1], _axisMaximums[2], _axisMaximums[3]);
- //UDEBUG("border hor=%f ver=%f", (float)_horizontalAxis->border(), (float)_verticalAxis->border());
- //UDEBUG("rect = %d,%d %d,%d", _graphicsViewHolder->pos().x(), _graphicsViewHolder->pos().y(), _graphicsViewHolder->width(), _graphicsViewHolder->height());
- //UDEBUG("%d,%d", event->pos().x(), event->pos().y());
- //UDEBUG("x/y %d,%d", x, y);
- //UDEBUG("max %d,%d", maxX, maxY);
-
- //UDEBUG("map %f,%f", x, y);
- x = _axisMaximums[0] + float(xPos)*(_axisMaximums[1] - _axisMaximums[0]) / float(maxX);
- y = _axisMaximums[2] + float(maxY - yPos)*(_axisMaximums[3] - _axisMaximums[2]) / float(maxY);
- return true;
-}
-
-void UPlot::contextMenuEvent(QContextMenuEvent * event)
-{
- QAction * action = _menu->exec(event->globalPos());
-
- if(!action)
- {
- return;
- }
- else if(action == _aShowLegend)
- {
- this->showLegend(_aShowLegend->isChecked());
- }
- else if(action == _aShowGrid)
- {
- this->showGrid(_aShowGrid->isChecked());
- }
- else if(action == _aShowRefreshRate)
- {
- this->showRefreshRate(_aShowRefreshRate->isChecked());
- }
- else if(action == _aMouseTracking)
- {
- this->trackMouse(_aMouseTracking->isChecked());
- }
- else if(action == _aGraphicsView)
- {
- this->setGraphicsView(_aGraphicsView->isChecked());
- }
- else if(action == _aKeepAllData)
- {
- this->keepAllData(_aKeepAllData->isChecked());
- }
- else if(action == _aLimit0 ||
- action == _aLimit10 ||
- action == _aLimit50 ||
- action == _aLimit100 ||
- action == _aLimit500 ||
- action == _aLimit1000 ||
- action == _aLimitCustom)
- {
- this->setMaxVisibleItems(action->text().toInt());
- }
- else if(action == _aAddVerticalLine || action == _aAddHorizontalLine)
- {
- bool ok;
- QString text = QInputDialog::getText(this, action->text(), tr("New line name :"), QLineEdit::Normal, "", &ok);
- while(ok && text.isEmpty())
- {
- QMessageBox::warning(this, action->text(), tr("The name is not valid or it is already used in this plot."));
- text = QInputDialog::getText(this, action->text(), tr("New line name :"), QLineEdit::Normal, "", &ok);
- }
- if(ok)
- {
- double min = _axisMaximums[2];
- double max = _axisMaximums[3];
- QString axis = "Y";
- if(action == _aAddVerticalLine)
- {
- min = _axisMaximums[0];
- max = _axisMaximums[1];
- axis = "X";
- }
- double value = QInputDialog::getDouble(this,
- action->text(),
- tr("%1 value (min=%2, max=%3):").arg(axis).arg(min).arg(max),
- (min+max)/2,
- -2147483647,
- 2147483647,
- 4,
- &ok);
- if(ok)
- {
- if(action == _aAddHorizontalLine)
- {
- this->addThreshold(text, value, Qt::Horizontal);
- }
- else
- {
- this->addThreshold(text, value, Qt::Vertical);
- }
- }
- }
- }
- else if(action == _aChangeTitle)
- {
- bool ok;
- QString text = _title->text();
- if(text.isEmpty())
- {
- text = this->objectName();
- }
- text = QInputDialog::getText(this, _aChangeTitle->text(), tr("Title :"), QLineEdit::Normal, text, &ok);
- if(ok)
- {
- this->setTitle(text);
- }
- }
- else if(action == _aChangeXLabel)
- {
- bool ok;
- QString text = QInputDialog::getText(this, _aChangeXLabel->text(), tr("X axis label :"), QLineEdit::Normal, _xLabel->text(), &ok);
- if(ok)
- {
- this->setXLabel(text);
- }
- }
- else if(action == _aChangeYLabel)
- {
- bool ok;
- QString text = QInputDialog::getText(this, _aChangeYLabel->text(), tr("Y axis label :"), QLineEdit::Normal, _yLabel->text(), &ok);
- if(ok)
- {
- this->setYLabel(text, _yLabel->orientation());
- }
- }
- else if(action == _aYLabelVertical)
- {
- this->setYLabel(_yLabel->text(), _aYLabelVertical->isChecked()?Qt::Vertical:Qt::Horizontal);
- }
- else if(action == _aChangeBackgroundColor)
- {
- QColor color = QColorDialog::getColor(_bgColor, this);
- if(color.isValid())
- {
- this->setBackgroundColor(color);
- }
- }
- else if(action == _aSaveFigure)
- {
-
- QString text;
-#ifdef QT_SVG_LIB
- text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), (QDir::homePath() + "/") + this->title() + ".png", "*.png *.xpm *.jpg *.pdf *.svg");
-#else
- text = QFileDialog::getSaveFileName(this, tr("Save figure to ..."), (QDir::homePath() + "/") + this->title() + ".png", "*.png *.xpm *.jpg *.pdf");
-#endif
- if(!text.isEmpty())
- {
- bool flatModified = false;
- if(!_legend->isFlat())
- {
- _legend->setFlat(true);
- flatModified = true;
- }
-
- QPalette p(palette());
- // Set background color to white
- QColor c = p.color(QPalette::Background);
- p.setColor(QPalette::Background, Qt::white);
- setPalette(p);
-
-#ifdef QT_SVG_LIB
- if(QFileInfo(text).suffix().compare("svg") == 0)
- {
- QSvgGenerator generator;
- generator.setFileName(text);
- generator.setSize(this->size());
- QPainter painter;
- painter.begin(&generator);
- this->render(&painter);
- painter.end();
- }
- else
- {
-#endif
- if(QFileInfo(text).suffix().compare("pdf") == 0)
- {
- QPrinter printer;
- printer.setOutputFormat(QPrinter::PdfFormat);
- printer.setOutputFileName(text);
- this->render(&printer);
- }
- else
- {
- QPixmap figure = QPixmap::grabWidget(this);
- figure.save(text);
- }
-#ifdef QT_SVG_LIB
- }
-#endif
- // revert background color
- p.setColor(QPalette::Background, c);
- setPalette(p);
-
- if(flatModified)
- {
- _legend->setFlat(false);
- }
- }
- }
- else if(action == _aAutoScreenCapture)
- {
- if(_aAutoScreenCapture->isChecked())
- {
- this->selectScreenCaptureFormat();
- }
- }
- else if(action == _aClearData)
- {
- this->clearData();
- }
- else
- {
- ULOGGER_WARN("Unknown action");
- }
-}
-
-void UPlot::setWorkingDirectory(const QString & workingDirectory)
-{
- if(QDir(_workingDirectory).exists())
- {
- _workingDirectory = workingDirectory;
- }
- else
- {
- ULOGGER_ERROR("The directory \"%s\" doesn't exist", workingDirectory.toStdString().c_str());
- }
-}
-
-void UPlot::captureScreen()
-{
- if(!_aAutoScreenCapture->isChecked())
- {
- return;
- }
- QString targetDir = _workingDirectory + "/ScreensCaptured";
- QDir dir;
- if(!dir.exists(targetDir))
- {
- dir.mkdir(targetDir);
- }
- targetDir += "/";
- targetDir += this->title().replace(" ", "_");
- if(!dir.exists(targetDir))
- {
- dir.mkdir(targetDir);
- }
- targetDir += "/";
- QString name = (QDateTime::currentDateTime().toString("yyMMddhhmmsszzz") + ".") + _autoScreenCaptureFormat;
- QPixmap figure = QPixmap::grabWidget(this);
- figure.save(targetDir + name);
-}
-
-void UPlot::selectScreenCaptureFormat()
-{
- QStringList items;
- items << QString("png") << QString("jpg");
- bool ok;
- QString item = QInputDialog::getItem(this, tr("Select format"), tr("Format:"), items, 0, false, &ok);
- if(ok && !item.isEmpty())
- {
- _autoScreenCaptureFormat = item;
- }
- this->captureScreen();
-}
-
-void UPlot::clearData()
-{
- for(int i=0; i<_curves.size(); ++i)
- {
- // Don't clear threshold curves
- if(qobject_cast(_curves.at(i)) == 0)
- {
- _curves.at(i)->clear();
- }
- }
- _aGraphicsView->isChecked()?this->replot(0):this->update();
-}
-
-// for convenience...
-UPlotCurveThreshold * UPlot::addThreshold(const QString & name, float value, Qt::Orientation orientation)
-{
- UPlotCurveThreshold * curve = new UPlotCurveThreshold(name, value, orientation, this);
- QPen pen = curve->pen();
- pen.setStyle((Qt::PenStyle)(_penStyleCount++ % 4 + 2));
- curve->setPen(pen);
- if(!this->addCurve(curve))
- {
- if(curve)
- {
- delete curve;
- }
- }
- else
- {
- _aGraphicsView->isChecked()?this->replot(0):this->update();
- }
- return curve;
-}
-
-void UPlot::setTitle(const QString & text)
-{
- _title->setText(text);
- _title->setVisible(!text.isEmpty());
- this->update();
- if(_aGraphicsView->isChecked())
- {
- QTimer::singleShot(10, this, SLOT(updateAxis()));
- }
-}
-
-void UPlot::setXLabel(const QString & text)
-{
- _xLabel->setText(text);
- _xLabel->setVisible(!text.isEmpty());
- this->update();
- if(_aGraphicsView->isChecked())
- {
- QTimer::singleShot(10, this, SLOT(updateAxis()));
- }
-}
-
-void UPlot::setYLabel(const QString & text, Qt::Orientation orientation)
-{
- _yLabel->setText(text);
- _yLabel->setOrientation(orientation);
- _yLabel->setVisible(!text.isEmpty());
- _aYLabelVertical->setChecked(orientation==Qt::Vertical);
- this->update();
- if(_aGraphicsView->isChecked())
- {
- QTimer::singleShot(10, this, SLOT(updateAxis()));
- }
-}
-
-void UPlot::setBackgroundColor(const QColor & color)
-{
- if(color.isValid())
- {
- _bgColor = color;
- _view->scene()->setBackgroundBrush(QBrush(_bgColor));
- for(QList::iterator iter=_curves.begin(); iter!=_curves.end(); ++iter)
- {
- (*iter)->setItemsColor(QColor(255-_bgColor.red(), 255-_bgColor.green(), 255-_bgColor.blue(), _bgColor.alpha()));
- }
- }
-}
-
-void UPlot::addItem(QGraphicsItem * item)
-{
- item->setParentItem(_sceneRoot);
- item->setZValue(1.0f);
-}
-
-void UPlot::showLegend(bool shown)
-{
- _legend->setVisible(shown);
- _aShowLegend->setChecked(shown);
- this->update();
- if(_aGraphicsView->isChecked())
- {
- QTimer::singleShot(10, this, SLOT(updateAxis()));
- }
-}
-
-void UPlot::showGrid(bool shown)
-{
- _aShowGrid->setChecked(shown);
- _aGraphicsView->isChecked()?this->replot(0):this->update();
-}
-
-void UPlot::showRefreshRate(bool shown)
-{
- _aShowRefreshRate->setChecked(shown);
- _refreshRate->setVisible(shown);
- this->update();
- if(_aGraphicsView->isChecked())
- {
- QTimer::singleShot(10, this, SLOT(updateAxis()));
- }
-}
-
-void UPlot::trackMouse(bool tracking)
-{
- _aMouseTracking->setChecked(tracking);
- this->setMouseTracking(tracking);
-}
-
-void UPlot::setGraphicsView(bool on)
-{
- _aGraphicsView->setChecked(on);
- _view->setVisible(on);
- _aGraphicsView->isChecked()?this->replot(0):this->update();
- _aMouseTracking->setEnabled(!on);
-}
-
-void UPlot::keepAllData(bool kept)
-{
- _aKeepAllData->setChecked(kept);
-}
-
-void UPlot::setMaxVisibleItems(int maxVisibleItems)
-{
- if(maxVisibleItems <= 0)
- {
- _aLimit0->setChecked(true);
- }
- else if(maxVisibleItems == 10)
- {
- _aLimit10->setChecked(true);
- }
- else if(maxVisibleItems == 50)
- {
- _aLimit50->setChecked(true);
- }
- else if(maxVisibleItems == 100)
- {
- _aLimit100->setChecked(true);
- }
- else if(maxVisibleItems == 500)
- {
- _aLimit500->setChecked(true);
- }
- else if(maxVisibleItems == 1000)
- {
- _aLimit1000->setChecked(true);
- }
- else
- {
- _aLimitCustom->setVisible(true);
- _aLimitCustom->setChecked(true);
- _aLimitCustom->setText(QString::number(maxVisibleItems));
- }
- _maxVisibleItems = maxVisibleItems;
- updateAxis();
-}
-
-QRectF UPlot::sceneRect() const
-{
- return _view->sceneRect();
-}
-
-void UPlot::removeCurves()
-{
- QList tmp = _curves;
- for(QList::iterator iter=tmp.begin(); iter!=tmp.end(); ++iter)
- {
- this->removeCurve(*iter);
- }
- _curves.clear();
-}
-
-void UPlot::removeCurve(const UPlotCurve * curve)
-{
- QList::iterator iter = qFind(_curves.begin(), _curves.end(), curve);
-#if PRINT_DEBUG
- ULOGGER_DEBUG("Plot=\"%s\" removing curve=\"%s\"", this->objectName().toStdString().c_str(), curve?curve->name().toStdString().c_str():"");
-#endif
- if(iter!=_curves.end())
- {
- UPlotCurve * c = *iter;
- c->detach(this);
- _curves.erase(iter);
- _legend->remove(c);
- if(!qobject_cast(c))
- {
- // transfer update connection to next curve
- for(int i=_curves.size()-1; i>=0; --i)
- {
- if(!qobject_cast(_curves.at(i)))
- {
- connect(_curves.at(i), SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateAxis()));
- break;
- }
- }
- }
-
- if(c->parent() == this)
- {
- delete c;
- }
- // Update axis
- updateAxis();
- }
-}
-
-void UPlot::showCurve(const UPlotCurve * curve, bool shown)
-{
- QList::iterator iter = qFind(_curves.begin(), _curves.end(), curve);
- if(iter!=_curves.end())
- {
- UPlotCurve * value = *iter;
- if(value->isVisible() != shown)
- {
- value->setVisible(shown);
- this->updateAxis();
- }
- }
-}
-
-void UPlot::moveCurve(const UPlotCurve * curve, int index)
-{
- // this will change the print order
- int currentIndex = -1;
- UPlotCurve * c = 0;
- for(int i=0; i<_curves.size(); ++i)
- {
- if(_curves.at(i) == curve)
- {
- c = _curves.at(i);
- currentIndex = i;
- break;
- }
- }
-
- if(c && currentIndex != index)
- {
- _curves.removeAt(currentIndex);
- QList children = _sceneRoot->childItems();
- _curves.insert(index, c);
- if(currentIndex > index)
- {
- children[currentIndex]->stackBefore(children[index]);
- }
- else
- {
- if(currentIndexstackBefore(children[currentIndex]);
- }
- else
- {
- children[currentIndex]->stackBefore(children[index]);
- }
- }
- if(currentIndex == children.size()-2 && currentIndex < index)
- {
- children[index]->stackBefore(children[currentIndex]);
- }
- }
- this->update();
- }
-}