Marble

OsmRelationManagerWidget.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
4//
5
6// Self
7#include "OsmRelationManagerWidget.h"
8#include "OsmRelationManagerWidget_p.h"
9#include "ui_OsmRelationManagerWidget.h"
10
11// Qt
12#include <QDebug>
13#include <QMenu>
14#include <QPointer>
15#include <QTreeWidget>
16
17// Marble
18#include "GeoDataPlacemark.h"
19#include "osm/OsmObjectManager.h"
20#include "osm/OsmPlacemarkData.h"
21#include "osm/OsmRelationEditorDialog.h"
22
23namespace Marble
24{
25
26OsmRelationManagerWidget::OsmRelationManagerWidget(GeoDataPlacemark *placemark, const QHash<qint64, OsmPlacemarkData> *relations, QWidget *parent)
27 : QWidget(parent)
28 , d(new OsmRelationManagerWidgetPrivate)
29{
30 d->m_placemark = placemark;
31 d->m_allRelations = relations;
32 d->setupUi(this);
33 d->populateRelationsList();
34 d->m_relationDropMenu = new QMenu(d->m_addRelation);
35 d->m_currentRelations->setRootIsDecorated(false);
36 d->m_currentRelations->setEditTriggers(QTreeWidget::DoubleClicked);
37 d->m_currentRelations->setContextMenuPolicy(Qt::CustomContextMenu);
38 d->m_currentRelations->setMinimumWidth(d->m_currentRelations->columnCount() * d->m_currentRelations->columnWidth(0) + 10);
39
40 d->m_addRelation->setMenu(d->m_relationDropMenu);
41 d->populateDropMenu();
42
43 connect(d->m_currentRelations, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, SLOT(handleDoubleClick(QTreeWidgetItem *, int)));
44 connect(d->m_currentRelations, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(handleRelationContextMenuRequest(QPoint)));
45 connect(d->m_relationDropMenu, SIGNAL(triggered(QAction *)), this, SLOT(addRelation(QAction *)));
46 connect(d->m_currentRelations, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(handleItemChange(QTreeWidgetItem *, int)));
47}
48
49OsmRelationManagerWidget::~OsmRelationManagerWidget()
50{
51 delete d;
52}
53
54void OsmRelationManagerWidget::addRelation(QAction *relationAction)
55{
56 // The QAction::text() adds a '&' for some reason
57 QString relationText = relationAction->text().remove(QLatin1Char('&'));
58
59 if (relationText == tr("New Relation")) {
60 OsmPlacemarkData relationData;
61 QPointer<OsmRelationEditorDialog> relationEditor = new OsmRelationEditorDialog(&relationData);
62 const int result = relationEditor->exec();
63 delete relationEditor;
64 if (result == QDialog::Rejected) {
65 return;
66 }
67
68 auto newRelationItem = new QTreeWidgetItem();
69 newRelationItem->setText(Column::Name, relationData.tagValue(QStringLiteral("name")));
70 newRelationItem->setText(Column::Type, relationData.tagValue(QStringLiteral("type")));
71 newRelationItem->setData(Column::Name, Qt::UserRole, relationData.id());
72 d->m_currentRelations->addTopLevelItem(newRelationItem);
73
74 // Make the user complete the role column
75 newRelationItem->setFlags(newRelationItem->flags() | Qt::ItemIsEditable);
76 d->m_currentRelations->editItem(newRelationItem, Column::Role);
77
78 // This tells the annotate plugin to add the new relation to its list
79 Q_EMIT relationCreated(relationData);
80 } else {
81 qint64 id = relationAction->data().toLongLong();
82 OsmPlacemarkData relationData = d->m_allRelations->value(id);
83 auto newRelationItem = new QTreeWidgetItem();
84 newRelationItem->setText(Column::Name, relationData.tagValue(QStringLiteral("name")));
85 newRelationItem->setText(Column::Type, relationData.tagValue(QStringLiteral("type")));
86 newRelationItem->setData(Column::Name, Qt::UserRole, relationData.id());
87 d->m_currentRelations->addTopLevelItem(newRelationItem);
88
89 // Make the user complete the role column
90 newRelationItem->setFlags(newRelationItem->flags() | Qt::ItemIsEditable);
91 d->m_currentRelations->editItem(newRelationItem, Column::Role);
92 }
93}
94
95void OsmRelationManagerWidget::update()
96{
97 d->populateRelationsList();
98 d->populateDropMenu();
99}
100
101void OsmRelationManagerWidget::handleDoubleClick(QTreeWidgetItem *item, int column)
102{
103 Qt::ItemFlags flags = item->flags();
104
105 // Only the "role" column should be editable
106 if (column == Column::Role) {
107 item->setFlags(flags | Qt::ItemIsEditable);
108 // If the double click didn't occur on the "role" column, and the item
109 // is editable make it uneditable
110 } else if (flags & Qt::ItemIsEditable) {
111 item->setFlags(flags ^ Qt::ItemIsEditable);
112 }
113}
114
115void OsmRelationManagerWidget::handleItemChange(QTreeWidgetItem *item, int column)
116{
117 // Only the role column should be editable
118 if (column != Column::Role) {
119 return;
120 }
121
122 QString role = item->text(Column::Role);
123 qint64 id = item->data(Column::Name, Qt::UserRole).toLongLong();
124
125 d->m_placemark->osmData().addRelation(id, OsmType::Way, role);
126 update();
127}
128
129void OsmRelationManagerWidget::handleRelationContextMenuRequest(const QPoint &point)
130{
131 QTreeWidgetItem *requestedItem = d->m_currentRelations->itemAt(point);
132 if (!requestedItem) {
133 return;
134 }
135 QMenu relationEditMenu;
136 relationEditMenu.addAction(tr("Remove"));
137 relationEditMenu.addAction(tr("Edit"));
138 QAction *selectedItem = relationEditMenu.exec(d->m_currentRelations->mapToGlobal(point));
139 if (selectedItem) {
140 qint64 id = requestedItem->data(Column::Name, Qt::UserRole).toLongLong();
141
142 if (selectedItem->text() == tr("Remove")) {
143 d->m_placemark->osmData().removeRelation(id);
144 update();
145 } else if (selectedItem->text() == tr("Edit")) {
146 OsmPlacemarkData relationData = d->m_allRelations->value(id);
147 QPointer<OsmRelationEditorDialog> relationEditor = new OsmRelationEditorDialog(&relationData);
148 const int result = relationEditor->exec();
149 delete relationEditor;
150 if (result == QDialog::Rejected) {
151 return;
152 }
153
154 Q_EMIT relationCreated(relationData);
155 update();
156 }
157 }
158}
159
160}
161
162#include "moc_OsmRelationManagerWidget.cpp"
This class is used to encapsulate the osm data fields kept within a placemark's extendedData.
QString tagValue(const QString &key) const
tagValue returns the value of the tag that has key as key or an empty qstring if there is no such tag
The OsmRelationEditorDialog class small dialog that is used to edit relations The dialog has a line e...
void update(Part *part, const QByteArray &data, qint64 dataSize)
Binds a QML item to a specific geodetic location in screen coordinates.
QVariant data() const const
QAction * addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut)
QAction * exec()
CustomContextMenu
UserRole
ItemIsEditable
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
virtual QVariant data(int column, int role) const const
Qt::ItemFlags flags() const const
void setFlags(Qt::ItemFlags flags)
QString text(int column) const const
qlonglong toLongLong(bool *ok) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:14 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.