Files
qt5-legatus-legacy/Lts/Plugins/PlanEditor/model_tree_widget.cpp
2026-08-13 18:33:10 +02:00

328 lines
11 KiB
C++
Executable File

/**
**
** @RDE_HEADER@
** model_tree_widget.cpp
** $Id$
** $HeadURL$
** $Author$
**
** -----------------------------------------------------------------------------------------------
**
** Hardware-Environment: Intel-PC
** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5
**
** Language ........: C++ 11
**
** -----------------------------------------------------------------------------------------------
**
** Author ...........: Jörg Turla, SPD G, Tel. 3132
**
** -----------------------------------------------------------------------------------------------
**
** Notes .........:
**
** 14.06.2016, JT : First edition for use with Qt5
**
** -----------------------------------------------------------------------------------------------
*/
#include "model_tree_widget.h"
#include "plan_editor.h"
#include "plan_editor_internal.h"
#include "plan_editor_utils.h"
#include "icon_names.h"
#include <QtCore/QEvent>
#include <QtGui/QKeyEvent>
#include <QtWidgets/QAbstractItemView>
#include <QtWidgets/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLabel>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStyledItemDelegate>
#include <QtWidgets/QTableView>
#include <QtWidgets/QTextEdit>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QTreeWidgetItem>
#include <QtWidgets/QTreeWidget>
#include <QtWidgets/QVBoxLayout>
namespace PlanEditor
{
class EditNameDelegate : public QStyledItemDelegate
{
Q_OBJECT
PlanEditor &m_planEditor;
QTreeWidget *m_treeWidget;
public:
explicit EditNameDelegate(PlanEditor &planEditor, QTreeWidget *treeWidget)
: QStyledItemDelegate(treeWidget)
, m_planEditor(planEditor)
, m_treeWidget(treeWidget) {;}
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &opt, const QModelIndex &index) const override
{
if (index.column() == 1)
{
QWidget *editor = QStyledItemDelegate::createEditor(parent, opt, index);
editor->installEventFilter(const_cast<EditNameDelegate *>(this));
return editor;
}
return nullptr;
} // QWidget * createEditor( QWidget * parent, const QStyleOptionViewItem & opt, const QModelIndex & index ) override
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override
{
if (index.column() == 1)
{
QStyledItemDelegate::setModelData(editor, model, index);
ModelTreeWidgetItem *item = static_cast<ModelTreeWidgetItem *>(m_treeWidget->currentItem());
if (item)
item->userDefinedNameChanged(*(m_planEditor.m_internal->m_geoModel));
}
} // void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const override
bool eventFilter(QObject *watchedEditor, QEvent *ev) override
{
if (ev == nullptr) return false;
if (watchedEditor == nullptr) return false;
QWidget *widget = dynamic_cast<QWidget *>(watchedEditor);
if (widget == nullptr) return false;
if (QEvent::KeyRelease == ev->type())
{
QKeyEvent *kev = static_cast<QKeyEvent *>(ev);
if (Qt::Key_Return == kev->key())
{
emit commitData(widget);
emit closeEditor(widget, QAbstractItemDelegate::EditNextItem);
}
if (Qt::Key_Escape == kev->key())
emit closeEditor(widget, QAbstractItemDelegate::EditNextItem);
}
if (QEvent::FocusOut == ev->type())
{
if (widget->isActiveWindow() || (QApplication::focusWidget() != widget))
{
QWidget *w = QApplication::focusWidget();
while (w)
{
// don't worry about focus changes internally in the editor
if (w == widget) return false;
w = w->parentWidget();
}
// Opening a modal dialog will start a new eventloop
// that will process the deleteLater event.
if (QApplication::activeModalWidget() && !QApplication::activeModalWidget()->isAncestorOf(widget))
return false;
emit commitData(widget);
emit closeEditor(widget);
}
}
return false;
} // bool eventFilter(QObject * watchedEditor, QEvent * e) override
}; // EditNameDelegate
bool ModelTreeWidget::isEmpty() const
{
return ((nullptr == m_treeWidget->model()) || (m_treeWidget->model()->rowCount() < 1));
} // bool ModelTreeWidget::isEmpty() const
void ModelTreeWidget::showNeedSaveFlag(bool on)
{
m_needSaveFlag = on;
buildTitle();
// QString title = tr("Plan Model Tree");
// m_treeGroup->setTitle(on ? title + QStringLiteral(" [*]") : title);
} // void ModelTreeWidget::showNeedSaveFlag( bool on )
void ModelTreeWidget::setNameOfPlan( const QString & nameOfPlan )
{
m_nameOfPlan = nameOfPlan;
buildTitle();
} // void ModelTreeWidget::setNameOfPlan( const QString & nameOfPlan )
void ModelTreeWidget::buildTitle()
{
QString title = tr("Plan Model Tree");
if (!m_nameOfPlan.isEmpty()) title += QStringLiteral(" [%1]").arg(m_nameOfPlan);
m_treeGroup->setTitle(m_needSaveFlag ? title + QStringLiteral(" [*]") : title);
} // void ModelTreeWidget::buildTitle()
ModelTreeWidget::ModelTreeWidget(PlanEditor *planEditor, QWidget *parent)
: Dialog(parent, LtsWidgets::ButtonCombination::SeamlessDialog)
, m_treeWidget(nullptr)
, m_itemTreeRoot(nullptr)
{
setUnchangeable();
m_planEditor = planEditor;
//setTitle(tr("Plan Model Tree"));
QVBoxLayout *treeBaseLayout = new QVBoxLayout(this);
QGroupBox *treeGroup = m_treeGroup = new QGroupBox(this);
QVBoxLayout *treeLayer = new QVBoxLayout(treeGroup);
showNeedSaveFlag(false);
m_treeWidget = new QTreeWidget(treeGroup);
m_treeWidget -> setColumnCount(2);
m_treeWidget -> setHeaderLabels(QStringList() << tr("Graphic Node") << tr("User Defined Name"));
m_treeWidget -> setSelectionMode(QAbstractItemView::ExtendedSelection);
m_treeWidget -> setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked | QAbstractItemView::AnyKeyPressed);
m_treeWidget -> setItemDelegate(new EditNameDelegate(*planEditor, m_treeWidget));
m_treeWidget -> setUniformRowHeights(false);
m_itemTreeRoot = m_treeWidget->invisibleRootItem();
connect(m_treeWidget, &QTreeWidget::itemSelectionChanged, this, [this, planEditor]() // lambda slot function to select items
{
m_treeWidget->blockSignals(true);
{
ModelTreeWidgetItem *currentItem = static_cast<ModelTreeWidgetItem *>(m_treeWidget->currentItem());
if (currentItem)
{
bool isSelected = currentItem->isSelected();
QTreeWidgetItem *parent = currentItem->parent();
// first go up to top level group
while (parent && (rootItem() != parent))
{
currentItem = static_cast<ModelTreeWidgetItem *>(parent);
parent = currentItem->parent();
}
// now select or deselect all children of top level group
currentItem->setGroupSelected(isSelected);
}
for (int i = 0; i < m_itemTreeRoot->childCount(); ++i)
{
ModelTreeWidgetItem *treeItem = static_cast<ModelTreeWidgetItem *>(m_itemTreeRoot->child(i));
if (treeItem)
treeItem->selectionChanged(*planEditor, *(planEditor->m_internal->m_geoModel));
}
}
m_treeWidget->blockSignals(false);
});
connect(m_treeWidget, &QTreeWidget::itemClicked, this, [this](QTreeWidgetItem * item, int column)
{
if (!item) return;
if (column == ModelTreeWidgetItem::nameColumn)
{
m_treeWidget -> editItem(item, ModelTreeWidgetItem::nameColumn);
return;
}
});
connect(m_treeWidget, &QTreeWidget::itemChanged, [](QTreeWidgetItem * item, int column)
{
if (!item) return;
ModelTreeWidgetItem *treeItem = dynamic_cast<ModelTreeWidgetItem *>(item);
if ((ModelTreeWidgetItem::itemColumn == column) && (treeItem))
treeItem->setGroupSelected(treeItem->checkState(ModelTreeWidgetItem::itemColumn) == Qt::Checked);
});
QToolBar *toolBar = new QToolBar(treeGroup);
QAction *toolAction;
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(GROUP_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onGroup);
toolAction -> setToolTip(tr("Group selected feature"));
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(UNGROUP_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onUngroup);
toolAction -> setToolTip(tr("Ungroup selected feature"));
toolBar->addSeparator();
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(DRAW_SYMBOL_ICON_NAME)), QString(), planEditor, &PlanEditor::onChooseSymbol );
toolAction->setToolTip(tr("Choose and draw symbol from symbol dictionary"));
toolBar->addSeparator();
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(EDIT_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onEditGraphicGeometry);
toolAction -> setToolTip(tr("Edit geometry of selected feature"));
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(ATTR_EDIT_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onEditAttributes);
toolAction->setToolTip(tr("Edit Attributes of selected feature"));
toolBar->addSeparator();
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(CENTER_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onCenterViewSelected);
toolAction -> setToolTip(tr("Center Map to selected features"));
toolBar->addSeparator();
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(DELETE_SELECTED_ICON_NAME)), QString(), planEditor, &PlanEditor::onDelete);
toolAction -> setToolTip(tr("Delete selected features"));
toolBar->addSeparator();
toolAction = toolBar->addAction(Utils::getIcon(QLatin1String(HELP_SYMBOL_ICON_NAME)), QString(), planEditor, &PlanEditor::onShowHelp);
toolAction -> setToolTip(tr("Help"));
treeLayer -> addWidget(toolBar, 0);
treeLayer -> addWidget(m_treeWidget, 2);
treeBaseLayout -> addWidget(treeGroup, 2);
setObjectName(QLatin1String("PlanItemTree"));
} // ModelTreeWidget::ModelTreeWidget(PlanEditor *planEditor, QWidget *parent)
void ModelTreeWidget::haveChanges(bool on)
{
if (hasUnsavedChanges() != on)
{
on ? slotChangesMade() : __unchange__();
showNeedSaveFlag(on);
}
}
// void ModelTreeWidget::haveChanges(bool on)
void ModelTreeWidget::keyPressEvent(QKeyEvent *event)
{
if ((event->key() == Qt::Key_Delete) && (m_planEditor))
{
m_planEditor->onDelete();
// Qt-Doc 5.12:
// Note that QKeyEvent starts with isAccepted() == true, so you do not need
// to call QKeyEvent::accept() - just do not call the base class
// implementation if you act upon the key.
return;
}
BaseClass::keyPressEvent(event);
}
} // namespace PlanEditor
#include "model_tree_widget.moc"