File indexing completed on 2024-05-12 15:29:53
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com> 0004 // 0005 0006 // Self 0007 #include "OsmRelationManagerWidget.h" 0008 #include "OsmRelationManagerWidget_p.h" 0009 #include "ui_OsmRelationManagerWidget.h" 0010 0011 // Qt 0012 #include <QTreeWidget> 0013 #include <QMenu> 0014 #include <QPointer> 0015 #include <QDebug> 0016 0017 // Marble 0018 #include "GeoDataPlacemark.h" 0019 #include "GeoDataGeometry.h" 0020 #include "osm/OsmPlacemarkData.h" 0021 #include "osm/OsmObjectManager.h" 0022 #include "osm/OsmRelationEditorDialog.h" 0023 0024 namespace Marble 0025 { 0026 0027 OsmRelationManagerWidget::OsmRelationManagerWidget( GeoDataPlacemark *placemark, 0028 const QHash<qint64, OsmPlacemarkData> *relations, 0029 QWidget *parent ) 0030 : QWidget( parent ), 0031 d( new OsmRelationManagerWidgetPrivate ) 0032 { 0033 d->m_placemark = placemark; 0034 d->m_allRelations = relations; 0035 d->setupUi( this ); 0036 d->populateRelationsList(); 0037 d->m_relationDropMenu = new QMenu( d->m_addRelation ); 0038 d->m_currentRelations->setRootIsDecorated( false ); 0039 d->m_currentRelations->setEditTriggers( QTreeWidget::DoubleClicked ); 0040 d->m_currentRelations->setContextMenuPolicy( Qt::CustomContextMenu ); 0041 d->m_currentRelations->setMinimumWidth( d->m_currentRelations->columnCount() * d->m_currentRelations->columnWidth( 0 ) + 10 ); 0042 0043 d->m_addRelation->setMenu( d->m_relationDropMenu ); 0044 d->populateDropMenu(); 0045 0046 QObject::connect( d->m_currentRelations, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), 0047 this, SLOT(handleDoubleClick(QTreeWidgetItem*,int)) ); 0048 QObject::connect( d->m_currentRelations, SIGNAL(customContextMenuRequested(QPoint)), 0049 this, SLOT(handleRelationContextMenuRequest(QPoint)) ); 0050 QObject::connect( d->m_relationDropMenu, SIGNAL(triggered(QAction*)), 0051 this, SLOT(addRelation(QAction*)) ); 0052 QObject::connect( d->m_currentRelations, SIGNAL(itemChanged(QTreeWidgetItem*,int)), 0053 this, SLOT(handleItemChange(QTreeWidgetItem*,int)) ); 0054 } 0055 0056 OsmRelationManagerWidget::~OsmRelationManagerWidget() 0057 { 0058 delete d; 0059 } 0060 0061 void OsmRelationManagerWidget::addRelation( QAction *relationAction ) 0062 { 0063 // The QAction::text() adds a '&' for some reason 0064 QString relationText = relationAction->text().remove(QLatin1Char('&')); 0065 0066 if ( relationText == tr( "New Relation" ) ) { 0067 OsmPlacemarkData relationData; 0068 QPointer<OsmRelationEditorDialog> relationEditor = new OsmRelationEditorDialog( &relationData ); 0069 const int result = relationEditor->exec(); 0070 delete relationEditor; 0071 if (result == QDialog::Rejected) { 0072 return; 0073 } 0074 0075 QTreeWidgetItem *newRelationItem = new QTreeWidgetItem(); 0076 newRelationItem->setText(Column::Name, relationData.tagValue(QStringLiteral("name"))); 0077 newRelationItem->setText(Column::Type, relationData.tagValue(QStringLiteral("type"))); 0078 newRelationItem->setData( Column::Name, Qt::UserRole, relationData.id() ); 0079 d->m_currentRelations->addTopLevelItem( newRelationItem ); 0080 0081 // Make the user complete the role column 0082 newRelationItem->setFlags( newRelationItem->flags() | Qt::ItemIsEditable ); 0083 d->m_currentRelations->editItem( newRelationItem, Column::Role ); 0084 0085 // This tells the annotate plugin to add the new relation to its list 0086 emit relationCreated( relationData ); 0087 } 0088 else { 0089 qint64 id = relationAction->data().toLongLong(); 0090 OsmPlacemarkData relationData = d->m_allRelations->value( id ); 0091 QTreeWidgetItem *newRelationItem = new QTreeWidgetItem(); 0092 newRelationItem->setText(Column::Name, relationData.tagValue(QStringLiteral("name"))); 0093 newRelationItem->setText(Column::Type, relationData.tagValue(QStringLiteral("type"))); 0094 newRelationItem->setData( Column::Name, Qt::UserRole, relationData.id() ); 0095 d->m_currentRelations->addTopLevelItem( newRelationItem ); 0096 0097 // Make the user complete the role column 0098 newRelationItem->setFlags( newRelationItem->flags() | Qt::ItemIsEditable ); 0099 d->m_currentRelations->editItem( newRelationItem, Column::Role ); 0100 } 0101 } 0102 0103 void OsmRelationManagerWidget::update() 0104 { 0105 d->populateRelationsList(); 0106 d->populateDropMenu(); 0107 } 0108 0109 void OsmRelationManagerWidget::handleDoubleClick( QTreeWidgetItem * item, int column ) 0110 { 0111 Qt::ItemFlags flags = item->flags(); 0112 0113 // Only the "role" column should be editable 0114 if ( column == Column::Role ) { 0115 item->setFlags( flags | Qt::ItemIsEditable ); 0116 // If the double click didn't occur on the "role" column, and the item 0117 // is editable make it uneditable 0118 } else if ( flags & Qt::ItemIsEditable ) { 0119 item->setFlags( flags ^ Qt::ItemIsEditable ); 0120 } 0121 } 0122 0123 void OsmRelationManagerWidget::handleItemChange( QTreeWidgetItem *item, int column ) 0124 { 0125 // Only the role column should be editable 0126 if ( column != Column::Role ) { 0127 return; 0128 } 0129 0130 QString role = item->text( Column::Role ); 0131 qint64 id = item->data( Column::Name, Qt::UserRole ).toLongLong(); 0132 0133 d->m_placemark->osmData().addRelation( id, OsmType::Way, role ); 0134 update(); 0135 } 0136 0137 void OsmRelationManagerWidget::handleRelationContextMenuRequest( const QPoint& point ) 0138 { 0139 QMenu relationEditMenu; 0140 relationEditMenu.addAction( tr( "Remove" ) ); 0141 relationEditMenu.addAction( tr( "Edit" ) ); 0142 QAction* selectedItem = relationEditMenu.exec( d->m_currentRelations->mapToGlobal( point ) ); 0143 if ( selectedItem ) { 0144 0145 QTreeWidgetItem *requestedItem = d->m_currentRelations->itemAt( point ); 0146 qint64 id = requestedItem->data( Column::Name, Qt::UserRole ).toLongLong(); 0147 0148 if ( selectedItem->text() == tr( "Remove" ) ) { 0149 d->m_placemark->osmData().removeRelation( id ); 0150 update(); 0151 } 0152 else if ( selectedItem->text() == tr( "Edit" ) ) { 0153 OsmPlacemarkData relationData = d->m_allRelations->value( id ); 0154 QPointer<OsmRelationEditorDialog> relationEditor = new OsmRelationEditorDialog( &relationData ); 0155 const int result = relationEditor->exec(); 0156 delete relationEditor; 0157 if (result == QDialog::Rejected) { 0158 return; 0159 } 0160 0161 emit relationCreated( relationData ); 0162 update(); 0163 } 0164 } 0165 } 0166 0167 } 0168 0169 #include "moc_OsmRelationManagerWidget.cpp"