diff --git a/src/kdefrontend/ui/datapickerimagewidget.ui b/src/kdefrontend/ui/datapickerimagewidget.ui
index c7e8d6cdd..02c3a8763 100644
--- a/src/kdefrontend/ui/datapickerimagewidget.ui
+++ b/src/kdefrontend/ui/datapickerimagewidget.ui
@@ -1,1105 +1,1102 @@
DatapickerImageWidget
0
0
784
1181
-
0
0
0
General
-
Name:
-
0
0
true
-
Comment:
-
0
0
true
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
75
true
Plot
-
Image:
-
Specify the name of the image file.
true
-
0
0
Select the image file to import
-
Type:
-
-
Rotation:
-
0
0
°
-360.000000000000000
360.000000000000000
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
1.
-
-
0
0
-9999.000000000000000
9999.000000000000000
-
0
0
-
- 2
-
-9999.000000000000000
9999.000000000000000
-
0
0
-9999.000000000000000
9999.000000000000000
-
y=
Qt::AlignCenter
-
x=
Qt::AlignCenter
-
z=
Qt::AlignCenter
-
0
0
-9999.000000000000000
9999.000000000000000
-
0
0
-9999.000000000000000
9999.000000000000000
-
y=
Qt::AlignCenter
-
0
0
-9999.000000000000000
9999.000000000000000
-
0
0
-9999.000000000000000
9999.000000000000000
-
x=
Qt::AlignCenter
-
Qt::Horizontal
40
20
-
Qt::Horizontal
40
20
-
z=
Qt::AlignCenter
-
0
0
-9999.000000000000000
9999.000000000000000
-
y=
Qt::AlignCenter
-
Qt::Horizontal
40
20
-
0
0
-9999.000000000000000
9999.000000000000000
-
z=
Qt::AlignCenter
-
x=
Qt::AlignCenter
-
2.
-
3.
-
x+y+z=
-
-
75
true
Segments
-
Length:
-
0
0
px
-
Point separation:
-
Qt::Horizontal
QSizePolicy::Fixed
13
23
-
0
0
px
-
Qt::Vertical
20
231
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
75
true
Reference Points
Ref. Points Symbol
-
75
true
General
-
Style:
-
Qt::Horizontal
QSizePolicy::Fixed
13
23
-
0
0
-
Size:
-
pt
0.500000000000000
-
Rotation:
-
0
0
°
-360
360
10
0
-
Opacity:
-
0
0
The opacity ranges from 0 to 100, where 0 is fully transparent and 100 is fully opaque.
%
0
100
10
100
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
75
true
Filling
-
Style:
-
-
Color:
-
0
0
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
75
true
Border
-
Style:
-
-
Color:
-
0
0
-
Width:
-
pt
0.500000000000000
-
Qt::Vertical
20
40
-
Visible
Edit Image
-
-
-
-
Intensity:
-
-
-
-
0
0
Vertical position relative to label's parent
-
-
Qt::Vertical
QSizePolicy::Fixed
20
18
-
Value:
-
Hue:
-
Qt::Vertical
20
40
-
Current image:
-
-
-
Saturation:
-
Foreground:
-
-
Qt::Horizontal
QSizePolicy::Fixed
13
23
KColorButton
QPushButton
leName
leComment
leFileName
bOpen
cbGraphType
sbRotation
sbPositionX1
sbPositionY1
sbPositionZ1
sbPositionX2
sbPositionY2
sbPositionZ2
sbPositionX3
sbPositionY3
sbPositionZ3
sbTernaryScale
sbMinSegmentLength
sbPointSeparation
sbSymbolBorderWidth
sbSymbolRotation
cbSymbolStyle
sbSymbolOpacity
chbSymbolVisible
cbSymbolFillingStyle
cbPlotImageType
tabWidget
kcbSymbolFillingColor
sbSymbolSize
cbSymbolBorderStyle
kcbSymbolBorderColor
diff --git a/src/kdefrontend/widgets/DatapickerImageWidget.cpp b/src/kdefrontend/widgets/DatapickerImageWidget.cpp
index aa24592f1..a6fc7bcca 100644
--- a/src/kdefrontend/widgets/DatapickerImageWidget.cpp
+++ b/src/kdefrontend/widgets/DatapickerImageWidget.cpp
@@ -1,899 +1,904 @@
/***************************************************************************
File : DatapickerImageWidget.cpp
Project : LabPlot
Description : widget for datapicker properties
--------------------------------------------------------------------
Copyright : (C) 2015-2016 by Ankit Wagadre (wagadre.ankit@gmail.com)
Copyright : (C) 2015-2019 by Alexander Semke (alexander.semke@web.de)
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program 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 General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
* Boston, MA 02110-1301 USA *
* *
***************************************************************************/
#include "DatapickerImageWidget.h"
#include "backend/datapicker/DatapickerPoint.h"
#include "commonfrontend/widgets/qxtspanslider.h"
#include "kdefrontend/GuiTools.h"
#include "backend/worksheet/Worksheet.h"
#include "backend/worksheet/plots/cartesian/Symbol.h"
#include "backend/datapicker/ImageEditor.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
HistogramView::HistogramView(QWidget* parent, int range) : QGraphicsView(parent),
m_scene(new QGraphicsScene()),
m_range(range) {
setTransform(QTransform());
QRectF pageRect( 0, 0, 1000, 100 );
m_scene->setSceneRect(pageRect);
setScene(m_scene);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
m_lowerSlider = new QGraphicsRectItem(pageRect, nullptr);
m_lowerSlider->setPen(QPen(Qt::black, 0.5));
m_lowerSlider->setBrush(Qt::blue);
m_lowerSlider->setOpacity(0.2);
m_scene->addItem(m_lowerSlider);
m_upperSlider = new QGraphicsRectItem(pageRect, nullptr);
m_upperSlider->setPen(QPen(Qt::black, 0.5));
m_upperSlider->setBrush(Qt::blue);
m_upperSlider->setOpacity(0.2);
m_scene->addItem(m_upperSlider);
}
void HistogramView::setScalePixmap(const QString& file) {
// scene rect is 1000*100 where upper 1000*80 is for histogram graph
// and lower 1000*20 is for histogram scale
QGraphicsPixmapItem* pixmap = new QGraphicsPixmapItem(QPixmap(file).scaled( 1000, 20, Qt::IgnoreAspectRatio), nullptr);
pixmap->setZValue(-1);
pixmap->setPos(0, 90);
m_scene->addItem(pixmap);
}
void HistogramView::setSpan(int l, int h) {
l = l*1000/m_range;
h = h*1000/m_range;
m_lowerSlider->setPos(QPointF(l - 1000, 0));
m_upperSlider->setPos(QPointF(h, 0));
invalidateScene(sceneRect(), QGraphicsScene::BackgroundLayer);
}
void HistogramView::resizeEvent(QResizeEvent *event) {
fitInView(m_scene->sceneRect(), Qt::IgnoreAspectRatio);
QGraphicsView::resizeEvent(event);
}
void HistogramView::drawBackground(QPainter* painter, const QRectF& rect) {
if (!bins)
return;
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
int max = 1;
for (int i = 0; i <= m_range; i++)
if (bins [i] > max)
max = bins [i];
// convert y-scale count to log scale so small counts are still visible
// scene rect is 1000*100 where upper 1000*80 is for histogram graph
// and lower 1000*20 is for histogram scale
QPainterPath path(QPointF(0, (log(bins[0])*100/log(max))));
for (int i = 1; i <= m_range; i++) {
int x = i*1000/m_range;
int y = 80;
if ( bins[i] > 1 )
y = 80 - (log(bins[i])*80/log(max));
path.lineTo(QPointF(x, y));
}
painter->drawPath(path);
invalidateScene(rect, QGraphicsScene::BackgroundLayer);
painter->restore();
}
DatapickerImageWidget::DatapickerImageWidget(QWidget* parent) : BaseDock(parent), m_image(nullptr) {
ui.setupUi(this);
m_leName = ui.leName;
m_leComment = ui.leComment;
ui.leFileName->setClearButtonEnabled(true);
ui.bOpen->setIcon( QIcon::fromTheme("document-open") );
ui.leFileName->setCompleter(new QCompleter(new QDirModel, this));
auto* editTabLayout = static_cast(ui.tEdit->layout());
editTabLayout->setContentsMargins(2,2,2,2);
editTabLayout->setHorizontalSpacing(2);
editTabLayout->setVerticalSpacing(4);
ssHue = new QxtSpanSlider(Qt::Horizontal, ui.tEdit);
ssHue->setToolTip(i18n("Select the range for the hue.\nEverything outside of this range will be set to white."));
ssHue->setRange(0, 360);
editTabLayout->addWidget(ssHue, 3, 2);
ssSaturation = new QxtSpanSlider(Qt::Horizontal, ui.tEdit);
ssSaturation->setToolTip(i18n("Select the range for the saturation.\nEverything outside of this range will be set to white."));
ssSaturation->setRange(0,100);
editTabLayout->addWidget(ssSaturation, 5, 2);
ssValue = new QxtSpanSlider(Qt::Horizontal, ui.tEdit);
ssValue->setToolTip(i18n("Select the range for the value, the degree of lightness of the color.\nEverything outside of this range will be set to white."));
ssValue->setRange(0,100);
editTabLayout->addWidget(ssValue, 7, 2);
ssIntensity = new QxtSpanSlider(Qt::Horizontal, ui.tEdit);
ssIntensity->setToolTip(i18n("Select the range for the intensity.\nEverything outside of this range will be set to white."));
ssIntensity->setRange(0, 100);
editTabLayout->addWidget(ssIntensity, 9, 2);
ssForeground = new QxtSpanSlider(Qt::Horizontal, ui.tEdit);
ssForeground->setToolTip(i18n("Select the range for the colors that are not part of the background color.\nEverything outside of this range will be set to white."));
ssForeground->setRange(0, 100);
editTabLayout->addWidget(ssForeground, 11, 2);
ui.cbGraphType->addItem(i18n("Cartesian (x, y)"));
ui.cbGraphType->addItem(i18n("Polar (x, y°)"));
ui.cbGraphType->addItem(i18n("Polar (x, y(rad))"));
ui.cbGraphType->addItem(i18n("Logarithmic (ln(x), y)"));
ui.cbGraphType->addItem(i18n("Logarithmic (x, ln(y))"));
ui.cbGraphType->addItem(i18n("Ternary (x, y, z)"));
ui.lTernaryScale->setHidden(true);
ui.sbTernaryScale->setHidden(true);
ui.lPositionZ1->setHidden(true);
ui.lPositionZ2->setHidden(true);
ui.lPositionZ3->setHidden(true);
ui.sbPositionZ1->setHidden(true);
ui.sbPositionZ2->setHidden(true);
ui.sbPositionZ3->setHidden(true);
ui.cbPlotImageType->addItem(i18n("No Image"));
ui.cbPlotImageType->addItem(i18n("Original Image"));
ui.cbPlotImageType->addItem(i18n("Processed Image"));
QString valueFile = QStandardPaths::locate(QStandardPaths::AppDataLocation, "pics/colorchooser/colorchooser_value.xpm");
QString hueFile = QStandardPaths::locate(QStandardPaths::AppDataLocation, "pics/colorchooser/colorchooser_hue.xpm");
QString saturationFile = QStandardPaths::locate(QStandardPaths::AppDataLocation, "pics/colorchooser/colorchooser_saturation.xpm");
gvHue = new HistogramView(ui.tEdit, ImageEditor::colorAttributeMax(DatapickerImage::Hue));
gvHue->setToolTip(i18n("Select the range for the hue.\nEverything outside of this range will be set to white."));
editTabLayout->addWidget(gvHue, 2, 2);
gvHue->setScalePixmap(hueFile);
gvSaturation = new HistogramView(ui.tEdit, ImageEditor::colorAttributeMax(DatapickerImage::Saturation));
gvSaturation->setToolTip(i18n("Select the range for the saturation.\nEverything outside of this range will be set to white."));
editTabLayout->addWidget(gvSaturation, 4, 2);
gvSaturation->setScalePixmap(saturationFile);
gvValue = new HistogramView(ui.tEdit, ImageEditor::colorAttributeMax(DatapickerImage::Value));
gvValue->setToolTip(i18n("Select the range for the value, the degree of lightness of the color.\nEverything outside of this range will be set to white."));
editTabLayout->addWidget(gvValue, 6,2);
gvValue->setScalePixmap(valueFile);
gvIntensity = new HistogramView(ui.tEdit, ImageEditor::colorAttributeMax(DatapickerImage::Intensity));
gvIntensity->setToolTip(i18n("Select the range for the intensity.\nEverything outside of this range will be set to white."));
editTabLayout->addWidget(gvIntensity, 8, 2);
gvIntensity->setScalePixmap(valueFile);
gvForeground = new HistogramView(ui.tEdit, ImageEditor::colorAttributeMax(DatapickerImage::Foreground));
gvForeground->setToolTip(i18n("Select the range for the colors that are not part of the background color.\nEverything outside of this range will be set to white."));
editTabLayout->addWidget(gvForeground, 10, 2);
gvForeground->setScalePixmap(valueFile);
//SLOTS
//general
connect(ui.leName, &QLineEdit::textChanged, this, &DatapickerImageWidget::nameChanged);
connect(ui.leComment, &QLineEdit::textChanged, this, &DatapickerImageWidget::commentChanged);
connect(ui.bOpen, &QPushButton::clicked, this, &DatapickerImageWidget::selectFile);
connect(ui.leFileName, &QLineEdit::returnPressed, this, &DatapickerImageWidget::fileNameChanged);
connect(ui.leFileName, &QLineEdit::textChanged, this, &DatapickerImageWidget::fileNameChanged);
// edit image
connect(ui.cbPlotImageType, static_cast(&QComboBox::currentIndexChanged),
this, &DatapickerImageWidget::plotImageTypeChanged);
connect(ui.sbRotation, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::rotationChanged);
connect(ssIntensity, &QxtSpanSlider::spanChanged, this, &DatapickerImageWidget::intensitySpanChanged);
connect(ssIntensity, &QxtSpanSlider::spanChanged, gvIntensity, &HistogramView::setSpan);
connect(ssForeground, &QxtSpanSlider::spanChanged, this, &DatapickerImageWidget::foregroundSpanChanged);
connect(ssForeground, &QxtSpanSlider::spanChanged, gvForeground, &HistogramView::setSpan );
connect(ssHue, &QxtSpanSlider::spanChanged, this, &DatapickerImageWidget::hueSpanChanged);
connect(ssHue, &QxtSpanSlider::spanChanged, gvHue, &HistogramView::setSpan );
connect(ssSaturation, &QxtSpanSlider::spanChanged, this, &DatapickerImageWidget::saturationSpanChanged);
connect(ssSaturation, &QxtSpanSlider::spanChanged, gvSaturation, &HistogramView::setSpan );
connect(ssValue, &QxtSpanSlider::spanChanged, this, &DatapickerImageWidget::valueSpanChanged);
connect(ssValue, &QxtSpanSlider::spanChanged, gvValue, &HistogramView::setSpan );
connect(ui.sbMinSegmentLength, static_cast(&QSpinBox::valueChanged),
this, &DatapickerImageWidget::minSegmentLengthChanged);
connect(ui.sbPointSeparation, static_cast(&QSpinBox::valueChanged),
this, &DatapickerImageWidget::pointSeparationChanged);
//axis point
connect(ui.cbGraphType, static_cast(&QComboBox::currentIndexChanged),
this, &DatapickerImageWidget::graphTypeChanged);
connect(ui.sbTernaryScale, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::ternaryScaleChanged);
connect(ui.sbPositionX1, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionY1, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionX2, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionY2, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionX3, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionY3, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionZ1, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionZ2, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
connect(ui.sbPositionZ3, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::logicalPositionChanged);
//SYMBOL
connect(ui.cbSymbolStyle, static_cast(&QComboBox::currentIndexChanged),
this, &DatapickerImageWidget::pointsStyleChanged);
connect(ui.sbSymbolSize, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::pointsSizeChanged);
connect(ui.sbSymbolRotation,static_cast(&QSpinBox::valueChanged),
this, &DatapickerImageWidget::pointsRotationChanged);
connect(ui.sbSymbolOpacity, static_cast(&QSpinBox::valueChanged),
this, &DatapickerImageWidget::pointsOpacityChanged);
//Filling
connect(ui.cbSymbolFillingStyle, static_cast(&QComboBox::currentIndexChanged),
this, &DatapickerImageWidget::pointsFillingStyleChanged);
connect(ui.kcbSymbolFillingColor, &KColorButton::changed, this, &DatapickerImageWidget::pointsFillingColorChanged);
//border
connect(ui.cbSymbolBorderStyle, static_cast(&QComboBox::currentIndexChanged),
this, &DatapickerImageWidget::pointsBorderStyleChanged);
connect(ui.kcbSymbolBorderColor, &KColorButton::changed, this, &DatapickerImageWidget::pointsBorderColorChanged);
connect(ui.sbSymbolBorderWidth, static_cast(&QDoubleSpinBox::valueChanged),
this, &DatapickerImageWidget::pointsBorderWidthChanged);
connect(ui.chbSymbolVisible, &QCheckBox::clicked, this, &DatapickerImageWidget::pointsVisibilityChanged);
init();
}
void DatapickerImageWidget::init() {
m_initializing = true;
GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, Qt::black);
QPainter pa;
int iconSize = 20;
QPixmap pm(iconSize, iconSize);
QPen pen(Qt::SolidPattern, 0);
ui.cbSymbolStyle->setIconSize(QSize(iconSize, iconSize));
QTransform trafo;
trafo.scale(15, 15);
//TODO: constant?
for (int i = 1; i < 19; ++i) {
auto style = (Symbol::Style)i;
pm.fill(Qt::transparent);
pa.begin(&pm);
pa.setPen( pen );
pa.setRenderHint(QPainter::Antialiasing);
pa.translate(iconSize/2,iconSize/2);
pa.drawPath(trafo.map(Symbol::pathFromStyle(style)));
pa.end();
ui.cbSymbolStyle->addItem(QIcon(pm), Symbol::nameFromStyle(style));
}
GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, Qt::black);
m_initializing = false;
}
void DatapickerImageWidget::setImages(QList list) {
m_initializing = true;
m_imagesList = list;
m_image = list.first();
m_aspect = list.first()->parentAspect();
if (list.size() == 1) {
ui.lName->setEnabled(true);
ui.leName->setEnabled(true);
ui.lComment->setEnabled(true);
ui.leComment->setEnabled(true);
ui.leName->setText(m_image->parentAspect()->name());
ui.leComment->setText(m_image->parentAspect()->comment());
} else {
ui.lName->setEnabled(false);
ui.leName->setEnabled(false);
ui.lComment->setEnabled(false);
ui.leComment->setEnabled(false);
ui.leName->setText(QString());
ui.leComment->setText(QString());
}
this->load();
initConnections();
handleWidgetActions();
updateSymbolWidgets();
m_initializing = false;
}
void DatapickerImageWidget::initConnections() {
connect(m_image->parentAspect(), &AbstractAspect::aspectDescriptionChanged, this, &DatapickerImageWidget::imageDescriptionChanged);
connect(m_image, &DatapickerImage::fileNameChanged, this, &DatapickerImageWidget::imageFileNameChanged);
connect(m_image, &DatapickerImage::rotationAngleChanged, this, &DatapickerImageWidget::imageRotationAngleChanged);
connect(m_image, &AbstractAspect::aspectRemoved, this, &DatapickerImageWidget::updateSymbolWidgets);
connect(m_image, &AbstractAspect::aspectAdded, this, &DatapickerImageWidget::updateSymbolWidgets);
connect(m_image, &DatapickerImage::axisPointsChanged, this, &DatapickerImageWidget::imageAxisPointsChanged);
connect(m_image, &DatapickerImage::settingsChanged, this, &DatapickerImageWidget::imageEditorSettingsChanged);
connect(m_image, &DatapickerImage::minSegmentLengthChanged, this, &DatapickerImageWidget::imageMinSegmentLengthChanged);
connect(m_image, &DatapickerImage::pointStyleChanged, this, &DatapickerImageWidget::symbolStyleChanged);
connect(m_image, &DatapickerImage::pointSizeChanged, this, &DatapickerImageWidget::symbolSizeChanged);
connect(m_image, &DatapickerImage::pointRotationAngleChanged, this, &DatapickerImageWidget::symbolRotationAngleChanged);
connect(m_image, &DatapickerImage::pointOpacityChanged, this, &DatapickerImageWidget::symbolOpacityChanged);
connect(m_image, &DatapickerImage::pointBrushChanged, this, &DatapickerImageWidget::symbolBrushChanged);
connect(m_image, &DatapickerImage::pointPenChanged, this, &DatapickerImageWidget::symbolPenChanged);
connect(m_image, &DatapickerImage::pointVisibilityChanged, this, &DatapickerImageWidget::symbolVisibleChanged);
}
void DatapickerImageWidget::handleWidgetActions() {
QString fileName = ui.leFileName->text().trimmed();
bool b = !fileName.isEmpty();
ui.tEdit->setEnabled(b);
ui.cbGraphType->setEnabled(b);
ui.sbRotation->setEnabled(b);
ui.sbPositionX1->setEnabled(b);
ui.sbPositionX2->setEnabled(b);
ui.sbPositionX3->setEnabled(b);
ui.sbPositionY1->setEnabled(b);
ui.sbPositionY2->setEnabled(b);
ui.sbPositionY3->setEnabled(b);
ui.sbMinSegmentLength->setEnabled(b);
ui.sbPointSeparation->setEnabled(b);
if (b) {
//upload histogram to view
gvIntensity->bins = m_image->intensityBins;
gvForeground->bins = m_image->foregroundBins;
gvHue->bins = m_image->hueBins;
gvSaturation->bins = m_image->saturationBins;
gvValue->bins = m_image->valueBins;
}
}
//**********************************************************
//****** SLOTs for changes triggered in DatapickerImageWidget ********
//**********************************************************
//"General"-tab
void DatapickerImageWidget::selectFile() {
KConfigGroup conf(KSharedConfig::openConfig(), "DatapickerImageWidget");
QString dir = conf.readEntry("LastImageDir", "");
QString formats;
for (const QByteArray& format : QImageReader::supportedImageFormats()) {
QString f = "*." + QString(format.constData());
if (f == QLatin1String("*.svg"))
continue;
formats.isEmpty() ? formats += f : formats += " " + f;
}
QString path = QFileDialog::getOpenFileName(this, i18n("Select the image file"), dir, i18n("Images (%1)", formats));
if (path.isEmpty())
return; //cancel was clicked in the file-dialog
int pos = path.lastIndexOf(QDir::separator());
if (pos != -1) {
QString newDir = path.left(pos);
if (newDir != dir)
conf.writeEntry("LastImageDir", newDir);
}
ui.leFileName->setText( path );
handleWidgetActions();
for (auto* image : m_imagesList)
image->setFileName(path);
}
void DatapickerImageWidget::fileNameChanged() {
if (m_initializing)
return;
handleWidgetActions();
QString fileName = ui.leFileName->text();
if (!fileName.isEmpty() && !QFile::exists(fileName))
ui.leFileName->setStyleSheet("QLineEdit{background:red;}");
else
ui.leFileName->setStyleSheet(QString());
for (auto* image : m_imagesList)
image->setFileName(fileName);
}
void DatapickerImageWidget::graphTypeChanged() {
if (m_initializing)
return;
DatapickerImage::ReferencePoints points = m_image->axisPoints();
points.type = DatapickerImage::GraphType(ui.cbGraphType->currentIndex());
if (points.type != DatapickerImage::Ternary) {
ui.lTernaryScale->setHidden(true);
ui.sbTernaryScale->setHidden(true);
ui.lPositionZ1->setHidden(true);
ui.lPositionZ2->setHidden(true);
ui.lPositionZ3->setHidden(true);
ui.sbPositionZ1->setHidden(true);
ui.sbPositionZ2->setHidden(true);
ui.sbPositionZ3->setHidden(true);
} else {
ui.lTernaryScale->setHidden(false);
ui.sbTernaryScale->setHidden(false);
ui.lPositionZ1->setHidden(false);
ui.lPositionZ2->setHidden(false);
ui.lPositionZ3->setHidden(false);
ui.sbPositionZ1->setHidden(false);
ui.sbPositionZ2->setHidden(false);
ui.sbPositionZ3->setHidden(false);
}
for (auto* image : m_imagesList)
image->setAxisPoints(points);
}
void DatapickerImageWidget::ternaryScaleChanged(double value) {
if (m_initializing)
return;
DatapickerImage::ReferencePoints points = m_image->axisPoints();
points.ternaryScale = value;
for (auto* image : m_imagesList)
image->setAxisPoints(points);
}
void DatapickerImageWidget::logicalPositionChanged() {
+ DEBUG("DatapickerImageWidget::logicalPositionChanged() m_initializing = " << m_initializing)
if (m_initializing)
return;
DatapickerImage::ReferencePoints points = m_image->axisPoints();
points.logicalPos[0].setX(ui.sbPositionX1->value());
points.logicalPos[0].setY(ui.sbPositionY1->value());
points.logicalPos[1].setX(ui.sbPositionX2->value());
points.logicalPos[1].setY(ui.sbPositionY2->value());
points.logicalPos[2].setX(ui.sbPositionX3->value());
points.logicalPos[2].setY(ui.sbPositionY3->value());
points.logicalPos[0].setZ(ui.sbPositionZ1->value());
points.logicalPos[1].setZ(ui.sbPositionZ2->value());
points.logicalPos[2].setZ(ui.sbPositionZ3->value());
for (auto* image : m_imagesList)
image->setAxisPoints(points);
}
void DatapickerImageWidget::pointsStyleChanged(int index) {
auto style = Symbol::Style(index + 1);
//enable/disable the filling options in the GUI depending on the currently selected points.
if (style != Symbol::Line && style != Symbol::Cross) {
ui.cbSymbolFillingStyle->setEnabled(true);
bool noBrush = (Qt::BrushStyle(ui.cbSymbolFillingStyle->currentIndex()) == Qt::NoBrush);
ui.kcbSymbolFillingColor->setEnabled(!noBrush);
} else {
ui.kcbSymbolFillingColor->setEnabled(false);
ui.cbSymbolFillingStyle->setEnabled(false);
}
bool noLine = (Qt::PenStyle(ui.cbSymbolBorderStyle->currentIndex()) == Qt::NoPen);
ui.kcbSymbolBorderColor->setEnabled(!noLine);
ui.sbSymbolBorderWidth->setEnabled(!noLine);
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPointStyle(style);
}
void DatapickerImageWidget::pointsSizeChanged(double value) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPointSize( Worksheet::convertToSceneUnits(value, Worksheet::Point) );
}
void DatapickerImageWidget::pointsRotationChanged(int value) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPointRotationAngle(value);
}
void DatapickerImageWidget::pointsOpacityChanged(int value) {
if (m_initializing)
return;
qreal opacity = (float)value/100.;
for (auto* image : m_imagesList)
image->setPointOpacity(opacity);
}
void DatapickerImageWidget::pointsFillingStyleChanged(int index) {
auto brushStyle = Qt::BrushStyle(index);
ui.kcbSymbolFillingColor->setEnabled(!(brushStyle == Qt::NoBrush));
if (m_initializing)
return;
QBrush brush;
for (auto* image : m_imagesList) {
brush = image->pointBrush();
brush.setStyle(brushStyle);
image->setPointBrush(brush);
}
}
void DatapickerImageWidget::pointsFillingColorChanged(const QColor& color) {
if (m_initializing)
return;
QBrush brush;
for (auto* image : m_imagesList) {
brush = image->pointBrush();
brush.setColor(color);
image->setPointBrush(brush);
}
m_initializing = true;
GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, color );
m_initializing = false;
}
void DatapickerImageWidget::pointsBorderStyleChanged(int index) {
auto penStyle = Qt::PenStyle(index);
if ( penStyle == Qt::NoPen ) {
ui.kcbSymbolBorderColor->setEnabled(false);
ui.sbSymbolBorderWidth->setEnabled(false);
} else {
ui.kcbSymbolBorderColor->setEnabled(true);
ui.sbSymbolBorderWidth->setEnabled(true);
}
if (m_initializing)
return;
QPen pen;
for (auto* image : m_imagesList) {
pen = image->pointPen();
pen.setStyle(penStyle);
image->setPointPen(pen);
}
}
void DatapickerImageWidget::pointsBorderColorChanged(const QColor& color) {
if (m_initializing)
return;
QPen pen;
for (auto* image : m_imagesList) {
pen = image->pointPen();
pen.setColor(color);
image->setPointPen(pen);
}
m_initializing = true;
GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, color);
m_initializing = false;
}
void DatapickerImageWidget::pointsBorderWidthChanged(double value) {
if (m_initializing)
return;
QPen pen;
for (auto* image : m_imagesList) {
pen = image->pointPen();
pen.setWidthF( Worksheet::convertToSceneUnits(value, Worksheet::Point) );
image->setPointPen(pen);
}
}
void DatapickerImageWidget::pointsVisibilityChanged(bool state) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPointVisibility(state);
}
void DatapickerImageWidget::intensitySpanChanged(int lowerLimit, int upperLimit) {
if (m_initializing)
return;
DatapickerImage::EditorSettings settings = m_image->settings();
settings.intensityThresholdHigh = upperLimit;
settings.intensityThresholdLow = lowerLimit;
for (auto* image : m_imagesList)
image->setSettings(settings);
}
void DatapickerImageWidget::foregroundSpanChanged(int lowerLimit, int upperLimit) {
if (m_initializing)
return;
DatapickerImage::EditorSettings settings = m_image->settings();
settings.foregroundThresholdHigh = upperLimit;
settings.foregroundThresholdLow = lowerLimit;
for (auto* image : m_imagesList)
image->setSettings(settings);
}
void DatapickerImageWidget::hueSpanChanged(int lowerLimit, int upperLimit) {
if (m_initializing)
return;
DatapickerImage::EditorSettings settings = m_image->settings();
settings.hueThresholdHigh = upperLimit;
settings.hueThresholdLow = lowerLimit;
for (auto* image : m_imagesList)
image->setSettings(settings);
}
void DatapickerImageWidget::saturationSpanChanged(int lowerLimit, int upperLimit) {
if (m_initializing)
return;
DatapickerImage::EditorSettings settings = m_image->settings();
settings.saturationThresholdHigh = upperLimit;
settings.saturationThresholdLow = lowerLimit;
for (auto* image : m_imagesList)
image->setSettings(settings);
}
void DatapickerImageWidget::valueSpanChanged(int lowerLimit, int upperLimit) {
if (m_initializing)
return;
DatapickerImage::EditorSettings settings = m_image->settings();
settings.valueThresholdHigh = upperLimit;
settings.valueThresholdLow = lowerLimit;
for (auto* image : m_imagesList)
image->setSettings(settings);
}
void DatapickerImageWidget::plotImageTypeChanged(int index) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPlotImageType(DatapickerImage::PlotImageType(index));
}
void DatapickerImageWidget::rotationChanged(double value) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setRotationAngle(value);
}
void DatapickerImageWidget::minSegmentLengthChanged(int value) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setminSegmentLength(value);
}
void DatapickerImageWidget::pointSeparationChanged(int value) {
if (m_initializing)
return;
for (auto* image : m_imagesList)
image->setPointSeparation(value);
}
//*******************************************************************
//******** SLOTs for changes triggered in DatapickerImage ***********
//*******************************************************************
/*!
* called when the name or comment of image's parent (datapicker) was changed.
*/
void DatapickerImageWidget::imageDescriptionChanged(const AbstractAspect* aspect) {
if (m_image->parentAspect() != aspect)
return;
m_initializing = true;
if (aspect->name() != ui.leName->text()) {
ui.leName->setText(aspect->name());
} else if (aspect->comment() != ui.leComment->text()) {
ui.leComment->setText(aspect->comment());
}
m_initializing = false;
}
void DatapickerImageWidget::imageFileNameChanged(const QString& name) {
m_initializing = true;
ui.leFileName->setText(name);
m_initializing = false;
}
void DatapickerImageWidget::imageRotationAngleChanged(float angle) {
m_initializing = true;
ui.sbRotation->setValue(angle);
m_initializing = false;
}
void DatapickerImageWidget::imageAxisPointsChanged(const DatapickerImage::ReferencePoints& axisPoints) {
+ DEBUG("DatapickerImageWidget::imageAxisPointsChanged()")
m_initializing = true;
ui.cbGraphType->setCurrentIndex((int) axisPoints.type);
ui.sbTernaryScale->setValue(axisPoints.ternaryScale);
- ui.sbPositionX1->setValue(axisPoints.logicalPos[0].x());
+ // this breaks the double spin boxes by setting the value just changed
+ // is there any case where axisPoints.logicalPos is really changed outside the position double spin boxes?
+ /* ui.sbPositionX1->setValue(axisPoints.logicalPos[0].x());
ui.sbPositionY1->setValue(axisPoints.logicalPos[0].y());
ui.sbPositionX2->setValue(axisPoints.logicalPos[1].x());
ui.sbPositionY2->setValue(axisPoints.logicalPos[1].y());
ui.sbPositionX3->setValue(axisPoints.logicalPos[2].x());
ui.sbPositionY3->setValue(axisPoints.logicalPos[2].y());
ui.sbPositionZ1->setValue(axisPoints.logicalPos[0].z());
ui.sbPositionZ2->setValue(axisPoints.logicalPos[1].z());
ui.sbPositionZ3->setValue(axisPoints.logicalPos[2].z());
+ */
m_initializing = false;
}
void DatapickerImageWidget::imageEditorSettingsChanged(const DatapickerImage::EditorSettings& settings) {
m_initializing = true;
ssIntensity->setSpan(settings.intensityThresholdLow, settings.intensityThresholdHigh);
ssForeground->setSpan(settings.foregroundThresholdLow, settings.foregroundThresholdHigh);
ssHue->setSpan(settings.hueThresholdLow, settings.hueThresholdHigh);
ssSaturation->setSpan(settings.saturationThresholdLow, settings.saturationThresholdHigh);
ssValue->setSpan(settings.valueThresholdLow, settings.valueThresholdHigh);
gvIntensity->setSpan(settings.intensityThresholdLow, settings.intensityThresholdHigh);
gvForeground->setSpan(settings.foregroundThresholdLow, settings.foregroundThresholdHigh);
gvHue->setSpan(settings.hueThresholdLow, settings.hueThresholdHigh);
gvSaturation->setSpan(settings.saturationThresholdLow, settings.saturationThresholdHigh);
gvValue->setSpan(settings.valueThresholdLow, settings.valueThresholdHigh);
m_initializing = false;
}
void DatapickerImageWidget::imageMinSegmentLengthChanged(const int value) {
m_initializing = true;
ui.sbMinSegmentLength->setValue(value);
m_initializing = false;
}
void DatapickerImageWidget::updateSymbolWidgets() {
int pointCount = m_image->childCount(AbstractAspect::IncludeHidden);
if (pointCount)
ui.tSymbol->setEnabled(true);
else
ui.tSymbol->setEnabled(false);
}
void DatapickerImageWidget::symbolStyleChanged(Symbol::Style style) {
m_initializing = true;
ui.cbSymbolStyle->setCurrentIndex((int)style - 1);
m_initializing = false;
}
void DatapickerImageWidget::symbolSizeChanged(qreal size) {
m_initializing = true;
ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(size, Worksheet::Point) );
m_initializing = false;
}
void DatapickerImageWidget::symbolRotationAngleChanged(qreal angle) {
m_initializing = true;
ui.sbSymbolRotation->setValue(round(angle));
m_initializing = false;
}
void DatapickerImageWidget::symbolOpacityChanged(qreal opacity) {
m_initializing = true;
ui.sbSymbolOpacity->setValue( round(opacity*100.0) );
m_initializing = false;
}
void DatapickerImageWidget::symbolBrushChanged(const QBrush& brush) {
m_initializing = true;
ui.cbSymbolFillingStyle->setCurrentIndex((int) brush.style());
ui.kcbSymbolFillingColor->setColor(brush.color());
GuiTools::updateBrushStyles(ui.cbSymbolFillingStyle, brush.color());
m_initializing = false;
}
void DatapickerImageWidget::symbolPenChanged(const QPen& pen) {
m_initializing = true;
ui.cbSymbolBorderStyle->setCurrentIndex( (int) pen.style());
ui.kcbSymbolBorderColor->setColor( pen.color());
GuiTools::updatePenStyles(ui.cbSymbolBorderStyle, pen.color());
ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(pen.widthF(), Worksheet::Point));
m_initializing = false;
}
void DatapickerImageWidget::symbolVisibleChanged(bool on) {
m_initializing = true;
ui.chbSymbolVisible->setChecked(on);
m_initializing = false;
}
//**********************************************************
//******************** SETTINGS ****************************
//**********************************************************
void DatapickerImageWidget::load() {
if (!m_image)
return;
m_initializing = true;
ui.leFileName->setText( m_image->fileName() );
//highlight the text field for the background image red if an image is used and cannot be found
if (!m_image->fileName().isEmpty() && !QFile::exists(m_image->fileName()))
ui.leFileName->setStyleSheet("QLineEdit{background:red;}");
else
ui.leFileName->setStyleSheet(QString());
ui.cbGraphType->setCurrentIndex((int) m_image->axisPoints().type);
ui.sbTernaryScale->setValue(m_image->axisPoints().ternaryScale);
ui.sbPositionX1->setValue(m_image->axisPoints().logicalPos[0].x());
ui.sbPositionY1->setValue(m_image->axisPoints().logicalPos[0].y());
ui.sbPositionX2->setValue(m_image->axisPoints().logicalPos[1].x());
ui.sbPositionY2->setValue(m_image->axisPoints().logicalPos[1].y());
ui.sbPositionX3->setValue(m_image->axisPoints().logicalPos[2].x());
ui.sbPositionY3->setValue(m_image->axisPoints().logicalPos[2].y());
ui.sbPositionZ1->setValue(m_image->axisPoints().logicalPos[0].z());
ui.sbPositionZ2->setValue(m_image->axisPoints().logicalPos[1].z());
ui.sbPositionZ3->setValue(m_image->axisPoints().logicalPos[2].z());
ui.cbPlotImageType->setCurrentIndex((int) m_image->plotImageType());
ssIntensity->setSpan(m_image->settings().intensityThresholdLow, m_image->settings().intensityThresholdHigh);
ssForeground->setSpan(m_image->settings().foregroundThresholdLow, m_image->settings().foregroundThresholdHigh);
ssHue->setSpan(m_image->settings().hueThresholdLow, m_image->settings().hueThresholdHigh);
ssSaturation->setSpan(m_image->settings().saturationThresholdLow, m_image->settings().saturationThresholdHigh);
ssValue->setSpan(m_image->settings().valueThresholdLow, m_image->settings().valueThresholdHigh);
gvIntensity->setSpan(m_image->settings().intensityThresholdLow, m_image->settings().intensityThresholdHigh);
gvForeground->setSpan(m_image->settings().foregroundThresholdLow, m_image->settings().foregroundThresholdHigh);
gvHue->setSpan(m_image->settings().hueThresholdLow, m_image->settings().hueThresholdHigh);
gvSaturation->setSpan(m_image->settings().saturationThresholdLow, m_image->settings().saturationThresholdHigh);
gvValue->setSpan(m_image->settings().valueThresholdLow, m_image->settings().valueThresholdHigh);
ui.sbPointSeparation->setValue(m_image->pointSeparation());
ui.sbMinSegmentLength->setValue(m_image->minSegmentLength());
ui.cbSymbolStyle->setCurrentIndex( (int)m_image->pointStyle() - 1 );
ui.sbSymbolSize->setValue( Worksheet::convertFromSceneUnits(m_image->pointSize(), Worksheet::Point) );
ui.sbSymbolRotation->setValue( m_image->pointRotationAngle() );
ui.sbSymbolOpacity->setValue( round(m_image->pointOpacity()*100.0) );
ui.cbSymbolFillingStyle->setCurrentIndex( (int) m_image->pointBrush().style() );
ui.kcbSymbolFillingColor->setColor( m_image->pointBrush().color() );
ui.cbSymbolBorderStyle->setCurrentIndex( (int) m_image->pointPen().style() );
ui.kcbSymbolBorderColor->setColor( m_image->pointPen().color() );
ui.sbSymbolBorderWidth->setValue( Worksheet::convertFromSceneUnits(m_image->pointPen().widthF(), Worksheet::Point) );
ui.chbSymbolVisible->setChecked( m_image->pointVisibility() );
m_initializing = false;
}