Skip to content

Commit

Permalink
embedding of single layer
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Jun 8, 2011
1 parent a579685 commit 39fcdb7
Show file tree
Hide file tree
Showing 13 changed files with 260 additions and 50 deletions.
17 changes: 17 additions & 0 deletions src/app/qgisapp.cpp
Expand Up @@ -779,6 +779,7 @@ void QgisApp::createActions()
connect( mActionNewVectorLayer, SIGNAL( triggered() ), this, SLOT( newVectorLayer() ) );
connect( mActionNewSpatialiteLayer, SIGNAL( triggered() ), this, SLOT( newSpatialiteLayer() ) );
connect( mActionShowRasterCalculator, SIGNAL( triggered() ), this, SLOT( showRasterCalculator() ) );
connect( mActionEmbedLayers, SIGNAL( triggered() ) , this, SLOT( embedLayers() ) );
connect( mActionAddOgrLayer, SIGNAL( triggered() ), this, SLOT( addVectorLayer() ) );
connect( mActionAddRasterLayer, SIGNAL( triggered() ), this, SLOT( addRasterLayer() ) );
connect( mActionAddPgLayer, SIGNAL( triggered() ), this, SLOT( addDatabaseLayer() ) );
Expand Down Expand Up @@ -5048,6 +5049,16 @@ void QgisApp::addMapLayer( QgsMapLayer *theMapLayer )

}

void QgisApp::embedLayers()
{
//dialog to select groups/layers from other project files

//hardcoded for debugging
QString filepath="/home/marco/geodaten/projekte/composertest.qgs";
QString id="komb113320110516093016594";
QgsProject::instance()->createEmbeddedLayer( id, filepath );
}

void QgisApp::setExtent( QgsRectangle theRect )
{
mMapCanvas->setExtent( theRect );
Expand Down Expand Up @@ -6513,6 +6524,11 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
if ( !ml )
return;

if( !QgsProject::instance()->layerIsEmbedded( ml->id() ).isEmpty() )
{
return; //don't show properties of embedded layers
}

if ( ml->type() == QgsMapLayer::RasterLayer )
{
QgsRasterLayerProperties *rlp = NULL; // See note above about reusing this
Expand All @@ -6525,6 +6541,7 @@ void QgisApp::showLayerProperties( QgsMapLayer *ml )
rlp = new QgsRasterLayerProperties( ml, mMapCanvas );
connect( rlp, SIGNAL( refreshLegend( QString, bool ) ), mMapLegend, SLOT( refreshLayerSymbology( QString, bool ) ) );
}

rlp->exec();
delete rlp; // delete since dialog cannot be reused without updating code
}
Expand Down
4 changes: 4 additions & 0 deletions src/app/qgisapp.h
Expand Up @@ -249,6 +249,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow

QAction *actionNewVectorLayer() { return mActionNewVectorLayer; }
QAction *actionNewSpatialLiteLayer() { return mActionNewSpatialiteLayer; }
QAction *actionEmbedLayers() { return mActionEmbedLayers; }
QAction *actionAddOgrLayer() { return mActionAddOgrLayer; }
QAction *actionAddRasterLayer() { return mActionAddRasterLayer; }
QAction *actionAddPgLayer() { return mActionAddPgLayer; }
Expand Down Expand Up @@ -541,6 +542,7 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
void fileNew( bool thePromptToSaveFlag );
//! Calculate new rasters from existing ones
void showRasterCalculator();
void embedLayers();

//! Create a new empty vector layer
void newVectorLayer();
Expand Down Expand Up @@ -763,6 +765,8 @@ class QgisApp : public QMainWindow, private Ui::MainWindow
//! Activates label property tool
void changeLabelProperties();



signals:
/** emitted when a key is pressed and we want non widget sublasses to be able
to pick up on this (e.g. maplayer) */
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -141,7 +141,7 @@ void QgsMapLayer::drawLabels( QgsRenderContext& rendererContext )
// QgsDebugMsg("entered.");
}

bool QgsMapLayer::readXML( QDomNode & layer_node )
bool QgsMapLayer::readXML( const QDomNode& layer_node )
{
QgsCoordinateReferenceSystem savedCRS;
CUSTOM_CRS_VALIDATION savedValidation;
Expand Down Expand Up @@ -269,7 +269,7 @@ bool QgsMapLayer::readXML( QDomNode & layer_node )
} // void QgsMapLayer::readXML


bool QgsMapLayer::readXml( QDomNode & layer_node )
bool QgsMapLayer::readXml( const QDomNode& layer_node )
{
// NOP by default; children will over-ride with behavior specific to them

Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsmaplayer.h
Expand Up @@ -155,7 +155,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
@returns true if successful
*/
bool readXML( QDomNode & layer_node );
bool readXML( const QDomNode& layer_node );


/** stores state in Dom node
Expand Down Expand Up @@ -378,7 +378,7 @@ class CORE_EXPORT QgsMapLayer : public QObject
/** called by readXML(), used by children to read state specific to them from
project files.
*/
virtual bool readXml( QDomNode & layer_node );
virtual bool readXml( const QDomNode& layer_node );

/** called by writeXML(), used by children to write state specific to them to
project files.
Expand Down
235 changes: 198 additions & 37 deletions src/core/qgsproject.cpp
Expand Up @@ -682,54 +682,66 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
QDomNode node = nl.item( i );
QDomElement element = node.toElement();

QString type = element.attribute( "type" );

QgsDebugMsg( "Layer type is " + type );

QgsMapLayer *mapLayer = NULL;

if ( type == "vector" )
if( element.attribute("embedded") == "1" )
{
mapLayer = new QgsVectorLayer;
createEmbeddedLayer( element.attribute( "id" ), readPath( element.attribute( "project" ) ) );
continue;
}
else if ( type == "raster" )
{
mapLayer = new QgsRasterLayer;
}
else if ( type == "plugin" )
else
{
QString typeName = element.attribute( "name" );
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
}
#if 0
QString type = element.attribute( "type" );
QgsDebugMsg( "Layer type is " + type );
QgsMapLayer *mapLayer = NULL;

if ( type == "vector" )
{
mapLayer = new QgsVectorLayer;
}
else if ( type == "raster" )
{
mapLayer = new QgsRasterLayer;
}
else if ( type == "plugin" )
{
QString typeName = element.attribute( "name" );
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
}

Q_CHECK_PTR( mapLayer );
Q_CHECK_PTR( mapLayer );

if ( !mapLayer )
{
QgsDebugMsg( "Unable to create layer" );
if ( !mapLayer )
{
QgsDebugMsg( "Unable to create layer" );

return qMakePair( false, brokenNodes );
}
return qMakePair( false, brokenNodes );
}

// have the layer restore state that is stored in Dom node
if ( mapLayer->readXML( node ) && mapLayer->isValid() )
{
mapLayer = QgsMapLayerRegistry::instance()->addMapLayer( mapLayer );
QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( vLayer && vLayer->vectorJoins().size() > 0 )
// have the layer restore state that is stored in Dom node
if ( mapLayer->readXML( node ) && mapLayer->isValid() )
{
vLayerList.push_back( qMakePair( vLayer, element ) );
mapLayer = QgsMapLayerRegistry::instance()->addMapLayer( mapLayer );
QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( vLayer && vLayer->vectorJoins().size() > 0 )
{
vLayerList.push_back( qMakePair( vLayer, element ) );
}
}
}
else
{
delete mapLayer;
else
{
delete mapLayer;

QgsDebugMsg( "Unable to load " + type + " layer" );
QgsDebugMsg( "Unable to load " + type + " layer" );

returnStatus = false; // flag that we had problems loading layers
returnStatus = false; // flag that we had problems loading layers

brokenNodes.push_back( node );
brokenNodes.push_back( node );
}
#endif //0
if( !addLayer( element, brokenNodes, vLayerList ) )
{
returnStatus = false;
}
}
emit layerLoaded( i + 1, nl.count() );
}
Expand All @@ -754,6 +766,55 @@ QPair< bool, QList<QDomNode> > QgsProject::_getMapLayers( QDomDocument const &do
} // _getMapLayers


bool QgsProject::addLayer( const QDomElement& layerElem, QList<QDomNode>& brokenNodes, QList< QPair< QgsVectorLayer*, QDomElement > >& vectorLayerList )
{
QString type = layerElem.attribute( "type" );
QgsDebugMsg( "Layer type is " + type );
QgsMapLayer *mapLayer = NULL;

if ( type == "vector" )
{
mapLayer = new QgsVectorLayer;
}
else if ( type == "raster" )
{
mapLayer = new QgsRasterLayer;
}
else if ( type == "plugin" )
{
QString typeName = layerElem.attribute( "name" );
mapLayer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
}

Q_CHECK_PTR( mapLayer );

if ( !mapLayer )
{
QgsDebugMsg( "Unable to create layer" );

return false;
}

// have the layer restore state that is stored in Dom node
if ( mapLayer->readXML( layerElem ) && mapLayer->isValid() )
{
mapLayer = QgsMapLayerRegistry::instance()->addMapLayer( mapLayer );
QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
if ( vLayer && vLayer->vectorJoins().size() > 0 )
{
vectorLayerList.push_back( qMakePair( vLayer, layerElem ) );
}
return true;
}
else
{
delete mapLayer;

QgsDebugMsg( "Unable to load " + type + " layer" );
brokenNodes.push_back( layerElem );
return false;
}
}


/**
Expand Down Expand Up @@ -1022,7 +1083,19 @@ bool QgsProject::write()

if ( ml )
{
ml->writeXML( projectLayersNode, *doc );
QString externalProjectFile = layerIsEmbedded( ml->id() );
if( externalProjectFile.isEmpty() )
{
ml->writeXML( projectLayersNode, *doc );
}
else //layer defined in an external project file
{
QDomElement mapLayerElem = doc->createElement("maplayer");
mapLayerElem.setAttribute("embedded", 1 );
mapLayerElem.setAttribute("project", writePath( externalProjectFile ) );
mapLayerElem.setAttribute("id", ml->id() );
projectLayersNode.appendChild( mapLayerElem );
}
}
li++;
}
Expand Down Expand Up @@ -1529,6 +1602,94 @@ void QgsProject::setBadLayerHandler( QgsProjectBadLayerHandler* handler )
mBadLayerHandler = handler;
}

void QgsProject::addEmbeddedLayer( const QString& layerId, const QString& projectFilePath )
{
mEmbeddedLayers.insert( layerId, projectFilePath );
}

QString QgsProject::layerIsEmbedded( const QString& id ) const
{
QHash< QString, QString >::const_iterator it = mEmbeddedLayers.find( id );
if( it == mEmbeddedLayers.constEnd() )
{
return QString();
}
return it.value();
};

QgsMapLayer* QgsProject::createEmbeddedLayer( const QString& layerId, const QString& projectFilePath )
{
QFile projectFile( projectFilePath );
if( !projectFile.open( QIODevice::ReadOnly ) )
{
return 0;
}

QDomDocument projectDocument;
if( !projectDocument.setContent( &projectFile ) )
{
return 0;
}

QDomElement projectLayersElem = projectDocument.documentElement().firstChildElement("projectlayers");
if( projectLayersElem.isNull() )
{
return 0;
}

QDomNodeList mapLayerNodes = projectLayersElem.elementsByTagName("maplayer");
for( int i = 0; i < mapLayerNodes.size(); ++i )
{
//get layer id
QDomElement mapLayerElem = mapLayerNodes.at(i).toElement();
QString id = mapLayerElem.firstChildElement("id").text();
if( id == layerId )
{
#if 0
if( !addLayer( element, brokenNodes, vLayerList ) )
{
returnStatus = false;
}
#endif //0
QString type = mapLayerElem.attribute("type");
QgsMapLayer* layer = 0;
if( type == "vector" )
{
layer = new QgsVectorLayer();
}
else if( type == "raster" )
{
layer = new QgsRasterLayer();
}
else if( type == "plugin" )
{
QString typeName = mapLayerElem.attribute( "name" );
layer = QgsPluginLayerRegistry::instance()->createLayer( typeName );
}
else
{
return 0;
}

// have the layer restore state that is stored in Dom node
if ( layer->readXML( mapLayerElem ) )
{
QgsMapLayerRegistry::instance()->addMapLayer( layer );
QgsProject::instance()->addEmbeddedLayer( layerId, projectFilePath );
}
else
{
delete layer;
QgsDebugMsg( "unable to load " + type + " layer" );
return 0;
}
return layer;
}
}

return 0;
}

void QgsProjectBadLayerDefaultHandler::handleBadLayers( QList<QDomNode> /*layers*/, QDomDocument /*projectDom*/ )
{
// just ignore any bad layers
Expand Down

0 comments on commit 39fcdb7

Please sign in to comment.