Parameters: added Mem/StereoFromMotion (default false) and RGBD/ProximityOdomGuess (default false). Visual proximity detection is done before computing the loop closure transform (the later is ignored if visual proximity succeeded with a node close to loop closure, add Loop/Suppressed_hypothesis_id statistics to know when this happens). Changed Loop/Map_correction to Loop/Odom_correction (to better see the actual jumps of localization about /base_link frame, not /odom frame). util3d::generateWords3DMono() is now using openCV's implementation of five-point algorithm (this fixed some cases for which the older approach couldn't find any solution). UPlot: added scrolling area on the legend, added global legend option to show all curve statistics (mean, stddev,max). MainWindow's open dialog: reopen last directory when reopening a different database. ParametersToolBox: show default parameter value in tooltip. rtabmap-report: add --start option. rtabmap-reprocess: show details about proximity and loop detections, reset all localization statistics after changing database.

This commit is contained in:
matlabbe
2020-05-19 15:01:50 -04:00
parent 55509c6c27
commit c7b84c60bc
31 changed files with 1889 additions and 1335 deletions

View File

@@ -329,6 +329,7 @@ private:
QString _newDatabasePath;
QString _newDatabasePathOutput;
QString _openedDatabasePath;
QString _defaultOpenDatabasePath;
bool _databaseUpdated;
bool _odomImageShow;
bool _odomImageDepthShow;

View File

@@ -37,6 +37,7 @@ class QGraphicsView;
class QGraphicsScene;
class QGraphicsItem;
class QFormLayout;
class QScrollArea;
/**
* UPlotItem is a QGraphicsEllipseItem and can be inherited to do custom behaviors
@@ -353,6 +354,7 @@ public:
virtual ~UPlotLegendItem();
const UPlotCurve * curve() const {return _curve;}
QPixmap createSymbol(const QPen & pen, const QBrush & brush);
void showStdDevMeanMax(bool shown);
Q_SIGNALS:
void legendItemRemoved(const UPlotCurve *);
@@ -418,6 +420,9 @@ private:
QMenu * _menu;
QAction * _aUseFlatButtons;
QAction * _aCopyAllCurvesToClipboard;
QAction * _aShowAllStdDevMeanMax;
QLayout * _contentLayout;
QScrollArea * _scrollArea;
};

View File

@@ -4817,7 +4817,7 @@ void MainWindow::newDatabase()
void MainWindow::openDatabase()
{
QString path = QFileDialog::getOpenFileName(this, tr("Open database..."), _preferencesDialog->getWorkingDirectory(), tr("RTAB-Map database files (*.db)"));
QString path = QFileDialog::getOpenFileName(this, tr("Open database..."), _defaultOpenDatabasePath.isEmpty()?_preferencesDialog->getWorkingDirectory():_defaultOpenDatabasePath, tr("RTAB-Map database files (*.db)"));
if(!path.isEmpty())
{
this->openDatabase(path);
@@ -4843,6 +4843,7 @@ void MainWindow::openDatabase(const QString & path, const ParametersMap & overri
this->clearTheCache();
_openedDatabasePath = path;
_defaultOpenDatabasePath = path;
// look if there are saved parameters
DBDriver * driver = DBDriver::create();

View File

@@ -521,7 +521,9 @@ void ParametersToolBox::addParameter(QVBoxLayout * layout, const QString & key,
QString tmp = key.split('/').last();
QLabel * label = new QLabel(tmp, this);
label->setObjectName(key+"/label");
label->setToolTip(QString("<FONT>%1</FONT>").arg(Parameters::getDescription(key.toStdString()).c_str()));
label->setToolTip(QString("<FONT>%1 [default=%2]</FONT>")
.arg(Parameters::getDescription(key.toStdString()).c_str())
.arg(uValue(Parameters::getDefaultParameters(), key.toStdString(), std::string("?")).c_str()));
label->setTextInteractionFlags(Qt::TextSelectableByMouse);
hLayout->addWidget(label);
hLayout->addWidget(widget);

View File

@@ -871,6 +871,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->surf_doubleSpinBox_maxDepth->setObjectName(Parameters::kKpMaxDepth().c_str());
_ui->surf_doubleSpinBox_minDepth->setObjectName(Parameters::kKpMinDepth().c_str());
_ui->checkBox_memDepthAsMask->setObjectName(Parameters::kMemDepthAsMask().c_str());
_ui->checkBox_memStereoFromMotion->setObjectName(Parameters::kMemStereoFromMotion().c_str());
_ui->surf_spinBox_wordsPerImageTarget->setObjectName(Parameters::kKpMaxFeatures().c_str());
_ui->spinBox_KPGridRows->setObjectName(Parameters::kKpGridRows().c_str());
_ui->spinBox_KPGridCols->setObjectName(Parameters::kKpGridCols().c_str());
@@ -1030,6 +1031,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->localDetection_maxPaths->setObjectName(Parameters::kRGBDProximityMaxPaths().c_str());
_ui->localDetection_pathFilteringRadius->setObjectName(Parameters::kRGBDProximityPathFilteringRadius().c_str());
_ui->localDetection_angle->setObjectName(Parameters::kRGBDProximityAngle().c_str());
_ui->checkBox_localSpaceOdomGuess->setObjectName(Parameters::kRGBDProximityOdomGuess().c_str());
_ui->checkBox_localSpacePathOdomPosesUsed->setObjectName(Parameters::kRGBDProximityPathRawPosesUsed().c_str());
_ui->rgdb_localImmunizationRatio->setObjectName(Parameters::kRGBDLocalImmunizationRatio().c_str());
_ui->loopClosure_reextract->setObjectName(Parameters::kRGBDLoopClosureReextractFeatures().c_str());

View File

@@ -63,9 +63,9 @@
<property name="geometry">
<rect>
<x>0</x>
<y>-455</y>
<y>0</y>
<width>680</width>
<height>3497</height>
<height>3270</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_16">
@@ -95,7 +95,7 @@
<enum>QFrame::Raised</enum>
</property>
<property name="currentIndex">
<number>21</number>
<number>19</number>
</property>
<widget class="QWidget" name="page_22">
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
@@ -4951,7 +4951,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>13</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -5231,21 +5231,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
</layout>
</widget>
<widget class="QWidget" name="page_77">
<layout class="QVBoxLayout" name="verticalLayout_135">
<item>
<spacer name="verticalSpacer_75">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>471</height>
</size>
</property>
</spacer>
</item>
</layout>
<layout class="QVBoxLayout" name="verticalLayout_135"/>
</widget>
<widget class="QWidget" name="page_80">
<layout class="QVBoxLayout" name="verticalLayout_140">
@@ -5364,7 +5350,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>596</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -8631,7 +8617,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<layout class="QVBoxLayout" name="verticalLayout_60">
<item>
<layout class="QGridLayout" name="gridLayout_32" columnstretch="0,1">
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLabel" name="label_22">
<property name="toolTip">
<string>0 means that the response (hessian) threshold
@@ -8650,7 +8636,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QLabel" name="label_81">
<property name="toolTip">
<string>0 means that the response (hessian) threshold
@@ -8669,7 +8655,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="9" column="1">
<item row="10" column="1">
<widget class="QLabel" name="label_99">
<property name="text">
<string>Top ROI ratio (0 = no change).</string>
@@ -8682,7 +8668,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QDoubleSpinBox" name="surf_doubleSpinBox_ratioBadSign">
<property name="decimals">
<number>2</number>
@@ -8784,14 +8770,14 @@ generate the number of words requested.</string>
</item>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLineEdit" name="lineEdit_kp_roi">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="QLabel" name="label_101">
<property name="text">
<string>ROI ratios [left, right, top, bottom] between 0 and 1.</string>
@@ -8823,7 +8809,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi1">
<property name="suffix">
<string> %</string>
@@ -8868,7 +8854,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QSpinBox" name="surf_spinBox_wordsPerImageTarget">
<property name="minimum">
<number>-1</number>
@@ -8881,7 +8867,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi0">
<property name="suffix">
<string> %</string>
@@ -8891,7 +8877,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QLabel" name="label_97">
<property name="text">
<string>Left ROI ratio (0 = no change).</string>
@@ -8904,7 +8890,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QLabel" name="label_98">
<property name="text">
<string>Right ROI ratio (0 = no change).</string>
@@ -8917,7 +8903,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi2">
<property name="suffix">
<string> %</string>
@@ -8927,7 +8913,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QDoubleSpinBox" name="doubleSpinBox_kp_roi3">
<property name="suffix">
<string> %</string>
@@ -8937,7 +8923,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="10" column="1">
<item row="11" column="1">
<widget class="QLabel" name="label_100">
<property name="text">
<string>Bottom ROI ratio (0 = no change).</string>
@@ -8972,7 +8958,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="11" column="1">
<item row="12" column="1">
<widget class="QLabel" name="label_50">
<property name="toolTip">
<string>0 means that the response (hessian) threshold
@@ -8991,7 +8977,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="11" column="0">
<item row="12" column="0">
<widget class="QSpinBox" name="spinBox_KPGridRows">
<property name="minimum">
<number>1</number>
@@ -9004,7 +8990,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="12" column="0">
<item row="13" column="0">
<widget class="QSpinBox" name="spinBox_KPGridCols">
<property name="minimum">
<number>1</number>
@@ -9017,7 +9003,7 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="12" column="1">
<item row="13" column="1">
<widget class="QLabel" name="label_86">
<property name="toolTip">
<string>0 means that the response (hessian) threshold
@@ -9062,6 +9048,32 @@ generate the number of words requested.</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_582">
<property name="toolTip">
<string>0 means that the response (hessian) threshold
used for the detector will not be adapted.
Otherwise, the threshold is modified to
generate the number of words requested.</string>
</property>
<property name="text">
<string>Triangulate features without depth using stereo from motion (odometry). It would be ignored if depth as mask is checked and the feature detector used supports masking.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_memStereoFromMotion">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
@@ -10497,7 +10509,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</item>
<item>
<layout class="QGridLayout" name="gridLayout_50" columnstretch="0,1">
<item row="4" column="0">
<item row="5" column="0">
<widget class="QDoubleSpinBox" name="localDetection_pathFilteringRadius">
<property name="suffix">
<string> m</string>
@@ -10513,7 +10525,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="5" column="1">
<item row="6" column="1">
<widget class="QLabel" name="label_scanMatching_4">
<property name="text">
<string>When comparing to a local path, merge the laser scans using the odometry poses instead of the ones in the optimized local graph.</string>
@@ -10526,7 +10538,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QLabel" name="label_space3_3">
<property name="text">
<string>Path filtering radius to avoid merging laser scans which are close. 0 to ignore. A path should also be inside that radius to be considered for proximity detection.</string>
@@ -10539,7 +10551,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QCheckBox" name="checkBox_localSpacePathOdomPosesUsed">
<property name="text">
<string/>
@@ -10569,7 +10581,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="7" column="1">
<item row="8" column="1">
<widget class="QLabel" name="label_scanMatching_6">
<property name="text">
<string>Save scan matching IDs in link's user data.</string>
@@ -10582,7 +10594,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QCheckBox" name="checkBox_localSpaceScanMatchingIDsSaved">
<property name="text">
<string/>
@@ -10664,6 +10676,26 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QLabel" name="label_scanMatching_13">
<property name="text">
<string>Use odometry as motion guess for visual proximity detection.</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QCheckBox" name="checkBox_localSpaceOdomGuess">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
@@ -14901,7 +14933,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1029</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -15124,7 +15156,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -15193,7 +15225,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -15387,7 +15419,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>961</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -16200,7 +16232,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>1090</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -16236,7 +16268,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@@ -21674,19 +21706,6 @@ Lower the ratio -&gt; higher the precision.</string>
</widget>
</widget>
</item>
<item>
<spacer name="verticalSpacer_42">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>

View File

@@ -36,6 +36,7 @@
#include <QToolButton>
#include <QLabel>
#include <QMenu>
#include <QStyle>
#include <QInputDialog>
#include <QMessageBox>
#include <QFileDialog>
@@ -1453,18 +1454,7 @@ void UPlotLegendItem::contextMenuEvent(QContextMenuEvent * event)
}
else if(action == _aShowStdDevMeanMax)
{
if(_aShowStdDevMeanMax->isChecked())
{
connect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
updateStdDevMeanMax();
}
else
{
disconnect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
QString nameSpaced = _curve->name();
nameSpaced.replace('_', ' ');
this->setText(nameSpaced);
}
showStdDevMeanMax(_aShowStdDevMeanMax->isChecked());
}
else if(action == _aRemoveCurve)
{
@@ -1480,6 +1470,23 @@ void UPlotLegendItem::contextMenuEvent(QContextMenuEvent * event)
}
}
void UPlotLegendItem::showStdDevMeanMax(bool shown)
{
_aShowStdDevMeanMax->setChecked(shown);
if(shown)
{
connect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
updateStdDevMeanMax();
}
else
{
disconnect(_curve, SIGNAL(dataChanged(const UPlotCurve *)), this, SLOT(updateStdDevMeanMax()));
QString nameSpaced = _curve->name();
nameSpaced.replace('_', ' ');
this->setText(nameSpaced);
}
}
QPixmap UPlotLegendItem::createSymbol(const QPen & pen, const QBrush & brush)
{
QPixmap pixmap(50, 50);
@@ -1501,7 +1508,7 @@ void UPlotLegendItem::updateStdDevMeanMax()
float max = uMax(y.data(), y.size());
QString nameSpaced = _curve->name();
nameSpaced.replace('_', ' ');
nameSpaced += QString("\n(%1=%2, %3=%4, max=%5)").arg(QChar(0xbc, 0x03)).arg(mean).arg(QChar(0xc3, 0x03)).arg(stdDev).arg(max);
nameSpaced += QString("\n(%1=%2, %3=%4, max=%5, n=%6)").arg(QChar(0xbc, 0x03)).arg(QString::number(mean, 'f', 3)).arg(QChar(0xc3, 0x03)).arg(QString::number(stdDev, 'f', 3)).arg(QString::number(max, 'f', 3)).arg(y.size());
this->setText(nameSpaced);
}
@@ -1519,15 +1526,30 @@ UPlotLegend::UPlotLegend(QWidget * parent) :
_aUseFlatButtons->setCheckable(true);
_aUseFlatButtons->setChecked(_flat);
_aCopyAllCurvesToClipboard = new QAction(tr("Copy all curve data to clipboard"), this);
_aShowAllStdDevMeanMax = new QAction(tr("Show all %1, %2, max").arg(QChar(0xbc, 0x03)).arg(QChar(0xc3, 0x03)), this);
_aShowAllStdDevMeanMax->setCheckable(true);
_aShowAllStdDevMeanMax->setChecked(false);
_menu = new QMenu(tr("Legend"), this);
_menu->addAction(_aUseFlatButtons);
_menu->addAction(_aShowAllStdDevMeanMax);
_menu->addAction(_aCopyAllCurvesToClipboard);
QVBoxLayout * vLayout = new QVBoxLayout(this);
vLayout->setContentsMargins(0,0,0,0);
this->setLayout(vLayout);
vLayout->addStretch(0);
vLayout->setSpacing(0);
_scrollArea = new QScrollArea(this);
_scrollArea->setWidgetResizable( true );
_scrollArea->setFrameShape(QFrame::NoFrame);
this->setLayout(new QVBoxLayout());
this->layout()->setContentsMargins(0,0,0,0);
this->layout()->addWidget(_scrollArea);
QWidget * _scrollAreaWidgetContent = new QWidget();
_scrollArea->setWidget( _scrollAreaWidgetContent );
_contentLayout = new QVBoxLayout();
_scrollAreaWidgetContent->setLayout(_contentLayout);
_contentLayout->setContentsMargins(0,0,0,0);
((QVBoxLayout*)_contentLayout)->addStretch(0);
_contentLayout->setSpacing(0);
}
UPlotLegend::~UPlotLegend()
@@ -1573,7 +1595,9 @@ void UPlotLegend::addItem(UPlotCurve * curve)
hLayout->setMargin(0);
// add to the legend
((QVBoxLayout*)this->layout())->insertLayout(this->layout()->count()-1, hLayout);
((QVBoxLayout*)_contentLayout)->insertLayout(_contentLayout->count()-1, hLayout);
_scrollArea->setMinimumWidth(std::min(480, _scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
}
}
@@ -1585,6 +1609,7 @@ bool UPlotLegend::remove(const UPlotCurve * curve)
if(items.at(i)->curve() == curve)
{
delete items.at(i);
_scrollArea->setMinimumWidth(std::min(480, _scrollArea->widget()->sizeHint().width()+QApplication::style()->pixelMetric(QStyle::PM_ScrollBarExtent)));
return true;
}
}
@@ -1603,24 +1628,24 @@ void UPlotLegend::moveUp(UPlotLegendItem * item)
{
int index = -1;
QLayoutItem * layoutItem = 0;
for(int i=0; i<this->layout()->count(); ++i)
for(int i=0; i<_contentLayout->count(); ++i)
{
if(this->layout()->itemAt(i)->layout() &&
this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
if(_contentLayout->itemAt(i)->layout() &&
_contentLayout->itemAt(i)->layout()->indexOf(item) != -1)
{
layoutItem = this->layout()->itemAt(i);
layoutItem = _contentLayout->itemAt(i);
index = i;
break;
}
}
if(index > 0 && layoutItem)
{
this->layout()->removeItem(layoutItem);
_contentLayout->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);
((QVBoxLayout*)_contentLayout)->insertLayout(index-1, hLayout);
delete layoutItem;
Q_EMIT legendItemMoved(item->curve(), index-1);
}
@@ -1630,24 +1655,24 @@ void UPlotLegend::moveDown(UPlotLegendItem * item)
{
int index = -1;
QLayoutItem * layoutItem = 0;
for(int i=0; i<this->layout()->count(); ++i)
for(int i=0; i<_contentLayout->count(); ++i)
{
if(this->layout()->itemAt(i)->layout() &&
this->layout()->itemAt(i)->layout()->indexOf(item) != -1)
if(_contentLayout->itemAt(i)->layout() &&
_contentLayout->itemAt(i)->layout()->indexOf(item) != -1)
{
layoutItem = this->layout()->itemAt(i);
layoutItem = _contentLayout->itemAt(i);
index = i;
break;
}
}
if(index < this->layout()->count()-2 && layoutItem)
if(index < _contentLayout->count()-2 && layoutItem)
{
this->layout()->removeItem(layoutItem);
_contentLayout->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);
((QVBoxLayout*)_contentLayout)->insertLayout(index+1, hLayout);
delete layoutItem;
Q_EMIT legendItemMoved(item->curve(), index+1);
}
@@ -1739,6 +1764,14 @@ void UPlotLegend::contextMenuEvent(QContextMenuEvent * event)
}
}
}
else if(action == _aShowAllStdDevMeanMax)
{
QList<UPlotLegendItem *> items = this->findChildren<UPlotLegendItem*>();
for(int i=0; i<items.size(); ++i)
{
items.at(i)->showStdDevMeanMax(_aShowAllStdDevMeanMax->isChecked());
}
}
}
void UPlotLegend::redirectToggled(bool toggled)