File indexing completed on 2025-01-05 03:59:23

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