Dxf/Dwg new import mode expand blocks & add inserts

This commit is contained in:
Damiano Lombardi 2023-06-15 09:19:15 +02:00
parent a8d6324876
commit 18a81b32bf
4 changed files with 164 additions and 45 deletions

View File

@ -57,6 +57,17 @@ QgsDwgImportDialog::QgsDwgImportDialog( QWidget *parent, Qt::WindowFlags f )
mDatabaseFileWidget->setStorageMode( QgsFileWidget::SaveFile ); mDatabaseFileWidget->setStorageMode( QgsFileWidget::SaveFile );
mDatabaseFileWidget->setConfirmOverwrite( false ); mDatabaseFileWidget->setConfirmOverwrite( false );
mBlockModeComboBox->addItem( tr( "Expand block geometries" ), static_cast<int>( BlockImportFlag::BlockImportExpandGeometry ) );
mBlockModeComboBox->addItem( tr( "Expand block geometries and add insert points" ), static_cast<int>( BlockImportFlag::BlockImportExpandGeometry ) | static_cast<int>( BlockImportFlag::BlockImportAddInsertPoints ) );
mBlockModeComboBox->addItem( tr( "Add only insert points" ), static_cast<int>( BlockImportFlag::BlockImportAddInsertPoints ) );
const QgsSettings s;
int index = mBlockModeComboBox->findData( s.value( QStringLiteral( "/DwgImport/lastBlockImportFlags" ), static_cast<int>( BlockImportFlag::BlockImportExpandGeometry ) ) );
mBlockModeComboBox->setCurrentIndex( index );
cbMergeLayers->setChecked( s.value( QStringLiteral( "/DwgImport/lastMergeLayers" ), false ).toBool() );
cbUseCurves->setChecked( s.value( QStringLiteral( "/DwgImport/lastUseCurves" ), true ).toBool() );
mDatabaseFileWidget->setDefaultRoot( s.value( QStringLiteral( "/DwgImport/lastDirDatabase" ), QDir::homePath() ).toString() );
connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsDwgImportDialog::buttonBox_accepted ); connect( buttonBox, &QDialogButtonBox::accepted, this, &QgsDwgImportDialog::buttonBox_accepted );
connect( mDatabaseFileWidget, &QgsFileWidget::fileChanged, this, &QgsDwgImportDialog::mDatabaseFileWidget_textChanged ); connect( mDatabaseFileWidget, &QgsFileWidget::fileChanged, this, &QgsDwgImportDialog::mDatabaseFileWidget_textChanged );
connect( pbBrowseDrawing, &QPushButton::clicked, this, &QgsDwgImportDialog::pbBrowseDrawing_clicked ); connect( pbBrowseDrawing, &QPushButton::clicked, this, &QgsDwgImportDialog::pbBrowseDrawing_clicked );
@ -67,12 +78,8 @@ QgsDwgImportDialog::QgsDwgImportDialog( QWidget *parent, Qt::WindowFlags f )
connect( leLayerGroup, &QLineEdit::textChanged, this, &QgsDwgImportDialog::leLayerGroup_textChanged ); connect( leLayerGroup, &QLineEdit::textChanged, this, &QgsDwgImportDialog::leLayerGroup_textChanged );
connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsDwgImportDialog::showHelp ); connect( buttonBox, &QDialogButtonBox::helpRequested, this, &QgsDwgImportDialog::showHelp );
connect( mLayers, &QTableWidget::itemClicked, this, &QgsDwgImportDialog::layersClicked ); connect( mLayers, &QTableWidget::itemClicked, this, &QgsDwgImportDialog::layersClicked );
connect( mBlockModeComboBox, &QComboBox::currentTextChanged, this, &QgsDwgImportDialog::blockModeCurrentIndexChanged );
const QgsSettings s; connect( cbUseCurves, &QCheckBox::clicked, this, &QgsDwgImportDialog::useCurvesClicked );
cbExpandInserts->setChecked( s.value( QStringLiteral( "/DwgImport/lastExpandInserts" ), true ).toBool() );
cbMergeLayers->setChecked( s.value( QStringLiteral( "/DwgImport/lastMergeLayers" ), false ).toBool() );
cbUseCurves->setChecked( s.value( QStringLiteral( "/DwgImport/lastUseCurves" ), true ).toBool() );
mDatabaseFileWidget->setDefaultRoot( s.value( QStringLiteral( "/DwgImport/lastDirDatabase" ), QDir::homePath() ).toString() );
leDrawing->setReadOnly( true ); leDrawing->setReadOnly( true );
pbImportDrawing->setHidden( true ); pbImportDrawing->setHidden( true );
@ -108,7 +115,7 @@ QgsDwgImportDialog::~QgsDwgImportDialog()
mPreviewLayers.clear(); mPreviewLayers.clear();
QgsSettings s; QgsSettings s;
s.setValue( QStringLiteral( "/DwgImport/lastExpandInserts" ), cbExpandInserts->isChecked() ); s.setValue( QStringLiteral( "/DwgImport/lastBlockImportFlags" ), mBlockModeComboBox->currentData() );
s.setValue( QStringLiteral( "/DwgImport/lastMergeLayers" ), cbMergeLayers->isChecked() ); s.setValue( QStringLiteral( "/DwgImport/lastMergeLayers" ), cbMergeLayers->isChecked() );
s.setValue( QStringLiteral( "/DwgImport/lastUseCurves" ), cbUseCurves->isChecked() ); s.setValue( QStringLiteral( "/DwgImport/lastUseCurves" ), cbUseCurves->isChecked() );
} }
@ -266,8 +273,11 @@ void QgsDwgImportDialog::pbImportDrawing_clicked()
lblMessage->setVisible( true ); lblMessage->setVisible( true );
const BlockImportFlags blockImportFlags = BlockImportFlags( mBlockModeComboBox->currentData().toInt() );
const bool expandInserts = blockImportFlags & BlockImportFlag::BlockImportExpandGeometry;
QString error; QString error;
if ( importer.import( leDrawing->text(), error, cbExpandInserts->isChecked(), cbUseCurves->isChecked(), lblMessage ) ) if ( importer.import( leDrawing->text(), error, expandInserts, cbUseCurves->isChecked(), lblMessage ) )
{ {
bar->pushMessage( tr( "Drawing import completed." ), Qgis::MessageLevel::Info ); bar->pushMessage( tr( "Drawing import completed." ), Qgis::MessageLevel::Info );
} }
@ -463,7 +473,8 @@ QList<QgsVectorLayer *> QgsDwgImportDialog::createLayers( const QStringList &lay
layers.append( l ); layers.append( l );
} }
if ( !cbExpandInserts->isChecked() ) const BlockImportFlags blockImportFlags = BlockImportFlags( mBlockModeComboBox->currentData().toInt() );
if ( blockImportFlags & BlockImportFlag::BlockImportAddInsertPoints )
{ {
l = createLayer( layerFilter, QStringLiteral( "inserts" ) ); l = createLayer( layerFilter, QStringLiteral( "inserts" ) );
if ( l && l->renderer() ) if ( l && l->renderer() )
@ -584,9 +595,26 @@ void QgsDwgImportDialog::layersClicked( QTableWidgetItem *item )
mPreviewLayers = createLayers( QStringList( layerName ) ); mPreviewLayers = createLayers( QStringList( layerName ) );
QList<QgsMapLayer *> mapLayers; QList<QgsMapLayer *> mapLayers;
for ( QgsVectorLayer *vectorLayer : mPreviewLayers ) const QList<QgsVectorLayer *> constPreviewLayers = mPreviewLayers;
for ( QgsVectorLayer *vectorLayer : constPreviewLayers )
mapLayers.append( vectorLayer ); mapLayers.append( vectorLayer );
mMapCanvas->setLayers( mapLayers ); mMapCanvas->setLayers( mapLayers );
mMapCanvas->setExtent( mMapCanvas->fullExtent() ); mMapCanvas->setExtent( mMapCanvas->fullExtent() );
} }
void QgsDwgImportDialog::blockModeCurrentIndexChanged()
{
if ( mDatabaseFileWidget->filePath().isEmpty() || leDrawing->text().isEmpty() )
return;
pbImportDrawing_clicked();
}
void QgsDwgImportDialog::useCurvesClicked()
{
if ( mDatabaseFileWidget->filePath().isEmpty() || leDrawing->text().isEmpty() )
return;
pbImportDrawing_clicked();
}

View File

@ -44,6 +44,8 @@ class APP_EXPORT QgsDwgImportDialog : public QDialog, private Ui::QgsDwgImportBa
void leLayerGroup_textChanged( const QString &text ); void leLayerGroup_textChanged( const QString &text );
void showHelp(); void showHelp();
void layersClicked( QTableWidgetItem *item ); void layersClicked( QTableWidgetItem *item );
void blockModeCurrentIndexChanged();
void useCurvesClicked();
private: private:
@ -53,6 +55,13 @@ class APP_EXPORT QgsDwgImportDialog : public QDialog, private Ui::QgsDwgImportBa
Visibility = 1 Visibility = 1
}; };
enum BlockImportFlag
{
BlockImportExpandGeometry = 1 << 0,
BlockImportAddInsertPoints = 1 << 1
};
Q_DECLARE_FLAGS( BlockImportFlags, BlockImportFlag )
QgsVectorLayer *createLayer( const QString &layer, const QString &table ); QgsVectorLayer *createLayer( const QString &layer, const QString &table );
QList<QgsVectorLayer *> createLayers( const QStringList &layerNames ); QList<QgsVectorLayer *> createLayers( const QStringList &layerNames );
void createGroup( QgsLayerTreeGroup *group, const QString &name, const QStringList &layers, bool visible ); void createGroup( QgsLayerTreeGroup *group, const QString &name, const QStringList &layers, bool visible );

View File

@ -113,11 +113,7 @@
<item row="7" column="1"> <item row="7" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_4"> <layout class="QHBoxLayout" name="horizontalLayout_4">
<item> <item>
<widget class="QCheckBox" name="cbExpandInserts"> <widget class="QComboBox" name="mBlockModeComboBox"/>
<property name="text">
<string>Expand block references</string>
</property>
</widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="cbUseCurves"> <widget class="QCheckBox" name="cbUseCurves">
@ -282,7 +278,7 @@
<tabstop>leDrawing</tabstop> <tabstop>leDrawing</tabstop>
<tabstop>pbImportDrawing</tabstop> <tabstop>pbImportDrawing</tabstop>
<tabstop>pbBrowseDrawing</tabstop> <tabstop>pbBrowseDrawing</tabstop>
<tabstop>cbExpandInserts</tabstop> <tabstop>mBlockModeComboBox</tabstop>
<tabstop>cbUseCurves</tabstop> <tabstop>cbUseCurves</tabstop>
<tabstop>leLayerGroup</tabstop> <tabstop>leLayerGroup</tabstop>
<tabstop>mLayers</tabstop> <tabstop>mLayers</tabstop>

View File

@ -30,14 +30,18 @@ class TestQgsDwgImportDialog : public QObject
private slots: private slots:
void initTestCase();// will be called before the first testfunction is executed. void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase(); // will be called after the last testfunction was executed. void cleanupTestCase() {} // will be called after the last testfunction was executed.
void cleanup() {} // will be called after every testfunction. void cleanup(); // will be called after every testfunction.
void importDwgDocument(); void importDwgDocument();
void importDwgDocumentExpandBlockGeometries();
void importDwgDocumentBlockOnlyInsertPoints();
private: private:
QgisApp *mQgisApp = nullptr; QgisApp *mQgisApp = nullptr;
QString mDataDir; QString mDataDir;
void checkGroupContent( QgsLayerTreeGroup *parentGroup, const QString &groupName, const QStringList &contentLayerNames );
}; };
@ -51,7 +55,7 @@ void TestQgsDwgImportDialog::initTestCase()
mDataDir += "/dwg"; mDataDir += "/dwg";
} }
void TestQgsDwgImportDialog::cleanupTestCase() void TestQgsDwgImportDialog::cleanup()
{ {
QgsProject::instance()->removeAllMapLayers(); QgsProject::instance()->removeAllMapLayers();
} }
@ -64,14 +68,16 @@ void TestQgsDwgImportDialog::importDwgDocument()
QTemporaryDir temporaryDir; QTemporaryDir temporaryDir;
dwgImportDialog.mDatabaseFileWidget->setFilePath( temporaryDir.filePath( "entities.gpkg" ) ); dwgImportDialog.mDatabaseFileWidget->setFilePath( temporaryDir.filePath( "entities.gpkg" ) );
// Set Expand Blocks mode
const QgsDwgImportDialog::BlockImportFlags blockImportMode( QgsDwgImportDialog::BlockImportExpandGeometry | QgsDwgImportDialog::BlockImportAddInsertPoints );
const int index = dwgImportDialog.mBlockModeComboBox->findData( static_cast<int>( blockImportMode ) );
dwgImportDialog.mBlockModeComboBox->setCurrentIndex( index );
// Set source drawing and import // Set source drawing and import
QString uri = QString( mDataDir + "/entities.dwg" ); QString uri = QString( mDataDir + "/entities.dwg" );
dwgImportDialog.leDrawing->setText( uri ); dwgImportDialog.leDrawing->setText( uri );
dwgImportDialog.pbImportDrawing_clicked(); dwgImportDialog.pbImportDrawing_clicked();
// Set Expand Inserts checkbox
dwgImportDialog.cbExpandInserts->setChecked( false );
// Check that a default group name was assigned // Check that a default group name was assigned
QCOMPARE( dwgImportDialog.leLayerGroup->text(), "entities" ); QCOMPARE( dwgImportDialog.leLayerGroup->text(), "entities" );
@ -84,33 +90,113 @@ void TestQgsDwgImportDialog::importDwgDocument()
QVERIFY( groupEntities ); QVERIFY( groupEntities );
// Group 0 // Group 0
QgsLayerTreeGroup *group0 = groupEntities->findGroup( "0" ); checkGroupContent( groupEntities,
QVERIFY( group0 ); "0",
QStringList() << "hatches" << "lines" << "polylines" << "texts" << "points" << "inserts" );
QStringList layerNames = QStringList() << "hatches"
<< "lines"
<< "polylines"
<< "texts"
<< "points"
<< "inserts";
const auto layerTreeLayers0 = group0->findLayers();
for ( QgsLayerTreeLayer *layerTreeLayer : layerTreeLayers0 )
QVERIFY2( layerNames.removeOne( layerTreeLayer->name() ), QString( "Unexpected layer name: '%1'" ).arg( layerTreeLayer->name() ).toLatin1() );
QVERIFY2( layerNames.isEmpty(), QString( "Missing layers in group '0': '%1'" ).arg( layerNames.join( ", " ) ).toLatin1() );
// Group grün // Group grün
QgsLayerTreeGroup *groupGruen = groupEntities->findGroup( "grün" ); checkGroupContent( groupEntities,
QVERIFY( groupGruen ); "grün",
QStringList() << "hatches" << "lines" << "polylines" );
}
layerNames = QStringList() << "hatches" void TestQgsDwgImportDialog::importDwgDocumentExpandBlockGeometries()
<< "lines" {
<< "polylines"; QgsDwgImportDialog dwgImportDialog( nullptr, Qt::WindowFlags() );
const auto layerTreeLayersGruen = groupGruen->findLayers();
for ( QgsLayerTreeLayer *layerTreeLayer : layerTreeLayersGruen )
QVERIFY2( layerNames.removeOne( layerTreeLayer->name() ), QString( "Unexpected layer name: '%1'" ).arg( layerTreeLayer->name() ).toLatin1() );
QVERIFY2( layerNames.isEmpty(), QString( "Missing layers in group 'grün': '%1'" ).arg( layerNames.join( ", " ) ).toLatin1() ); // Set target gpkg
QTemporaryDir temporaryDir;
dwgImportDialog.mDatabaseFileWidget->setFilePath( temporaryDir.filePath( "entitiesExpandBlockGeometries.gpkg" ) );
// Set Expand Blocks mode
const QgsDwgImportDialog::BlockImportFlags blockImportMode = QgsDwgImportDialog::BlockImportExpandGeometry;
const int index = dwgImportDialog.mBlockModeComboBox->findData( static_cast<int>( blockImportMode ) );
dwgImportDialog.mBlockModeComboBox->setCurrentIndex( index );
// Set source drawing and import
QString uri = QString( mDataDir + "/entities.dwg" );
dwgImportDialog.leDrawing->setText( uri );
dwgImportDialog.pbImportDrawing_clicked();
// Check that a default group name was assigned
QCOMPARE( dwgImportDialog.leLayerGroup->text(), "entities" );
dwgImportDialog.leLayerGroup->setText( "entitiesExpandBlockGeometries" );
dwgImportDialog.buttonBox_accepted();
QgsLayerTreeGroup *rootGroup = QgsLayerTree::toGroup( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup() );
QVERIFY( rootGroup );
QgsLayerTreeGroup *groupEntities = rootGroup->findGroup( "entitiesExpandBlockGeometries" );
QVERIFY( groupEntities );
// Group 0
checkGroupContent( groupEntities,
"0",
QStringList() << "hatches" << "lines" << "polylines" << "texts" << "points" );
// Group grün
checkGroupContent( groupEntities,
"grün",
QStringList() << "hatches" << "lines" << "polylines" );
}
void TestQgsDwgImportDialog::importDwgDocumentBlockOnlyInsertPoints()
{
QgsDwgImportDialog dwgImportDialog( nullptr, Qt::WindowFlags() );
// Set target gpkg
QTemporaryDir temporaryDir;
dwgImportDialog.mDatabaseFileWidget->setFilePath( temporaryDir.filePath( "entitiesBlockOnlyInsertPoints.gpkg" ) );
// Set Expand Blocks mode
const QgsDwgImportDialog::BlockImportFlags blockImportMode = QgsDwgImportDialog::BlockImportAddInsertPoints;
const int index = dwgImportDialog.mBlockModeComboBox->findData( static_cast<int>( blockImportMode ) );
dwgImportDialog.mBlockModeComboBox->setCurrentIndex( index );
// Set source drawing and import
QString uri = QString( mDataDir + "/entities.dwg" );
dwgImportDialog.leDrawing->setText( uri );
dwgImportDialog.pbImportDrawing_clicked();
// Check that a default group name was assigned
QCOMPARE( dwgImportDialog.leLayerGroup->text(), "entities" );
dwgImportDialog.leLayerGroup->setText( "entitiesBlockOnlyInsertPoints" );
dwgImportDialog.buttonBox_accepted();
QgsLayerTreeGroup *rootGroup = QgsLayerTree::toGroup( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup() );
QVERIFY( rootGroup );
QgsLayerTreeGroup *groupEntities = rootGroup->findGroup( "entitiesBlockOnlyInsertPoints" );
QVERIFY( groupEntities );
// Group 0
checkGroupContent( groupEntities,
"0",
QStringList() << "hatches" << "lines" << "polylines" << "texts" << "points" << "inserts" );
// Group grün
checkGroupContent( groupEntities,
"grün",
QStringList() << "hatches" << "lines" << "polylines" );
}
void TestQgsDwgImportDialog::checkGroupContent( QgsLayerTreeGroup *parentGroup, const QString &groupName, const QStringList &contentLayerNames )
{
// Group
QgsLayerTreeGroup *group = parentGroup->findGroup( groupName );
QVERIFY( group );
QStringList layerNames = contentLayerNames;
const auto layerTreeLayers = group->findLayers();
for ( QgsLayerTreeLayer *layerTreeLayer : layerTreeLayers )
QVERIFY2( layerNames.removeOne( layerTreeLayer->name() ), QString( "Unexpected layer '%1' in group '%2'" ).arg( layerTreeLayer->name(), groupName ).toLatin1() );
QVERIFY2( layerNames.isEmpty(), QString( "Missing layers in group '%1': '%2'" ).arg( groupName, layerNames.join( ", " ) ).toLatin1() );
} }
QGSTEST_MAIN( TestQgsDwgImportDialog ) QGSTEST_MAIN( TestQgsDwgImportDialog )