Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Viewer/SituationMap/MapImpl/layer_control_widget.cpp
T
torstenandCopilot 124fbb4de8 Fix Qt6 deprecated APIs: QCheckBox::checkStateChanged, ExploratoryLocationViewshed
- Replace QCheckBox::stateChanged with checkStateChanged in:
  - lts_dialog.cpp
  - simple_esri_layer.cpp (2 occurrences)
  - layer_control_widget.cpp
  - symbol_dialog.cpp
- Replace LocationViewshed with ExploratoryLocationViewshed (ArcGIS SDK v300):
  - viewshed_analysis.h/.cpp
  - ViewshedLocation.h/.cpp
  - function_dialog.cpp (include)
- Update ViewshedLocation member variable type to ExploratoryLocationViewshed

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-13 14:41:33 +02:00

1135 lines
35 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Interface
* $Id$
* $HeadURL$
* $Author$
*/
// Own
#include "layer_control_widget.h"
#include <Map/map.h>
#include <Map/layer_parameter.h>
#include <Map/situation_map_utils.h>
// Qt
#include <QApplication>
#include <QLabel>
#include <QCheckBox>
#include <QPushButton>
#include <QSlider>
#include <QGridLayout>
#include <QDrag>
#include <QMimeData>
#include <QMouseEvent>
#include <QComboBox>
#include <QTimer>
#include <QBuffer>
#include <QToolButton>
#include <QSignalBlocker>
#include <cmath>
namespace SituationMap
{
const QLatin1String MIMETYPE("application/x-dndEsriLayerItemData");
//----------------------------------------------------------------------------
const char LayernameProperty[] = "layername";
//----------------------------------------------------------------------------
class DragableCheckBox : public QCheckBox
{
Q_OBJECT
using BaseClass = QCheckBox;
public:
DragableCheckBox() = default;
explicit DragableCheckBox(const QString &text)
: QCheckBox(text)
{}
~DragableCheckBox() = default;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
private:
QPoint m_dragStartPos;
}; // class LayerControlWidget::Private
//-----------------------------------------------------------------------------
void DragableCheckBox::mousePressEvent(QMouseEvent *event)
{
// qWarning() << LOGFUNCTION << " START";
if (event->button() == Qt::LeftButton)
m_dragStartPos = event->pos();
BaseClass::mousePressEvent(event);
// qWarning() << LOGFUNCTION << " END";
}
void DragableCheckBox::mouseMoveEvent(QMouseEvent *event)
{
// qWarning() << LOGFUNCTION << " START";
if (!(event->buttons() & Qt::LeftButton))
return;
if ((event->pos() - m_dragStartPos).manhattanLength()
< QApplication::startDragDistance())
return;
QByteArray itemData;
QDataStream dataStream(&itemData, QIODevice::WriteOnly);
dataStream << this->property(LayernameProperty).toString(); // == layername
QMimeData *mimeData = new QMimeData;
mimeData->setData(MIMETYPE, itemData);
QDrag *drag = new QDrag(this);
drag->setMimeData(mimeData);
drag->exec(Qt::MoveAction);
// qWarning() << LOGFUNCTION << " END";
}
//-----------------------------------------------------------------------------
struct SliderStruct
{
QCheckBox *cbOnOff = nullptr;
QSlider *sl_opacity = nullptr;
QSlider *sl_brightness = nullptr;
QSlider *sl_contrast = nullptr;
QSlider *sl_gamma = nullptr;
};
class LayerControlWidget::Private
{
public:
Private() = default;
// OWN data:
SituationMap::Map *m_map = nullptr; // Use INTERFACE
QString m_debugInfo;
bool m_zoomRotScaleEnabled = true;
bool m_layerEnabled = true;
bool m_basemapEnabled = true;
QVBoxLayout *m_layout = nullptr;
// MapLayer:
QGridLayout *m_mapLayerLayout = nullptr;
// BaseMapSelection:
QHBoxLayout *m_baseMapSelectLayout = nullptr;
QList<QToolButton *> m_baseMapSelectIcons;
QLabel *m_lbBasemap = nullptr;
QMap<QString, SliderStruct> m_sliderMap;
// Zoom and rotation
QHBoxLayout *m_zoomLayout = nullptr; // will contain zoom and rotation elements
QSlider *m_zoomSlider = nullptr;
QSlider *m_rotationSlider = nullptr;
QSlider *m_symbolSizeSlider = nullptr; // 10 ... 200
QTimer *m_symbolSizeTimer = nullptr;
}; // class LayerControlWidget::Private
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// class LayerControlWidget
//-----------------------------------------------------------------------------
LayerControlWidget::LayerControlWidget(QWidget *parent,
Map *map,
bool enableLayer,
bool enableBasemap,
const QString &debugInfo)
: QWidget(parent)
, d(new Private)
, m_logger(getLogger("LayerControlWidget"))
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START"
<< " debugInfo='" << debugInfo << "'";
d->m_debugInfo = debugInfo;
d->m_map = map;
d->m_layerEnabled = enableLayer;
d->m_basemapEnabled = enableBasemap;
d->m_layout = new QVBoxLayout();
this->setLayout(d->m_layout);
setAcceptDrops(true);
// use QueuedConnect to let dropEvent (and destroying of QDrag object) finish
// BEFORE the panel is updated (and DragableCheckBox - parent of QDrag object - are deleted.)
connect(d->m_map, &Map::layerOrderChanged, this, &LayerControlWidget::updatePanelLayer, Qt::ConnectionType::QueuedConnection);
connect(d->m_map, &Map::layerParameterChanged, this, &LayerControlWidget::onLayerParamterChanged);
connect(d->m_map, &Map::mapReady, this, &LayerControlWidget::onMapReady, Qt::ConnectionType::QueuedConnection);
updatePanel();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
LayerControlWidget::~LayerControlWidget()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
delete d;
}
bool LayerControlWidget::updatePanel()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
updatePanelZoomRotationScales();
updatePanelLayer();
// updatePanelBasemap();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return true;
}
bool LayerControlWidget::updatePanelZoomRotationScales()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (! d->m_zoomRotScaleEnabled)
return false;
if (d->m_zoomLayout)
return true;
d->m_zoomLayout = new QHBoxLayout();
d->m_layout->addLayout(d->m_zoomLayout);
d->m_zoomSlider = generateZoomSlider();
d->m_zoomLayout->addWidget(d->m_zoomSlider);
// problems around scale in 3D:
d->m_zoomSlider->setEnabled(d->m_map->mode() == Mode::Mode_2D);
QComboBox *cmbScale = new QComboBox();
d->m_zoomLayout->addWidget(cmbScale);
cmbScale->addItem(tr("Presets"));
cmbScale->insertSeparator(1);
using scaleDataTyp = QPair<QString, int>;
const auto scaleData = {
scaleDataTyp(QLatin1String(" 1:25000"), 400000),
scaleDataTyp(QLatin1String(" 1:50000"), 200000),
scaleDataTyp(QLatin1String("1:100000"), 100000)
};
for (const scaleDataTyp &item : scaleData)
cmbScale->addItem(item.first, QVariant(item.second)); // stored in Qt::UserRole
// c++11 -> lambda :-)
connect(cmbScale, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, [this, cmbScale](int index)
{
if (index <= 1) return; // 1 Damit 'Presets' + Separator ohne Auswirkung bleibt
int selectedScale = cmbScale->currentData().toInt();
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " cmbScale selectedScale=" << selectedScale;
d->m_map->setScale(selectedScale);
cmbScale->setCurrentIndex(0); // Textausgabe auf 'Presets' setzen
});
//
// Rotation:
//
if (! d->m_rotationSlider)
{
d->m_rotationSlider = generateRotationSlider();
d->m_layout->addWidget(d->m_rotationSlider);
}
//
// SymbolSize:
//
if (! d->m_symbolSizeSlider)
{
d->m_symbolSizeSlider = generateSymbolSizeSlider();
d->m_layout->addWidget(d->m_symbolSizeSlider);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return true;
}
bool LayerControlWidget::updatePanelLayer()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
//
// Layer:
//
// reNew the part of mapLayer :
if (d->m_mapLayerLayout)
{
for (int row = 0; row < d->m_mapLayerLayout->rowCount(); ++row)
{
for (int col = 0; col < d->m_mapLayerLayout->columnCount(); ++col)
{
QLayoutItem *item = d->m_mapLayerLayout->itemAtPosition(row, col);
if (item)
{
QWidget *w = item->widget();
delete w;
// w->deleteLater() --> QCoreApplication::postEvent: Unexpected null receiver (ication/ngl_qt_msg_handler.inc:25)
}
}
}
}
delete d->m_mapLayerLayout;
d->m_mapLayerLayout = nullptr;
d->m_sliderMap.clear();
if (! d->m_layerEnabled)
return false;
d->m_mapLayerLayout = new QGridLayout();
d->m_layout->addLayout(d->m_mapLayerLayout);
int row = 0;
QCheckBox *cbExpand = new QCheckBox(tr("Expand"), this);
d->m_mapLayerLayout->addWidget(cbExpand, row++, 0);
cbExpand->setChecked(false);
connect(cbExpand, &QCheckBox::clicked, this, &LayerControlWidget::expandCollapse);
//
// Fill MapLayerLayout :
//
if (d->m_map)
{
int col = 0;
const auto header = {
tr("Layer"),
tr("Opacity"),
tr("Brightness"),
tr("Contrast"),
tr("Gamma")
};
for (const QString &name : header)
d->m_mapLayerLayout->addWidget(new QLabel(name), row, col++);
const QStringList sl = d->m_map->layerFactory().layernames();
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " layers=" << sl.join(QLatin1Char(';'));
row += sl.count();
for (const QString &layername : sl)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " layerName=" << layername;
int col = 0;
const LayerParameter &lp = d->m_map->layerFactory().layerParameter(layername);
const LayerType &layerType = d->m_map->layerFactory().layerType(layername);
DragableCheckBox *cbOnOff = new DragableCheckBox();
if (lp.displayName.isEmpty())
cbOnOff->setText(layername);
else
cbOnOff->setText(lp.displayName);
cbOnOff->setProperty(LayernameProperty, layername);
d->m_sliderMap[layername].cbOnOff = cbOnOff;
cbOnOff->setObjectName(QLatin1String("DragableCheckBox_") + layername);
cbOnOff->setChecked(lp.visible);
const QString &tooltip = generateToolTip(layername, lp);
if (!tooltip.isEmpty())
cbOnOff->setToolTip(tooltip);
connect(cbOnOff, &QCheckBox::checkStateChanged, this, &LayerControlWidget::layerOnOff);
d->m_mapLayerLayout->addWidget(cbOnOff, row, col++);
mySlider *sl_opac = new mySlider(layername, 0, 100);
d->m_sliderMap[layername].sl_opacity = sl_opac;
sl_opac->setObjectName(QLatin1String("sl_opac"));
sl_opac->setValue(lp.opacity);
connect(sl_opac, &mySlider::valueChanged, this, &LayerControlWidget::opacity);
d->m_mapLayerLayout->addWidget(sl_opac, row, col++);
if (layerType == SituationMap::LayerType::Basemap)
{
mySlider *sl_brightness = new mySlider(layername, -100, 100);
d->m_sliderMap[layername].sl_brightness = sl_brightness;
sl_brightness->setObjectName(QLatin1String("sl_brightness"));
sl_brightness->setValue(lp.brightness);
connect(sl_brightness, &mySlider::valueChanged, this, &LayerControlWidget::brightness);
d->m_mapLayerLayout->addWidget(sl_brightness, row, col++);
mySlider *sl_contrast = new mySlider(layername, -100, 100);
d->m_sliderMap[layername].sl_contrast = sl_contrast;
sl_contrast->setObjectName(QLatin1String("sl_contrast"));
sl_contrast->setValue(lp.contrast);
connect(sl_contrast, &mySlider::valueChanged, this, &LayerControlWidget::contrast);
d->m_mapLayerLayout->addWidget(sl_contrast, row, col++);
mySlider *sl_gamma = new mySlider(layername, -100, 100);
d->m_sliderMap[layername].sl_gamma = sl_gamma;
sl_gamma->setObjectName(QLatin1String("sl_gamma"));
sl_gamma->setValue(lp.gamma);
connect(sl_gamma, &mySlider::valueChanged, this, &LayerControlWidget::gamma);
d->m_mapLayerLayout->addWidget(sl_gamma, row, col++);
}
--row;
}
#ifdef ONLY_FOR_TESTS
QPushButton *pbAddBasemapLayer = new QPushButton(QLatin1String("add BasemapLayer"));
d->m_mapLayerLayout->addWidget(pbAddBasemapLayer);
QLatin1String newBasemapName("basemapAddedByBtn");
QLatin1String newBasemapUrl("http://192.168.133.88:6080/arcgis/rest/services/BremenGeoTiff/MapServer");
// QLatin1String newBasemap("http://192.168.133.88:6080/arcgis/rest/services/BremenGeoTiffUTM/MapServer");
pbAddBasemapLayer->setToolTip(newBasemapUrl);
connect(pbAddBasemapLayer, &QPushButton::clicked, this, [this]()
{
bool success = d->m_map->layerFactory().addBasemap(newBasemapName, newBasemapUrl);
INFO_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " adding basemapLayer, success=" << success;
});
QPushButton *pbRemoveBasemapLayer = new QPushButton(QLatin1String("remove BasemapLayer"));
d->m_mapLayerLayout->addWidget(pbRemoveBasemapLayer);
pbRemoveBasemapLayer->setToolTip(newBasemapUrl);
connect(pbRemoveBasemapLayer, &QPushButton::clicked, this, [this]()
{
bool success = d->m_map->layerFactory().removeBasemap(newBasemapName);
INFO_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " removing basemapLayer, success=" << success;
});
#endif
expandCollapse(cbExpand->isChecked());
}
else
ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " no map !!!";
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return true;
}
bool LayerControlWidget::updatePanelBasemap()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
// clear old widgets:
d->m_baseMapSelectIcons.clear();
if (d->m_baseMapSelectLayout)
{
QLayoutItem *item;
while ((item = d->m_baseMapSelectLayout->takeAt(0)))
{
QWidget *w = item->widget();
delete w;
delete item;
}
}
delete d->m_baseMapSelectLayout;
d->m_baseMapSelectLayout = nullptr;
if (! d->m_basemapEnabled)
return false;
// create from scratch:
if (! d->m_baseMapSelectLayout)
{
QVBoxLayout *vBox = new QVBoxLayout();
if (! d->m_lbBasemap)
d->m_lbBasemap = new QLabel(tr("Basemaps:"));
vBox->addWidget(d->m_lbBasemap);
d->m_baseMapSelectLayout = new QHBoxLayout();
vBox->addLayout(d->m_baseMapSelectLayout);
d->m_layout->addLayout(vBox);
LayerFactory &layFac = d->m_map->layerFactory();
const QStringList &basemapLayernames = layFac.layernames(LayerType::Basemap);
for (const QString &layername : basemapLayernames)
{
// baseMapProxy->setStyleSheet(QLatin1String("QPushButton {background-color: transparent; border: 1px solid transparent;}"));
const LayerParameter &lp = d->m_map->layerFactory().layerParameter(layername);
QToolButton *baseMapProxy = new QToolButton(this);
baseMapProxy->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); // eTextUnderIcon?
baseMapProxy->setText(lp.displayName);
baseMapProxy->setObjectName(d->m_debugInfo + layername);
baseMapProxy->setProperty(LayernameProperty, layername);
baseMapProxy->setIcon(QIcon(QPixmap::fromImage(lp.previewImage)));
baseMapProxy->setIconSize(QSize(40,40));
baseMapProxy->setCheckable(true);
baseMapProxy->setChecked(true); // Assume that all are enable by default
const QString &tooltip = generateToolTip(layername, lp);
if (!tooltip.isEmpty())
baseMapProxy->setToolTip(tooltip);
d->m_baseMapSelectLayout->addWidget(baseMapProxy);
d->m_baseMapSelectIcons.append(baseMapProxy);
connect(baseMapProxy, &QToolButton::clicked, this, &LayerControlWidget::onBaseMapSelection);
} // Q_FOREACH
d->m_baseMapSelectLayout->addStretch(42);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return true;
}
void LayerControlWidget::expandCollapse(bool expanded)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
for (int row = 1; row < d->m_mapLayerLayout->rowCount(); ++row)
{
for (int col = 2; col < d->m_mapLayerLayout->columnCount(); ++col)
{
QLayoutItem *item = d->m_mapLayerLayout->itemAtPosition(row, col);
if (item)
{
QWidget *w = item->widget();
if (w)
w->setVisible(expanded);
}
}
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
QString LayerControlWidget::generateToolTip(const QString &layername,
const LayerParameter &lp)
{
QString tooltip;
tooltip.append(QStringLiteral("<html>"));
tooltip.append(QStringLiteral("<p><b>displayName=%1</b></p>").arg(lp.displayName));
if (! lp.previewImage.isNull())
{
// without a temporary file:
QByteArray data;
QBuffer buffer(&data);
lp.previewImage.save(&buffer, "PNG", 100);
QString html(QLatin1String("<br />"));
html.append(QStringLiteral("<img src='data:image/png;base64,%1'>").arg(QString::fromLatin1(data.toBase64())));
tooltip.append(html);
}
if (lp.basemapType != BasemapType::Undefined)
tooltip.append(QStringLiteral("<p>BasemapType=%1</p>").arg(toDisplayString(lp.basemapType)));
tooltip.append(QStringLiteral("<p>layername=%1</p>").arg(layername));
tooltip.append(QStringLiteral("<p>description=%1</p>").arg(lp.description));
tooltip.append(QStringLiteral("<p>svcDescription=%1</p>").arg(lp.svcDescription));
tooltip.append(QStringLiteral("<p>url=%1</p>").arg(lp.url.toString()));
tooltip.append(QStringLiteral("<p>minScale=%1 - maxScale=%2</p>").arg((int)lp.minScale).arg((int)lp.maxScale));
tooltip.append(QStringLiteral("</html>"));
return tooltip;
}
QSlider *LayerControlWidget::generateZoomSlider()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QSlider *slider = new QSlider(Qt::Orientation::Horizontal);
// 1. Init
if (d->m_map->isReady())
{
// This branch is taken in case of FunctionDialog:
onZoomSliderInit(slider);
}
// 2. extentChanged
// Attention: use identical signal at any other zoom/scale-Slider!!!
connect(d->m_map, &Map::extentChangedDelayed, this, &LayerControlWidget::onMapExtentChanged);
// 3. valueChanged
connect(slider, &QSlider::valueChanged, this, &LayerControlWidget::onZoomSliderValueChanged);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return slider;
}
QSlider *LayerControlWidget::generateRotationSlider()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QSlider *slider = new QSlider();
slider->setToolTip(tr("Rotation"));
slider->setOrientation(Qt::Orientation::Horizontal);
slider->setTickPosition(QSlider::TicksBelow);
slider->setTickInterval(10);
slider->setSingleStep(10);
slider->setMinimum(0);
slider->setMaximum(359);
slider->setValue(0);
if (d->m_map->isReady())
slider->setValue(d->m_map->rotation());
connect(slider, &QSlider::valueChanged, this, &LayerControlWidget::onRotationSliderValueChanged);
connect(d->m_map, &Map::rotationChanged, this, &LayerControlWidget::onRotationOfMapChanged);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return slider;
}
QSlider *LayerControlWidget::generateSymbolSizeSlider()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QSlider *slider = new QSlider();
slider->setToolTip(tr("Symbol Size"));
slider->setOrientation(Qt::Orientation::Horizontal);
slider->setTickPosition(QSlider::TicksBelow);
slider->setTickInterval(10); // 10%
slider->setMinimum(SituationMap::symbolScaleMinimum * 100); // 10%
slider->setMaximum(SituationMap::symbolScaleMaximum * 100); // 200%
slider->setSingleStep(10); // 10%
if (d->m_map->isReady())
slider->setValue(d->m_map->symbolScale() * 100);
connect(slider, &QSlider::valueChanged, this, &LayerControlWidget::onSymbolSizeSliderValueChanged);
connect(d->m_map, &Map::symbolScaleChanged, this, &LayerControlWidget::onSymbolSizeOfMapChanged);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return slider;
}
void LayerControlWidget::onZoomSliderInit(QSlider *slider)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (! slider)
return;
const QSignalBlocker blocker(slider);
slider->setToolTip(tr("Zoom"));
slider->setMinimum(sqrt(d->m_map->maxScale()));
slider->setMaximum(sqrt(d->m_map->minScale()));
onMapExtentChanged();
if (slider->minimum() == slider->maximum())
{
WARNING_LOG(m_logger) << LOGFUNCTION << " min/max value are identical, debugInfo='" << d->m_debugInfo << "'"
<< " minimum=" << slider->minimum()
<< " maximum=" << slider->maximum()
<< " value=" << slider->value();
slider->setMinimum(sqrt(500));
slider->setMaximum(sqrt(100000));
WARNING_LOG(m_logger) << LOGFUNCTION << " min/max value are identical, debugInfo='" << d->m_debugInfo << "'"
<< " minimum=" << slider->minimum()
<< " maximum=" << slider->maximum()
<< " value=" << slider->value();
}
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'"
<< " minimum=" << slider->minimum()
<< " maximum=" << slider->maximum()
<< " value=" << slider->value();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onZoomSliderValueChanged()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QSlider *slider = qobject_cast<QSlider *>(sender());
if (! slider)
return;
if (d->m_map->isReady())
d->m_map->setScale(slider->value() * slider->value());
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'"
<< " new target value: " << slider->value() * slider->value();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onRotationSliderValueChanged()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START"
<< " rawValue = " << d->m_rotationSlider->value();
if (d->m_map->isReady()
// && slider->isSliderDown()
)
{
// ERROR_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " push new value "
// << " slider= " << slider
// << slider->value();
d->m_map->setRotation(d->m_rotationSlider->value());
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onRotationOfMapChanged(double rotation)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START" << " rotation " << rotation;
if (! d->m_rotationSlider)
return;
if (d->m_map->isReady() && !d->m_rotationSlider->isSliderDown())
{
const QSignalBlocker blocker(d->m_rotationSlider);
d->m_rotationSlider->setValue(rotation);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onSymbolSizeSliderValueChanged()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START"
<< " rawValue = " << d->m_symbolSizeSlider->value();
if (!d->m_symbolSizeTimer)
{
d->m_symbolSizeTimer = new QTimer(this);
d->m_symbolSizeTimer->setSingleShot(true);
d->m_symbolSizeTimer->setInterval(500); // msec
connect(d->m_symbolSizeTimer, &QTimer::timeout, this, &LayerControlWidget::onSymbolSizeSliderValueChangedTimeout);
}
d->m_symbolSizeTimer->start(); // start -> restart
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onSymbolSizeSliderValueChangedTimeout()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START"
<< " rawValue = " << d->m_symbolSizeSlider->value();
double symSize = d->m_symbolSizeSlider->value() / 100.0;
d->m_map->setSymbolScale(symSize);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onSymbolSizeOfMapChanged(double symbolSize)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START" << " symbolSize " << symbolSize;
if (! d->m_symbolSizeSlider)
return;
int symSizeInt = symbolSize * 100;
const QSignalBlocker blocker(d->m_symbolSizeSlider);
d->m_symbolSizeSlider->setValue(symSizeInt);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onBaseMapSelection()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QObject *pb = qobject_cast<QObject *>(sender());
if (! pb)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " cast failed";
return;
}
// check/uncheck all:
for (auto widget : std::as_const(d->m_baseMapSelectIcons))
widget->setChecked(widget == pb);
LayerFactory &layFac = d->m_map->layerFactory();
const QStringList &basemapLayernames = layFac.layernames(LayerType::Basemap);
const QString &curName = pb->property(LayernameProperty).toString();
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " sender=" << curName;
for (const QString &name : basemapLayernames)
{
bool isCur = name.compare(curName) == 0;
LayerParameter lp = layFac.layerParameter(name);
if (isCur)
lp.resetView();
lp.visible = isCur;
layFac.setLayerParameter(name, lp);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onMapReady()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
onZoomSliderInit(d->m_zoomSlider);
onRotationOfMapChanged(d->m_map->rotation());
onSymbolSizeOfMapChanged(d->m_map->symbolScale());
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::onMapExtentChanged()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (d->m_zoomSlider && d->m_zoomSlider->isEnabled() && d->m_map->isReady() && (!d->m_zoomSlider->isSliderDown()))
{
const QSignalBlocker blocker(d->m_zoomSlider);
float newVal = sqrt(d->m_map->scale());
d->m_zoomSlider->setValue(newVal);
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'"
<< " d->m_map->scale(): " << d->m_map->scale()
<< "; newVal: " << newVal
<< "; value set to: " << d->m_zoomSlider->value();
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::layerOnOff()
{
QCheckBox *cb = qobject_cast<QCheckBox *>(sender());
if (!cb)
return;
QString layername = cb->property(LayernameProperty).toString();
// get LayerParameter, update data and set:
LayerParameter lp = d->m_map->layerFactory().layerParameter(layername);
lp.visible = cb->isChecked();
d->m_map->layerFactory().setLayerParameter(layername, lp);
}
void LayerControlWidget::opacity(int)
{
mySlider *sl = qobject_cast<mySlider *>(sender());
if (!sl)
return;
QString layername = sl->m_layername;
LayerParameter lp = d->m_map->layerFactory().layerParameter(layername);
lp.opacity = sl->value();
d->m_map->layerFactory().setLayerParameter(layername, lp);
}
void LayerControlWidget::brightness(int)
{
mySlider *sl = qobject_cast<mySlider *>(sender());
if (!sl)
return;
QString layername = sl->m_layername;
LayerParameter lp = d->m_map->layerFactory().layerParameter(layername);
lp.brightness = sl->value();
d->m_map->layerFactory().setLayerParameter(layername, lp);
}
void LayerControlWidget::contrast(int)
{
mySlider *sl = qobject_cast<mySlider *>(sender());
if (!sl)
return;
QString layername = sl->m_layername;
LayerParameter lp = d->m_map->layerFactory().layerParameter(layername);
lp.contrast = sl->value();
d->m_map->layerFactory().setLayerParameter(layername, lp);
}
void LayerControlWidget::gamma(int)
{
mySlider *sl = qobject_cast<mySlider *>(sender());
if (!sl)
return;
QString layername = sl->m_layername;
LayerParameter lp = d->m_map->layerFactory().layerParameter(layername);
lp.gamma = sl->value();
d->m_map->layerFactory().setLayerParameter(layername, lp);
}
void LayerControlWidget::onLayerParamterChanged(const QString &layername, const LayerParameter &newLayerParameter)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START"
<< " layername= '" << layername << "'";
// INFO_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'"
// << " layername=" << layername
// << " lp=" << newLayerParameter;
if (! d->m_sliderMap.contains(layername))
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'"
<< " layername='" << layername << "' is new -> updatePanel";
updatePanelLayer();
return;
}
// refresh GUI:
if (d->m_sliderMap.contains(layername))
{
SliderStruct &data = d->m_sliderMap[layername];
if (data.cbOnOff) data.cbOnOff ->setChecked(newLayerParameter.visible);
if (data.sl_opacity) data.sl_opacity ->setValue(newLayerParameter.opacity);
if (data.sl_brightness) data.sl_brightness->setValue(newLayerParameter.brightness);
if (data.sl_contrast) data.sl_contrast ->setValue(newLayerParameter.contrast);
if (data.sl_gamma) data.sl_gamma ->setValue(newLayerParameter.gamma);
}
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
QString LayerControlWidget::layernameAt(const QPoint &pos) const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
QWidget *child = childAt(pos);
if (!child)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " no child";
return QString();
}
DragableCheckBox *cb = dynamic_cast<DragableCheckBox *>(child);
if (!cb)
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " dynacast failed";
return QString();
}
const QString &childLayername = cb->property(LayernameProperty).toString();
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " childLayername=" << childLayername;
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return childLayername;
}
QStringList LayerControlWidget::newLayerOrder(const QString &draggedLayername, const QString &childLayername)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
// get current order:
QStringList sl = d->m_map->layerFactory().layernames();
if (draggedLayername == childLayername)
return sl;
// remove
sl.removeOne(draggedLayername);
// find new position:
int idx = sl.indexOf(childLayername);
// insert AFTER;
sl.insert(++idx, draggedLayername);
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
return sl;
}
void LayerControlWidget::dragMoveEvent(QDragMoveEvent *event)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (event->mimeData()->hasFormat(MIMETYPE))
{
if (event->source() == this)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
else
{
QByteArray itemData = event->mimeData()->data(MIMETYPE);
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString draggedLayername;
dataStream >> draggedLayername;
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " draggedLayername=" << draggedLayername;
const QString &childLayername = layernameAt(event->pos());
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " childLayername=" << childLayername;
if (childLayername.isEmpty() ||
(draggedLayername == childLayername))
event->ignore();
else
{
const QStringList &newOrder = newLayerOrder(draggedLayername, childLayername);
bool ok = d->m_map->layerFactory().checkLayerOrder(newOrder);
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " layerOrder ok: " << ok;
if (ok)
event->acceptProposedAction();
else
event->ignore();
}
}
}
else
event->ignore();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::dragEnterEvent(QDragEnterEvent *event)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (event->mimeData()->hasFormat(MIMETYPE))
{
event->acceptProposedAction();
// if (event->source() != this) {
//// event->setDropAction(Qt::MoveAction);
// event->accept();
// } else {
// event->acceptProposedAction();
// }
}
else
event->ignore();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
void LayerControlWidget::dropEvent(QDropEvent *event)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " START";
if (event->mimeData()->hasFormat(MIMETYPE))
{
QByteArray itemData = event->mimeData()->data(MIMETYPE);
QDataStream dataStream(&itemData, QIODevice::ReadOnly);
QString draggedLayername;
dataStream >> draggedLayername;
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " draggedLayername=" << draggedLayername;
if (event->source() == this)
{
event->setDropAction(Qt::MoveAction);
event->accept();
}
else
{
event->acceptProposedAction();
const QString &childLayername = layernameAt(event->pos());
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " childLayername=" << childLayername;
if (draggedLayername == childLayername)
return;
const QStringList &newOrder = newLayerOrder(draggedLayername, childLayername);
bool ok = d->m_map->layerFactory().orderLayerTo(newOrder);
DEBUG_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " layerOrder ok: " << ok;
}
}
else
event->ignore();
TRACE_LOG(m_logger) << LOGFUNCTION << " debugInfo='" << d->m_debugInfo << "'" << " END";
}
} // namespace SituationMap
#include "layer_control_widget.moc"