diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt index fe525c23dd9..6ae99b2a4fa 100644 --- a/src/app/CMakeLists.txt +++ b/src/app/CMakeLists.txt @@ -88,8 +88,6 @@ SET(QGIS_APP_SRCS legend/qgslegend.cpp legend/qgslegenditem.cpp legend/qgslegendlayer.cpp - legend/qgslegendlayerfile.cpp - legend/qgslegendlayerfilegroup.cpp legend/qgslegendpropertygroup.cpp legend/qgslegendpropertyitem.cpp legend/qgslegendsymbologygroup.cpp @@ -184,7 +182,6 @@ SET (QGIS_APP_MOC_HDRS legend/qgslegend.h legend/qgslegendlayer.h - legend/qgslegendlayerfile.h ogr/qgsopenvectorlayerdialog.h ogr/qgsnewogrconnection.h diff --git a/src/app/legend/qgslegend.cpp b/src/app/legend/qgslegend.cpp index 01c0dbba83a..39d8c672e06 100755 --- a/src/app/legend/qgslegend.cpp +++ b/src/app/legend/qgslegend.cpp @@ -25,8 +25,6 @@ #include "qgslegendlayer.h" #include "qgslegendpropertygroup.h" #include "qgslegendsymbologyitem.h" -#include "qgslegendlayerfile.h" -#include "qgslegendlayerfilegroup.h" #include "qgsmapcanvas.h" #include "qgsmapcanvasmap.h" #include "qgsmaplayer.h" @@ -63,7 +61,6 @@ QgsLegend::QgsLegend( QWidget * parent, const char *name ) : QTreeWidget( parent ), mMousePressedFlag( false ), mItemBeingMoved( 0 ), - mShowLegendLayerFiles( false ), mToggleEditingAction( 0 ), mMapCanvas( 0 ), mMinimumIconSize( 20, 20 ) @@ -175,8 +172,6 @@ void QgsLegend::removeLayer( QString layer_key ) QTreeWidgetItem* theItem = firstItem(); QgsDebugMsg( "called." ); - QgsLegendLayer* lastLL = NULL; - while ( theItem ) { QgsLegendItem *li = dynamic_cast( theItem ); @@ -184,29 +179,17 @@ void QgsLegend::removeLayer( QString layer_key ) { // save legend layer (parent of a legend layer file we're going to delete) QgsLegendLayer* ll = qobject_cast( li ); - if ( ll ) lastLL = ll; - QgsLegendLayerFile* llf = qobject_cast( li ); - if ( llf ) + if ( ll && ll->layer() && ll->layer()->getLayerID() == layer_key ) { - if ( llf->layer() && llf->layer()->getLayerID() == layer_key ) - { - //remove the map entry for the checkbox - mStateOfCheckBoxes.erase( llf ); - removeItem( llf ); - delete llf; + //remove the map entry for the checkbox + mStateOfCheckBoxes.erase( ll ); + removeItem( ll ); + delete ll; - // delete also parent legend layer if now it's empty - if ( lastLL->mapLayers().size() == 0 ) - { - mStateOfCheckBoxes.erase( lastLL ); - removeItem( lastLL ); - delete lastLL; - } - - break; - } + break; } + } theItem = nextItem( theItem ); } @@ -385,68 +368,9 @@ void QgsLegend::mouseReleaseEvent( QMouseEvent * e ) return; } - QgsLegendItem::LEGEND_ITEM_TYPE originType = origin->type(); - QgsLegendItem::LEGEND_ITEM_TYPE destType = dest->type(); - - if ( originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE_GROUP ) - { - QgsDebugMsg( "Legend layer file moved to layer file group" ); - // Not used... delete? - //QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); - if ( dest->childCount() > 1 ) - { - //find the first layer in the legend layer group != origLayer and copy its settings - QgsLegendItem* currentItem = dynamic_cast( dest->child( 0 ) ); - while ( currentItem ) - { - if ( currentItem != origin ) - { - QgsMapLayer* origLayer = (( QgsLegendLayerFile* )( origin ) )->layer(); - QgsMapLayer* currentLayer = (( QgsLegendLayerFile* )( currentItem ) )->layer(); - origLayer->copySymbologySettings( *currentLayer ); - break; - } - currentItem = currentItem->nextSibling(); - } - } - } - else if ( originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE ) - { - QgsDebugMsg( "Legend layer file moved to legend layer file" ); - // Not used. Delete? - // QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer(); - // QgsMapLayer* destLayer = ((QgsLegendLayerFile*)(dest))->layer(); - - if ( dest == origin )//origin item has been moved in mouseMoveEvent such that it is under the mouse cursor now - { - if ( origin->parent()->childCount() > 1 ) - { - //find the first layer in the legend layer group != origLayer and copy its settings - QTreeWidgetItem* currentItem = dest->parent()->child( 0 ); - while ( currentItem ) - { - if ( currentItem != origin ) - { - QgsMapLayer* origLayer = (( QgsLegendLayerFile* )( origin ) )->layer(); - QgsMapLayer* currentLayer = (( QgsLegendLayerFile* )( currentItem ) )->layer(); - origLayer->copySymbologySettings( *currentLayer ); - break; - } - currentItem = dynamic_cast( currentItem )->nextSibling(); - } - } - } - else - { - QgsMapLayer* origLayer = (( QgsLegendLayerFile* )( origin ) )->layer(); - QgsMapLayer* destLayer = (( QgsLegendLayerFile* )( dest ) )->layer(); - origLayer->copySymbologySettings( *destLayer ); - } - } - else { // Do the actual move here. - QgsDebugMsg( "Other type of drag'n'drop happened!" ); + QgsDebugMsg( "Drag'n'drop happened!" ); if ( mDropAction == AFTER ) //over center of item { QgsDebugMsg( "Drop AFTER" ); @@ -506,11 +430,7 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi if ( li ) { - if ( li->type() == QgsLegendItem::LEGEND_LAYER_FILE ) - { - ( static_cast( li ) )->addToPopupMenu( theMenu, mToggleEditingAction ); - } - else if ( li->type() == QgsLegendItem::LEGEND_LAYER ) + if ( li->type() == QgsLegendItem::LEGEND_LAYER ) { ( static_cast( li ) )->addToPopupMenu( theMenu, mToggleEditingAction ); @@ -537,11 +457,6 @@ void QgsLegend::handleRightClickEvent( QTreeWidgetItem* item, const QPoint& posi theMenu.addAction( QgisApp::getThemeIcon( "/mActionExpandTree.png" ), tr( "&Expand all" ), this, SLOT( expandAll() ) ); theMenu.addAction( QgisApp::getThemeIcon( "/mActionCollapseTree.png" ), tr( "&Collapse all" ), this, SLOT( collapseAll() ) ); - QAction* showFileGroupsAction = theMenu.addAction( tr( "Show file groups" ), this, SLOT( showLegendLayerFileGroups() ) ); - showFileGroupsAction->setCheckable( true ); - showFileGroupsAction->blockSignals( true ); - showFileGroupsAction->setChecked( mShowLegendLayerFiles ); - showFileGroupsAction->blockSignals( false ); theMenu.exec( position ); } @@ -576,40 +491,28 @@ void QgsLegend::addLayer( QgsMapLayer * layer ) return; } - QgsLegendLayer * llayer = new QgsLegendLayer( layer->name() );//generate entry for mStateOfCheckBoxes below - QgsLegendLayerFileGroup * llfgroup = new QgsLegendLayerFileGroup( llayer, QString( "Files" ) ); - QgsLegendLayerFile * llfile = new QgsLegendLayerFile( llfgroup, QgsLegendLayerFile::nameFromLayer( layer ), layer ); + QgsLegendLayer* llayer = new QgsLegendLayer( layer ); + llayer->updateIcon(); llayer->setToolTip( 0, layer->publicSource() ); //set the correct check states blockSignals( true ); - if ( llfile->isVisible() ) + if ( llayer->isVisible() ) { - llfile->setCheckState( 0, Qt::Checked ); llayer->setCheckState( 0, Qt::Checked ); - mStateOfCheckBoxes.insert( std::make_pair( llfile, Qt::Checked ) ); //insert the check state into the map to query for changes later mStateOfCheckBoxes.insert( std::make_pair( llayer, Qt::Checked ) ); } else { - llfile->setCheckState( 0, Qt::Unchecked ); llayer->setCheckState( 0, Qt::Unchecked ); - mStateOfCheckBoxes.insert( std::make_pair( llfile, Qt::Unchecked ) ); //insert the check state into the map to query for changes later mStateOfCheckBoxes.insert( std::make_pair( llayer, Qt::Unchecked ) ); } blockSignals( false ); insertTopLevelItem( 0, llayer ); setItemExpanded( llayer, true ); - setItemExpanded( llfgroup, false ); - //only if qsetting for 'legend layer file visible' is not set - if ( !mShowLegendLayerFiles ) - { - llfgroup->setHidden( true ); - } - llfile->updateLegendItem(); refreshLayerSymbology( layer->getLayerID() ); updateMapCanvasLayerSet(); @@ -630,28 +533,22 @@ void QgsLegend::addLayer( QgsMapLayer * layer ) } } -QgsLegendLayerFile* QgsLegend::currentLayerFile() +QgsLegendLayer* QgsLegend::currentLegendLayer() { QgsLegendItem* citem = dynamic_cast( currentItem() ); if ( citem ) { - QgsLegendLayerFile* llf = qobject_cast( citem ); - if ( llf ) - { - return llf; //the current item is itself a legend layer file - } - QgsLegendLayer* ll = qobject_cast( citem ); if ( ll ) { - return ll->firstLayerFile(); //the current item is a legend layer, so return its first layer + return ll; //the current item is a legend layer, so return it } QgsLegendLayer* lpl = dynamic_cast( citem->parent() ); if ( lpl ) { - return lpl->firstLayerFile(); //the parent of the current item is a legend layer, return its first layer + return lpl; //the parent of the current item is a legend layer, return it } } @@ -660,10 +557,10 @@ QgsLegendLayerFile* QgsLegend::currentLayerFile() QgsMapLayer* QgsLegend::currentLayer() { - QgsLegendLayerFile* llf = currentLayerFile(); - if ( llf ) + QgsLegendLayer* ll = currentLegendLayer(); + if ( ll ) { - return llf->layer(); + return ll->layer(); } else { @@ -703,45 +600,17 @@ void QgsLegend::legendLayerRemove() //if the current item is a legend layer: remove all layers of the current legendLayer QgsLegendLayer* ll = dynamic_cast( currentItem() ); - if ( ll ) - { - std::list maplayers = ll->mapLayers(); - int layerCount = maplayers.size(); - - for ( std::list::iterator it = maplayers.begin(); it != maplayers.end(); ++it ) - { - //remove the layer - if ( *it ) - { - removeLayer( *it, true ); - } - } - - if ( layerCount == 0 ) - { - // delete the item only when it didn't have any child legend layer files - // (otherwise it is deleted in QgsLegend::removeLayer when deleting last legend layer file) - mStateOfCheckBoxes.erase( ll ); - removeItem( ll ); - delete ll; - } - - adjustIconSize(); + if ( !ll ) return; - } - //if the current item is a legend layer file - QgsLegendLayerFile* llf = dynamic_cast( currentItem() ); - if ( llf ) - { - if ( llf->layer() ) - { - //the map layer registry emits a signal an this will remove the legend layer - //from the legend and from memory by calling QgsLegend::removeLayer(QString layer key) - QgsMapLayerRegistry::instance()->removeMapLayer( llf->layer()->getLayerID() ); - } - } - return; + removeLayer( ll->layer(), true ); + + mStateOfCheckBoxes.erase( ll ); + removeItem( ll ); + delete ll; + + adjustIconSize(); + } bool QgsLegend::removeLayer( QgsMapLayer* ml, bool askCancelOnEditable ) @@ -807,31 +676,22 @@ void QgsLegend::legendLayerShowProperties() } QgsLegendItem* li = dynamic_cast( currentItem() ); - QgsLegendLayerFile* llf = 0; if ( !li ) { return; } - if ( li->type() == QgsLegendItem::LEGEND_LAYER_FILE ) - { - llf = qobject_cast( li ); - } - else if ( li->type() == QgsLegendItem::LEGEND_LAYER ) - { - QgsLegendLayer* ll = qobject_cast( li ); - llf = ll->firstLayerFile(); - } - - if ( !llf ) - { + if ( li->type() != QgsLegendItem::LEGEND_LAYER ) + return; + + QgsLegendLayer* ll = qobject_cast( li ); + if ( !ll ) return; - } //QgsDebugMsg("Showing layer properties dialog"); - QgsMapLayer* ml = llf->layer(); + QgsMapLayer* ml = ll->layer(); /* TODO: Consider reusing the property dialogs again. @@ -875,7 +735,7 @@ void QgsLegend::legendLayerShowProperties() delete vlp; // delete since dialog cannot be reused without updating code } - llf->updateLegendItem(); + ll->updateIcon(); } @@ -890,18 +750,12 @@ void QgsLegend::legendLayerShowInOverview() if ( !li ) return; - if ( li->type() == QgsLegendItem::LEGEND_LAYER_FILE ) - { - QgsLegendLayerFile* llf = qobject_cast( li ); - if ( !llf ) return; - llf->showInOverview(); - } - else if ( li->type() == QgsLegendItem::LEGEND_LAYER ) - { - QgsLegendLayer* ll = qobject_cast( li ); - if ( !ll ) return; - ll->showInOverview(); - } + if ( li->type() == QgsLegendItem::LEGEND_LAYER ) + return; + + QgsLegendLayer* ll = qobject_cast( li ); + if ( !ll ) return; + ll->showInOverview(); } void QgsLegend::expandAll() @@ -933,7 +787,6 @@ bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document ) QDomElement legendsymbolnode; QDomElement legendpropertynode; QDomElement legendlayerfilenode; - QgsLegendLayerFile* llf; Qt::CheckState cstate; //check state for legend layers and legend groups QTreeWidgetItem* currentItem = firstItem(); @@ -951,14 +804,7 @@ bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document ) legendnode = tmplegendnode; } legendgroupnode = document.createElement( "legendgroup" ); - if ( isItemExpanded( item ) ) - { - legendgroupnode.setAttribute( "open", "true" ); - } - else - { - legendgroupnode.setAttribute( "open", "false" ); - } + legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); legendgroupnode.setAttribute( "name", item->text( 0 ) ); cstate = item->checkState( 0 ); if ( cstate == Qt::Checked ) @@ -985,14 +831,7 @@ bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document ) legendnode = tmplegendnode; } legendlayernode = document.createElement( "legendlayer" ); - if ( isItemExpanded( item ) ) - { - legendlayernode.setAttribute( "open", "true" ); - } - else - { - legendlayernode.setAttribute( "open", "false" ); - } + legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); cstate = item->checkState( 0 ); if ( cstate == Qt::Checked ) { @@ -1008,76 +847,45 @@ bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document ) } legendlayernode.setAttribute( "name", item->text( 0 ) ); legendnode.appendChild( legendlayernode ); - break; - case QgsLegendItem::LEGEND_PROPERTY_GROUP: - legendpropertynode = document.createElement( "propertygroup" ); - if ( isItemExpanded( item ) ) + // save the information about layer + // emulate a legend layer file group and a legend layer file + // to keep it compatible with older projects { - legendpropertynode.setAttribute( "open", "true" ); - } - else - { - legendpropertynode.setAttribute( "open", "false" ); - } - legendlayernode.appendChild( legendpropertynode ); - break; + QgsLegendLayer *ll = dynamic_cast( item ); + QgsMapLayer* layer = ll->layer(); - case QgsLegendItem::LEGEND_SYMBOL_GROUP: - legendsymbolnode = document.createElement( "symbolgroup" ); - if ( isItemExpanded( item ) ) - { - legendsymbolnode.setAttribute( "open", "true" ); - } - else - { - legendsymbolnode.setAttribute( "open", "false" ); - } - legendlayernode.appendChild( legendsymbolnode ); - break; + layerfilegroupnode = document.createElement( "filegroup" ); + layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" ); + legendlayernode.appendChild( layerfilegroupnode ); - - case QgsLegendItem::LEGEND_LAYER_FILE_GROUP: - layerfilegroupnode = document.createElement( "filegroup" ); - if ( isItemExpanded( item ) ) - { - layerfilegroupnode.setAttribute( "open", "true" ); - } - else - { - layerfilegroupnode.setAttribute( "open", "false" ); - } - if ( isItemHidden( item ) ) - { - layerfilegroupnode.setAttribute( "hidden", "true" ); - } - else - { - layerfilegroupnode.setAttribute( "hidden", "false" ); - } - - legendlayernode.appendChild( layerfilegroupnode ); - break; - - case QgsLegendItem::LEGEND_LAYER_FILE: - legendlayerfilenode = document.createElement( "legendlayerfile" ); - llf = qobject_cast( item ); - if ( llf ) - { - QgsMapLayer* layer = llf->layer(); + legendlayerfilenode = document.createElement( "legendlayerfile" ); // layer id legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() ); layerfilegroupnode.appendChild( legendlayerfilenode ); // visible flag - legendlayerfilenode.setAttribute( "visible", llf->isVisible() ); + legendlayerfilenode.setAttribute( "visible", ll->isVisible() ); // show in overview flag - legendlayerfilenode.setAttribute( "isInOverview", llf->isInOverview() ); + legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() ); } break; + case QgsLegendItem::LEGEND_PROPERTY_GROUP: + legendpropertynode = document.createElement( "propertygroup" ); + legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + legendlayernode.appendChild( legendpropertynode ); + break; + + case QgsLegendItem::LEGEND_SYMBOL_GROUP: + legendsymbolnode = document.createElement( "symbolgroup" ); + legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + legendlayernode.appendChild( legendsymbolnode ); + break; + default: //do nothing for the leaf nodes break; } @@ -1093,7 +901,6 @@ bool QgsLegend::readXML( QDomNode& legendnode ) QDomNode child; QgsLegendGroup* lastGroup = 0; //pointer to the last inserted group QgsLegendLayer* lastLayer = 0; //pointer to the last inserted legendlayer - QgsLegendLayerFileGroup* lastLayerFileGroup = 0; //pointer to the last inserted layerfilegroup child = legendnode.firstChild(); @@ -1142,103 +949,37 @@ bool QgsLegend::readXML( QDomNode& legendnode ) } else if ( childelem.tagName() == "legendlayer" ) { - //add the legendlayer to the legend (but no legendlayerfile yet, follows later) - //if childelem is in a legendgroup element, add the layer to the group - QgsLegendLayer* theLayer; - if ( child.parentNode().toElement().tagName() == "legendgroup" ) - { - theLayer = new QgsLegendLayer( lastGroup, name ); - } - else - { - theLayer = new QgsLegendLayer( this, name ); - lastGroup = 0; - } - childelem.attribute( "open" ) == "true" ? expanded.push_back( theLayer ) : collapsed.push_back( theLayer ); + bool isOpen; // to recieve info whether the item is open or closed + lastLayer = readLayerFromXML(childelem, isOpen); - //set the checkbox of the legend layer to the right state - blockSignals( true ); - QString checked = childelem.attribute( "checked", "Qt::Checked" ); // Default is to show - if ( checked == "Qt::Checked" ) + if (lastLayer) { - theLayer->setCheckState( 0, Qt::Checked ); - mStateOfCheckBoxes.insert( std::make_pair( theLayer, Qt::Checked ) ); - } - else if ( checked == "Qt::Unchecked" ) - { - theLayer->setCheckState( 0, Qt::Unchecked ); - mStateOfCheckBoxes.insert( std::make_pair( theLayer, Qt::Unchecked ) ); - } - else if ( checked == "Qt::PartiallyChecked" ) - { - theLayer->setCheckState( 0, Qt::PartiallyChecked ); - mStateOfCheckBoxes.insert( std::make_pair( theLayer, Qt::PartiallyChecked ) ); - } - blockSignals( false ); - lastLayer = theLayer; - } - else if ( childelem.tagName() == "legendlayerfile" ) - { - //find out the legendlayer - QgsMapLayer* theMapLayer = QgsMapLayerRegistry::instance()->mapLayer( childelem.attribute( "layerid" ) ); - if ( theMapLayer == NULL ) //the layer cannot be found (e.g. the file has been moved) - { - // remove the whole legendlayer if this is the only legendlayerfile - if ( childelem.previousSibling().isNull() && childelem.nextSibling().isNull() ) + // add to tree - either as a top-level node or a child of a group + if ( child.parentNode().toElement().tagName() == "legendgroup" ) { - collapsed.removeAll( lastLayer ); - expanded.removeAll( lastLayer ); - delete lastLayer; - lastLayer = 0; - } - } - else if ( lastLayerFileGroup ) - { - QgsLegendLayerFile* theLegendLayerFile = new QgsLegendLayerFile( lastLayerFileGroup, QgsLegendLayerFile::nameFromLayer( theMapLayer ), theMapLayer ); - - // load layer's visibility and 'show in overview' flag - theLegendLayerFile->setVisible( atoi( childelem.attribute( "visible", "1" ).toUtf8() ) ); //Default is visible - theLegendLayerFile->setInOverview( atoi( childelem.attribute( "isInOverview" ).toUtf8() ) ); - - // set the check state - blockSignals( true ); - if ( theLegendLayerFile->isVisible() ) - { - mStateOfCheckBoxes.insert( std::make_pair( theLegendLayerFile, Qt::Checked ) ); - theLegendLayerFile->setCheckState( 0, Qt::Checked ); + lastGroup->addChild( lastLayer ); } else { - mStateOfCheckBoxes.insert( std::make_pair( theLegendLayerFile, Qt::Unchecked ) ); - theLegendLayerFile->setCheckState( 0, Qt::Unchecked ); - } - blockSignals( false ); - - //set the layer type icon if this legendlayerfile is the last in the file group - if ( child.nextSibling().isNull() ) - { - static_cast( theLegendLayerFile->parent()->parent() )->updateIcon(); + addTopLevelItem(lastLayer); + lastGroup = 0; } - theLegendLayerFile->updateLegendItem(); - refreshLayerSymbology( theMapLayer->getLayerID() ); + // expanded or collapsed + isOpen ? expanded.push_back( lastLayer ) : collapsed.push_back( lastLayer ); - // setup connections that will update the layer icons - if ( qobject_cast( theMapLayer ) ) - { - QgsDebugMsg( "Connecting signals for updating icons, layer " + theMapLayer->name() ); - connect( theMapLayer, SIGNAL( editingStarted() ), lastLayer, SLOT( updateIcon() ) ); - connect( theMapLayer, SIGNAL( editingStopped() ), lastLayer, SLOT( updateIcon() ) ); - } + // load symbology + refreshLayerSymbology( lastLayer->layer()->getLayerID() ); } } + else if ( childelem.tagName() == "legendlayerfile" ) + { + // do nothing, this has been handled in readLayerFromXML() + } else if ( childelem.tagName() == "filegroup" ) { - QgsLegendLayerFileGroup* theFileGroup = new QgsLegendLayerFileGroup( lastLayer, "Files" ); - childelem.attribute( "open" ) == "true" ? expandItem( theFileGroup ) : collapseItem( theFileGroup ); - childelem.attribute( "hidden" ) == "true" ? theFileGroup->setHidden( true ) : theFileGroup->setHidden( false ); - lastLayerFileGroup = theFileGroup; + // do nothing, this has been handled in readLayerFromXML() } else if ( childelem.tagName() == "propertygroup" ) { @@ -1259,6 +1000,64 @@ bool QgsLegend::readXML( QDomNode& legendnode ) return true; } + +QgsLegendLayer* QgsLegend::readLayerFromXML(QDomElement& childelem, bool& isOpen) +{ + QDomElement fileGroupElem = childelem.firstChildElement("filegroup"); + if (fileGroupElem.isNull()) + return NULL; // we need a file group! + + QDomElement fileElem = fileGroupElem.firstChildElement("legendlayerfile"); + if (fileElem.isNull()) // we need a file element! + return NULL; + + QgsMapLayer* theMapLayer = QgsMapLayerRegistry::instance()->mapLayer( fileElem.attribute( "layerid" ) ); + if ( theMapLayer == NULL ) //the layer cannot be found (e.g. the file has been moved) + { + return NULL; + } + + // create the item + QgsLegendLayer* ll = new QgsLegendLayer( theMapLayer ); + + // load layer's visibility and 'show in overview' flag + ll->setInOverview( atoi( fileElem.attribute( "isInOverview" ).toUtf8() ) ); + + //set the layer type icon + ll->updateIcon(); + + // setup connections that will update the layer icons + if ( qobject_cast( theMapLayer ) ) + { + QgsDebugMsg( "Connecting signals for updating icons, layer " + theMapLayer->name() ); + connect( theMapLayer, SIGNAL( editingStarted() ), ll, SLOT( updateIcon() ) ); + connect( theMapLayer, SIGNAL( editingStopped() ), ll, SLOT( updateIcon() ) ); + } + + // expanded or collapsed + isOpen = (childelem.attribute( "open" ) == "true"); + + //set the checkbox of the legend layer to the right state + blockSignals( true ); + QString checked = childelem.attribute( "checked", "Qt::Checked" ); // Default is to show + if ( checked == "Qt::Checked" ) + { + ll->setVisible(true); + ll->setCheckState( 0, Qt::Checked ); + mStateOfCheckBoxes.insert( std::make_pair( ll, Qt::Checked ) ); + } + else if ( checked == "Qt::Unchecked" ) + { + ll->setVisible(false); + ll->setCheckState( 0, Qt::Unchecked ); + mStateOfCheckBoxes.insert( std::make_pair( ll, Qt::Unchecked ) ); + } + blockSignals( false ); + + return ll; +} + + void QgsLegend::storeInitialPosition( QTreeWidgetItem* li ) { if ( li == firstItem() ) //the item is the first item in the list view @@ -1325,20 +1124,15 @@ void QgsLegend::resetToInitialPosition( QTreeWidgetItem* li ) QgsLegendLayer* QgsLegend::findLegendLayer( const QString& layerKey ) { QgsLegendLayer* theLegendLayer = 0; - std::list theMapLayers; QTreeWidgetItem* theItem = firstItem(); do { theLegendLayer = dynamic_cast( theItem ); if ( theLegendLayer ) //item is a legend layer { - theMapLayers = theLegendLayer->mapLayers(); - for ( std::list::iterator it = theMapLayers.begin(); it != theMapLayers.end(); ++it ) + if (theLegendLayer->layer()->getLayerID() == layerKey) { - if (( *it )->getLayerID() == layerKey ) - { - return theLegendLayer; - } + return theLegendLayer; } } } @@ -1556,10 +1350,10 @@ void QgsLegend::updateMapCanvasLayerSet() while ( theItem ) { QgsLegendItem *li = dynamic_cast( theItem ); - QgsLegendLayerFile* llf = qobject_cast( li ); - if ( llf ) + QgsLegendLayer* ll = qobject_cast( li ); + if ( ll ) { - QgsMapCanvasLayer& lyr = llf->canvasLayer(); + QgsMapCanvasLayer& lyr = ll->canvasLayer(); layers.append( lyr ); } theItem = nextItem( theItem ); @@ -1579,10 +1373,10 @@ void QgsLegend::enableOverviewModeAllLayers( bool isInOverview ) QTreeWidgetItem* theItem = firstItem(); while ( theItem ) { - QgsLegendLayerFile* llf = dynamic_cast( theItem ); - if ( llf ) + QgsLegendLayer* ll = dynamic_cast( theItem ); + if ( ll ) { - llf->setInOverview( isInOverview ); + ll->setInOverview( isInOverview ); } theItem = nextItem( theItem ); } @@ -1597,10 +1391,10 @@ std::deque QgsLegend::layerIDs() while ( theItem ) { QgsLegendItem *li = dynamic_cast( theItem ); - QgsLegendLayerFile* llf = qobject_cast( li ); - if ( llf ) + QgsLegendLayer* ll = qobject_cast( li ); + if ( ll ) { - QgsMapLayer *lyr = llf->layer(); + QgsMapLayer *lyr = ll->layer(); layers.push_front( lyr->getLayerID() ); } theItem = nextItem( theItem ); @@ -1677,21 +1471,6 @@ void QgsLegend::removePixmapHeightValue( int height ) //todo: adapt the icon size if height is the largest value and the size of the next element is higher than the minimum } -void QgsLegend::setName( QgsLegendLayerFile* legendLayerFile, - QString layerName ) -{ - if ( legendLayerFile ) - { - QTreeWidgetItem* p = legendLayerFile->parent(); - if ( p ) - { - p = p->parent(); - if ( p ) - p->setText( 0, layerName ); - } - } - -} void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row ) { @@ -1700,15 +1479,14 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row ) return; } + bool renderFlagState = mMapCanvas->renderFlag(); + //if the text of a QgsLegendLayer has changed, change the display names of all its maplayers + // TODO: is this still necessary? QgsLegendLayer* theLegendLayer = dynamic_cast( item ); //item is a legend layer if ( theLegendLayer ) { - std::list theMapLayers = theLegendLayer->mapLayers(); - for ( std::list::iterator it = theMapLayers.begin(); it != theMapLayers.end(); ++it ) - { - ( *it )->setLayerName( theLegendLayer->text( 0 ) ); - } + theLegendLayer->layer()->setLayerName( theLegendLayer->text( 0 ) ); } std::map::iterator it = mStateOfCheckBoxes.find( item ); @@ -1719,46 +1497,14 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row ) if ( it->second == item->checkState( 0 ) ) return; - QgsLegendLayerFile* llf = dynamic_cast( item ); //item is a layer file - if ( llf ) - { - if ( llf->layer() ) - { - llf->setVisible( item->checkState( 0 ) == Qt::Checked ); - } - //update check state of the legend layer - QgsLegendLayer* ll = dynamic_cast( item->parent()->parent() ); - if ( ll ) - { - ll->updateCheckState(); - mStateOfCheckBoxes[ll] = ll->checkState( 0 ); - } - //update check state of the legend group (if any) - if ( item->parent()->parent()->parent() ) - { - QgsLegendGroup* lg = dynamic_cast( item->parent()->parent()->parent() ); - if ( lg ) - { - lg->updateCheckState(); - mStateOfCheckBoxes[lg] = lg->checkState( 0 ); - } - } - mStateOfCheckBoxes[item] = item->checkState( 0 ); - // Setting the renderFlag to true will trigger a render, - // so only do this if the flag is alread set to true. - if ( mMapCanvas->renderFlag() ) - mMapCanvas->setRenderFlag( true ); - } - - std::list subfiles; QgsLegendGroup* lg = dynamic_cast( item ); //item is a legend group if ( lg ) { //set all the child layer files to the new check state - subfiles = lg->legendLayerFiles(); + std::list subfiles = lg->legendLayers(); bool renderFlagState = mMapCanvas->renderFlag(); mMapCanvas->setRenderFlag( false ); - for ( std::list::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter ) + for ( std::list::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter ) { #ifdef QGISDEBUG if ( item->checkState( 0 ) == Qt::Checked ) @@ -1784,12 +1530,6 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row ) } } - //update the check states of all child legend layers - for ( int i = 0; i < lg->childCount(); ++i ) - { - static_cast( lg->child( i ) )->updateCheckState(); - mStateOfCheckBoxes[lg->child( i )] = lg->child( i )->checkState( 0 ); - } // If it was on, turn it back on, otherwise leave it // off, as turning it on causes a refresh. if ( renderFlagState ) @@ -1800,22 +1540,15 @@ void QgsLegend::handleItemChange( QTreeWidgetItem* item, int row ) QgsLegendLayer* ll = dynamic_cast( item ); //item is a legend layer if ( ll ) { - //set all the child layer files to the new check state - subfiles = ll->legendLayerFiles(); - bool renderFlagState = mMapCanvas->renderFlag(); - mMapCanvas->freeze( true ); - mMapCanvas->setRenderFlag( false ); - for ( std::list::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter ) + blockSignals( true ); + ll->setCheckState( 0, item->checkState( 0 ) ); + blockSignals( false ); + mStateOfCheckBoxes[ll] = item->checkState( 0 ); + if (ll->layer() ) { - blockSignals( true ); - ( *iter )->setCheckState( 0, item->checkState( 0 ) ); - blockSignals( false ); - mStateOfCheckBoxes[( *iter )] = item->checkState( 0 ); - if (( *iter )->layer() ) - { - ( *iter )->setVisible( item->checkState( 0 ) == Qt::Checked ); - } + ll->setVisible( item->checkState( 0 ) == Qt::Checked ); } + if ( ll->parent() ) { static_cast( ll->parent() )->updateCheckState(); @@ -1857,84 +1590,17 @@ void QgsLegend::makeToTopLevelItem() } } -void QgsLegend::showLegendLayerFileGroups() -{ - // Toggle the boolean associated with the checkbox - mShowLegendLayerFiles = !mShowLegendLayerFiles; - - QgsLegendLayerFileGroup* theFileGroup = 0; - QTreeWidgetItem* theItem = firstItem(); - - if ( !theItem ) - { - return; - } - - do - { - // This call seems to fix a bug in Qt4.2 (qgis trac #405) whereby the - // setHidden() call in the if statement below doesn't result in - // correct drawing of the visible file group part of the tree, - // but doing this setHidden() call does result in correct drawing. - theItem->setHidden( false ); - - theFileGroup = dynamic_cast( theItem ); - if ( theFileGroup ) - { - theFileGroup->setHidden( !mShowLegendLayerFiles ); - } - } - while (( theItem = nextItem( theItem ) ) ); -} void QgsLegend::legendLayerZoom() { - std::list layerFiles; - //find current Layer QgsLegendLayer* currentLayer = dynamic_cast( currentItem() ); - if ( currentLayer ) - { - layerFiles = currentLayer->legendLayerFiles(); - } - else - { - QgsLegendLayerFile* llf = dynamic_cast( currentItem() ); - if ( llf ) - { - // user selected legend layer file - use just that one - layerFiles.push_back( llf ); - } - } - - if ( layerFiles.size() == 0 ) + if ( !currentLayer ) return; - QgsMapLayer* theLayer; - bool first( true ); - QgsRectangle extent; + QgsMapLayer* theLayer = currentLayer->layer(); + QgsRectangle extent = theLayer->extent(); - for ( std::list::iterator it = layerFiles.begin(); it != layerFiles.end(); ++it ) - { - theLayer = ( *it )->layer(); - if ( !theLayer ) - continue; - - QgsRectangle lyrExtent = mMapCanvas->mapRenderer()->layerExtentToOutputExtent( theLayer, theLayer->extent() ); - - if ( !lyrExtent.isFinite() ) - lyrExtent = theLayer->extent(); - - if ( first ) - { - extent = lyrExtent; - first = false; - } - else - { - extent.combineExtentWith( &lyrExtent ); - } - } // Increase bounding box with 5%, so that layer is a bit inside the borders extent.scale( 1.05 ); @@ -1948,17 +1614,12 @@ void QgsLegend::legendLayerZoom() void QgsLegend::legendLayerZoomNative() { - QgsLegendItem* citem = dynamic_cast( currentItem() ); - if ( !citem ) - { + //find current Layer + QgsLegendLayer* currentLayer = dynamic_cast( currentItem() ); + if ( !currentLayer ) return; - } - QgsLegendLayer* ll = qobject_cast( citem ); - if ( !ll ) - { - return; - } - QgsRasterLayer *layer = qobject_cast( ll->firstMapLayer() ); + + QgsRasterLayer *layer = qobject_cast( currentLayer->layer() ); if ( layer ) { QgsDebugMsg( "Raster units per pixel : " + QString::number( layer->rasterUnitsPerPixel() ) ); @@ -1985,33 +1646,21 @@ void QgsLegend::legendLayerAttributeTable() // try whether it's a legend layer QgsLegendLayer* ll = dynamic_cast( currentItem() ); - if ( ll ) - { - vlayer = qobject_cast( ll->firstMapLayer() ); - } - - if ( !vlayer ) - { - // try whether it's a legend layer file - QgsLegendLayerFile* llf = dynamic_cast( currentItem() ); - if ( llf ) - { - vlayer = qobject_cast( llf->layer() ); - } - } - - if ( vlayer ) - { - QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( vlayer ); - mDialog->show(); - // the dialog will be deleted by itself on close - } - else + if ( !ll ) { // nothing selected QMessageBox::information( this, tr( "No Layer Selected" ), tr( "To open an attribute table, you must select a vector layer in the legend" ) ); + return; + } + + vlayer = qobject_cast( ll->layer() ); + if ( vlayer ) + { + QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( vlayer ); + mDialog->show(); + // the dialog will be deleted by itself on close } } diff --git a/src/app/legend/qgslegend.h b/src/app/legend/qgslegend.h index 3c71b6b2a6d..1636c090e97 100755 --- a/src/app/legend/qgslegend.h +++ b/src/app/legend/qgslegend.h @@ -26,11 +26,11 @@ #include class QgsLegendLayer; -class QgsLegendLayerFile; class QgsLegendItem; class QgsMapLayer; class QgsMapCanvas; class QDomDocument; +class QDomElement; class QDomNode; class QMouseEvent; class QTreeWidgetItem; @@ -69,12 +69,6 @@ class QTreeWidgetItem;
  • QgsLegendPropertyItem - A list of properties related to the layer. Double clicking a property item will invoke a dialog that will let you change the property settings. Can only exist inside a property group
  • -
  • QgsLegendLayerFileGroup - each QgsLegendLayer can have one or more files associated - with it. This is the container group for these files. Can - only exist inside of a QgsLegendLayer.
  • -
  • QgsLegendLayerFile - A file node that relates to a file on disk. Assigning multiple - file nodes in a file group allows you treat them as if they are - one entity.
  • @note Additional group types may be defined in the future to accommodate WMS, PostGIS etc layers. @author Gary E.Sherman, Tim Sutton, Marco Hugentobler and Jens Oberender @@ -101,10 +95,10 @@ class QgsLegend : public QTreeWidget //! Destructor ~QgsLegend(); - /** Returns QgsLegendLayerFile associated with current layer */ - QgsLegendLayerFile* currentLayerFile(); + /** Returns QgsLegendLayer associated with current layer */ + QgsLegendLayer* currentLegendLayer(); - /*!Returns the current layer if the current item is a QgsLegendLayerFile. + /*!Returns the current layer if the current item is a QgsLegendLayer. If the current item is a QgsLegendLayer, its first maplayer is returned. Else, 0 is returned.*/ QgsMapLayer* currentLayer(); @@ -168,10 +162,6 @@ class QgsLegend : public QTreeWidget /**Removes an entry from mPixmapHeightValues*/ void removePixmapHeightValue( int height ); - /** Sets the name of the QgsLegendLayer that is the parent of - the given QgsLegendLayerFile */ - void setName( QgsLegendLayerFile* w, QString layerName ); - /**Sets the toggle editing action. Usually called from QgisApp*/ void setToggleEditingAction( QAction* editingAction ) {mToggleEditingAction = editingAction;} @@ -219,7 +209,7 @@ class QgsLegend : public QTreeWidget /** called to write legend settings to project */ void writeProject( QDomDocument & ); - /**Removes the current LegendLayer and all its LegendLayerFiles*/ + /**Removes the current LegendLayer*/ void legendLayerRemove(); /**Removes a layer. If the layer is editable, a dialog is shown where user can select 'save', 'discard' and optionally 'cancel'. Cancel @@ -332,6 +322,9 @@ class QgsLegend : public QTreeWidget /** Returns the last visible item in the tree widget */ QTreeWidgetItem *lastVisibleItem(); + /** read layer settings from XML element and add item */ + QgsLegendLayer* readLayerFromXML(QDomElement& childelem, bool& isOpen); + private slots: /**Calls 'handleRightClickEvent' on the item*/ @@ -350,8 +343,6 @@ class QgsLegend : public QTreeWidget void openEditor(); /**Removes the current item and inserts it as a toplevel item at the end of the legend*/ void makeToTopLevelItem(); - /**Show/ Hide the legend layer file groups*/ - void showLegendLayerFileGroups(); private: @@ -396,8 +387,6 @@ class QgsLegend : public QTreeWidget HIERARCHY_POSITION_TYPE mRestoreInformation; QTreeWidgetItem* mRestoreItem; - bool mShowLegendLayerFiles; - /**Stores the layer ordering before a mouse Move. After the move, this is used to decide if the mapcanvas really has to be refreshed*/ std::deque mLayersPriorToMove; diff --git a/src/app/legend/qgslegendgroup.cpp b/src/app/legend/qgslegendgroup.cpp index ff12fa5c330..658b724fab8 100644 --- a/src/app/legend/qgslegendgroup.cpp +++ b/src/app/legend/qgslegendgroup.cpp @@ -21,7 +21,6 @@ #include "qgisapp.h" #include "qgslegendgroup.h" #include "qgslegendlayer.h" -#include "qgslegendlayerfile.h" #include #include @@ -96,7 +95,7 @@ QgsLegendItem::DRAG_ACTION QgsLegendGroup::accept( const QgsLegendItem* li ) con return NO_ACTION; } -bool QgsLegendGroup::insert( QgsLegendItem* theItem ) +/*bool QgsLegendGroup::insert( QgsLegendItem* theItem ) { if ( theItem->type() == LEGEND_LAYER ) { @@ -106,18 +105,17 @@ bool QgsLegendGroup::insert( QgsLegendItem* theItem ) // XXX - mloskot - I don't know what to return // but this function must return a value return true; -} +}*/ -std::list QgsLegendGroup::legendLayerFiles() +std::list QgsLegendGroup::legendLayers() { - std::list result; + std::list result; for ( int i = 0; i < childCount(); ++i ) { QgsLegendLayer* childItem = dynamic_cast( child( i ) ); if ( childItem ) { - std::list childList = childItem->legendLayerFiles(); - result.splice( result.end(), childList ); + result.push_back(childItem); } } return result; @@ -125,15 +123,15 @@ std::list QgsLegendGroup::legendLayerFiles() void QgsLegendGroup::updateCheckState() { - std::list llfiles = legendLayerFiles(); - if ( llfiles.size() < 1 ) + std::list llayers = legendLayers(); + if ( llayers.size() == 0 ) { return; } - std::list::iterator iter = llfiles.begin(); + std::list::iterator iter = llayers.begin(); Qt::CheckState theState = ( *iter )->checkState( 0 ); - for ( ; iter != llfiles.end(); ++iter ) + for ( ; iter != llayers.end(); ++iter ) { if ( theState != ( *iter )->checkState( 0 ) ) { diff --git a/src/app/legend/qgslegendgroup.h b/src/app/legend/qgslegendgroup.h index 3b5f76c354d..c2a0eb5bf1b 100644 --- a/src/app/legend/qgslegendgroup.h +++ b/src/app/legend/qgslegendgroup.h @@ -23,7 +23,6 @@ #include #include -class QgsLegendLayerFile; /** This is a specialised version of QLegendItem that specifies that the items below this point will be treated as a group. For example hiding this node will hide all layers below that are members of the group. @@ -41,10 +40,10 @@ class QgsLegendGroup : public QgsLegendItem QgsLegendItem::DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; bool isLeafNode(); - bool insert( QgsLegendItem* theItem ); - /**Returns all legend layer files under this group*/ - std::list legendLayerFiles(); - /**Goes through all the legendlayerfiles and sets check state to checked/partially checked/unchecked*/ + //bool insert( QgsLegendItem* theItem ); + /**Returns all legend layers under this group*/ + std::list legendLayers(); + /**Goes through all the legendlayers and sets check state to checked/partially checked/unchecked*/ void updateCheckState(); }; diff --git a/src/app/legend/qgslegenditem.h b/src/app/legend/qgslegenditem.h index 99ea8b5e0be..86028057087 100644 --- a/src/app/legend/qgslegenditem.h +++ b/src/app/legend/qgslegenditem.h @@ -66,7 +66,6 @@ class QgsLegendItem : public QTreeWidgetItem, public QObject virtual bool isLeafNode() = 0; virtual LEGEND_ITEM_TYPE type() const {return mType;} - virtual void addItem( QgsLegendItem* ) {} /**Returns the type of action that will be done if a drag, originating at a certain item type, will be released at this item*/ virtual DRAG_ACTION accept( LEGEND_ITEM_TYPE type ) = 0; diff --git a/src/app/legend/qgslegendlayer.cpp b/src/app/legend/qgslegendlayer.cpp index b7173662a94..a12a9b0a204 100644 --- a/src/app/legend/qgslegendlayer.cpp +++ b/src/app/legend/qgslegendlayer.cpp @@ -22,8 +22,6 @@ #include "qgisapp.h" #include "qgslegend.h" #include "qgslegendlayer.h" -#include "qgslegendlayerfile.h" -#include "qgslegendlayerfilegroup.h" #include "qgslegendsymbologyitem.h" #include "qgslogger.h" @@ -35,6 +33,10 @@ #include "qgssymbol.h" #include "qgsvectorlayer.h" #include "qgsvectordataprovider.h" +#include "qgsvectorfilewriter.h" +#include "qgsgenericprojectionselector.h" +#include "qgsattributetabledialog.h" +#include "qgsencodingfiledialog.h" #include #include @@ -45,32 +47,39 @@ #include #include -QgsLegendLayer::QgsLegendLayer( QTreeWidgetItem* parent, QString name ) - : QgsLegendItem( parent, name ) -{ - mType = LEGEND_LAYER; - setFlags( Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ); - setCheckState( 0, Qt::Checked ); - setText( 0, name ); - setupFont(); -} -QgsLegendLayer::QgsLegendLayer( QTreeWidget* parent, QString name ): QgsLegendItem( parent, name ) +QgsLegendLayer::QgsLegendLayer( QgsMapLayer* layer ) + : QgsLegendItem( ), + mLyr( layer ) { mType = LEGEND_LAYER; setFlags( Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ); setCheckState( 0, Qt::Checked ); - setText( 0, name ); + setText( 0, layer->name() ); setupFont(); -} -QgsLegendLayer::QgsLegendLayer( QString name ): QgsLegendItem() -{ - mType = LEGEND_LAYER; - setFlags( Qt::ItemIsEditable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ); - setCheckState( 0, Qt::Checked ); - setText( 0, name ); - setupFont(); + // Set the initial visibility flag for layers + // This user option allows the user to turn off initial drawing of + // layers when they are added to the map. This is useful when adding + // many layers and the user wants to adjusty symbology, etc prior to + // actually viewing the layer. + QSettings settings; + bool visible = settings.value( "/qgis/new_layers_visible", true ).toBool(); + mLyr.setVisible( visible ); + + // not in overview by default + mLyr.setInOverview( FALSE ); + + // Add check if vector layer when connecting to selectionChanged slot + // Ticket #811 - racicot + QgsMapLayer *currentLayer = mLyr.layer(); + QgsVectorLayer *isVectLyr = qobject_cast( currentLayer ); + if ( isVectLyr ) + { + connect( mLyr.layer(), SIGNAL( editingStarted() ), this, SLOT( updateLegendItem() ) ); + connect( mLyr.layer(), SIGNAL( editingStopped() ), this, SLOT( updateLegendItem() ) ); + } + connect( mLyr.layer(), SIGNAL( layerNameChanged() ), this, SLOT( layerNameChanged() ) ); } QgsLegendLayer::~QgsLegendLayer() @@ -126,133 +135,10 @@ QgsLegendItem::DRAG_ACTION QgsLegendLayer::accept( const QgsLegendItem* li ) con return NO_ACTION; } -QgsLegendLayerFile* QgsLegendLayer::firstLayerFile() const + +QgsMapLayer* QgsLegendLayer::layer() { - //first find the legend layer file group - QgsLegendLayerFileGroup* llfg = 0; - for ( int i = 0; i < childCount(); ++i ) - { - llfg = dynamic_cast( child( i ) ); - if ( llfg ) - { - break; - } - } - - if ( !llfg ) - { - return 0; - } - - QTreeWidgetItem* llf = llfg->child( 0 ); - if ( !llf ) - { - return 0; - } - QgsLegendLayerFile* legendlayerfile = dynamic_cast( llf ); - return legendlayerfile; -} - -QgsMapLayer* QgsLegendLayer::firstMapLayer() const -{ - QgsLegendLayerFile* llf = firstLayerFile(); - if ( llf ) - { - return llf->layer(); - } - else - { - return 0; - } -} - -std::list QgsLegendLayer::mapLayers() -{ - std::list list; - std::list llist = legendLayerFiles(); - for ( std::list::iterator it = llist.begin(); it != llist.end(); ++it ) - { - list.push_back(( *it )->layer() ); - } - return list; -} - -std::list QgsLegendLayer::legendLayerFiles() -{ - std::list list; - - //find the layer file group - QgsLegendLayerFileGroup* theLayerGroup = 0; - for ( int i = 0; i < childCount(); ++i ) - { - theLayerGroup = dynamic_cast( child( i ) ); - if ( theLayerGroup ) - { - break; - } - } - - //add all the legend layer files in the group - if ( theLayerGroup ) - { - QgsLegendLayerFile* theFile = 0; - for ( int i = 0; i < theLayerGroup->childCount(); ++i ) - { - theFile = dynamic_cast( theLayerGroup->child( i ) ); - if ( theFile ) - { - list.push_back( theFile ); - } - } - } - return list; -} - -void QgsLegendLayer::updateLayerSymbologySettings( const QgsMapLayer* mapLayer ) -{ - if ( mapLayer ) - { - //find all layers - std::list theMapLayers = mapLayers(); - for ( std::list::iterator it = theMapLayers.begin(); it != theMapLayers.end(); ++it ) - { - if (( *it ) != mapLayer ) - { - ( *it )->copySymbologySettings( *mapLayer ); - } - } - // source might have changed - e.g. other subset - setToolTip( 0, mapLayer->publicSource() ); - } -} - -void QgsLegendLayer::updateCheckState() -{ - std::list llfiles = legendLayerFiles(); - if ( llfiles.size() < 1 ) - { - return; - } - - std::list::iterator iter = llfiles.begin(); - Qt::CheckState theState = ( *iter )->checkState( 0 ); - for ( ; iter != llfiles.end(); ++iter ) - { - if ( theState != ( *iter )->checkState( 0 ) ) - { - theState = Qt::PartiallyChecked; - break; - } - } - - if ( theState != checkState( 0 ) ) - { - treeWidget()->blockSignals( true ); - setCheckState( 0, theState ); - //notify the legend that the check state has changed - legend()->updateCheckStates( this, theState ); - treeWidget()->blockSignals( false ); - } + return mLyr.layer(); } void QgsLegendLayer::refreshSymbology( const QString& key, double widthScale ) @@ -307,9 +193,6 @@ void QgsLegendLayer::changeSymbologySettings( const QgsMapLayer* theMapLayer, ++childposition; } - //copy the legend settings for the other layer files in the same legend layer - updateLayerSymbologySettings( theMapLayer ); - } @@ -401,48 +284,48 @@ void QgsLegendLayer::updateIcon() { QPixmap newIcon( getOriginalPixmap() ); - QgsMapLayer* theLayer = firstMapLayer(); + QgsMapLayer* theLayer = layer(); - if ( mapLayers().size() == 1 ) + //overview + // FIXME: overview icon is missing + /* + if ( theFile->isInOverview() ) { - //overview - // FIXME: overview icon is missing - /* - if ( theFile->isInOverview() ) - { - // Overlay the overview icon on the default icon - QPixmap myPixmap = QgisApp::getThemePixmap( "/mIconOverview.png" ); - QPainter p( &newIcon ); - p.drawPixmap( 0, 0, myPixmap ); - p.end(); - }*/ + // Overlay the overview icon on the default icon + QPixmap myPixmap = QgisApp::getThemePixmap( "/mIconOverview.png" ); + QPainter p( &newIcon ); + p.drawPixmap( 0, 0, myPixmap ); + p.end(); + }*/ - //editable - if ( theLayer->isEditable() ) - { - QPixmap myPixmap = QgisApp::getThemePixmap( "/mIconEditable.png" ); - // use editable icon instead of the layer's type icon - newIcon = myPixmap; + //editable + if ( theLayer->isEditable() ) + { + QPixmap myPixmap = QgisApp::getThemePixmap( "/mIconEditable.png" ); + // use editable icon instead of the layer's type icon + newIcon = myPixmap; - // Overlay the editable icon on the default icon - /*QPainter p( &newIcon ); - p.drawPixmap( 0, 0, myPixmap ); - p.end();*/ - } + // Overlay the editable icon on the default icon + /*QPainter p( &newIcon ); + p.drawPixmap( 0, 0, myPixmap ); + p.end();*/ } + // TODO: projection error icon? + QIcon theIcon( newIcon ); setIcon( 0, theIcon ); } -QPixmap QgsLegendLayer::getOriginalPixmap() const +QPixmap QgsLegendLayer::getOriginalPixmap() { - QgsMapLayer* firstLayer = firstMapLayer(); - if ( firstLayer ) + QgsMapLayer* theLayer = layer(); + if ( theLayer ) { - if ( firstLayer->type() == QgsMapLayer::VectorLayer ) + + if ( theLayer->type() == QgsMapLayer::VectorLayer ) { - QgsVectorLayer* vlayer = qobject_cast( firstLayer ); + QgsVectorLayer* vlayer = qobject_cast( theLayer ); switch ( vlayer->geometryType() ) { case QGis::Point: @@ -458,9 +341,9 @@ QPixmap QgsLegendLayer::getOriginalPixmap() const return QgisApp::getThemePixmap( "/mIconLayer.png" ); } } - else if ( firstLayer->type() == QgsMapLayer::RasterLayer ) + else if ( theLayer->type() == QgsMapLayer::RasterLayer ) { - QgsRasterLayer* rlayer = qobject_cast( firstLayer ); + QgsRasterLayer* rlayer = qobject_cast( theLayer ); QPixmap myPixmap( 32, 32 ); rlayer->thumbnailAsPixmap( &myPixmap ); return myPixmap; @@ -473,25 +356,23 @@ QPixmap QgsLegendLayer::getOriginalPixmap() const void QgsLegendLayer::addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ) { - std::list files = legendLayerFiles(); - QgsMapLayer* firstLayer = NULL; - if ( files.size() > 0 ) - { - firstLayer = files.front()->layer(); - } + + QgsMapLayer* lyr = layer(); // zoom to layer extent theMenu.addAction( QgisApp::getThemeIcon( "/mActionZoomToLayer.png" ), tr( "&Zoom to layer extent" ), legend(), SLOT( legendLayerZoom() ) ); - if ( firstLayer && firstLayer->type() == QgsMapLayer::RasterLayer ) + if ( lyr->type() == QgsMapLayer::RasterLayer ) { theMenu.addAction( tr( "&Zoom to best scale (100%)" ), legend(), SLOT( legendLayerZoomNative() ) ); } // show in overview QAction* showInOverviewAction = theMenu.addAction( tr( "&Show in overview" ), this, SLOT( showInOverview() ) ); - showInOverviewAction->setCheckable( true ); // doesn't support tristate - showInOverviewAction->setChecked( isInOverview() ); + showInOverviewAction->setCheckable( true ); + showInOverviewAction->blockSignals( true ); + showInOverviewAction->setChecked( mLyr.isInOverview() ); + showInOverviewAction->blockSignals( false ); // remove from canvas theMenu.addAction( QgisApp::getThemeIcon( "/mActionRemove.png" ), @@ -499,42 +380,30 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu, QAction* toggleEditingActio theMenu.addSeparator(); - if ( firstLayer && firstLayer->type() == QgsMapLayer::VectorLayer ) + if ( lyr->type() == QgsMapLayer::VectorLayer ) { + QgsVectorLayer* vlayer = qobject_cast( lyr ); + // attribute table QAction* tableAction = theMenu.addAction( tr( "&Open attribute table" ), this, SLOT( table() ) ); - if ( files.size() != 1 ) - { - tableAction->setEnabled( false ); - } // allow editing - if ( toggleEditingAction ) + int cap = vlayer->dataProvider()->capabilities(); + if ( cap & QgsVectorDataProvider::EditingCapabilities ) { - theMenu.addAction( toggleEditingAction ); - } - - QgsVectorLayer* mypVectorLayer = qobject_cast( firstLayer ); - - if ( files.size() != 1 ) - { - toggleEditingAction->setEnabled( false ); - } - if ( mypVectorLayer ) - { - toggleEditingAction->setChecked( mypVectorLayer->isEditable() ); + if ( toggleEditingAction ) + { + theMenu.addAction( toggleEditingAction ); + toggleEditingAction->setChecked( vlayer->isEditable() ); + } } // save as shapefile QAction* saveShpAction = theMenu.addAction( tr( "Save as shapefile..." ), this, SLOT( saveAsShapefile() ) ); - if ( files.size() != 1 ) - { - saveShpAction->setEnabled( false ); - } // save selection as shapefile QAction* saveSelectionAction = theMenu.addAction( tr( "Save selection as shapefile..." ), this, SLOT( saveSelectionAsShapefile() ) ); - if ( files.size() != 1 || mypVectorLayer->selectedFeatureCount() == 0 ) + if ( vlayer->selectedFeatureCount() == 0 ) { saveSelectionAction->setEnabled( false ); } @@ -542,79 +411,212 @@ void QgsLegendLayer::addToPopupMenu( QMenu& theMenu, QAction* toggleEditingActio theMenu.addSeparator(); } + // properties goes on bottom of menu for consistency with normal ui standards + // e.g. kde stuff + theMenu.addAction( tr( "&Properties" ), legend(), SLOT( legendLayerShowProperties() ) ); - QAction* propertiesAction = theMenu.addAction( tr( "&Properties" ), legend(), SLOT( legendLayerShowProperties() ) ); - if ( files.size() != 1 ) - { - propertiesAction->setEnabled( false ); - } +} +void QgsLegendLayer::table() +{ + QgsVectorLayer * myLayer = qobject_cast( mLyr.layer() ); + QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer ); + mDialog->show(); + // the dialog will be deleted by itself on close +} + +void QgsLegendLayer::saveAsShapefile() +{ + saveAsShapefileGeneral( FALSE ); +} + +void QgsLegendLayer::saveSelectionAsShapefile() +{ + saveAsShapefileGeneral( TRUE ); +} + +////////// + +void QgsLegendLayer::setVisible( bool visible ) +{ + mLyr.setVisible( visible ); +} + +bool QgsLegendLayer::isVisible() +{ + return mLyr.isVisible(); +} + + +void QgsLegendLayer::setInOverview( bool isInOverview ) +{ + mLyr.setInOverview( isInOverview ); } bool QgsLegendLayer::isInOverview() { - // QAction doesn't support tristate checkboxes - // returns true if just some are in overview - bool hasVisible = false; - - // find out whether we're showing or hiding them - std::list maplayers = legendLayerFiles(); - for ( std::list::iterator it = maplayers.begin(); it != maplayers.end(); ++it ) - { - if ( *it && ( *it )->isInOverview() ) - { - hasVisible = true; - break; - } - } - - return hasVisible; + return mLyr.isInOverview(); } void QgsLegendLayer::showInOverview() { - std::list maplayers = legendLayerFiles(); - bool showLayers = ( ! isInOverview() ); - - // set overview visibility - for ( std::list::iterator it = maplayers.begin(); it != maplayers.end(); ++it ) - { - if ( *it ) - ( *it )->setInOverview( showLayers ); - } + // toggle current status + setInOverview( ! isInOverview() ); legend()->updateMapCanvasLayerSet(); legend()->updateOverview(); } -void QgsLegendLayer::table() + + + +void QgsLegendLayer::saveAsShapefileGeneral( bool saveOnlySelection ) { - std::list maplayers = legendLayerFiles(); - if ( maplayers.size() > 1 ) + QgsCoordinateReferenceSystem destCRS; + + if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer ) + return; + + QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); + + // get a name for the shapefile + // Get a file to process, starting at the current directory + QSettings settings; + QString filter = QString( "Shapefiles (*.shp)" ); + QString dirName = settings.value( "/UI/lastShapefileDir", "." ).toString(); + + QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog( 0, + tr( "Save layer as..." ), + dirName, + filter, + QString( "" ) ); + openFileDialog->setAcceptMode( QFileDialog::AcceptSave ); + + // allow for selection of more than one file + //openFileDialog->setMode(QFileDialog::AnyFile); + + if ( openFileDialog->exec() != QDialog::Accepted ) + return; + + + QString encoding = openFileDialog->encoding(); + QString shapefileName = openFileDialog->selectedFiles().first(); + settings.setValue( "/UI/lastShapefileDir", QFileInfo( shapefileName ).absolutePath() ); + + + if ( shapefileName.isNull() ) + return; + + // add the extension if not present + if ( shapefileName.indexOf( ".shp" ) == -1 ) { - QMessageBox::information( 0, tr( "Multiple layers" ), - tr( "This item contains multiple layers. Displaying multiple layers in the table is not supported." ) ); + shapefileName += ".shp"; } - else if ( maplayers.size() == 1 ) + + destCRS = vlayer->srs(); + // Find out if we have projections enabled or not + if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) { - maplayers.front()->table(); + destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); + } + + QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector(); + mySelector->setSelectedCrsId( destCRS.srsid() ); + mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. " + "The data points will be transformed from the layer coordinate reference system." ) ); + + if ( mySelector->exec() ) + { + QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId ); + destCRS = srs; + // destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId) + } + else + { + // Aborted CS selection, don't save. + delete mySelector; + return; + } + + delete mySelector; + + // overwrite the file - user will already have been prompted + // to verify they want to overwrite by the file dialog above + if ( QFile::exists( shapefileName ) ) + { + if ( !QgsVectorFileWriter::deleteShapeFile( shapefileName ) ) + { + return; + } + } + + // ok if the file existed it should be deleted now so we can continue... + QApplication::setOverrideCursor( Qt::WaitCursor ); + + QgsVectorFileWriter::WriterError error; + error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, &destCRS, saveOnlySelection ); + + QApplication::restoreOverrideCursor(); + + switch ( error ) + { + case QgsVectorFileWriter::NoError: + QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to Shapefile has been completed" ) ); + break; + + case QgsVectorFileWriter::ErrDriverNotFound: + QMessageBox::warning( 0, tr( "Driver not found" ), tr( "ESRI Shapefile driver is not available" ) ); + break; + + case QgsVectorFileWriter::ErrCreateDataSource: + QMessageBox::warning( 0, tr( "Error creating shapefile" ), + tr( "The shapefile could not be created (%1)" ).arg( shapefileName ) ); + break; + + case QgsVectorFileWriter::ErrCreateLayer: + QMessageBox::warning( 0, tr( "Error" ), tr( "Layer creation failed" ) ); + break; + + case QgsVectorFileWriter::ErrAttributeTypeUnsupported: + QMessageBox::warning( 0, tr( "Error" ), + tr( "Layer attribute table contains unsupported datatype(s)" ) ); + break; + + case QgsVectorFileWriter::ErrAttributeCreationFailed: + QMessageBox::warning( 0, tr( "Error" ), + tr( "Creation of an attribute failed" ) ); + break; } } -void QgsLegendLayer::saveAsShapefile() + + +QString QgsLegendLayer::nameFromLayer( QgsMapLayer* layer ) { - std::list maplayers = legendLayerFiles(); - if ( maplayers.size() == 1 ) + QString sourcename = layer->publicSource(); //todo: move this duplicated code into a new function + if ( sourcename.startsWith( "host", Qt::CaseInsensitive ) ) { - maplayers.front()->saveAsShapefile(); + //this layer is a database layer + //modify source string such that password is not visible + sourcename = layer->name(); } + else + { + //modify source name such that only the file is visible + sourcename = layer->publicSource().section( '/', -1, -1 ); + } + return sourcename; } -void QgsLegendLayer::saveSelectionAsShapefile() + +QgsMapCanvasLayer& QgsLegendLayer::canvasLayer() { - std::list maplayers = legendLayerFiles(); - if ( maplayers.size() == 1 ) - { - maplayers.front()->saveSelectionAsShapefile(); - } + return mLyr; } + +void QgsLegendLayer::layerNameChanged() +{ + QString name = mLyr.layer()->name(); + setText( 0, name ); +} + diff --git a/src/app/legend/qgslegendlayer.h b/src/app/legend/qgslegendlayer.h index 2382839c2d2..a563d68f7fa 100644 --- a/src/app/legend/qgslegendlayer.h +++ b/src/app/legend/qgslegendlayer.h @@ -20,12 +20,12 @@ #ifndef QGSLEGENDLAYER_H #define QGSLEGENDLAYER_H -//#include #include #include +#include "qgsmapcanvas.h" + class QgsLegendLayer; -class QgsLegendLayerFile; class QgsLegendPropertyGroup; class QgsMapLayer; class QgsRasterLayer; @@ -45,25 +45,17 @@ class QgsLegendLayer : public QgsLegendItem Q_OBJECT public: - QgsLegendLayer( QTreeWidgetItem *, QString ); - QgsLegendLayer( QTreeWidget*, QString ); - QgsLegendLayer( QString name ); + QgsLegendLayer( QgsMapLayer* layer ); ~QgsLegendLayer(); bool isLeafNode(); QgsLegendItem::DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; - /**Returns the map layer associated with the first QgsLegendLayerFile or 0 if - there is no QgsLegendLayerFile*/ - QgsMapLayer* firstMapLayer() const; - /**Returns first map layer's file or 0 if there's no QgsLegendLayerFile */ - QgsLegendLayerFile* firstLayerFile() const; - /**Returns the map layers associated with the QgsLegendLayerFiles*/ - std::list mapLayers(); - /**Returns the legend layer file items associated with this legend layer*/ - std::list legendLayerFiles(); + /**Returns the map layer associated the item*/ + QgsMapLayer* layer(); + QgsMapCanvasLayer& canvasLayer(); /**Goes through all the legendlayerfiles and sets check state to checked/partially checked/unchecked*/ - void updateCheckState(); + //void updateCheckState(); /**Updates symbology of the layer and copies symbology to other layer files in the group*/ void refreshSymbology( const QString& key, double widthScale = 1.0 ); @@ -71,9 +63,19 @@ class QgsLegendLayer : public QgsLegendItem /** called to add appropriate menu items to legend's popup menu */ void addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ); + /** Set layer to be visible in canvas */ + void setVisible( bool visible = TRUE ); + /** Find out whether the layer is visible */ + bool isVisible(); + + void setInOverview( bool isInOverview = TRUE ); /**Determines whether there are layers in overview*/ bool isInOverview(); + /**Returns a label for a layer. Is static such that + the name can be passed to the constructor of QgsLegendLayer*/ + static QString nameFromLayer( QgsMapLayer* layer ); + public slots: /**Toggle show in overview*/ @@ -85,10 +87,12 @@ class QgsLegendLayer : public QgsLegendItem void saveAsShapefile(); void saveSelectionAsShapefile(); - /**Goes through all the legendlayerfiles and adds editing/overview pixmaps to the icon. If not all layer files - have the same editing/overview state, a tristate is applied*/ + /**update the layer's icon to show whether is in editing mode or in overview */ void updateIcon(); + /**Layer name has changed - set it also in legend*/ + void layerNameChanged(); + protected: /** Prepare and change symbology for vector layer */ @@ -97,19 +101,13 @@ class QgsLegendLayer : public QgsLegendItem /** Prepare and change symbology for raster layer */ void rasterLayerSymbology( QgsRasterLayer* mapLayer ); - /** Removes the symbology items of a layer and adds new ones. - * If other files are in the same legend layer, the new symbology settings are copied. - * Note: the QIcon* are deleted and therefore need to be allocated by calling - * functions using operator new - */ + /** Removes the symbology items of a layer and adds new ones. */ void changeSymbologySettings( const QgsMapLayer* mapLayer, const SymbologyList& newSymbologyItems ); - /** Copies the symbology settings of the layer to all maplayers in the QgsLegendLayerFileGroup. - * This method should be called whenever a layer in this group changes it symbology settings - */ - void updateLayerSymbologySettings( const QgsMapLayer* mapLayer ); + QPixmap getOriginalPixmap(); - QPixmap getOriginalPixmap() const; + /**Save as shapefile (called from saveAsShapefile and saveSelectionAsShapefile)*/ + void saveAsShapefileGeneral( bool saveOnlySelection ); private: /** Helper method to make the font bold from all ctors. @@ -117,6 +115,11 @@ class QgsLegendLayer : public QgsLegendItem * from the QTreeWidgetItem base class. */ void setupFont(); + + protected: + + /** layer identified by its layer id */ + QgsMapCanvasLayer mLyr; }; #endif diff --git a/src/app/legend/qgslegendlayerfile.cpp b/src/app/legend/qgslegendlayerfile.cpp deleted file mode 100644 index c306e5ab2a9..00000000000 --- a/src/app/legend/qgslegendlayerfile.cpp +++ /dev/null @@ -1,424 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Tim Sutton * - * aps02ts@macbuntu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include "qgsapplication.h" -#include "qgisapp.h" -#include "qgslegend.h" -#include "qgslegendlayer.h" -#include "qgslegendlayerfile.h" -#include "qgsmaplayer.h" -#include "qgsmaprenderer.h" -#include "qgsrasterlayer.h" -#include "qgsvectorfilewriter.h" -#include "qgsvectorlayer.h" -#include "qgsvectordataprovider.h" -#include "qgsgenericprojectionselector.h" - -// attribute table -#include "qgsattributetabledialog.h" - - -#include "qgsencodingfiledialog.h" - -#include -#include -#include -#include -#include - - -QgsLegendLayerFile::QgsLegendLayerFile( QTreeWidgetItem * theLegendItem, QString theString, QgsMapLayer* theLayer ) - : QgsLegendItem( theLegendItem, theString ), mLyr( theLayer ) -{ - // Set the initial visibility flag for layers - // This user option allows the user to turn off initial drawing of - // layers when they are added to the map. This is useful when adding - // many layers and the user wants to adjusty symbology, etc prior to - // actually viewing the layer. - QSettings settings; - bool visible = settings.value( "/qgis/new_layers_visible", true ).toBool(); - mLyr.setVisible( visible ); - - // not in overview by default - mLyr.setInOverview( FALSE ); - - mType = LEGEND_LAYER_FILE; - - setFlags( Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable ); - setCheckState( 0, Qt::Checked ); - setText( 0, theString ); - - // Add check if vector layer when connecting to selectionChanged slot - // Ticket #811 - racicot - QgsMapLayer *currentLayer = mLyr.layer(); - QgsVectorLayer *isVectLyr = qobject_cast( currentLayer ); - if ( isVectLyr ) - { - connect( mLyr.layer(), SIGNAL( editingStarted() ), this, SLOT( updateLegendItem() ) ); - connect( mLyr.layer(), SIGNAL( editingStopped() ), this, SLOT( updateLegendItem() ) ); - } - connect( mLyr.layer(), SIGNAL( layerNameChanged() ), this, SLOT( layerNameChanged() ) ); -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayerFile::accept( LEGEND_ITEM_TYPE type ) -{ - return NO_ACTION; -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayerFile::accept( const QgsLegendItem* li ) const -{ - if ( li->type() == QgsLegendItem::LEGEND_LAYER_FILE ) - { - if ( li->parent() == this->parent() ) - { - return REORDER; - } - } - return NO_ACTION; -} - -QPixmap QgsLegendLayerFile::getOriginalPixmap() const -{ - QPixmap myPixmap = QgisApp::getThemePixmap( "mActionFileSmall.png" ); - return myPixmap; -} - -void QgsLegendLayerFile::updateLegendItem() -{ - QPixmap pix = legend()->pixmaps().mOriginalPixmap; - - if ( mLyr.isInOverview() ) - { - //add overview glasses to the pixmap - QPainter p( &pix ); - p.drawPixmap( 0, 0, legend()->pixmaps().mInOverviewPixmap ); - } - if ( mLyr.layer()->isEditable() ) - { - //add editing icon to the pixmap - QPainter p( &pix ); - p.drawPixmap( 30, 0, legend()->pixmaps().mEditablePixmap ); - } - - /* - // TODO: - if(mLyr.layer()->hasProjectionError()) - { - //add overview glasses to the pixmap - QPainter p(&pix); - p.drawPixmap(60,0, legend()->pixmaps().mProjectionErrorPixmap); - } - */ - - QIcon theIcon( pix ); - setIcon( 0, theIcon ); - -} - -void QgsLegendLayerFile::setIconAppearance( bool isInOverview, - bool editable ) -{ - QPixmap newIcon( getOriginalPixmap() ); - - if ( isInOverview ) - { - // Overlay the overview icon on the default icon - QPixmap myPixmap = QgisApp::getThemePixmap( "mIconOverview.png" ); - QPainter p( &newIcon ); - p.drawPixmap( 0, 0, myPixmap ); - p.end(); - } - - if ( editable ) - { - // Overlay the editable icon on the default icon - QPixmap myPixmap = QgisApp::getThemePixmap( "mIconEditable.png" ); - QPainter p( &newIcon ); - p.drawPixmap( 0, 0, myPixmap ); - p.end(); - } - - QIcon theIcon( newIcon ); - setIcon( 0, theIcon ); - - //also update the icon of the legend layer - (( QgsLegendLayer* )( parent()->parent() ) )->updateIcon(); -} - - -QString QgsLegendLayerFile::nameFromLayer( QgsMapLayer* layer ) -{ - QString sourcename = layer->publicSource(); //todo: move this duplicated code into a new function - if ( sourcename.startsWith( "host", Qt::CaseInsensitive ) ) - { - //this layer is a database layer - //modify source string such that password is not visible - sourcename = layer->name(); - } - else - { - //modify source name such that only the file is visible - sourcename = layer->publicSource().section( '/', -1, -1 ); - } - return sourcename; -} - - -void QgsLegendLayerFile::setVisible( bool visible ) -{ - mLyr.setVisible( visible ); -} - -bool QgsLegendLayerFile::isVisible() -{ - return mLyr.isVisible(); -} - -void QgsLegendLayerFile::setInOverview( bool isInOverview ) -{ - mLyr.setInOverview( isInOverview ); -} - -bool QgsLegendLayerFile::isInOverview() -{ - return mLyr.isInOverview(); -} - -void QgsLegendLayerFile::showInOverview() -{ - // toggle current status - setInOverview( ! isInOverview() ); - - legend()->updateMapCanvasLayerSet(); - legend()->updateOverview(); -} - -void QgsLegendLayerFile::saveAsShapefile() -{ - saveAsShapefileGeneral( FALSE ); -} - -void QgsLegendLayerFile::table() -{ - QgsVectorLayer * myLayer = qobject_cast( mLyr.layer() ); - QgsAttributeTableDialog *mDialog = new QgsAttributeTableDialog( myLayer ); - mDialog->show(); - // the dialog will be deleted by itself on close -} - -void QgsLegendLayerFile::saveSelectionAsShapefile() -{ - saveAsShapefileGeneral( TRUE ); -} - -void QgsLegendLayerFile::saveAsShapefileGeneral( bool saveOnlySelection ) -{ - QgsCoordinateReferenceSystem destCRS; - - if ( mLyr.layer()->type() != QgsMapLayer::VectorLayer ) - return; - - QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); - - // get a name for the shapefile - // Get a file to process, starting at the current directory - QSettings settings; - QString filter = QString( "Shapefiles (*.shp)" ); - QString dirName = settings.value( "/UI/lastShapefileDir", "." ).toString(); - - QgsEncodingFileDialog* openFileDialog = new QgsEncodingFileDialog( 0, - tr( "Save layer as..." ), - dirName, - filter, - QString( "" ) ); - openFileDialog->setAcceptMode( QFileDialog::AcceptSave ); - - // allow for selection of more than one file - //openFileDialog->setMode(QFileDialog::AnyFile); - - if ( openFileDialog->exec() != QDialog::Accepted ) - return; - - - QString encoding = openFileDialog->encoding(); - QString shapefileName = openFileDialog->selectedFiles().first(); - settings.setValue( "/UI/lastShapefileDir", QFileInfo( shapefileName ).absolutePath() ); - - - if ( shapefileName.isNull() ) - return; - - // add the extension if not present - if ( shapefileName.indexOf( ".shp" ) == -1 ) - { - shapefileName += ".shp"; - } - - destCRS = vlayer->srs(); - // Find out if we have projections enabled or not - if ( QgisApp::instance()->mapCanvas()->mapRenderer()->hasCrsTransformEnabled() ) - { - destCRS = QgisApp::instance()->mapCanvas()->mapRenderer()->destinationSrs(); - } - - QgsGenericProjectionSelector * mySelector = new QgsGenericProjectionSelector(); - mySelector->setSelectedCrsId( destCRS.srsid() ); - mySelector->setMessage( tr( "Select the coordinate reference system for the saved shapefile. " - "The data points will be transformed from the layer coordinate reference system." ) ); - - if ( mySelector->exec() ) - { - QgsCoordinateReferenceSystem srs( mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId ); - destCRS = srs; - // destCRS->createFromId(mySelector->selectedCrsId(), QgsCoordinateReferenceSystem::InternalCrsId) - } - else - { - // Aborted CS selection, don't save. - delete mySelector; - return; - } - - delete mySelector; - - // overwrite the file - user will already have been prompted - // to verify they want to overwrite by the file dialog above - if ( QFile::exists( shapefileName ) ) - { - if ( !QgsVectorFileWriter::deleteShapeFile( shapefileName ) ) - { - return; - } - } - - // ok if the file existed it should be deleted now so we can continue... - QApplication::setOverrideCursor( Qt::WaitCursor ); - - QgsVectorFileWriter::WriterError error; - error = QgsVectorFileWriter::writeAsShapefile( vlayer, shapefileName, encoding, &destCRS, saveOnlySelection ); - - QApplication::restoreOverrideCursor(); - - switch ( error ) - { - case QgsVectorFileWriter::NoError: - QMessageBox::information( 0, tr( "Saving done" ), tr( "Export to Shapefile has been completed" ) ); - break; - - case QgsVectorFileWriter::ErrDriverNotFound: - QMessageBox::warning( 0, tr( "Driver not found" ), tr( "ESRI Shapefile driver is not available" ) ); - break; - - case QgsVectorFileWriter::ErrCreateDataSource: - QMessageBox::warning( 0, tr( "Error creating shapefile" ), - tr( "The shapefile could not be created (%1)" ).arg( shapefileName ) ); - break; - - case QgsVectorFileWriter::ErrCreateLayer: - QMessageBox::warning( 0, tr( "Error" ), tr( "Layer creation failed" ) ); - break; - - case QgsVectorFileWriter::ErrAttributeTypeUnsupported: - QMessageBox::warning( 0, tr( "Error" ), - tr( "Layer attribute table contains unsupported datatype(s)" ) ); - break; - - case QgsVectorFileWriter::ErrAttributeCreationFailed: - QMessageBox::warning( 0, tr( "Error" ), - tr( "Creation of an attribute failed" ) ); - break; - } -} - -bool QgsLegendLayerFile::isEditing() -{ - QgsVectorLayer* vlayer = qobject_cast( mLyr.layer() ); - return vlayer && vlayer->isEditable(); -} - -void QgsLegendLayerFile::layerNameChanged() -{ - QString name = mLyr.layer()->name(); - setText( 0, name ); - - // set also parent's name - legend()->setName( this, name ); -} - -void QgsLegendLayerFile::addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ) -{ - QgsMapLayer* lyr = layer(); - - // zoom to layer extent - theMenu.addAction( QgisApp::getThemeIcon( "/mActionZoomToLayer.png" ), - tr( "&Zoom to layer extent" ), legend(), SLOT( legendLayerZoom() ) ); - - // show in overview - QAction* showInOverviewAction = theMenu.addAction( tr( "&Show in overview" ), this, SLOT( showInOverview() ) ); - showInOverviewAction->setCheckable( true ); - showInOverviewAction->blockSignals( true ); - showInOverviewAction->setChecked( mLyr.isInOverview() ); - showInOverviewAction->blockSignals( false ); - - // remove from canvas - theMenu.addAction( QgisApp::getThemeIcon( "/mActionRemove.png" ), - tr( "&Remove" ), legend(), SLOT( legendLayerRemove() ) ); - - theMenu.addSeparator(); - - if ( lyr->type() == QgsMapLayer::VectorLayer ) - { - QgsVectorLayer* vlayer = qobject_cast( lyr ); - - // attribute table - theMenu.addAction( tr( "&Open attribute table" ), this, SLOT( table() ) ); - - // editing - int cap = vlayer->dataProvider()->capabilities(); - if ( cap & QgsVectorDataProvider::EditingCapabilities ) - { - if ( toggleEditingAction ) - { - theMenu.addAction( toggleEditingAction ); - } - } - - // save as shapefile - theMenu.addAction( tr( "Save as shapefile..." ), this, SLOT( saveAsShapefile() ) ); - - QAction* saveSelectionAction = theMenu.addAction( tr( "Save selection as shapefile..." ), this, SLOT( saveSelectionAsShapefile() ) ); - if ( vlayer->selectedFeatureCount() == 0 ) - { - saveSelectionAction->setEnabled( false ); - } - - theMenu.addSeparator(); - } - else if ( lyr->type() == QgsMapLayer::RasterLayer ) - { - // TODO: what was this for? - //QgsRasterLayer* rlayer = qobject_cast(lyr); - //theMenu.addAction(tr("&Convert to..."), rlayer, SLOT(convertTo())); - } - - // properties goes on bottom of menu for consistency with normal ui standards - // e.g. kde stuff - theMenu.addAction( tr( "&Properties" ), legend(), SLOT( legendLayerShowProperties() ) ); -} diff --git a/src/app/legend/qgslegendlayerfile.h b/src/app/legend/qgslegendlayerfile.h deleted file mode 100644 index 0ae84c5689a..00000000000 --- a/src/app/legend/qgslegendlayerfile.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2005 by Tim Sutton * - * aps02ts@macbuntu * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef QGSLEGENDLAYERFILE_H -#define QGSLEGENDLAYERFILE_H - -#include - -#include "qgslegenditem.h" -#include "qgsmapcanvas.h" - -class QgsMapLayer; - -/** -@author Tim Sutton -*/ -class QgsLegendLayerFile : public QgsLegendItem -{ - Q_OBJECT - - public: - QgsLegendLayerFile( QTreeWidgetItem * theLegendItem, QString theString, QgsMapLayer* theLayer ); - - bool isLeafNode() {return true;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; - QgsMapLayer* layer() { return mLyr.layer(); } - const QgsMapLayer* layer() const { return mLyr.layer(); } - QgsMapCanvasLayer& canvasLayer() { return mLyr; } - - QPixmap getOriginalPixmap() const; - - void setIconAppearance( bool isInOverview, bool editable ); - - /**Returns a label for a layer. Is static such that - the name can be passed to the constructor of QgsLegendLayerFile*/ - static QString nameFromLayer( QgsMapLayer* layer ); - - void setVisible( bool visible = TRUE ); - bool isVisible(); - - void setInOverview( bool isInOverview = TRUE ); - bool isInOverview(); - - /** called to add appropriate menu items to legend's popup menu */ - void addToPopupMenu( QMenu& theMenu, QAction* toggleEditingAction ); - - public slots: - /** updates item to the current state of the layer */ - void updateLegendItem(); - - /**Open attribute table*/ - void table(); - - /**Save as shapefile*/ - void saveAsShapefile(); - - /**Save selection as shapefile*/ - void saveSelectionAsShapefile(); - - /**Return editing status for layer*/ - bool isEditing(); - - /**Toggle show in overview*/ - void showInOverview(); - - /**Layer name has changed - set it also in legend*/ - void layerNameChanged(); - - protected: - - /**Save as shapefile (called from saveAsShapefile and saveSelectionAsShapefile)*/ - void saveAsShapefileGeneral( bool saveOnlySelection ); - - /** layer identified by its layer id */ - QgsMapCanvasLayer mLyr; -}; - -#endif diff --git a/src/app/legend/qgslegendlayerfilegroup.cpp b/src/app/legend/qgslegendlayerfilegroup.cpp deleted file mode 100644 index 392fc61f9a8..00000000000 --- a/src/app/legend/qgslegendlayerfilegroup.cpp +++ /dev/null @@ -1,158 +0,0 @@ -/*************************************************************************** - qgslegendlayerfilegroup.cpp - description - ------------------- - begin : Juli 2005 - copyright : (C) 2005 by Marco Hugentobler - email : marco.hugentobler@autoform.ch - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgslegendlayer.h" -#include "qgslegendlayerfilegroup.h" -#include "qgslegendlayerfile.h" -#include "qgslegendsymbologygroup.h" -#include "qgsmaplayer.h" -#include "qgslogger.h" - -QgsLegendLayerFileGroup::QgsLegendLayerFileGroup( QTreeWidgetItem* theItem, QString theString ): QgsLegendItem( theItem, theString ) -{ - mType = LEGEND_LAYER_FILE_GROUP; - setText( 0, theString ); -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayerFileGroup::accept( LEGEND_ITEM_TYPE type ) -{ - if ( type == LEGEND_LAYER_FILE ) - { - return INSERT; //there should be a way to already test, if the layers are symbology compatible - } - else - { - return NO_ACTION; - } -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayerFileGroup::accept( const QgsLegendItem* li ) const -{ - QgsDebugMsg( "entered." ); - if ( li ) - { - LEGEND_ITEM_TYPE type = li->type(); - if ( type == LEGEND_LAYER_FILE /*&& this != li->parent()*/ ) - { - if ( child( 0 ) == 0 ) - { - return INSERT; - } - else - { - QgsLegendLayerFile* llf = dynamic_cast( child( 0 ) ); - if ( llf ) - { - QgsMapLayer* childlayer = llf->layer(); - const QgsMapLayer* newlayer = qobject_cast( li )->layer(); - if ( newlayer->hasCompatibleSymbology( *childlayer ) ) - { - return INSERT; - } - } - } - } - } - return NO_ACTION; -} - -bool QgsLegendLayerFileGroup::insert( QgsLegendItem* newItem ) -{ - if ( newItem->type() == LEGEND_LAYER_FILE ) - { - QgsLegendItem* oldItem = firstChild(); - - if ( !oldItem )//this item is the first child - { - insertChild( 0, newItem ); - return true; - } - //there are already legend layer files - - //find the lowest sibling - while ( oldItem->nextSibling() != 0 ) - { - oldItem = oldItem->nextSibling(); - } - QgsLegendLayerFile* thefile = qobject_cast( oldItem ); - - if ( !thefile ) - { - return false; - } - QgsMapLayer* thelayer = thefile->layer(); - if ( !thelayer ) - { - return false; - } - QgsMapLayer* newLayer = qobject_cast( newItem )->layer(); - if ( newLayer->hasCompatibleSymbology( *thelayer ) ) - { - insertChild( childCount(), newItem ); - return true; - } - else - { - return false; - } - } - else - { - return false; - } -} - -bool QgsLegendLayerFileGroup::containsLegendLayerFile( const QgsLegendLayerFile* llf ) const -{ - bool result = false; - for ( int i = 0; i < childCount(); ++i ) - { - if ( llf == child( i ) ) - { - result = true; - break; - } - } - return result; -} - -void QgsLegendLayerFileGroup::receive( QgsLegendItem* newChild ) -{ - if ( newChild->type() == LEGEND_LAYER_FILE ) - { - QgsLegendLayer* ll = dynamic_cast( parent() ); - if ( ll ) - { - ll->updateIcon(); - ll->updateCheckState(); - } - } -} - -void QgsLegendLayerFileGroup::release( QgsLegendItem* formerChild ) -{ - QgsDebugMsg( "entered." ); - if ( formerChild->type() == LEGEND_LAYER_FILE ) - { - QgsLegendLayer* ll = dynamic_cast( parent() ); - if ( ll ) - { - ll->updateIcon(); - ll->updateCheckState(); - } - } -} diff --git a/src/app/legend/qgslegendlayerfilegroup.h b/src/app/legend/qgslegendlayerfilegroup.h deleted file mode 100644 index a4fe57b6ffa..00000000000 --- a/src/app/legend/qgslegendlayerfilegroup.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - qgslegendlayerfilegroup.h - description - ------------------- - begin : Juli 2005 - copyright : (C) 2005 by Marco Hugentobler - email : marco.hugentobler@autoform.ch - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgslegenditem.h" - -class QgsLegendLayerFile; - -class QgsLegendLayerFileGroup: public QgsLegendItem -{ - public: - QgsLegendLayerFileGroup( QTreeWidgetItem* theItem, QString theString ); - bool isLeafNode() {return false;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; - bool insert( QgsLegendItem* theItem ); - /**Returns true if llf is a childelement*/ - bool containsLegendLayerFile( const QgsLegendLayerFile* llf ) const; - /**Makes the parent QgsLegendLayer update the checkState and the icon after a new - QgsLegendLayerFile was inserted*/ - void receive( QgsLegendItem* newChild ); - /**Cleanups when after a child QgsLegendLayerFile item has left. Tells the parent QgsLegendLayer to - refresh the checkState and the icon*/ - void release( QgsLegendItem* formerChild ); -}; diff --git a/src/app/legend/qgslegendsymbologygroup.cpp b/src/app/legend/qgslegendsymbologygroup.cpp index 614e68c2adb..fbdad48f951 100644 --- a/src/app/legend/qgslegendsymbologygroup.cpp +++ b/src/app/legend/qgslegendsymbologygroup.cpp @@ -19,8 +19,6 @@ ***************************************************************************/ #include "qgsapplication.h" #include "qgisapp.h" -#include "qgslegendlayerfile.h" -#include "qgslegendlayerfilegroup.h" #include "qgslegendsymbologygroup.h" #include "qgsmaplayer.h" #include diff --git a/src/app/qgisapp.cpp b/src/app/qgisapp.cpp index e1fa363caf2..98bbad26987 100644 --- a/src/app/qgisapp.cpp +++ b/src/app/qgisapp.cpp @@ -106,7 +106,6 @@ #include "qgshelpviewer.h" #include "qgsgenericprojectionselector.h" #include "qgslegend.h" -#include "qgslegendlayerfile.h" #include "qgslegendlayer.h" #include "qgslogger.h" #include "qgsmapcanvas.h" @@ -4050,12 +4049,12 @@ void QgisApp::attributeTable() void QgisApp::saveAsShapefile() { - mMapLegend->currentLayerFile()->saveAsShapefile(); + mMapLegend->currentLegendLayer()->saveAsShapefile(); } void QgisApp::saveSelectionAsShapefile() { - mMapLegend->currentLayerFile()->saveSelectionAsShapefile(); + mMapLegend->currentLegendLayer()->saveSelectionAsShapefile(); } void QgisApp::layerProperties() @@ -4576,8 +4575,8 @@ void QgisApp::toggleEditing() if ( mMapCanvas && mMapCanvas->isDrawing() ) return; - QgsLegendLayerFile* currentLayerFile = mMapLegend->currentLayerFile(); - if ( currentLayerFile ) + QgsLegendLayer* currentLayer = mMapLegend->currentLegendLayer(); + if ( currentLayer ) { toggleEditing( mMapLegend->currentLayer() ); }