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"