Files
qt5-legatus-legacy/Lts/Viewer/SituationMap/SymbologyGui/base_symbol_lookup_widget.cpp
T
2026-08-13 18:33:10 +02:00

483 lines
16 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Widget for selecting (base) symbols
* $Id$
* $HeadURL$
* $Author$
* Created by Norbert Thoden, NLE, 12.12.2019
*/
#include "base_symbol_lookup_widget.h"
#include "ui_base_symbol_lookup_widget.h"
#include <Symbology/sidc_builder_base.h> // for concreteSidcToBaseSymbolCode
#include <SymbologyImpl/base_symbol_model.h>
// Lts
//#include <LtsWidgets/lts_combo_box.h>
#include "LtsDataView/lts_data_view.h"
// Qt
#include <QMap>
#include <QtCore/QMimeData>
#include <QtCore/QSignalBlocker>
#include <QtGui/QDrag>
#include <QtGui/QPixmap>
#include <QtWidgets/QApplication>
#include <QtWidgets/QCheckBox>
#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QTableView>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QHeaderView>
#include <QtWidgets/QTreeView>
namespace AdvancedSymbology
{
namespace Gui
{
//------------------------------------------------------------------------------
// BaseSymbolLookupWidget::Private
//------------------------------------------------------------------------------
struct BaseSymbolLookupWidget::Private
{
MODEL_CONT modelContainer;
QMap<SYMBOL_TYPE, int> m_symbologyTypeToIdx;
QMap<int, SYMBOL_TYPE> m_idxToSymbologyType;
QMap<int, LtsDataView::LtsDataView *> m_idxToDataViewCont; // tabIdx -> view
QMap<int, BaseSymbolModel *> m_idxToModel; // tabIdx -> view
bool m_participantMode = false;
QCheckBox *m_cbPoint = nullptr;
QCheckBox *m_cbLine = nullptr;
QCheckBox *m_cbArea = nullptr;
QSet<QString> m_validBaseSymbolCodes;
};
//------------------------------------------------------------------------------
// BaseSymbolLookupWidget
//------------------------------------------------------------------------------
BaseSymbolLookupWidget::BaseSymbolLookupWidget(const MODEL_CONT &modelCont, QWidget *parent)
: QWidget(parent)
, m_logger(getLogger("BaseSymbolLookupWidget"))
, m_ui(new Ui::BaseSymbolLookupWidget)
, d(new Private())
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
m_ui->setupUi(this);
// clear, we use our own widgets:
m_ui->tabWidget->removeTab(0);
d->modelContainer = modelCont;
for (const auto &modelData : qAsConst(d->modelContainer))
{
if (!modelData.m_baseSymbolModel)
continue;
LtsDataView::LtsDataView *dv = new LtsDataView::LtsDataView(this);
BaseSymbolProxyModel *proxy = new BaseSymbolProxyModel(this);
proxy->setSourceModel(modelData.m_baseSymbolModel);
proxy->setDynamicSortFilter(false);
dv->setModel(proxy);
// connect:
connect(dv, &LtsDataView::LtsDataView::clicked, this, &BaseSymbolLookupWidget::onClicked);
connect(dv, &LtsDataView::LtsDataView::doubleClicked, this, &BaseSymbolLookupWidget::onDoubleClicked);
if (modelData.m_symbolType == SYMBOL_TYPE::ESRI)
{
// ESRI -> add some cbs for Point, Line, Area:
// HBox with 3 cbs:
QHBoxLayout *layoutGeomSelect = new QHBoxLayout();
d->m_cbPoint = new QCheckBox(tr("Point"), this);
d->m_cbLine = new QCheckBox(tr("Line"), this);
d->m_cbArea = new QCheckBox(tr("Area"), this);
layoutGeomSelect->addWidget(d->m_cbPoint, 0);
layoutGeomSelect->addWidget(d->m_cbLine, 0);
layoutGeomSelect->addWidget(d->m_cbArea, 0);
layoutGeomSelect->addStretch(9);
d->m_cbPoint->setChecked(proxy->filterPoints());
d->m_cbLine->setChecked(proxy->filterLines());
d->m_cbArea->setChecked(proxy->filterAreas());
connect(d->m_cbPoint, &QCheckBox::toggled, proxy, &BaseSymbolProxyModel::onFilterPoints);
connect(d->m_cbLine, &QCheckBox::toggled, proxy, &BaseSymbolProxyModel::onFilterLines);
connect(d->m_cbArea, &QCheckBox::toggled, proxy, &BaseSymbolProxyModel::onFilterAreas);
// VBox with layoutGeomSelect and LtsDataView
QVBoxLayout *layout = new QVBoxLayout();
layout->addLayout(layoutGeomSelect);
layout->addWidget(dv);
// wrap within a widget:
QWidget *w = new QWidget();
w->setLayout(layout);
int idx = m_ui->tabWidget->addTab(w, modelData.m_name);
d->m_symbologyTypeToIdx[modelData.m_symbolType] = idx;
d->m_idxToSymbologyType[idx] = modelData.m_symbolType;
d->m_idxToDataViewCont[idx] = dv;
d->m_idxToModel[idx] = modelData.m_baseSymbolModel;
}
else
{
const int idx = m_ui->tabWidget->addTab(dv, modelData.m_name);
d->m_symbologyTypeToIdx[modelData.m_symbolType] = idx;
d->m_idxToSymbologyType[idx] = modelData.m_symbolType;
d->m_idxToDataViewCont[idx] = dv;
d->m_idxToModel[idx] = modelData.m_baseSymbolModel;
}
showHideColumns(modelData.m_symbolType);
} // for
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
BaseSymbolLookupWidget::~BaseSymbolLookupWidget()
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
delete d;
delete m_ui;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void BaseSymbolLookupWidget::setValidBaseSymbolCodes(const QSet<QString> &validBaseSymbolCodes)
{
d->m_validBaseSymbolCodes = validBaseSymbolCodes;
const int tabCount = m_ui->tabWidget->count();
for (int tabIdx = 0; tabIdx < tabCount; ++tabIdx)
{
LtsDataView::LtsDataView *dv = d->m_idxToDataViewCont[tabIdx];
if (!dv)
continue;
BaseSymbolProxyModel *proxy = qobject_cast<BaseSymbolProxyModel *>(dv->proxyModel());
if (proxy)
proxy->setValidBaseSymbolCodes(d->m_validBaseSymbolCodes);
} // for
}
bool BaseSymbolLookupWidget::participantMode() const
{
return d->m_participantMode;
}
void BaseSymbolLookupWidget::setParticipantMode(bool onOff)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, participantMode =" << onOff;
d->m_participantMode = onOff;
if (d->m_participantMode)
{
d->m_cbPoint->setChecked(true);
d->m_cbLine->setChecked(false);
d->m_cbArea->setChecked(false);
}
else
{
d->m_cbPoint->setChecked(true);
d->m_cbLine->setChecked(true);
d->m_cbArea->setChecked(true);
}
d->m_cbPoint->setVisible(!d->m_participantMode);
d->m_cbLine->setVisible(!d->m_participantMode);
d->m_cbArea->setVisible(!d->m_participantMode);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
void BaseSymbolLookupWidget::showHideColumns(SYMBOL_TYPE symType)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, symType=" << static_cast<int>(symType);
if (!d->m_symbologyTypeToIdx.contains(symType))
return;
const int idx = d->m_symbologyTypeToIdx[symType];
LtsDataView::LtsDataView *dv = d->m_idxToDataViewCont[idx];
if (!dv)
return;
#ifdef LTS_DEBUG
const bool showAll = QGuiApplication::keyboardModifiers().testFlag(Qt::KeyboardModifier::ControlModifier);
#else
const bool showAll = false;
#endif // LTS_DEBUG
switch (symType)
{
case SYMBOL_TYPE::ESRI:
// dv->setColumnHidden(BaseSymbolModel::Columns::ID, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::ORIGINAL_KEY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::KEY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::OPERATOR_NAME, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::LAST_MODIFIED, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SIDC, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SEARCH_ICON, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FETCH_ICON, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::FIND_BASE_SYMBOL, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_PREVIEW, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_IMAGE, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::XML_SYMBOL_SIZE, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::CATEGORY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SYMBOLCLASS, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::TAGS, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::GCTSTRING, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::GEOMETRYTYPE, !showAll);
break;
case SYMBOL_TYPE::XML:
// dv->setColumnHidden(BaseSymbolModel::Columns::ID, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::ORIGINAL_KEY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::KEY, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::OPERATOR_NAME, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::LAST_MODIFIED, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SIDC, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SYMBOL_SET, true);
dv->setColumnHidden(BaseSymbolModel::Columns::SEARCH_ICON, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FETCH_ICON, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_BASE_SYMBOL, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::FIND_PREVIEW, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_IMAGE, !showAll);
// dv->setColumnHidden(BaseSymbolModel::Columns::XML_SYMBOL_SIZE, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::CATEGORY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SYMBOLCLASS, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::TAGS, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::GCTSTRING, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::GEOMETRYTYPE, !showAll);
break;
case SYMBOL_TYPE::ETS:
// dv->setColumnHidden(BaseSymbolModel::Columns::ID, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::ORIGINAL_KEY, true);
dv->setColumnHidden(BaseSymbolModel::Columns::KEY, true);
dv->setColumnHidden(BaseSymbolModel::Columns::OPERATOR_NAME, true);
dv->setColumnHidden(BaseSymbolModel::Columns::LAST_MODIFIED, true);
dv->setColumnHidden(BaseSymbolModel::Columns::SIDC, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SYMBOL_SET, true);
dv->setColumnHidden(BaseSymbolModel::Columns::SEARCH_ICON, true);
dv->setColumnHidden(BaseSymbolModel::Columns::FETCH_ICON, true);
// dv->setColumnHidden(BaseSymbolModel::Columns::FIND_BASE_SYMBOL, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_PREVIEW, true);
dv->setColumnHidden(BaseSymbolModel::Columns::FIND_IMAGE, true);
dv->setColumnHidden(BaseSymbolModel::Columns::XML_SYMBOL_SIZE, true);
// dv->setColumnHidden(BaseSymbolModel::Columns::CATEGORY, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::SYMBOLCLASS, true);
// dv->setColumnHidden(BaseSymbolModel::Columns::TAGS, !showAll);
dv->setColumnHidden(BaseSymbolModel::Columns::GCTSTRING, true);
dv->setColumnHidden(BaseSymbolModel::Columns::GEOMETRYTYPE, true);
break;
} // switch
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
}
bool BaseSymbolLookupWidget::setCurrentTab(SYMBOL_TYPE symType)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START, symType=" << static_cast<int>(symType);
if (!d->m_symbologyTypeToIdx.contains(symType))
return false;
const int idx = d->m_symbologyTypeToIdx[symType];
m_ui->tabWidget->setCurrentIndex(idx);
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return true;
}
void BaseSymbolLookupWidget::showEvent(QShowEvent *event)
{
Q_UNUSED(event);
showHideColumns(SYMBOL_TYPE::ESRI);
showHideColumns(SYMBOL_TYPE::XML);
showHideColumns(SYMBOL_TYPE::ETS);
}
QSharedPointer<BaseSymbolItem> BaseSymbolLookupWidget::getCurrentBaseSymbolItem() const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
const int tabIdx = m_ui->tabWidget->currentIndex();
LtsDataView::LtsDataView *dv = d->m_idxToDataViewCont[tabIdx];
BaseSymbolModel *bsm = d->m_idxToModel[tabIdx];
if (!dv || !bsm)
return nullptr;
// found :-)
QItemSelectionModel *selectModel = dv->selectionModel();
if (!selectModel || !selectModel->hasSelection())
return nullptr;
const QItemSelection &selectionSource = dv->mapSelectionToSource(selectModel->selection());
const int row = selectionSource.indexes().first().row(); // assume singleSelection
return bsm->getRowData(row);
}
QString BaseSymbolLookupWidget::getCurrentBaseSymbolCode() const
{
TRACE_LOG(m_logger) << LOGFUNCTION << " START";
QSharedPointer<BaseSymbolItem> bsi = getCurrentBaseSymbolItem();
if (bsi)
{
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " m_id" << bsi->m_id
<< ", baseSymbolCode" << bsi->baseSymbolCode();
return bsi->baseSymbolCode();
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return QString();
}
QString BaseSymbolLookupWidget::getCurrentSidc() const
{
QSharedPointer<BaseSymbolItem> bsi = getCurrentBaseSymbolItem();
if (bsi)
{
DEBUG_LOG(m_logger) << LOGFUNCTION
<< " m_id" << bsi->m_id
<< ", sidc" << bsi->sidc();
return bsi->sidc();
}
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return QString();
}
bool BaseSymbolLookupWidget::setCurrentSidc(const QString &sidc)
{
TRACE_LOG(m_logger) << LOGFUNCTION << " sidc='" << sidc << "'";
if (sidc.isEmpty())
{
DEBUG_LOG(m_logger) << LOGFUNCTION << " sidc is empty, maybe not set...";
return false;
}
if (!SidcCodec::isEncoded(sidc))
{
ERROR_LOG(m_logger) << LOGFUNCTION << " sidc isn't encoded: '" << sidc << "'";
return false;
}
SYMBOL_TYPE symType = SYMBOL_TYPE::ESRI;
QString baseSymbolCode = sidc;
const SidcCodec::SidcType sidcType = SidcCodec::decodeSidcType(sidc);
switch (sidcType)
{
case SidcCodec::SidcType::None:
{
ERROR_LOG(m_logger) << LOGFUNCTION << " SidcType::None isn't supported. Sidc= '" << sidc << "'";
return false;
}
case SidcCodec::SidcType::Complete:
baseSymbolCode = AdvancedSymbology::SidcBuilderBase::concreteSidcToBaseSymbolCode(sidc);
case SidcCodec::SidcType::Base:
break;
case SidcCodec::SidcType::CivilEts:
symType = SYMBOL_TYPE::ETS;
break;
case SidcCodec::SidcType::CivilXml:
symType = SYMBOL_TYPE::XML;
break;
default :
{
ERROR_LOG(m_logger) << LOGFUNCTION << " SidcType is unknown. Sidc= '" << sidc << "'";
return false;
}
} // switch
// switch to model/view/tabIdx
if (!d->m_symbologyTypeToIdx.contains(symType))
return false;
const int tabIdx = d->m_symbologyTypeToIdx[symType];
BaseSymbolModel *bsm = d->m_idxToModel[tabIdx];
LtsDataView::LtsDataView *dv = d->m_idxToDataViewCont[tabIdx];
if (!bsm || !dv)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " switch to model/view/tabIndex failed, sidc '" << sidc << "'";
return false;
}
// switch to tabIdx
m_ui->tabWidget->setCurrentIndex(tabIdx);
// switch to model/view
const int row = bsm->findRowForBaseSymbolCode(baseSymbolCode);
if (row >= 0)
{
const QModelIndex sourceIdx = bsm->index(row, 0);
dv->selectRow(dv->proxyModel()->mapFromSource(sourceIdx));
dv->scrollTo(dv->proxyModel()->mapFromSource(sourceIdx));
}
INFO_LOG(m_logger) << LOGFUNCTION << " sidc='" << sidc << "'"
<< " tabIdx = " << tabIdx
<< " findRowForBaseSymbolCode -> row = " << row;
TRACE_LOG(m_logger) << LOGFUNCTION << " END";
return (row >= 0);
}
void BaseSymbolLookupWidget::onClicked(const QModelIndex &index)
{
Q_UNUSED(index);
QSharedPointer<BaseSymbolItem> bsi = getCurrentBaseSymbolItem();
if (!bsi)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " item not found";
return;
}
const QString &curBsc = bsi->baseSymbolCode();
const QString &curSidc = bsi->sidc();
emit symbolClicked(curBsc, curSidc);
}
void BaseSymbolLookupWidget::onDoubleClicked(const QModelIndex &index)
{
Q_UNUSED(index);
QSharedPointer<BaseSymbolItem> bsi = getCurrentBaseSymbolItem();
if (!bsi)
{
ERROR_LOG(m_logger) << LOGFUNCTION << " item not found";
return;
}
const QString &curBsc = bsi->baseSymbolCode();
const QString &curSidc = bsi->sidc();
emit symbolDoubleClicked(curBsc, curSidc);
}
} // namespace Gui
} // namespace AdvancedSymbology