Index: debian/control =================================================================== --- debian/control (revision 14316) +++ debian/control (working copy) @@ -2,12 +2,13 @@ Section: science Priority: extra Maintainer: Quantum GIS developers -Build-Depends: debhelper (>= 5.0.51~), libgdal1-dev, libpq-dev, - libgeos-dev (>= 3.0.0), grass-dev, libsqlite3-dev, libgsl0-dev, proj (<< 4.7.0) | libproj-dev (>= 4.7.0), libexpat1-dev, - flex, bison, python-dev, cmake (>= 2.6), python-sip4 (>= 4.5.0), python-central (>=0.5), python, - sip4 (>= 4.5), libqt4-core (>=4.4.0), libqt4-dev (>=4.4.0), libqt4-gui (>=4.4.0), - libqt4-sql (>=4.4.0), python-qt4 (>=4.1.0), python-qt4-dev (>=4.1.0), - python-sip4-dev (>= 4.5.0), pyqt4-dev-tools, libqwt5-qt4-dev, libfcgi-dev, subversion +Build-Depends: debhelper (>= 7), libgdal1-dev, libpq-dev, + libgeos-dev (>= 3.0.0), grass-dev, libsqlite3-dev, libgsl0-dev, libproj-dev, + libexpat1-dev, flex, bison, python-dev, cmake (>= 2.6), python-sip (>= 4.5.0), + python-central (>=0.5), python, libqt4-core (>=4.4.0), libqt4-dev (>=4.4.0), + libqt4-gui (>=4.4.0), libqt4-sql (>=4.4.0), python-qt4 (>=4.1.0), + python-qt4-dev (>=4.1.0), python-sip-dev (>= 4.5.0), pyqt4-dev-tools, + libqwt5-qt4-dev, libspatialite-dev, libfcgi-dev, pkg-config, subversion Build-Conflicts: libqgis-dev, qgis-dev Standards-Version: 3.8.4 XS-Python-Version: current @@ -15,7 +16,7 @@ Package: qgis Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, qgis-common (= ${source:Version}), qgis-providers (= ${binary:Version}) +Depends: ${shlibs:Depends}, ${misc:Depends}, qgis-providers (= ${binary:Version}), qgis-common (= ${source:Version}) Recommends: qgis-plugin-grass, python-qgis Suggests: gpsbabel Conflicts: uim-qt3 @@ -30,7 +31,6 @@ Package: qgis-common Architecture: all -Depends: qgis (>= ${binary:Version}) Description: Quantum GIS - architecture-independent data Quantum GIS is a Geographic Information System (GIS) which manages, analyzes and display databases of geographic information. @@ -68,7 +68,7 @@ Package: qgis-plugin-grass Architecture: any -Depends: qgis (= ${binary:Version}), qgis-plugin-grass-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, grass +Depends: qgis (= ${binary:Version}), qgis-plugin-grass-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, grass640+42329 Description: GRASS plugin for Quantum GIS Quantum GIS is a Geographic Information System (GIS) which manages, analyzes and display databases of geographic information. @@ -79,6 +79,8 @@ Package: qgis-plugin-grass-common Architecture: all Depends: python +Replaces: qgis-common (<< 1.5) +Breaks: qgis-common (<< 1.5) Description: GRASS plugin for Quantum GIS - architecture-independent data Quantum GIS is a Geographic Information System (GIS) which manages, analyzes and display databases of geographic information. @@ -89,7 +91,7 @@ Package: python-qgis Section: python Architecture: any -Depends: python-qt4 (>=4.1.0), python-sip4 (>= 4.5.0), python-qgis-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends} +Depends: python-qt4 (>=4.1.0), python-sip (>= 4.5.0), python-qgis-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends} Provides: ${python:Provides} XB-Python-Version: ${python:Versions} Description: Python bindings to Quantum GIS @@ -113,7 +115,7 @@ Package: qgis-providers Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} +Depends: qgis-providers-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends} Replaces: qgis (<= 1.6) Breaks: qgis (<= 1.6) Description: collection of data providers to Quantum GIS Index: src/app/legend/qgslegendsymbologygroup.h =================================================================== --- src/app/legend/qgslegendsymbologygroup.h (revision 14316) +++ src/app/legend/qgslegendsymbologygroup.h (working copy) @@ -32,9 +32,7 @@ public: QgsLegendSymbologyGroup( QTreeWidgetItem * theItem, QString theString ); ~QgsLegendSymbologyGroup(); - bool isLeafNode() {return false;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; + /** Overloads cmpare function of QListViewItem * @note The symbology group must always be the second in the list */ Index: src/app/legend/qgslegendpropertygroup.h =================================================================== --- src/app/legend/qgslegendpropertygroup.h (revision 14316) +++ src/app/legend/qgslegendpropertygroup.h (working copy) @@ -34,9 +34,6 @@ ~QgsLegendPropertyGroup(); - bool isLeafNode() {return mLeafNodeFlag;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; /** Overloads cmpare function of QListViewItem * @note The property group must always be the first in the list */ Index: src/app/legend/qgslegendsymbologyitem.h =================================================================== --- src/app/legend/qgslegendsymbologyitem.h (revision 14316) +++ src/app/legend/qgslegendsymbologyitem.h (working copy) @@ -33,8 +33,6 @@ QgsLegendSymbologyItem( int pixmapWidth, int pixmapHeight ); ~QgsLegendSymbologyItem(); bool isLeafNode() {return true;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; int pixmapWidth() const {return mPixmapWidth;} int pixmapHeight() const {return mPixmapHeight;} void setLegend( QgsLegend* theLegend ); Index: src/app/legend/qgslegendpropertyitem.h =================================================================== --- src/app/legend/qgslegendpropertyitem.h (revision 14316) +++ src/app/legend/qgslegendpropertyitem.h (working copy) @@ -31,12 +31,7 @@ { public: QgsLegendPropertyItem( QTreeWidgetItem * theItem, QString theString ); - ~QgsLegendPropertyItem(); - - bool isLeafNode() {return mLeafNodeFlag;} - DRAG_ACTION accept( LEGEND_ITEM_TYPE type ); - QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const; }; #endif Index: src/app/legend/qgslegendlayer.cpp =================================================================== --- src/app/legend/qgslegendlayer.cpp (revision 14316) +++ src/app/legend/qgslegendlayer.cpp (working copy) @@ -99,48 +99,6 @@ setFont( 0, myFont ); } -bool QgsLegendLayer::isLeafNode() -{ - return false; -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayer::accept( LEGEND_ITEM_TYPE type ) -{ - if ( type == LEGEND_LAYER || type == LEGEND_GROUP ) - { - return REORDER; - } - else - { - return NO_ACTION; - } -} - -QgsLegendItem::DRAG_ACTION QgsLegendLayer::accept( const QgsLegendItem* li ) const -{ - if ( li && li != this ) - { - LEGEND_ITEM_TYPE type = li->type(); - if ( type == LEGEND_LAYER ) - { - //if(parent() == li->parent()) - //{ - return REORDER; - //} - } - else if ( type == LEGEND_GROUP ) - { - //only parent legend layers can change positions with groups - if ( parent() == 0 ) - { - return REORDER; - } - } - } - return NO_ACTION; -} - - QgsMapLayer* QgsLegendLayer::layer() { return mLyr.layer(); @@ -456,7 +414,8 @@ saveSelectionAsAction->setEnabled( false ); } - theMenu.addAction( tr( "&Query..." ), QgisApp::instance(), SLOT( layerSubsetString() ) ); + if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() ) + theMenu.addAction( tr( "&Query..." ), QgisApp::instance(), SLOT( layerSubsetString() ) ); theMenu.addSeparator(); } Index: src/app/legend/qgslegend.cpp =================================================================== --- src/app/legend/qgslegend.cpp (revision 14316) +++ src/app/legend/qgslegend.cpp (working copy) @@ -47,17 +47,11 @@ const int AUTOSCROLL_MARGIN = 16; -/** - @note - - set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash -*/ QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name ) - : QTreeWidget( parent ), - mMousePressedFlag( false ), - mItemBeingMoved( 0 ), - mMapCanvas( canvas ), - mMinimumIconSize( 20, 20 ) + : QTreeWidget( parent ) + , mMousePressedFlag( false ) + , mMapCanvas( canvas ) + , mMinimumIconSize( 20, 20 ) { setObjectName( name ); @@ -128,10 +122,20 @@ { if ( name.isEmpty() ) name = tr( "group" ); // some default name if none specified - QgsLegendGroup* group = new QgsLegendGroup( this, name ); + + QgsLegendGroup *parent = dynamic_cast( currentItem() ); + + QgsLegendGroup *group; + if ( parent ) + group = new QgsLegendGroup( parent, name ); + else + group = new QgsLegendGroup( this, name ); + group->setData( 0, Qt::UserRole, Qt::Checked ); QModelIndex groupIndex = indexFromItem( group ); setExpanded( groupIndex, expand ); + setCurrentItem( group ); + openEditor(); return groupIndex.row(); } @@ -142,7 +146,6 @@ mPixmapHeightValues.clear(); updateMapCanvasLayerSet(); setIconSize( mMinimumIconSize ); - mItemBeingMoved = 0; mDropTarget = 0; } @@ -162,7 +165,7 @@ QgsLegendItem* litem = dynamic_cast( theItem ); if ( litem && litem->type() == QgsLegendItem::LEGEND_LAYER ) { - theItem->setCheckState( 0, ( select ? Qt::Checked : Qt::Unchecked ) ); + theItem->setCheckState( 0, select ? Qt::Checked : Qt::Unchecked ); handleItemChange( theItem, 0 ); } } @@ -212,8 +215,8 @@ { if ( e->button() == Qt::LeftButton ) { - mLastPressPos = e->pos(); mMousePressedFlag = true; + mDropTarget = itemAt( e->pos() ); } else if ( e->button() == Qt::RightButton ) { @@ -230,201 +233,215 @@ void QgsLegend::mouseMoveEvent( QMouseEvent * e ) { - if ( mMousePressedFlag ) + if ( !mMousePressedFlag ) { - //set the flag back such that the else if(mItemBeingMoved) - //code part is passed during the next mouse moves - mMousePressedFlag = false; + QgsDebugMsg( "mouse not pressed" ); + return; + } - // remember item we've pressed as the one being moved - // and where it was originally - QTreeWidgetItem* item = itemAt( mLastPressPos ); - if ( item ) + + if ( mItemsBeingMoved.isEmpty() && !selectedItems().isEmpty() ) + { + if ( mDropTarget == itemAt( e->pos() ) ) + return; + + mLayersPriorToMove = layerIDs(); + QgsDebugMsg( "layers prior to move: " + mLayersPriorToMove.join( ", " ) ); + + // record which items were selected and hide them + foreach( QTreeWidgetItem *item, selectedItems() ) { - mItemBeingMoved = item; - mItemBeingMovedOrigPos = getItemPos( mItemBeingMoved ); + item->setHidden( true ); + mItemsBeingMoved << item; + } - //store information to insert the item back to the original position - storeInitialPosition( mItemBeingMoved ); + // remove and unhide items, whose parent is already to be moved + foreach( QTreeWidgetItem *item, mItemsBeingMoved ) + { + QTreeWidgetItem *parent = item->parent(); - setCursor( Qt::SizeVerCursor ); + bool parentHidden = false; + while ( !parentHidden && parent ) + { + parentHidden = parent->isHidden(); + parent = parent->parent(); + } + + if ( parentHidden ) + { + mItemsBeingMoved.removeOne( item ); + item->setHidden( false ); + } } + + setCursor( Qt::SizeVerCursor ); } - else if ( mItemBeingMoved ) + + if ( mItemsBeingMoved.isEmpty() ) { - QPoint p( e->pos() ); - mLastPressPos = p; + QgsDebugMsg( "nothing to move" ); + return; + } - // change the cursor appropriate to if drop is allowed - QTreeWidgetItem* item = itemAt( p ); + // change the cursor appropriate to if drop is allowed + QTreeWidgetItem* item = itemAt( e->pos() ); - hideLine(); - updateLineWidget(); - scrollToItem( item ); + hideLine(); + updateLineWidget(); + scrollToItem( item ); - QgsLegendItem* origin = dynamic_cast( mItemBeingMoved ); - QgsLegendItem* dest = dynamic_cast( item ); + if ( item ) + { + mDropTarget = item; + QgsLegendItem *litem = dynamic_cast( item ); + QgsLegendGroup *group = dynamic_cast( item ); + QgsLegendLayer *layer = dynamic_cast( item ); - if ( item ) + + if ( group ) + QgsDebugMsg( "group: " + group->text( 0 ) ); + else if ( layer ) + QgsDebugMsg( "layer: " + layer->text( 0 ) ); + else if ( litem ) + QgsDebugMsg( "litem: " + litem->text( 0 ) ); + else + QgsDebugMsg( "item: " + item->text( 0 ) ); + + if ( group || layer ) { - mDropTarget = item; - QgsLegendItem::DRAG_ACTION action = dest->accept( origin ); - if ( item != mItemBeingMoved ) + if ( yCoordAboveCenter( litem, e->y() ) ) //over center of item { - if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item + int line_y = visualItemRect( item ).top() + 1; + int line_left = visualItemRect( item ).left(); + + QgsDebugMsg( "insert before layer/group" ); + showLine( line_y, line_left ); + setCursor( QCursor( Qt::SizeVerCursor ) ); + + mDropAction = BEFORE; + } + else // below center of item + { + int line_y = visualItemRect( item ).bottom() - 2; + int line_left = visualItemRect( item ).left(); + + if ( group ) { - int line_y = visualItemRect( item ).top() + 1; - int line_left = visualItemRect( item ).left(); + QgsDebugMsg( "insert into group" ); + showLine( line_y, line_left ); + setCursor( QCursor( Qt::SizeVerCursor ) ); - if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT ) - { - QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" ); - mDropAction = BEFORE; - showLine( line_y, line_left ); - setCursor( QCursor( Qt::SizeVerCursor ) ); - } - else //no action - { - QgsDebugMsg( "mouseMoveEvent::NO_ACTION" ); - mDropAction = NO_ACTION; - setCursor( QCursor( Qt::ForbiddenCursor ) ); - } + mDropAction = INSERT; } - else // below center of item + else { - int line_y = visualItemRect( item ).bottom() - 2; - int line_left = visualItemRect( item ).left(); + QgsDebugMsg( "insert after layer" ); + showLine( line_y, line_left ); + setCursor( QCursor( Qt::SizeVerCursor ) ); - if ( action == QgsLegendItem::REORDER ) - { - QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" ); - mDropAction = AFTER; - showLine( line_y, line_left ); - setCursor( QCursor( Qt::SizeVerCursor ) ); - } - else if ( action == QgsLegendItem::INSERT ) - { - QgsDebugMsg( "mouseMoveEvent::INSERT" ); - mDropAction = INTO_GROUP; - showLine( line_y, line_left ); - setCursor( QCursor( Qt::SizeVerCursor ) ); - } - else//no action - { - mDropAction = NO_ACTION; - QgsDebugMsg( "mouseMoveEvent::NO_ACTION" ); - setCursor( QCursor( Qt::ForbiddenCursor ) ); - } + mDropAction = AFTER; } } - else - { - setCursor( QCursor( Qt::ForbiddenCursor ) ); - } } - else if ( !item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() && e->pos().x() >= 0 && e->pos().x() < viewport()->width() ) - { - // Outside the listed items, but check if we are in the empty area - // of the viewport, so we can drop after the last top level item. - QgsDebugMsg( "You are below the table" ); - mDropTarget = topLevelItem( topLevelItemCount() - 1 ); - dest = dynamic_cast( mDropTarget ); - QgsLegendItem::DRAG_ACTION action = dest->accept( origin ); - if ( action == QgsLegendItem::REORDER || action == QgsLegendItem::INSERT ) - { - QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" ); - mDropAction = AFTER; - showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 ); - setCursor( QCursor( Qt::SizeVerCursor ) ); - } - else //no action - { - QgsDebugMsg( "mouseMoveEvent::NO_ACTION" ); - mDropAction = NO_ACTION; - setCursor( QCursor( Qt::ForbiddenCursor ) ); - } - } - else { - QgsDebugMsg( "No item here" ); - mDropTarget = NULL; + QgsDebugMsg( "no action" ); setCursor( QCursor( Qt::ForbiddenCursor ) ); } } + else if ( !item + && e->pos().y() >= 0 && e->pos().y() < viewport()->height() + && e->pos().x() >= 0 && e->pos().x() < viewport()->width() ) + { + // Outside the listed items, but check if we are in the empty area + // of the viewport, so we can drop after the last top level item. + mDropTarget = topLevelItem( topLevelItemCount() - 1 ); + + QgsDebugMsg( "insert after last layer/group" ); + showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 ); + setCursor( QCursor( Qt::SizeVerCursor ) ); + + mDropAction = AFTER; + } + else + { + QgsDebugMsg( "No item here" ); + mDropTarget = NULL; + setCursor( QCursor( Qt::ForbiddenCursor ) ); + } } +void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item ) +{ + QgsLegendGroup *lg = dynamic_cast< QgsLegendGroup * >( item ); + if ( !lg ) + return; + + for ( int i = 0; i < item->childCount(); i++ ) + { + updateGroupCheckStates( item->child( i ) ); + } + + lg->updateCheckState(); +} + void QgsLegend::mouseReleaseEvent( QMouseEvent * e ) { QTreeWidget::mouseReleaseEvent( e ); - setCursor( QCursor( Qt::ArrowCursor ) ); - mMousePressedFlag = false; - // move only if we have a valid item and drop place - // otherwise reset the stored values - if ( !mItemBeingMoved || !mDropTarget ) - { - mItemBeingMoved = NULL; - mDropTarget = NULL; + if ( mItemsBeingMoved.isEmpty() ) return; - } + setCursor( QCursor( Qt::ArrowCursor ) ); hideLine(); - QgsLegendItem* origin = dynamic_cast( mItemBeingMoved ); - mItemBeingMoved = NULL; - QModelIndex oldIndex = indexFromItem( origin ); - - QgsLegendItem* dest = dynamic_cast( mDropTarget ); - mDropTarget = NULL; - - // no change? - if ( !dest || !origin || ( dest == origin ) ) + // unhide + foreach( QTreeWidgetItem *item, mItemsBeingMoved ) { - checkLayerOrderUpdate(); - return; + item->setHidden( false ); } + if ( mDropTarget ) { - // Do the actual move here. - QgsDebugMsg( "Drag'n'drop happened!" ); - if ( mDropAction == AFTER ) //over center of item + if ( mDropAction == AFTER ) { QgsDebugMsg( "Drop AFTER" ); - if ( dest->nextSibling() != origin ) + foreach( QTreeWidgetItem *item, mItemsBeingMoved ) { - moveItem( origin, dest ); - setCurrentItem( origin ); - emit itemMoved( oldIndex, indexFromItem( origin ) ); + moveItem( item, mDropTarget ); + mDropTarget = item; } } - else if ( mDropAction == BEFORE )// below center of item + else if ( mDropAction == BEFORE ) { - QgsDebugMsg( "Drop BEFORE" ); - if ( dest->findYoungerSibling() != origin ) + mDropTarget = previousSibling( mDropTarget ); + + foreach( QTreeWidgetItem *item, mItemsBeingMoved ) { - moveItem( origin, dest ); // Insert after, as above... - moveItem( dest, origin ); // ... and then switch places! - setCurrentItem( origin ); - emit itemMoved( oldIndex, indexFromItem( origin ) ); + moveItem( item, mDropTarget ); + mDropTarget = item; } } - else if ( mDropAction == INTO_GROUP ) + else { - QgsDebugMsg( "Drop INTO_GROUP" ); - if ( origin->parent() != dest ) + foreach( QTreeWidgetItem *item, mItemsBeingMoved ) { - insertItem( origin, dest ); - setCurrentItem( origin ); - emit itemMoved( oldIndex, indexFromItem( origin ) ); + insertItem( item, mDropTarget ); } } - else//no action + + mItemsBeingMoved.clear(); + + for ( int i = 0; i < topLevelItemCount(); i++ ) { - QgsDebugMsg( "Drop NO_ACTION" ); + updateGroupCheckStates( topLevelItem( i ) ); } } + else //no action + { + QgsDebugMsg( "Drop NO_ACTION" ); + } checkLayerOrderUpdate(); } @@ -446,7 +463,6 @@ QgsLegendItem* li = dynamic_cast( item ); if ( li ) { - if ( li->type() == QgsLegendItem::LEGEND_LAYER ) { qobject_cast( li )->addToPopupMenu( theMenu ); @@ -467,7 +483,6 @@ { theMenu.addAction( tr( "Re&name" ), this, SLOT( openEditor() ) ); } - } theMenu.addAction( QgisApp::getThemeIcon( "/folder_new.png" ), tr( "&Add group" ), this, SLOT( addGroup() ) ); @@ -565,8 +580,7 @@ QgsLegendLayer * ll = findLegendLayer( layer ); if ( ll ) { - Qt::CheckState cs = visible ? Qt::Checked : Qt::Unchecked; - ll->setCheckState( 0, cs ); + ll->setCheckState( 0, visible ? Qt::Checked : Qt::Unchecked ); } } @@ -644,7 +658,7 @@ } } -void QgsLegend::removeGroup( QgsLegendGroup * lg ) +void QgsLegend::removeGroup( QgsLegendGroup *lg ) { if ( !mMapCanvas || mMapCanvas->isDrawing() ) { @@ -655,17 +669,23 @@ QTreeWidgetItem * child = lg->child( 0 ); while ( child ) { - QgsLegendLayer* ll = dynamic_cast( child ); - if ( ll ) - QgsMapLayerRegistry::instance()->removeMapLayer( ll->layer()->getLayerID() ); + QgsLegendLayer *cl = dynamic_cast( child ); + QgsLegendGroup *cg = dynamic_cast( child ); + + if ( cl ) + QgsMapLayerRegistry::instance()->removeMapLayer( cl->layer()->getLayerID() ); + else if ( cg ) + removeGroup( cg ); + child = lg->child( 0 ); } + delete lg; adjustIconSize(); } -void QgsLegend::moveLayer( QgsMapLayer * ml, int groupIndex ) +void QgsLegend::moveLayer( QgsMapLayer *ml, int groupIndex ) { if ( !ml ) return; @@ -716,225 +736,253 @@ } } -bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document ) +bool QgsLegend::writeXML( QDomNode &legendnode, QDomDocument &document ) { - QDomNode tmplegendnode = legendnode; /*copy of the legendnode*/ - QDomElement legendgroupnode; - QDomElement legendlayernode; - QDomElement layerfilegroupnode; - QDomElement legendsymbolnode; - QDomElement legendpropertynode; - QDomElement legendlayerfilenode; - Qt::CheckState cstate; //check state for legend layers and legend groups + QList items; + for ( int i = 0; i < topLevelItemCount(); i++ ) + { + items << topLevelItem( i ); + } - for ( QTreeWidgetItem* currentItem = firstItem(); currentItem; currentItem = nextItem( currentItem ) ) + return writeXML( items, legendnode, document ); +} + +bool QgsLegend::writeXML( QList items, QDomNode &node, QDomDocument &document ) +{ + foreach( QTreeWidgetItem *currentItem, items ) { QgsLegendItem *item = dynamic_cast( currentItem ); if ( !item ) continue; - switch ( item->type() ) + if ( item->type() == QgsLegendItem::LEGEND_GROUP ) { - case QgsLegendItem::LEGEND_GROUP: - //make sure the legendnode is 'legend' again after a legend group - if ( !( item->parent() ) ) + QDomElement legendgroupnode = document.createElement( "legendgroup" ); + legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + legendgroupnode.setAttribute( "name", item->text( 0 ) ); + Qt::CheckState cstate = item->checkState( 0 ); + if ( cstate == Qt::Checked ) + { + legendgroupnode.setAttribute( "checked", "Qt::Checked" ); + } + else if ( cstate == Qt::Unchecked ) + { + legendgroupnode.setAttribute( "checked", "Qt::Unchecked" ); + } + else if ( cstate == Qt::PartiallyChecked ) + { + legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" ); + } + + QList children; + for ( int i = 0; i < currentItem->childCount(); i++ ) + { + children << currentItem->child( i ); + } + + writeXML( children, legendgroupnode, document ); + + node.appendChild( legendgroupnode ); + } + else if ( item->type() == QgsLegendItem::LEGEND_LAYER ) + { + QDomElement legendlayernode = document.createElement( "legendlayer" ); + legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + Qt::CheckState cstate = item->checkState( 0 ); + if ( cstate == Qt::Checked ) + { + legendlayernode.setAttribute( "checked", "Qt::Checked" ); + } + else if ( cstate == Qt::Unchecked ) + { + legendlayernode.setAttribute( "checked", "Qt::Unchecked" ); + } + else if ( cstate == Qt::PartiallyChecked ) + { + legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" ); + } + legendlayernode.setAttribute( "name", item->text( 0 ) ); + + for ( int i = 0; i < item->childCount(); i++ ) + { + QTreeWidgetItem *child = item->child( i ); + QgsLegendItem *litem = dynamic_cast( child ); + + if ( !litem ) { - legendnode = tmplegendnode; + QgsDebugMsg( "tree widget item not a legend item" ); + continue; } - legendgroupnode = document.createElement( "legendgroup" ); - legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); - legendgroupnode.setAttribute( "name", item->text( 0 ) ); - cstate = item->checkState( 0 ); - if ( cstate == Qt::Checked ) - { - legendgroupnode.setAttribute( "checked", "Qt::Checked" ); - } - else if ( cstate == Qt::Unchecked ) - { - legendgroupnode.setAttribute( "checked", "Qt::Unchecked" ); - } - else if ( cstate == Qt::PartiallyChecked ) - { - legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" ); - } - legendnode.appendChild( legendgroupnode ); - tmplegendnode = legendnode; - legendnode = legendgroupnode; - break; - case QgsLegendItem::LEGEND_LAYER: - //make sure the legendnode is 'legend' again after a legend group - if ( !( item->parent() ) ) + if ( litem->type() == QgsLegendItem::LEGEND_PROPERTY_GROUP ) { - legendnode = tmplegendnode; + QDomElement legendpropertynode = document.createElement( "propertygroup" ); + legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + legendlayernode.appendChild( legendpropertynode ); } - legendlayernode = document.createElement( "legendlayer" ); - legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); - cstate = item->checkState( 0 ); - if ( cstate == Qt::Checked ) + else if ( litem->type() == QgsLegendItem::LEGEND_SYMBOL_GROUP ) { - legendlayernode.setAttribute( "checked", "Qt::Checked" ); + QDomElement legendsymbolnode = document.createElement( "symbolgroup" ); + legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + legendlayernode.appendChild( legendsymbolnode ); } - else if ( cstate == Qt::Unchecked ) + else { - legendlayernode.setAttribute( "checked", "Qt::Unchecked" ); + QgsDebugMsg( "unexpected legend item type " + QString::number( litem->type() ) ); } - else if ( cstate == Qt::PartiallyChecked ) - { - legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" ); - } - legendlayernode.setAttribute( "name", item->text( 0 ) ); - legendnode.appendChild( legendlayernode ); + } - // save the information about layer - // emulate a legend layer file group and a legend layer file - // to keep it compatible with older projects - { - QgsLegendLayer *ll = dynamic_cast( item ); - QgsMapLayer* layer = ll->layer(); + node.appendChild( legendlayernode ); - layerfilegroupnode = document.createElement( "filegroup" ); - layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); - layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" ); - legendlayernode.appendChild( layerfilegroupnode ); + // save the information about layer + // emulate a legend layer file group and a legend layer file + // to keep it compatible with older projects + QgsLegendLayer *ll = dynamic_cast( item ); + QgsMapLayer* layer = ll->layer(); - legendlayerfilenode = document.createElement( "legendlayerfile" ); + QDomElement layerfilegroupnode = document.createElement( "filegroup" ); + layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" ); + layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" ); + legendlayernode.appendChild( layerfilegroupnode ); - // layer id - legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() ); - layerfilegroupnode.appendChild( legendlayerfilenode ); + QDomElement legendlayerfilenode = document.createElement( "legendlayerfile" ); - // visible flag - legendlayerfilenode.setAttribute( "visible", ll->isVisible() ); + // layer id + legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() ); + layerfilegroupnode.appendChild( legendlayerfilenode ); - // show in overview flag - legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() ); - } - break; + // visible flag + legendlayerfilenode.setAttribute( "visible", ll->isVisible() ); - 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; + // show in overview flag + legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() ); } + else + { + QgsDebugMsg( "unexpected legend item type " + QString::number( item->type() ) ); + } } + return true; } -bool QgsLegend::readXML( QDomNode& legendnode ) +bool QgsLegend::readXML( QgsLegendGroup *parent, const QDomNode &node ) { - QDomElement childelem; - QDomNode child; - QgsLegendGroup* lastGroup = 0; //pointer to the last inserted group - QgsLegendLayer* lastLayer = 0; //pointer to the last inserted legendlayer + const QDomNodeList &l = node.childNodes(); + for ( int i = 0; i < l.count(); i++ ) + { + QDomNode child = l.at( i ); + QDomElement childelem = child.toElement(); + QString name = childelem.attribute( "name" ); - child = legendnode.firstChild(); + //test every possibility of element... + if ( childelem.tagName() == "legendgroup" ) + { + QgsLegendGroup *theGroup; + if ( parent ) + theGroup = new QgsLegendGroup( parent, name ); + else + theGroup = new QgsLegendGroup( this, name ); - // For some unexplained reason, collapsing/expanding the legendLayer items - // immediately after they have been created doesn't work (they all end up - // expanded). The legendGroups and legendLayerFiles seems ok through. The - // workaround is to store the required states of the legendLayers and set - // them at the end of this function. - QList collapsed, expanded; + //set the checkbox of the legend group to the right state + blockSignals( true ); + QString checked = childelem.attribute( "checked" ); + if ( checked == "Qt::Checked" ) + { + theGroup->setCheckState( 0, Qt::Checked ); + theGroup->setData( 0, Qt::UserRole, Qt::Checked ); + } + else if ( checked == "Qt::Unchecked" ) + { + theGroup->setCheckState( 0, Qt::Unchecked ); + theGroup->setData( 0, Qt::UserRole, Qt::Checked ); + } + else if ( checked == "Qt::PartiallyChecked" ) + { + theGroup->setCheckState( 0, Qt::PartiallyChecked ); + theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked ); + } + blockSignals( false ); - if ( !child.isNull() ) - { - clear(); //remove all items first + readXML( theGroup, child ); - do + if ( childelem.attribute( "open" ) == "true" ) + { + expandItem( theGroup ); + } + else + { + collapseItem( theGroup ); + } + } + else if ( childelem.tagName() == "legendlayer" ) { - QDomElement childelem = child.toElement(); - QString name = childelem.attribute( "name" ); + bool isOpen; + QgsLegendLayer* currentLayer = readLayerFromXML( childelem, isOpen ); - //test every possibility of element... - if ( childelem.tagName() == "legendgroup" ) + if ( !currentLayer ) + return false; + + // add to tree - either as a top-level node or a child of a group + if ( parent ) { - QgsLegendGroup* theGroup = new QgsLegendGroup( this, name ); - childelem.attribute( "open" ) == "true" ? expanded.push_back( theGroup ) : collapsed.push_back( theGroup ); - //set the checkbox of the legend group to the right state - blockSignals( true ); - QString checked = childelem.attribute( "checked" ); - if ( checked == "Qt::Checked" ) + parent->addChild( currentLayer ); + } + else + { + addTopLevelItem( currentLayer ); + } + + const QDomNodeList &cnl = child.childNodes(); + for ( int j = 0; j < cnl.count(); j++ ) + { + const QDomElement &childelem = cnl.at( j ).toElement(); + + if ( childelem.tagName() == "legendlayerfile" ) { - theGroup->setCheckState( 0, Qt::Checked ); - theGroup->setData( 0, Qt::UserRole, Qt::Checked ); + // do nothing, this has been handled in readLayerFromXML() } - else if ( checked == "Qt::Unchecked" ) + else if ( childelem.tagName() == "filegroup" ) { - theGroup->setCheckState( 0, Qt::Unchecked ); - theGroup->setData( 0, Qt::UserRole, Qt::Checked ); + // do nothing, this has been handled in readLayerFromXML() } - else if ( checked == "Qt::PartiallyChecked" ) + else if ( childelem.tagName() == "propertygroup" ) { - theGroup->setCheckState( 0, Qt::PartiallyChecked ); - theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked ); + QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( currentLayer, "Properties" ); + setItemExpanded( thePropertyGroup, childelem.attribute( "open" ) == "true" ); } - blockSignals( false ); - lastGroup = theGroup; - } - else if ( childelem.tagName() == "legendlayer" ) - { - bool isOpen; // to receive info whether the item is open or closed - lastLayer = readLayerFromXML( childelem, isOpen ); - - if ( lastLayer ) + else { - - // add to tree - either as a top-level node or a child of a group - if ( child.parentNode().toElement().tagName() == "legendgroup" ) - { - lastGroup->addChild( lastLayer ); - } - else - { - addTopLevelItem( lastLayer ); - lastGroup = 0; - } - - // expanded or collapsed - isOpen ? expanded.push_back( lastLayer ) : collapsed.push_back( lastLayer ); - - // load symbology - refreshLayerSymbology( lastLayer->layer()->getLayerID() ); + QgsDebugMsg( "unexpected legendlayer child " + childelem.tagName() ); } } - else if ( childelem.tagName() == "legendlayerfile" ) + + // load symbology + refreshLayerSymbology( currentLayer->layer()->getLayerID() ); + + if ( isOpen ) { - // do nothing, this has been handled in readLayerFromXML() + expandItem( currentLayer ); } - else if ( childelem.tagName() == "filegroup" ) + else { - // do nothing, this has been handled in readLayerFromXML() + collapseItem( currentLayer ); } - else if ( childelem.tagName() == "propertygroup" ) - { - QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( lastLayer, "Properties" ); - childelem.attribute( "open" ) == "true" ? expandItem( thePropertyGroup ) : collapseItem( thePropertyGroup ); - } - child = nextDomNode( child ); } - while ( !( child.isNull() ) ); + else + { + QgsDebugMsg( "unexpected legend child " + childelem.tagName() ); + } } - // Do the tree item expands and collapses. - for ( int i = 0; i < expanded.size(); ++i ) - expandItem( expanded[i] ); - for ( int i = 0; i < collapsed.size(); ++i ) - collapseItem( collapsed[i] ); - return true; } +bool QgsLegend::readXML( QDomNode& legendnode ) +{ + clear(); //remove all items first + return readXML( 0, legendnode ); +} QgsLegendLayer* QgsLegend::readLayerFromXML( QDomElement& childelem, bool& isOpen ) { @@ -982,69 +1030,6 @@ } -void QgsLegend::storeInitialPosition( QTreeWidgetItem* li ) -{ - if ( li == firstItem() ) //the item is the first item in the list view - { - mRestoreInformation = FIRST_ITEM; - mRestoreItem = 0; - } - else if ( li->parent() == 0 ) //li is a toplevel item, but not the first one - { - mRestoreInformation = YOUNGER_SIBLING; - mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling(); - } - else if ( li == li->parent()->child( 0 ) )//li is not a toplevel item, but the first child - { - mRestoreInformation = FIRST_CHILD; - mRestoreItem = li->parent(); - } - else - { - mRestoreInformation = YOUNGER_SIBLING; - mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling(); - } - mLayersPriorToMove = layerIDs(); -} - -void QgsLegend::resetToInitialPosition( QTreeWidgetItem* li ) -{ - QgsLegendItem* formerParent = dynamic_cast( li->parent() ); //todo: make sure legend layers are updated - if ( mRestoreInformation == FIRST_ITEM ) - { - QgsDebugMsg( "FIRST_ITEM" ); - - removeItem( li ); - insertTopLevelItem( 0, li ); - } - else if ( mRestoreInformation == FIRST_CHILD ) - { - QgsDebugMsg( "FIRST_CHILD" ); - - removeItem( li ); - if ( formerParent ) - { - formerParent->release(( QgsLegendItem* )li ); - } - mRestoreItem->insertChild( 0, li ); - (( QgsLegendItem* )mRestoreItem )->receive(( QgsLegendItem* )li ); - } - else if ( mRestoreInformation == YOUNGER_SIBLING ) - { - QgsDebugMsg( "YOUNGER_SIBLING" ); - - if ( formerParent ) - { - formerParent->release(( QgsLegendItem* )li ); - } - dynamic_cast( li )->moveItem( dynamic_cast( mRestoreItem ) ); - if ( mRestoreItem->parent() ) - { - (( QgsLegendItem* )( mRestoreItem->parent() ) )->receive(( QgsLegendItem* )li ); - } - } -} - QgsLegendLayer* QgsLegend::findLegendLayer( const QString& layerKey ) { QgsLegendLayer* theLegendLayer = 0; @@ -1156,14 +1141,18 @@ { QList< GroupLayerInfo > groupLayerList; - int nTopLevelItems = topLevelItemCount(); - QTreeWidgetItem* currentTopLevelItem = 0; + QList< QTreeWidgetItem * > items; - for ( int i = 0; i < nTopLevelItems; ++i ) + for ( int i = 0; i < topLevelItemCount(); i++ ) { - currentTopLevelItem = topLevelItem( i ); - //layer? - QgsLegendLayer* lLayer = dynamic_cast( currentTopLevelItem ); + items << topLevelItem( i ); + } + + while ( !items.isEmpty() ) + { + QTreeWidgetItem *currentItem = items.takeFirst(); + + QgsLegendLayer* lLayer = dynamic_cast( currentItem ); if ( lLayer ) { if ( lLayer->layer() ) @@ -1173,15 +1162,17 @@ groupLayerList.push_back( qMakePair( QString(), layerList ) ); } } - //group? - QgsLegendGroup* lGroup = dynamic_cast( currentTopLevelItem ); + + QgsLegendGroup* lGroup = dynamic_cast( currentItem ); if ( lGroup ) { - int nLayers = lGroup->childCount(); + int nLayers = lGroup->childCount(); QList layerList; for ( int i = 0; i < nLayers; ++i ) { - QgsLegendLayer* lLayer = dynamic_cast( lGroup->child( i ) ); + QTreeWidgetItem *gItem = lGroup->child( i ); + + QgsLegendLayer* lLayer = dynamic_cast( gItem ); if ( lLayer ) { if ( lLayer->layer() ) @@ -1189,7 +1180,15 @@ layerList.push_back( lLayer->layer()->getLayerID() ); } } + + QgsLegendGroup* lGroup = dynamic_cast( gItem ); + if ( lGroup ) + { + layerList << lGroup->text( 0 ); + items << lGroup; + } } + groupLayerList.push_back( qMakePair( lGroup->text( 0 ), layerList ) ); } } @@ -1197,7 +1196,6 @@ return groupLayerList; } -/**Returns the first item in the hierarchy*/ QTreeWidgetItem* QgsLegend::firstItem() { return topLevelItem( 0 ); @@ -1219,28 +1217,22 @@ { return litem->nextSibling(); } - else if ( !litem->parent() ) + else if ( litem->parent() ) { - return 0; + QTreeWidgetItem *parent = litem->parent(); + + while ( parent ) + { + QgsLegendItem *sibling = dynamic_cast( parent )->nextSibling(); + + if ( sibling ) + return sibling; + + parent = parent->parent(); + } } - //go to other levels to find the next item - else if ( litem->parent() && dynamic_cast( litem->parent() )->nextSibling() ) - { - return dynamic_cast( litem->parent() )->nextSibling(); - } - else if ( litem->parent() && litem->parent()->parent() && dynamic_cast( litem->parent()->parent() )->nextSibling() ) - { - return dynamic_cast( litem->parent()->parent() )->nextSibling(); - } - else if ( litem->parent() && litem->parent()->parent() && litem->parent()->parent()->parent() && - dynamic_cast( litem->parent()->parent()->parent() )->nextSibling() )//maximum four nesting states in the current legend - { - return dynamic_cast( litem->parent()->parent()->parent() )->nextSibling(); - } - else - { - return 0; - } + + return 0; } QTreeWidgetItem* QgsLegend::nextSibling( QTreeWidgetItem* item ) @@ -1271,28 +1263,6 @@ } } -QDomNode QgsLegend::nextDomNode( const QDomNode& theNode ) -{ - if ( !theNode.firstChild().isNull() ) - { - return theNode.firstChild(); - } - - QDomNode currentNode = theNode; - do - { - if ( !currentNode.nextSibling().isNull() ) - { - return currentNode.nextSibling(); - } - currentNode = currentNode.parentNode(); - } - while ( !currentNode.isNull() ); - - QDomNode nullNode; - return nullNode; -} - void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into ) { QgsLegendItem* movedItem = dynamic_cast( move ); @@ -1316,9 +1286,13 @@ void QgsLegend::moveItem( QTreeWidgetItem* move, QTreeWidgetItem* after ) { QgsDebugMsg( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ) ); - QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) ); + if ( after ) + QgsDebugMsg( QString( "after layer : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) ); + else + QgsDebugMsg( "as toplevel item" ); static_cast( move )->storeAppearanceSettings();//store settings in the moved item and its childern + if ( move->parent() ) { move->parent()->takeChild( move->parent()->indexOfChild( move ) ); @@ -1327,14 +1301,23 @@ { takeTopLevelItem( indexOfTopLevelItem( move ) ); } - if ( after->parent() ) + + if ( after ) { - after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move ); + if ( after->parent() ) + { + after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move ); + } + else //toplevel item + { + insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move ); + } } - else //toplevel item + else { - insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move ); + insertTopLevelItem( 0, move ); } + static_cast( move )->restoreAppearanceSettings();//apply the settings again } @@ -1390,9 +1373,10 @@ updateOverview(); } -std::deque QgsLegend::layerIDs() +QStringList QgsLegend::layerIDs() { - std::deque layers; + QStringList layers; + for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) ) { QgsLegendItem *li = dynamic_cast( theItem ); @@ -1406,9 +1390,9 @@ #ifdef QGISDEBUG QgsDebugMsg( "QgsLegend::layerIDs()" ); - for ( std::deque::iterator it = layers.begin(); it != layers.end(); ++it ) + foreach( QString id, layers ) { - QgsDebugMsg( *it ); + QgsDebugMsg( id ); } #endif @@ -1501,39 +1485,44 @@ if ( lg ) { //set all the child layer files to the new check state - std::list subfiles = lg->legendLayers(); bool renderFlagState = mMapCanvas->renderFlag(); mMapCanvas->setRenderFlag( false ); - for ( std::list::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter ) + QList items; + items << item; + while ( !items.isEmpty() ) { -#ifdef QGISDEBUG - if ( item->checkState( 0 ) == Qt::Checked ) + QTreeWidgetItem *litem = items.takeFirst(); + + QgsLegendLayer *ll = dynamic_cast( litem ); + if ( ll ) { - QgsDebugMsg( "item checked" ); + blockSignals( true ); + ll->setCheckState( 0, item->checkState( 0 ) ); + blockSignals( false ); + + if ( ll->layer() ) + { + ll->setVisible( lg->checkState( 0 ) == Qt::Checked ); + } } - else if ( item->checkState( 0 ) == Qt::Unchecked ) + + QgsLegendGroup *lg = dynamic_cast( litem ); + if ( lg ) { - QgsDebugMsg( "item unchecked" ); + blockSignals( true ); + lg->setCheckState( 0, item->checkState( 0 ) ); + blockSignals( false ); + + for ( int i = 0; i < lg->childCount(); i++ ) + items << lg->child( i ); } - else if ( item->checkState( 0 ) == Qt::PartiallyChecked ) - { - QgsDebugMsg( "item partially checked" ); - } -#endif - blockSignals( true ); - ( *iter )->setCheckState( 0, item->checkState( 0 ) ); - blockSignals( false ); - item->setData( 0, Qt::UserRole, item->checkState( 0 ) ); - if (( *iter )->layer() ) - { - ( *iter )->setVisible( item->checkState( 0 ) == Qt::Checked ); - } } // If it was on, turn it back on, otherwise leave it // off, as turning it on causes a refresh. if ( renderFlagState ) mMapCanvas->setRenderFlag( true ); + item->setData( 0, Qt::UserRole, item->checkState( 0 ) ); } @@ -1549,11 +1538,14 @@ ll->setVisible( item->checkState( 0 ) == Qt::Checked ); } - if ( ll->parent() ) + QgsLegendGroup *lg = dynamic_cast( ll->parent() ); + while ( lg ) { - static_cast( ll->parent() )->updateCheckState(); - ll->parent()->setData( 0, Qt::UserRole, ll->parent()->checkState( 0 ) ); + lg->updateCheckState(); + lg->setData( 0, Qt::UserRole, lg->checkState( 0 ) ); + lg = dynamic_cast( lg->parent() ); } + // If it was on, turn it back on, otherwise leave it // off, as turning it on causes a refresh. if ( renderFlagState ) @@ -1708,7 +1700,7 @@ bool QgsLegend::checkLayerOrderUpdate() { - std::deque layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary + QStringList layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary if ( layersAfterRelease != mLayersPriorToMove ) { // z-order has changed - update layer set @@ -1761,7 +1753,7 @@ QgsLegendLayer* ll = dynamic_cast( item ); if ( ll ) { - ll->setCheckState( 0, ( lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked ) ); + ll->setCheckState( 0, lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked ); } } } Index: src/app/legend/qgslegendlayer.h =================================================================== --- src/app/legend/qgslegendlayer.h (revision 14316) +++ src/app/legend/qgslegendlayer.h (working copy) @@ -48,9 +48,6 @@ 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 the item*/ QgsMapLayer* layer(); QgsMapCanvasLayer& canvasLayer(); Index: src/app/legend/qgslegend.h =================================================================== --- src/app/legend/qgslegend.h (revision 14316) +++ src/app/legend/qgslegend.h (working copy) @@ -20,10 +20,9 @@ #ifndef QGSLEGEND_H #define QGSLEGEND_H -#include -#include -#include #include +#include +#include class QgsLegendGroup; class QgsLegendLayer; @@ -89,7 +88,6 @@ // declaration was public while the definition was private class QgsLegendPixmaps; - public: /*! Constructor. * @param qgis_app link to qgisapp @@ -162,7 +160,7 @@ void removeItem( QTreeWidgetItem* item ); /**Returns the ids of the layers contained in this legend. The order is bottom->top*/ - std::deque layerIDs(); + QStringList layerIDs(); /**Updates layer set of map canvas*/ void updateMapCanvasLayerSet(); @@ -191,9 +189,10 @@ /**Returns a layers check state*/ Qt::CheckState layerCheckState( QgsMapLayer * layer ); - void updateCheckStates( QTreeWidgetItem* item, Qt::CheckState state ) { item->setData( 0, Qt::UserRole, state ); } + void updateGroupCheckStates( QTreeWidgetItem *item ); + public slots: /*!Adds a new layer group with the maplayer to the canvas*/ @@ -270,6 +269,7 @@ /** Remove selected layers */ void removeSelectedLayers(); + protected: /*!Event handler for mouse movements. @@ -312,13 +312,6 @@ void mouseReleaseEvent( QMouseEvent * e ); void mouseDoubleClickEvent( QMouseEvent* e ); - /**Stores the necessary information about the position of an item in the hierarchy. Afterwards, - this item may be moved back to the original position with resetToInitialPosition()*/ - void storeInitialPosition( QTreeWidgetItem* li ); - - /**Moves an item back to the position where storeInitialPosition has been called*/ - void resetToInitialPosition( QTreeWidgetItem* li ); - /**Returns the legend layer to which a map layer belongs to*/ QgsLegendLayer* findLegendLayer( const QString& layerKey ); @@ -334,18 +327,23 @@ /**This function compares the layer order before a drag with the current layer ordering and triggers a canvas repaint if it has changed*/ bool checkLayerOrderUpdate(); - /**The target that the mouse is over when dragging */ + // mouse is pressed + bool mMousePressedFlag; + + // position of mouse when it is pressed at the start of a drag event. + QPoint mLastPressPos; + + // layer our prior to move + QStringList mLayersPriorToMove; + + // keep track of the items being dragged + QList< QTreeWidgetItem * > mItemsBeingMoved; + + // The target that the mouse is over when dragging QTreeWidgetItem *mDropTarget; - enum DROP_ACTION_TYPE - { - BEFORE, - AFTER, - INTO_GROUP, - NO_ACTION - }; - /** Set when mouse is moved over different kind of items, depending opn what they accept() */ - DROP_ACTION_TYPE mDropAction; + // The action when the mouse is released + enum { BEFORE, INSERT, AFTER } mDropAction; /** Hide the line that indicates insertion position */ void hideLine(); @@ -384,6 +382,8 @@ void makeToTopLevelItem(); private: + bool readXML( QgsLegendGroup *parent, const QDomNode &node ); + bool writeXML( QList items, QDomNode &node, QDomDocument &document ); /*! Prevent the copying of QgsLegends * @todo See if this is really required - we may want multiple map, canvas and @@ -399,38 +399,6 @@ QgsLegend & operator=( QgsLegend const & ); /*! - * Position of mouse when it is pressed at the start of a drag event. - */ - QPoint mLastPressPos; - - /**True if the mouse is pressed*/ - bool mMousePressedFlag; - - /// keep track of the Item being dragged - QTreeWidgetItem* mItemBeingMoved; - - /*! - * Position in the list of the item being moved as it was at the start of a drag event. - * An item at the top of the list will be 0 and each successive item below it - * will be 1,2 3 etc... regardless of nesting level. - */ - int mItemBeingMovedOrigPos; - - /**Information needed by 'storeInitialPosition' and 'resetToInitialPosition'*/ - enum HIERARCHY_POSITION_TYPE - { - FIRST_ITEM, - FIRST_CHILD, - YOUNGER_SIBLING - }; - HIERARCHY_POSITION_TYPE mRestoreInformation; - QTreeWidgetItem* mRestoreItem; - - /**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; - - /*! * A function to determine how far down in the list an item is (starting with one for the first Item). *If the item is not in the legend, -1 is returned * @see mItemBeingMovedOrigPos Index: src/app/legend/qgslegendvectorsymbologyitem.h =================================================================== --- src/app/legend/qgslegendvectorsymbologyitem.h (revision 14316) +++ src/app/legend/qgslegendvectorsymbologyitem.h (working copy) @@ -18,7 +18,7 @@ #ifndef QGSLEGENDVECTORSYMBOLOGYITEM_H #define QGSLEGENDVECTORSYMBOLOGYITEM_H -#include +#include #include "qgslegendsymbologyitem.h" class QgsSymbol; @@ -33,7 +33,7 @@ void handleDoubleClickEvent(); private: /**Collection of pointers to the vector layer symbols associated with this item*/ - std::list mSymbols; + QList mSymbols; }; #endif Index: src/app/legend/qgslegendgroup.cpp =================================================================== --- src/app/legend/qgslegendgroup.cpp (revision 14316) +++ src/app/legend/qgslegendgroup.cpp (working copy) @@ -57,47 +57,10 @@ {} -bool QgsLegendGroup::isLeafNode() -{ - return mLeafNodeFlag; -} - -QgsLegendItem::DRAG_ACTION QgsLegendGroup::accept( LEGEND_ITEM_TYPE type ) -{ - if ( type == LEGEND_GROUP ) - { - return REORDER; - } - if ( type == LEGEND_LAYER ) - { - return INSERT; - } - else - { - return NO_ACTION; - } -} - -QgsLegendItem::DRAG_ACTION QgsLegendGroup::accept( const QgsLegendItem* li ) const -{ - if ( li ) - { - LEGEND_ITEM_TYPE type = li->type(); - if ( type == LEGEND_GROUP ) - { - return REORDER; - } - if ( type == LEGEND_LAYER ) - { - return INSERT; - } - } - return NO_ACTION; -} - bool QgsLegendGroup::insert( QgsLegendItem* theItem ) { - if ( theItem->type() == LEGEND_LAYER ) + if ( theItem->type() == LEGEND_GROUP || + theItem->type() == LEGEND_LAYER ) { // Always insert at top of list insertChild( 0, theItem ); @@ -107,33 +70,53 @@ return true; } -std::list QgsLegendGroup::legendLayers() +QList QgsLegendGroup::legendLayers( bool recurse ) { - std::list result; + QList result; for ( int i = 0; i < childCount(); ++i ) { - QgsLegendLayer* childItem = dynamic_cast( child( i ) ); - if ( childItem ) + QgsLegendLayer *layer = dynamic_cast( child( i ) ); + if ( layer ) { - result.push_back( childItem ); + result.push_back( layer ); } + + if ( !recurse ) + continue; + + QgsLegendGroup *group = dynamic_cast( child( i ) ); + if ( group ) + { + result << group->legendLayers( true ); + } } return result; } void QgsLegendGroup::updateCheckState() { - std::list llayers = legendLayers(); - if ( llayers.size() == 0 ) + QList elements; + + for ( int i = 0; i < childCount(); i++ ) { - return; + QgsLegendItem *li = dynamic_cast( child( i ) ); + + if ( !li ) + continue; + + if ( dynamic_cast( li ) || dynamic_cast( li ) ) + { + elements << li; + } } - std::list::iterator iter = llayers.begin(); - Qt::CheckState theState = ( *iter )->checkState( 0 ); - for ( ; iter != llayers.end(); ++iter ) + if ( elements.isEmpty() ) + return; + + Qt::CheckState theState = elements[0]->checkState( 0 ); + foreach( QgsLegendItem *li, elements ) { - if ( theState != ( *iter )->checkState( 0 ) ) + if ( theState != li->checkState( 0 ) ) { theState = Qt::PartiallyChecked; break; Index: src/app/legend/qgslegendgroup.h =================================================================== --- src/app/legend/qgslegendgroup.h (revision 14316) +++ src/app/legend/qgslegendgroup.h (working copy) @@ -37,12 +37,9 @@ QgsLegendGroup( QString name ); ~QgsLegendGroup(); - 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 layers under this group*/ - std::list legendLayers(); + /**Returns all legend layers under this group (including those of subgroups by default)*/ + QList legendLayers( bool recurse = true ); /**Goes through all the legendlayers and sets check state to checked/partially checked/unchecked*/ void updateCheckState(); }; Index: src/app/legend/qgslegendsymbologygroup.cpp =================================================================== --- src/app/legend/qgslegendsymbologygroup.cpp (revision 14316) +++ src/app/legend/qgslegendsymbologygroup.cpp (working copy) @@ -37,16 +37,6 @@ QgsLegendSymbologyGroup::~QgsLegendSymbologyGroup() {} -QgsLegendItem::DRAG_ACTION QgsLegendSymbologyGroup::accept( LEGEND_ITEM_TYPE type ) -{ - return NO_ACTION; -} - -QgsLegendItem::DRAG_ACTION QgsLegendSymbologyGroup::accept( const QgsLegendItem* li ) const -{ - return NO_ACTION; -} - /** Overloads cmpare function of QListViewItem * @note The symbology group must always be the second in the list */ Index: src/app/legend/qgslegendpropertygroup.cpp =================================================================== --- src/app/legend/qgslegendpropertygroup.cpp (revision 14316) +++ src/app/legend/qgslegendpropertygroup.cpp (working copy) @@ -37,14 +37,3 @@ { } - -QgsLegendItem::DRAG_ACTION QgsLegendPropertyGroup::accept( LEGEND_ITEM_TYPE type ) -{ - return NO_ACTION; -} - -QgsLegendItem::DRAG_ACTION QgsLegendPropertyGroup::accept( const QgsLegendItem* li ) const -{ - return NO_ACTION; -} - Index: src/app/legend/qgslegendpropertyitem.cpp =================================================================== --- src/app/legend/qgslegendpropertyitem.cpp (revision 14316) +++ src/app/legend/qgslegendpropertyitem.cpp (working copy) @@ -34,15 +34,3 @@ { mType = LEGEND_PROPERTY_ITEM; } - -QgsLegendItem::DRAG_ACTION QgsLegendPropertyItem::accept( LEGEND_ITEM_TYPE type ) -{ - return NO_ACTION; -} - -QgsLegendItem::DRAG_ACTION QgsLegendPropertyItem::accept( const QgsLegendItem* li ) const -{ - return NO_ACTION; -} - - Index: src/app/legend/qgslegenditem.h =================================================================== --- src/app/legend/qgslegenditem.h (revision 14316) +++ src/app/legend/qgslegenditem.h (working copy) @@ -1,6 +1,6 @@ /*************************************************************************** - * Copyright (C) 2005 by Tim Sutton * - * aps02ts@macbuntu * + * 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 * @@ -62,13 +62,8 @@ NO_ACTION //do nothing }; - virtual bool isLeafNode() = 0; virtual LEGEND_ITEM_TYPE type() const {return mType;} - /**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; - /**Retrns the type of action that will be done if a legend item is dragged over this item*/ - virtual DRAG_ACTION accept( const QgsLegendItem* li ) const = 0; + /**Subclasses which allow insertion of other items may implement this method. @param theItem legend item to insert into this item @param changesettings Some insert actions may change the state of the layers or the map canvas. @@ -111,7 +106,6 @@ virtual void release( QgsLegendItem* formerChild ) {} protected: - bool mLeafNodeFlag; LEGEND_ITEM_TYPE mType; /**Stores expanded property when storeAppearanceSettings is called*/ bool mExpanded; Index: src/app/legend/qgslegendsymbologyitem.cpp =================================================================== --- src/app/legend/qgslegendsymbologyitem.cpp (revision 14316) +++ src/app/legend/qgslegendsymbologyitem.cpp (working copy) @@ -49,16 +49,6 @@ } } -QgsLegendItem::DRAG_ACTION QgsLegendSymbologyItem::accept( LEGEND_ITEM_TYPE type ) -{ - return NO_ACTION; -} - -QgsLegendItem::DRAG_ACTION QgsLegendSymbologyItem::accept( const QgsLegendItem* li ) const -{ - return NO_ACTION; -} - void QgsLegendSymbologyItem::setLegend( QgsLegend* theLegend ) { mLegend = theLegend; Index: src/app/qgsrasterlayerproperties.cpp =================================================================== --- src/app/qgsrasterlayerproperties.cpp (revision 14316) +++ src/app/qgsrasterlayerproperties.cpp (working copy) @@ -1887,7 +1887,6 @@ myGraphType = BAR_CHART; bool myIgnoreOutOfRangeFlag = true; bool myThoroughBandScanFlag = false; - int myLastBinWithData = 0; int myBandCountInt = mRasterLayer->bandCount(); QList myColors; myColors << Qt::black << Qt::red << Qt::green << Qt::blue << Qt::magenta << Qt::darkRed << Qt::darkGreen << Qt::darkBlue; Index: src/app/qgsvectorlayerproperties.cpp =================================================================== --- src/app/qgsvectorlayerproperties.cpp (revision 14316) +++ src/app/qgsvectorlayerproperties.cpp (working copy) @@ -289,6 +289,12 @@ void QgsVectorLayerProperties::toggleEditing() { emit toggleEditing( layer ); + + pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() && !layer->isEditable() ); + if ( layer->isEditable() ) + { + pbnQueryBuilder->setToolTip( tr( "Stop editing mode to enable this." ) ); + } } void QgsVectorLayerProperties::attributeAdded( int idx ) @@ -462,7 +468,11 @@ // on the builder. If the ability to enter a query directly into the box is required, // a mechanism to check it must be implemented. txtSubsetSQL->setEnabled( false ); - pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() ); + pbnQueryBuilder->setEnabled( layer && layer->dataProvider() && layer->dataProvider()->supportsSubsetString() && !layer->isEditable() ); + if ( layer->isEditable() ) + { + pbnQueryBuilder->setToolTip( tr( "Stop editing mode to enable this." ) ); + } //get field list for display field combo const QgsFieldMap& myFields = layer->pendingFields(); Index: src/app/qgisapp.cpp =================================================================== --- src/app/qgisapp.cpp (revision 14317) +++ src/app/qgisapp.cpp (working copy) @@ -5955,7 +5955,7 @@ if ( layer->type() == QgsMapLayer::VectorLayer ) { QgsVectorLayer* vlayer = qobject_cast( layer ); - const QgsVectorDataProvider* dprovider = vlayer->dataProvider(); + QgsVectorDataProvider* dprovider = vlayer->dataProvider(); bool layerHasSelection = vlayer->selectedFeatureCount() != 0; mActionSelect->setEnabled( true ); @@ -5969,7 +5969,6 @@ mActionLayerSaveAs->setEnabled( true ); mActionLayerSelectionSaveAs->setEnabled( true ); mActionCopyFeatures->setEnabled( layerHasSelection ); - mActionLayerSubsetString->setEnabled( true ); if ( !vlayer->isEditable() && mMapCanvas->mapTool() && mMapCanvas->mapTool()->isEditTool() ) { @@ -5978,6 +5977,8 @@ if ( dprovider ) { + mActionLayerSubsetString->setEnabled( dprovider->supportsSubsetString() && !vlayer->isEditable() ); + //start editing/stop editing if ( dprovider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) { @@ -6176,6 +6177,8 @@ } return; } + + mActionLayerSubsetString->setEnabled( false ); } /*************Raster layers*************/ else if ( layer->type() == QgsMapLayer::RasterLayer ) Index: src/gui/qgslegendinterface.h =================================================================== --- src/gui/qgslegendinterface.h (revision 14316) +++ src/gui/qgslegendinterface.h (working copy) @@ -74,7 +74,6 @@ virtual bool isLayerVisible( QgsMapLayer * ml ) = 0; signals: - //! emitted when a group index has changed void groupIndexChanged( int oldIndex, int newIndex ); Index: src/gui/qgsprojectbadlayerguihandler.cpp =================================================================== --- src/gui/qgsprojectbadlayerguihandler.cpp (revision 14316) +++ src/gui/qgsprojectbadlayerguihandler.cpp (working copy) @@ -13,10 +13,8 @@ { } - void QgsProjectBadLayerGuiHandler::handleBadLayers( QList layers, QDomDocument projectDom ) { - QgsDebugMsg( QString( "%1 bad layers found" ).arg( layers.size() ) ); // make sure we have arrow cursor (and not a wait cursor) @@ -39,7 +37,6 @@ QApplication::restoreOverrideCursor(); } - QgsProjectBadLayerGuiHandler::DataType QgsProjectBadLayerGuiHandler::dataType( QDomNode & layerNode ) { QString type = layerNode.toElement().attribute( "type" ); Index: src/mapserver/qgsprojectparser.cpp =================================================================== --- src/mapserver/qgsprojectparser.cpp (revision 14316) +++ src/mapserver/qgsprojectparser.cpp (working copy) @@ -36,7 +36,6 @@ void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const { QList layerElems = projectLayerElements(); - QgsMapLayer* currentLayer = 0; QStringList nonIdentifiableLayers = identifyDisabledLayers(); @@ -45,6 +44,28 @@ return; } + QMap layerMap; + + QList::const_iterator layerIt = layerElems.constBegin(); + for ( ; layerIt != layerElems.constEnd(); ++layerIt ) + { + QgsMapLayer *layer = createLayerFromElement( *layerIt ); + if ( layer ) + { + QgsMSDebugMsg( QString( "add layer %1 to map" ).arg( layer->getLayerID() ) ); + layerMap.insert( layer->getLayerID(), layer ); + } +#if QGSMSDEBUG + else + { + QString buf; + QTextStream s( &buf ); + layerIt->save( s, 0 ); + QgsMSDebugMsg( QString( "layer %1 not found" ).arg( buf ) ); + } +#endif + } + //According to the WMS spec, there can be only one toplevel layer. //So we create an artificial one here to be in accordance with the schema QString projTitle = projectTitle(); @@ -57,7 +78,6 @@ QDomText layerParentTitleText = doc.createTextNode( projTitle ); layerParentTitleElem.appendChild( layerParentTitleText ); layerParentElem.appendChild( layerParentTitleElem ); - parentElement.appendChild( layerParentElem ); //Map rectangle. If not empty, this will be set for every layer (instead of the bbox that comes from the data) QgsRectangle mapExtent = mapRectangle(); @@ -72,22 +92,110 @@ } } - QMap< QString, QDomElement > layerElemMap; //key: layer id, value: layer dom element ( used to apply legend groups ) + QDomElement legendElem = mXMLDoc->documentElement().firstChildElement( "legend" ); - QList::const_iterator layerIt = layerElems.constBegin(); - for ( ; layerIt != layerElems.constEnd(); ++layerIt ) + addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers, mapExtent, mapCRS ); + + parentElement.appendChild( layerParentElem ); +} + +void QgsProjectParser::addLayers( QDomDocument &doc, + QDomElement &parentElem, + const QDomElement &legendElem, + const QMap &layerMap, + const QStringList &nonIdentifiableLayers, + const QgsRectangle &mapExtent, + const QgsCoordinateReferenceSystem &mapCRS ) const +{ + QDomNodeList legendChildren = legendElem.childNodes(); + for ( int i = 0; i < legendChildren.size(); ++i ) { - currentLayer = createLayerFromElement( *layerIt ); - if ( currentLayer ) + QDomElement currentChildElem = legendChildren.at( i ).toElement(); + + QDomElement layerElem = doc.createElement( "Layer" ); + + if ( currentChildElem.tagName() == "legendgroup" ) { - QDomElement currentLayerElem = doc.createElement( "Layer" ); + QString name = currentChildElem.attribute( "name" ); + QDomElement nameElem = doc.createElement( "Name" ); + QDomText nameText = doc.createTextNode( name ); + nameElem.appendChild( nameText ); + layerElem.appendChild( nameElem ); + + QDomElement titleElem = doc.createElement( "Title" ); + QDomText titleText = doc.createTextNode( name ); + titleElem.appendChild( titleText ); + layerElem.appendChild( titleElem ); + + addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, mapExtent, mapCRS ); + + // combine bounding boxes of childs (groups/layers) + + QgsRectangle combinedGeographicBBox; + QSet combinedCRSSet; + bool firstBBox = true; + bool firstCRSSet = true; + + QDomNodeList layerChildren = layerElem.childNodes(); + for ( int j = 0; j < layerChildren.size(); ++j ) + { + QDomElement childElem = layerChildren.at( j ).toElement(); + + if ( childElem.tagName() != "Layer" ) + continue; + + QgsRectangle bbox; + if ( exGeographicBoundingBox( childElem, bbox ) ) + { + if ( firstBBox ) + { + combinedGeographicBBox = bbox; + firstBBox = false; + } + else + { + combinedGeographicBBox.combineExtentWith( &bbox ); + } + } + + //combine crs set + QSet crsSet; + if ( crsSetForLayer( childElem, crsSet ) ) + { + if ( firstCRSSet ) + { + combinedCRSSet = crsSet; + firstCRSSet = false; + } + else + { + combinedCRSSet.intersect( crsSet ); + } + } + } + + appendCRSElementsToLayer( layerElem, doc, combinedCRSSet.toList() ); + + const QgsCoordinateReferenceSystem& groupCRS = QgsEPSGCache::instance()->searchCRS( 4326 ); + appendExGeographicBoundingBox( layerElem, doc, combinedGeographicBBox, groupCRS ); + } + else if ( currentChildElem.tagName() == "legendlayer" ) + { + QString id = layerIdFromLegendLayer( currentChildElem ); + QgsMapLayer *currentLayer = layerMap[ id ]; + if ( !currentLayer ) + { + QgsMSDebugMsg( QString( "layer %1 not found" ).arg( id ) ); + continue; + } + if ( nonIdentifiableLayers.contains( currentLayer->getLayerID() ) ) { - currentLayerElem.setAttribute( "queryable", "0" ); + layerElem.setAttribute( "queryable", "0" ); } else { - currentLayerElem.setAttribute( "queryable", "1" ); + layerElem.setAttribute( "queryable", "1" ); } QDomElement nameElem = doc.createElement( "Name" ); @@ -95,29 +203,28 @@ //Because the id sometimes contains user/pw information and the name is more descriptive QDomText nameText = doc.createTextNode( currentLayer->name() ); nameElem.appendChild( nameText ); - currentLayerElem.appendChild( nameElem ); + layerElem.appendChild( nameElem ); QDomElement titleElem = doc.createElement( "Title" ); QDomText titleText = doc.createTextNode( currentLayer->name() ); titleElem.appendChild( titleText ); - currentLayerElem.appendChild( titleElem ); + layerElem.appendChild( titleElem ); QDomElement abstractElem = doc.createElement( "Abstract" ); - currentLayerElem.appendChild( abstractElem ); + layerElem.appendChild( abstractElem ); //CRS QList crsList = createCRSListForLayer( currentLayer ); - appendCRSElementsToLayer( currentLayerElem, doc, crsList ); - layerElemMap.insert( currentLayer->getLayerID(), currentLayerElem ); + appendCRSElementsToLayer( layerElem, doc, crsList ); //Ex_GeographicBoundingBox if ( mapExtent.isEmpty() ) { - appendExGeographicBoundingBox( currentLayerElem, doc, currentLayer->extent(), currentLayer->srs() ); + appendExGeographicBoundingBox( layerElem, doc, currentLayer->extent(), currentLayer->srs() ); } else { - appendExGeographicBoundingBox( currentLayerElem, doc, mapExtent, mapCRS ); + appendExGeographicBoundingBox( layerElem, doc, mapExtent, mapCRS ); } //only one default style in project file mode @@ -130,118 +237,27 @@ styleTitleElem.appendChild( styleTitleText ); styleElem.appendChild( styleNameElem ); styleElem.appendChild( styleTitleElem ); - currentLayerElem.appendChild( styleElem ); + layerElem.appendChild( styleElem ); } - } - - //apply legend settings (groups and layer in proper order) - QList< GroupLayerInfo > groupLayerRelationship = groupLayerRelationshipFromProject(); - QList< GroupLayerInfo >::const_iterator groupIt = groupLayerRelationship.constBegin(); - QDomElement layerElem; - QString entryName; - QList< QString > layerIdList; - - for ( ; groupIt != groupLayerRelationship.constEnd(); ++groupIt ) - { - entryName = groupIt->first; - layerIdList = groupIt->second; - if ( layerIdList.isEmpty() ) + else { + QgsMSDebugMsg( "unexpected child element" ); continue; } - if ( entryName.isNull() ) //a toplevel layer - { - layerElem = layerElemMap.take( layerIdList.first() ); - if ( !layerElem.isNull() ) - { - layerParentElem.appendChild( layerElem ); - } - } - else //a group - { - QDomElement layerGroupElem = doc.createElement( "Layer" ); - //name - QDomElement groupNameElem = doc.createElement( "Name" ); - QDomText groupNameText = doc.createTextNode( entryName ); - groupNameElem.appendChild( groupNameText ); - layerGroupElem.appendChild( groupNameElem ); - //title - QDomElement groupTitleElem = doc.createElement( "Title" ); - QDomText groupTitleText = doc.createTextNode( entryName ); - groupTitleElem.appendChild( groupTitleText ); - layerGroupElem.appendChild( groupTitleElem ); - QgsRectangle combinedGeographicBBox; - QSet combinedCRSSet; - bool firstBBox = true; - bool firstCRSSet = true; +#if QGSMSDEBUG + QString buf; + QTextStream s( &buf ); + layerElem.save( s, 0 ); + QgsMSDebugMsg( QString( "adding layer: %1" ).arg( buf ) ); +#endif - QList childLayerList; - - QList< QString >::const_iterator layerIt = layerIdList.constBegin(); - for ( ; layerIt != layerIdList.constEnd(); ++layerIt ) - { - layerElem = layerElemMap.take( *layerIt ); - QgsRectangle layerBBox; - QSet layerCRSSet; - - if ( !layerElem.isNull() ) - { - //combine layer bbox with group bbox - if ( exGeographicBoundingBox( layerElem, layerBBox ) ) - { - if ( firstBBox ) - { - combinedGeographicBBox = layerBBox; - firstBBox = false; - } - else - { - combinedGeographicBBox.combineExtentWith( &layerBBox ); - } - } - - //combine crs set - if ( crsSetForLayer( layerElem, layerCRSSet ) ) - { - if ( firstCRSSet ) - { - combinedCRSSet = layerCRSSet; - firstCRSSet = false; - } - else - { - combinedCRSSet.intersect( layerCRSSet ); - } - } - - //and insert layer element under this group element - //layerGroupElem.appendChild( layerElem ); - childLayerList.append( layerElem ); - } - } - - //write CRS elements - appendCRSElementsToLayer( layerGroupElem, doc, combinedCRSSet.toList() ); - - //write group EX_GeographicBoundingBox - const QgsCoordinateReferenceSystem& groupCRS = QgsEPSGCache::instance()->searchCRS( 4326 ); - appendExGeographicBoundingBox( layerGroupElem, doc, combinedGeographicBBox, groupCRS ); - - //append child layer elements - QList::const_iterator childIt = childLayerList.constBegin(); - for ( ; childIt != childLayerList.constEnd(); ++childIt ) - { - layerGroupElem.appendChild( *childIt ); - } - - //and append Layer element of the group to the document - layerParentElem.appendChild( layerGroupElem ); - } + parentElem.appendChild( layerElem ); } } + QList QgsProjectParser::mapLayerFromStyle( const QString& lName, const QString& styleName, bool allowCaching ) const { QList layerList; Index: src/mapserver/qgsgetrequesthandler.cpp =================================================================== --- src/mapserver/qgsgetrequesthandler.cpp (revision 14316) +++ src/mapserver/qgsgetrequesthandler.cpp (working copy) @@ -24,7 +24,7 @@ if ( qs ) { queryString = QString( qs ); - QgsMSDebugMsg( "qgsgetrequesthandler.cpp: query string is: " + queryString ) + QgsMSDebugMsg( "query string is: " + queryString ) } else { @@ -80,7 +80,7 @@ } parameters.insert( std::make_pair( key.toUpper(), value ) ); - QgsMSDebugMsg( "qgsgetrequesthandler.cpp: inserting pair " + key.toUpper() + " // " + value + " into the parameter map" ) + QgsMSDebugMsg( "inserting pair " + key.toUpper() + " // " + value + " into the parameter map" ) } //feature info format? @@ -160,7 +160,6 @@ void QgsGetRequestHandler::sendGetFeatureInfoResponse( const QDomDocument& infoDoc, const QString& infoFormat ) const { QByteArray ba; - QgsMSDebugMsg( "In sendGetFeatureInfoResponse" ) QgsMSDebugMsg( "Info format is:" + infoFormat ) if ( infoFormat == "text/xml" ) Index: src/mapserver/qgsremoteowsbuilder.cpp =================================================================== --- src/mapserver/qgsremoteowsbuilder.cpp (revision 14316) +++ src/mapserver/qgsremoteowsbuilder.cpp (working copy) @@ -88,7 +88,7 @@ if ( serviceName == "WFS" ) { - //support for old format where type is explicitely given and not part of url + //support for old format where type is explicitly given and not part of url QString tname = onlineResourceElement.attribute( "type" ); if ( !tname.isEmpty() ) { @@ -145,7 +145,7 @@ QgsRasterLayer* QgsRemoteOWSBuilder::wmsLayerFromUrl( const QString& url, const QString& layerName, QList& layersToRemove, bool allowCaching ) const { - QgsMSDebugMsg( "Entering QgsRemoteOWSBuilder::::wmsLayerFromUrl" ) + QgsMSDebugMsg( "Entering" ) QgsRasterLayer* result = 0; QString baseUrl, format, crs; QStringList layerList, styleList; @@ -219,7 +219,7 @@ QgsRasterLayer* QgsRemoteOWSBuilder::wcsLayerFromUrl( const QString& url, const QString& layerName, QList& filesToRemove, QList& layersToRemove, bool allowCaching ) const { - QgsMSDebugMsg( "Entering QgsRemoteOWSBuilder::wcsLayerFromUrl" ) + QgsMSDebugMsg( "Entering" ) //write server url and coverage name to a temporary file QString fileName = createTempFile(); Index: src/mapserver/qgswmsserver.cpp =================================================================== --- src/mapserver/qgswmsserver.cpp (revision 14316) +++ src/mapserver/qgswmsserver.cpp (working copy) @@ -44,7 +44,10 @@ #include #include -QgsWMSServer::QgsWMSServer( std::map parameters, QgsMapRenderer* renderer ): mParameterMap( parameters ), mConfigParser( 0 ), mMapRenderer( renderer ) +QgsWMSServer::QgsWMSServer( std::map parameters, QgsMapRenderer* renderer ) + : mParameterMap( parameters ) + , mConfigParser( 0 ) + , mMapRenderer( renderer ) { } @@ -58,7 +61,7 @@ QDomDocument QgsWMSServer::getCapabilities() { - QgsMSDebugMsg( "Entering QgsWMSServer::getCapabilities" ) + QgsMSDebugMsg( "Entering." ) QDomDocument doc; //wms:WMS_Capabilities element QDomElement wmsCapabilitiesElement = doc.createElement( "WMS_Capabilities"/*wms:WMS_Capabilities*/ ); @@ -72,7 +75,7 @@ if ( !wmsService.open( QIODevice::ReadOnly ) ) { //throw an exception... - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: external wms service capabilities not found" ) + QgsMSDebugMsg( "external wms service capabilities not found" ) } else { @@ -81,7 +84,7 @@ int errorLineNo; if ( !externServiceDoc.setContent( &wmsService, false, &parseError, &errorLineNo ) ) { - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: parse error at setting content of external wms service capabilities: "\ + QgsMSDebugMsg( "parse error at setting content of external wms service capabilities: " + parseError + " at line " + QString::number( errorLineNo ) ) wmsService.close(); } @@ -196,9 +199,6 @@ getFeatureInfoElem.appendChild( getFeatureInfoDhcTypeElement ); requestElement.appendChild( getFeatureInfoElem ); - - - //Exception element is mandatory QDomElement exceptionElement = doc.createElement( "Exception" ); QDomElement exFormatElement = doc.createElement( "Format" ); @@ -208,9 +208,9 @@ capabilityElement.appendChild( exceptionElement ); //add the xml content for the individual layers/styles - QgsMSDebugMsg( "Entering layersAndStylesCapabilities" ) + QgsMSDebugMsg( "calling layersAndStylesCapabilities" ) mConfigParser->layersAndStylesCapabilities( capabilityElement, doc ); - QgsMSDebugMsg( "Entering layersAndStylesCapabilities" ) + QgsMSDebugMsg( "layersAndStylesCapabilities returned" ) //for debugging: save the document to disk QFile capabilitiesFile( "/tmp/capabilities.txt" ); @@ -233,7 +233,7 @@ if ( readLayersAndStyles( layersList, stylesList ) != 0 ) { - QgsMSDebugMsg( "QgsWMSServer: error reading layers and styles" ) + QgsMSDebugMsg( "error reading layers and styles" ) return 0; } @@ -290,7 +290,7 @@ QgsComposerLayerItem* layerItem = dynamic_cast( rootItem->child( i ) ); if ( layerItem ) { - drawLegendLayerItem( layerItem, 0, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace, \ + drawLegendLayerItem( layerItem, 0, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 ); } } @@ -309,7 +309,7 @@ QgsComposerLayerItem* layerItem = dynamic_cast( rootItem->child( i ) ); if ( layerItem ) { - drawLegendLayerItem( layerItem, &p, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace, \ + drawLegendLayerItem( layerItem, &p, maxX, currentY, layerFont, itemFont, boxSpace, layerSpace, symbolSpace, iconLabelSpace, symbolWidth, symbolHeight, fontOversamplingFactor, theImage->dotsPerMeterX() * 0.0254 ); } } @@ -341,7 +341,7 @@ QImage* QgsWMSServer::getMap() { - QgsMSDebugMsg( "Entering QgsWMSServer::getMap" ) + QgsMSDebugMsg( "Entering" ) if ( !mConfigParser ) { QgsMSDebugMsg( "Error: mSLDParser is 0" ) @@ -359,7 +359,7 @@ if ( readLayersAndStyles( layersList, stylesList ) != 0 ) { - QgsMSDebugMsg( "QgsWMSServer: error reading layers and styles" ) + QgsMSDebugMsg( "error reading layers and styles" ) return 0; } @@ -653,7 +653,9 @@ std::map::const_iterator formatIt = mParameterMap.find( "FORMAT" ); if ( formatIt != mParameterMap.end() ) { - if ( formatIt->second.compare( "jpg", Qt::CaseInsensitive ) == 0 || formatIt->second.compare( "jpeg", Qt::CaseInsensitive ) == 0 || formatIt->second.compare( "image/jpeg", Qt::CaseInsensitive ) == 0 ) + if ( formatIt->second.compare( "jpg", Qt::CaseInsensitive ) == 0 + || formatIt->second.compare( "jpeg", Qt::CaseInsensitive ) == 0 + || formatIt->second.compare( "image/jpeg", Qt::CaseInsensitive ) == 0 ) { jpeg = true; } @@ -876,7 +878,7 @@ return 0; } -int QgsWMSServer::infoPointToLayerCoordinates( int i, int j, QgsPoint& layerCoords, QgsMapRenderer* mapRender, \ +int QgsWMSServer::infoPointToLayerCoordinates( int i, int j, QgsPoint& layerCoords, QgsMapRenderer* mapRender, QgsMapLayer* layer ) const { if ( !mapRender || !layer || !mapRender->coordinateTransform() ) @@ -891,8 +893,14 @@ return 0; } -int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer, const QgsPoint& infoPoint, int nFeatures, QDomDocument& infoDocument, QDomElement& layerElement, QgsMapRenderer* mapRender, \ - QMap& aliasMap, QSet& hiddenAttributes ) const +int QgsWMSServer::featureInfoFromVectorLayer( QgsVectorLayer* layer, + const QgsPoint& infoPoint, + int nFeatures, + QDomDocument& infoDocument, + QDomElement& layerElement, + QgsMapRenderer* mapRender, + QMap& aliasMap, + QSet& hiddenAttributes ) const { if ( !layer || !mapRender ) { @@ -903,7 +911,7 @@ QgsRectangle mapRect = mapRender->extent(); QgsRectangle layerRect = mapRender->mapToLayerCoordinates( layer, mapRect ); double searchRadius = ( layerRect.xMaximum() - layerRect.xMinimum() ) / 200; - QgsRectangle searchRect( infoPoint.x() - searchRadius, infoPoint.y() - searchRadius, \ + QgsRectangle searchRect( infoPoint.x() - searchRadius, infoPoint.y() - searchRadius, infoPoint.x() + searchRadius, infoPoint.y() + searchRadius ); //do a select with searchRect and go through all the features @@ -971,7 +979,10 @@ return 0; } -int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer, const QgsPoint& infoPoint, QDomDocument& infoDocument, QDomElement& layerElement ) const +int QgsWMSServer::featureInfoFromRasterLayer( QgsRasterLayer* layer, + const QgsPoint& infoPoint, + QDomDocument& infoDocument, + QDomElement& layerElement ) const { if ( !layer ) { @@ -991,7 +1002,9 @@ return 0; } -QStringList QgsWMSServer::layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS ) const +QStringList QgsWMSServer::layerSet( const QStringList& layersList, + const QStringList& stylesList, + const QgsCoordinateReferenceSystem& destCRS ) const { QStringList layerKeys; QStringList::const_iterator llstIt; @@ -1046,9 +1059,9 @@ return layerKeys; } -void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxX, double& currentY, const QFont& layerFont, \ - const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace, \ - double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor, \ +void QgsWMSServer::drawLegendLayerItem( QgsComposerLayerItem* item, QPainter* p, double& maxX, double& currentY, const QFont& layerFont, + const QFont& itemFont, double boxSpace, double layerSpace, double symbolSpace, + double iconLabelSpace, double symbolWidth, double symbolHeight, double fontOversamplingFactor, double dpi ) const { if ( !item ) @@ -1138,7 +1151,7 @@ { p->save(); p->scale( 1.0 / fontOversamplingFactor, 1.0 / fontOversamplingFactor ); - p->drawText(( boxSpace + currentSymbolWidth + iconLabelSpace ) * fontOversamplingFactor, \ + p->drawText(( boxSpace + currentSymbolWidth + iconLabelSpace ) * fontOversamplingFactor, ( currentY + symbolItemHeight / 2.0 ) * fontOversamplingFactor + itemFontMetrics.ascent() / 2.0, currentComposerItem->text() ); p->restore(); } @@ -1154,7 +1167,7 @@ } } -void QgsWMSServer::drawLegendSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, \ +void QgsWMSServer::drawLegendSymbol( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double& symbolWidth, double& symbolHeight, double layerOpacity, double dpi, double yDownShift ) const { if ( !p ) @@ -1262,7 +1275,7 @@ p->restore(); } -void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, \ +void QgsWMSServer::drawLegendSymbolV2( QgsComposerLegendItem* item, QPainter* p, double boxSpace, double currentY, double symbolWidth, double symbolHeight, double dpi, double yDownShift ) const { if ( !p ) @@ -1313,7 +1326,8 @@ p->setPen( QPen( Qt::NoPen ) ); QgsRasterLayer::DrawingStyle drawingStyle = layer->drawingStyle(); - if ( drawingStyle == QgsRasterLayer::SingleBandGray || drawingStyle == QgsRasterLayer::PalettedSingleBandGray \ + if ( drawingStyle == QgsRasterLayer::SingleBandGray + || drawingStyle == QgsRasterLayer::PalettedSingleBandGray || drawingStyle == QgsRasterLayer::MultiBandSingleGandGray ) { int grayValue = 0; Index: src/mapserver/qgsmapserverlogger.h =================================================================== --- src/mapserver/qgsmapserverlogger.h (revision 14316) +++ src/mapserver/qgsmapserverlogger.h (working copy) @@ -22,7 +22,7 @@ #include #ifdef QGSMSDEBUG -#define QgsMSDebugMsg(str) QgsMapServerLogger::instance()->printMessage(str); +#define QgsMSDebugMsg(str) QgsMapServerLogger::instance()->printMessage(__FILE__, __FUNCTION__, __LINE__, str); #else #define QgsMSDebugMsg(str) #endif @@ -41,6 +41,10 @@ void printMessage( const QString& message ); /**Prints only one char*/ void printChar( QChar c ); +#ifdef QGSMSDEBUG + /**Print a message to the Logfile*/ + void printMessage( const char *file, const char *function, int line, const QString& message ); +#endif private: static QgsMapServerLogger* mInstance; QgsMapServerLogger(); Index: src/mapserver/CMakeLists.txt =================================================================== --- src/mapserver/CMakeLists.txt (revision 14316) +++ src/mapserver/CMakeLists.txt (working copy) @@ -6,17 +6,12 @@ MESSAGE (SEND_ERROR "Fast CGI dependency was not found!") ENDIF (NOT FCGI_FOUND) -# We need to define the qgis base dir so we can pass it -# into the main entry point for the app so that at -# runtime it can find plugins and srs.db etc -ADD_DEFINITIONS(-DQGIS_LIB_DIR="\\"${QGIS_LIB_DIR}\\"") +ADD_DEFINITIONS(-DDIAGRAMSERVER=1) -#MH: for this we need to locate the headers of the diagram and interpolation plugin -#ADD_DEFINITIONS(-DDIAGRAMSERVER=1) - IF (CMAKE_BUILD_TYPE MATCHES Debug) ADD_DEFINITIONS(-DQGSMSDEBUG=1) ENDIF (CMAKE_BUILD_TYPE MATCHES Debug) + ######################################################## # Files @@ -49,6 +44,15 @@ qgsremotedatasourcebuilder.cpp qgssentdatasourcebuilder.cpp qgsmsutils.cpp + + ../plugins/diagram_overlay/qgsdiagramcategory.cpp + ../plugins/diagram_overlay/qgsdiagramfactory.cpp + ../plugins/diagram_overlay/qgswkndiagramfactory.cpp + ../plugins/diagram_overlay/qgsbardiagramfactory.cpp + ../plugins/diagram_overlay/qgspiediagramfactory.cpp + ../plugins/diagram_overlay/qgssvgdiagramfactory.cpp + ../plugins/diagram_overlay/qgsdiagramoverlay.cpp + ../plugins/diagram_overlay/qgsdiagramrenderer.cpp ) # SET (qgis_mapserv_UIS @@ -93,6 +97,7 @@ ../core/symbology-ng ../core/composer ../analysis/interpolation + ../plugins/diagram_overlay . ) Index: src/mapserver/qgis_map_serv.cpp =================================================================== --- src/mapserver/qgis_map_serv.cpp (revision 14316) +++ src/mapserver/qgis_map_serv.cpp (working copy) @@ -31,16 +31,12 @@ #include #include #include -#include -#include +#include //for CMAKE_INSTALL_PREFIX #include "qgsconfig.h" -#ifdef WIN32 -#include -#endif //WIN32 #include @@ -54,13 +50,7 @@ #ifdef QGSMSDEBUG //print out some infos about the request QgsMSDebugMsg( "************************new request**********************" ) - time_t t; - struct tm *currentTime; - time( &t ); - currentTime = localtime( &t ); - QgsMSDebugMsg( QString::number( currentTime->tm_year + 1900 ) + "/" \ - + QString::number( currentTime->tm_mon + 1 ) + "/" + QString::number( currentTime->tm_mday ) + ", " \ - + QString::number( currentTime->tm_hour ) + ":" + QString::number( currentTime->tm_min ) ) + QgsMSDebugMsg( QDateTime::currentDateTime().toString( "yyyy-mm-dd hh:mm:ss" ) ); if ( getenv( "REMOTE_ADDR" ) != NULL ) { @@ -115,10 +105,6 @@ int main( int argc, char * argv[] ) { - //#ifdef WIN32 //not needed any more since the QGIS mapserver uses a modified version of libfcgi - //_setmode(_fileno(FCGI_stdout->stdio_stream),_O_BINARY); //we need binary mode to print images to stdout on windows - //#endif - //close disturbing output chanels fclose( FCGI_stderr ); qInstallMsgHandler( dummyMessageHandler ); @@ -185,18 +171,18 @@ { if ( strcmp( requestMethod, "POST" ) == 0 ) { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Creating QgsSOAPRequestHandler" ) + QgsMSDebugMsg( "Creating QgsSOAPRequestHandler" ) theRequestHandler = new QgsSOAPRequestHandler(); } else { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Creating QgsGetRequestHandler" ) + QgsMSDebugMsg( "Creating QgsGetRequestHandler" ) theRequestHandler = new QgsGetRequestHandler(); } } else { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Creating QgsGetRequestHandler" ) + QgsMSDebugMsg( "Creating QgsGetRequestHandler" ) theRequestHandler = new QgsGetRequestHandler(); } @@ -208,7 +194,7 @@ } catch ( QgsMapServiceException& e ) { - QgsMSDebugMsg( "qgis_wms_serv.cpp: An exception was thrown during input parsing" ) + QgsMSDebugMsg( "An exception was thrown during input parsing" ) theRequestHandler->sendServiceException( e ); continue; } @@ -224,6 +210,7 @@ QgsConfigParser* adminConfigParser = configCache.searchConfiguration( configFilePath ); if ( !adminConfigParser ) { + QgsMSDebugMsg( "parse error on config file " + configFilePath ); theRequestHandler->sendServiceException( QgsMapServiceException( "", "Configuration file problem" ) ); continue; } @@ -236,7 +223,7 @@ if ( serviceIt == parameterMap.end() ) { //tell the user that service parameter is mandatory - QgsMSDebugMsg( "qgis_wms_serv.cpp: unable to find 'SERVICE' parameter, exiting..." ) + QgsMSDebugMsg( "unable to find 'SERVICE' parameter, exiting..." ) theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) ); delete theRequestHandler; continue; @@ -261,7 +248,7 @@ if ( requestIt == parameterMap.end() ) { //do some error handling - QgsMSDebugMsg( "qgis_wms_serv.cpp: unable to find 'REQUEST' parameter, exiting..." ) + QgsMSDebugMsg( "unable to find 'REQUEST' parameter, exiting..." ) theRequestHandler->sendServiceException( QgsMapServiceException( "OperationNotSupported", "Please check the value of the REQEST parameter" ) ); delete theRequestHandler; delete theServer; @@ -282,7 +269,7 @@ delete theServer; continue; } - QgsMSDebugMsg( "qgis_wms_serv.cpp: sending GetCapabilities response" ) + QgsMSDebugMsg( "sending GetCapabilities response" ) theRequestHandler->sendGetCapabilitiesResponse( capabilitiesDocument ); delete theRequestHandler; delete theServer; @@ -306,13 +293,13 @@ if ( result ) { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Sending GetMap response" ) + QgsMSDebugMsg( "Sending GetMap response" ) theRequestHandler->sendGetMapResponse( serviceIt->second, result ); } else { //do some error handling - QgsMSDebugMsg( "qgis_wms_serv.cpp: result image is 0" ) + QgsMSDebugMsg( "result image is 0" ) } delete result; delete theRequestHandler; @@ -382,13 +369,13 @@ if ( result ) { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Sending GetLegendGraphics response" ) + QgsMSDebugMsg( "Sending GetLegendGraphics response" ) //sending is the same for GetMap and GetLegendGraphics theRequestHandler->sendGetMapResponse( serviceIt->second, result ); } else { - QgsMSDebugMsg( "qgis_wms_serv.cpp: Error, 0 image in GetLegendGraphics" ) + QgsMSDebugMsg( "Error, 0 image in GetLegendGraphics" ) } delete result; delete theRequestHandler; Index: src/mapserver/qgsprojectparser.h =================================================================== --- src/mapserver/qgsprojectparser.h (revision 14316) +++ src/mapserver/qgsprojectparser.h (working copy) @@ -110,6 +110,14 @@ QList< GroupLayerInfo > groupLayerRelationshipFromProject() const; /**Returns the layer id under a tag in the QGIS projectfile*/ QString layerIdFromLegendLayer( const QDomElement& legendLayer ) const; + + void addLayers( QDomDocument &doc, + QDomElement &parentLayer, + const QDomElement &legendElem, + const QMap &layerMap, + const QStringList &nonIdentifiableLayers, + const QgsRectangle &mapExtent, + const QgsCoordinateReferenceSystem &mapCRS ) const; }; #endif // QGSPROJECTPARSER_H Index: src/mapserver/qgssentdatasourcebuilder.cpp =================================================================== --- src/mapserver/qgssentdatasourcebuilder.cpp (revision 14316) +++ src/mapserver/qgssentdatasourcebuilder.cpp (working copy) @@ -66,10 +66,10 @@ QgsVectorLayer* theVectorLayer = new QgsVectorLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ), "WFS" ); if ( !theVectorLayer || !theVectorLayer->isValid() ) { - QgsMSDebugMsg( "vectorLayerFromGML: invalid maplayer" ) + QgsMSDebugMsg( "invalid maplayer" ) return 0; } - QgsMSDebugMsg( "vectorLayerFromGML: returning maplayer" ) + QgsMSDebugMsg( "returning maplayer" ) layersToRemove.push_back( theVectorLayer ); //make sure the layer gets deleted after each request @@ -84,7 +84,7 @@ QgsRasterLayer* QgsSentDataSourceBuilder::rasterLayerFromSentRDS( const QDomElement& sentRDSElem, QList& filesToRemove, QList& layersToRemove ) const { - QgsMSDebugMsg( "Entering rasterLayerFromSentRDS" ) + QgsMSDebugMsg( "Entering" ) QString tempFilePath = createTempFile(); if ( tempFilePath.isEmpty() ) { Index: src/mapserver/qgssldparser.cpp =================================================================== --- src/mapserver/qgssldparser.cpp (revision 14316) +++ src/mapserver/qgssldparser.cpp (working copy) @@ -406,7 +406,7 @@ return 0; } - QgsMSDebugMsg( "Entering rendererFromUserStyle" ) + QgsMSDebugMsg( "Entering" ) QgsSLDRenderer* theRenderer = new QgsSLDRenderer( vec->geometryType() ); theRenderer->setScaleDenominator( mScaleDenominator ); @@ -437,7 +437,7 @@ bool QgsSLDParser::rasterSymbologyFromUserStyle( const QDomElement& userStyleElement, QgsRasterLayer* r ) const { - QgsMSDebugMsg( "Entering rasterSymbologyFromUserStyle" ) + QgsMSDebugMsg( "Entering" ) if ( !r ) { return false; @@ -978,7 +978,7 @@ int QgsSLDParser::layersAndStyles( QStringList& layers, QStringList& styles ) const { - QgsMSDebugMsg( "Entering QgsSLDParser::layersAndStyles" ) + QgsMSDebugMsg( "Entering." ) layers.clear(); styles.clear(); @@ -1074,7 +1074,7 @@ QgsMapLayer* QgsSLDParser::mapLayerFromUserLayer( const QDomElement& userLayerElem, const QString& layerName, bool allowCaching ) const { - QgsMSDebugMsg( "mapLayerFromUserLayer" ) + QgsMSDebugMsg( "Entering." ) QgsMSLayerBuilder* layerBuilder = 0; QDomElement builderRootElement; @@ -1190,7 +1190,7 @@ QgsVectorLayer* QgsSLDParser::vectorLayerFromGML( const QDomElement gmlRootElement ) const { - QgsMSDebugMsg( "Entering vectorLayerFromSentVDS" ) + QgsMSDebugMsg( "Entering." ) //QString tempFilePath = QgsMSUtils::createTempFilePath(); //QFile tempFile(tempFilePath); @@ -1211,10 +1211,10 @@ QgsVectorLayer* theVectorLayer = new QgsVectorLayer( tmpFile->fileName(), layerNameFromUri( tmpFile->fileName() ), "WFS" ); if ( !theVectorLayer || !theVectorLayer->isValid() ) { - QgsMSDebugMsg( "vectorLayerFromGML: invalid maplayer" ) + QgsMSDebugMsg( "invalid maplayer" ) return 0; } - QgsMSDebugMsg( "vectorLayerFromGML: returning maplayer" ) + QgsMSDebugMsg( "returning maplayer" ) mLayersToRemove.push_back( theVectorLayer ); //make sure the layer gets deleted after each request @@ -1223,7 +1223,7 @@ QgsVectorLayer* QgsSLDParser::contourLayerFromRaster( const QDomElement& userStyleElem, QgsRasterLayer* rasterLayer ) const { - QgsMSDebugMsg( "In method QgsSLDParser::contourLayerFromRaster" ) + QgsMSDebugMsg( "Entering." ) if ( !rasterLayer ) { @@ -1792,7 +1792,6 @@ return 4; } - int currentSize; QVariant currentThreshold; QgsDiagramItem currentItem; Index: src/mapserver/qgsmslayercache.cpp =================================================================== --- src/mapserver/qgsmslayercache.cpp (revision 14316) +++ src/mapserver/qgsmslayercache.cpp (working copy) @@ -39,7 +39,7 @@ QgsMSLayerCache::~QgsMSLayerCache() { - QgsMSDebugMsg( "Destructor QgsMSLayerCache: removing all entries" ) + QgsMSDebugMsg( "removing all entries" ) QMap, QgsMSLayerCacheEntry>::iterator it; for ( it = mEntries.begin(); it != mEntries.end(); ++it ) { @@ -147,7 +147,7 @@ QFile removeFile( *it ); if ( !removeFile.remove() ) { - QgsMSDebugMsg( "QgsMSLayerCache::freeEntryRessources: could not remove file: " + *it ) + QgsMSDebugMsg( "could not remove file: " + *it ) QgsMSDebugMsg( removeFile.errorString() ) } } Index: src/mapserver/qgsmapserverlogger.cpp =================================================================== --- src/mapserver/qgsmapserverlogger.cpp (revision 14316) +++ src/mapserver/qgsmapserverlogger.cpp (working copy) @@ -57,3 +57,13 @@ { mTextStream << c; } + +#ifdef QGSMSDEBUG +void QgsMapServerLogger::printMessage( const char *file, const char *function, int line, const QString& message ) +{ + mTextStream + << QString( "%1: %2: (%3) " ).arg( file ).arg( function ).arg( line ) + << message + << endl; +} +#endif Index: src/mapserver/qgshostedrdsbuilder.cpp =================================================================== --- src/mapserver/qgshostedrdsbuilder.cpp (revision 14316) +++ src/mapserver/qgshostedrdsbuilder.cpp (working copy) @@ -35,7 +35,7 @@ QgsMapLayer* QgsHostedRDSBuilder::createMapLayer( const QDomElement& elem, const QString& layerName, QList& filesToRemove, QList& layersToRemove, bool allowCaching ) const { - QgsMSDebugMsg( "Entering QgsHostedRDSBuilder::rasterLayerFromHostedRDS" ) + QgsMSDebugMsg( "entering." ) if ( elem.isNull() ) { Index: src/mapserver/qgssoaprequesthandler.cpp =================================================================== --- src/mapserver/qgssoaprequesthandler.cpp (revision 14316) +++ src/mapserver/qgssoaprequesthandler.cpp (working copy) @@ -57,7 +57,7 @@ bool conversionSuccess = false; lengthQString = QString( lengthString ); length = lengthQString.toInt( &conversionSuccess ); - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: length is: " + lengthQString ) + QgsMSDebugMsg( "length is: " + lengthQString ) if ( conversionSuccess ) { input = ( char* )malloc( length + 1 ); @@ -80,24 +80,24 @@ } else { - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: input is NULL " ) + QgsMSDebugMsg( "input is NULL " ) } free( input ); } else { - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: could not convert CONTENT_LENGTH to int" ) + QgsMSDebugMsg( "could not convert CONTENT_LENGTH to int" ) } } - //QgsMSDebugMsg("qgssoaprequesthandler.cpp: input string is: " + inputString) + //QgsMSDebugMsg("input string is: " + inputString) //inputString to QDomDocument QDomDocument inputXML; QString errorMsg; if ( !inputXML.setContent( inputString, true, &errorMsg ) ) { - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: soap request parse error" ) + QgsMSDebugMsg( "soap request parse error" ) QgsMSDebugMsg( "error message: " + errorMsg ) QgsMSDebugMsg( "the xml string was:" ) QgsMSDebugMsg( inputString ) @@ -118,7 +118,7 @@ QDomNodeList envelopeNodeList = inputXML.elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Envelope" ); if ( envelopeNodeList.size() < 1 ) { - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: Envelope element not found" ) + QgsMSDebugMsg( "Envelope element not found" ) throw QgsMapServiceException( "SOAPError", "Element not found" ); return result; } @@ -126,7 +126,7 @@ QDomNodeList bodyNodeList = envelopeNodeList.item( 0 ).toElement().elementsByTagNameNS( "http://schemas.xmlsoap.org/soap/envelope/", "Body" ); if ( bodyNodeList.size() < 1 ) { - QgsMSDebugMsg( "qgssoaprequesthandler.cpp: body node not found" ) + QgsMSDebugMsg( "body node not found" ) throw QgsMapServiceException( "SOAPError", "Element not found" ); return result; } @@ -283,7 +283,7 @@ if ( !common.open( QIODevice::ReadOnly ) ) { //throw an exception... - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: external orchestra common capabilities not found" ) + QgsMSDebugMsg( "external orchestra common capabilities not found" ) } else { @@ -292,7 +292,7 @@ int errorLineNo; if ( !externCapDoc.setContent( &common, false, &parseError, &errorLineNo ) ) { - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: parse error at setting content of external orchestra common capabilities: "\ + QgsMSDebugMsg( "parse error at setting content of external orchestra common capabilities: " + parseError + " at line " + QString::number( errorLineNo ) ); common.close(); } @@ -357,7 +357,7 @@ if ( !wmsService.open( QIODevice::ReadOnly ) ) { //throw an exception... - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: external wms service capabilities not found" ) + QgsMSDebugMsg( "external wms service capabilities not found" ) } else { @@ -366,7 +366,7 @@ int errorLineNo; if ( !externServiceDoc.setContent( &wmsService, false, &parseError, &errorLineNo ) ) { - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: parse error at setting content of external wms service capabilities: "\ + QgsMSDebugMsg( "parse error at setting content of external wms service capabilities: " + parseError + " at line " + QString::number( errorLineNo ) ) wmsService.close(); } @@ -404,7 +404,7 @@ if ( !common.open( QIODevice::ReadOnly ) ) { //throw an exception... - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: external orchestra common capabilities not found" ) + QgsMSDebugMsg( "external orchestra common capabilities not found" ) } else { @@ -413,7 +413,7 @@ int errorLineNo; if ( !externCapDoc.setContent( &common, false, &parseError, &errorLineNo ) ) { - QgsMSDebugMsg( "qgissoaprequesthandler.cpp: parse error at setting content of external orchestra common capabilities: "\ + QgsMSDebugMsg( "parse error at setting content of external orchestra common capabilities: " + parseError + " at line " + QString::number( errorLineNo ) ) common.close(); } @@ -706,7 +706,7 @@ int QgsSOAPRequestHandler::sendSOAPWithAttachments( QImage* img ) const { - QgsMSDebugMsg( "In sendSOAPWithAttachments" ) + QgsMSDebugMsg( "Entering." ) //create response xml document QDomDocument xmlResponse; //response xml, save this into mimeString QDomElement envelopeElement = xmlResponse.createElementNS( "http://schemas.xmlsoap.org/soap/envelope/", "Envelope" ); @@ -772,7 +772,7 @@ QFile theFile; QDir tmpDir; - QgsMSDebugMsg( "Entering sendUrlToFile" ) + QgsMSDebugMsg( "Entering." ) if ( findOutHostAddress( uri ) != 0 ) { Index: src/mapserver/qgshostedvdsbuilder.cpp =================================================================== --- src/mapserver/qgshostedvdsbuilder.cpp (revision 14316) +++ src/mapserver/qgshostedvdsbuilder.cpp (working copy) @@ -44,7 +44,7 @@ if ( providerType == "not found" || uri == "not found" ) { - QgsMSDebugMsg( "QgsHostedVDSBuilder::createMapLayer: error, provider type not found" ) + QgsMSDebugMsg( "error, provider type not found" ) return 0; } @@ -63,7 +63,7 @@ if ( !ml || !ml->isValid() ) { - QgsMSDebugMsg( "QgsHostedVDSBuilder::createMapLayer: error, VectorLayer is 0 or invalid" ) + QgsMSDebugMsg( "error, VectorLayer is 0 or invalid" ) delete ml; return 0; } Index: src/mapserver/qgsremotedatasourcebuilder.cpp =================================================================== --- src/mapserver/qgsremotedatasourcebuilder.cpp (revision 14316) +++ src/mapserver/qgsremotedatasourcebuilder.cpp (working copy) @@ -37,7 +37,7 @@ QgsMapLayer* QgsRemoteDataSourceBuilder::createMapLayer( const QDomElement& elem, const QString& layerName, QList& filesToRemove, QList& layersToRemove, bool allowCaching ) const { - QgsMSDebugMsg( "QgsRDSBuilder::createMapLayer" ); + QgsMSDebugMsg( "entering." ); QgsMapLayer* theLayer = 0; if ( elem.tagName() == "RemoteRDS" ) { @@ -56,7 +56,7 @@ QgsRasterLayer* QgsRemoteDataSourceBuilder::rasterLayerFromRemoteRDS( const QDomElement& remoteRDSElem, const QString& layerName, QList& filesToRemove, QList& layersToRemove, bool allowCaching ) const { - QgsMSDebugMsg( "QgsRDSBuilder::rasterLayerFromRemoteRDS" ); + QgsMSDebugMsg( "entering." ); //load file with QgsHttpTransaction or QgsFtpTransaction QByteArray fileContents; QString uri = remoteRDSElem.text(); Index: src/mapserver/qgsconfigparser.cpp =================================================================== --- src/mapserver/qgsconfigparser.cpp (revision 14316) +++ src/mapserver/qgsconfigparser.cpp (working copy) @@ -22,7 +22,10 @@ #include -QgsConfigParser::QgsConfigParser(): mFallbackParser( 0 ), mScaleDenominator( 0 ), mOutputUnits( QgsMapRenderer::Millimeters ) +QgsConfigParser::QgsConfigParser() + : mFallbackParser( 0 ) + , mScaleDenominator( 0 ) + , mOutputUnits( QgsMapRenderer::Millimeters ) { setDefaultLegendSettings(); } @@ -61,7 +64,10 @@ mExternalGMLDatasets.insert( layerName, gmlDoc ); } -void QgsConfigParser::appendExGeographicBoundingBox( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent, const QgsCoordinateReferenceSystem& layerCRS ) const +void QgsConfigParser::appendExGeographicBoundingBox( QDomElement& layerElem, + QDomDocument& doc, + const QgsRectangle& layerExtent, + const QgsCoordinateReferenceSystem& layerCRS ) const { if ( layerElem.isNull() ) { Index: src/core/qgsmaplayer.cpp =================================================================== --- src/core/qgsmaplayer.cpp (revision 14316) +++ src/core/qgsmaplayer.cpp (working copy) @@ -101,10 +101,10 @@ } /** Write property of QString layerName. */ -void QgsMapLayer::setLayerName( const QString & _newVal ) +void QgsMapLayer::setLayerName( const QString & name ) { - QgsDebugMsg( "new name is '" + _newVal + "'" ); - mLayerName = capitaliseLayerName( _newVal ); + QgsDebugMsg( "new name is '" + name + "'" ); + mLayerName = capitaliseLayerName( name ); emit layerNameChanged(); } Index: src/core/qgssearchtreenode.cpp =================================================================== --- src/core/qgssearchtreenode.cpp (revision 14316) +++ src/core/qgssearchtreenode.cpp (working copy) @@ -375,7 +375,7 @@ } } -bool QgsSearchTreeNode::checkAgainst( const QMap& fields, const QMap& attributes, QgsGeometry* geom ) +bool QgsSearchTreeNode::checkAgainst( const QgsFieldMap& fields, const QgsAttributeMap &attributes, QgsGeometry* geom ) { QgsFeature f; f.setAttributeMap( attributes ); @@ -524,7 +524,11 @@ return false; } -bool QgsSearchTreeNode::getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node, const QgsFieldMap& fields, const QMap& attributes, QgsGeometry* geom ) +bool QgsSearchTreeNode::getValue( QgsSearchTreeValue& value, + QgsSearchTreeNode* node, + const QgsFieldMap &fields, + const QgsAttributeMap &attributes, + QgsGeometry* geom ) { QgsFeature f; f.setAttributeMap( attributes ); @@ -533,7 +537,10 @@ return getValue( value, node, fields, f ); } -bool QgsSearchTreeNode::getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node, const QgsFieldMap& fields, QgsFeature &f ) +bool QgsSearchTreeNode::getValue( QgsSearchTreeValue& value, + QgsSearchTreeNode* node, + const QgsFieldMap& fields, + QgsFeature &f ) { value = node->valueAgainst( fields, f ); if ( value.isError() ) @@ -563,7 +570,9 @@ return true; } -QgsSearchTreeValue QgsSearchTreeNode::valueAgainst( const QgsFieldMap& fields, const QMap& attributes, QgsGeometry* geom ) +QgsSearchTreeValue QgsSearchTreeNode::valueAgainst( const QgsFieldMap& fields, + const QgsAttributeMap &attributes, + QgsGeometry* geom ) { QgsFeature f; f.setAttributeMap( attributes ); Index: src/core/qgssearchtreenode.h =================================================================== --- src/core/qgssearchtreenode.h (revision 14316) +++ src/core/qgssearchtreenode.h (working copy) @@ -151,7 +151,7 @@ bool checkAgainst( const QgsFieldMap& fields, QgsFeature &f ); //! @note deprecated - bool checkAgainst( const QMap& fields, const QMap& attributes, QgsGeometry* geom = 0 ); + bool checkAgainst( const QgsFieldMap& fields, const QgsAttributeMap& attributes, QgsGeometry* geom = 0 ); //! checks if there were errors during evaluation bool hasError() { return ( !mError.isEmpty() ); } @@ -161,12 +161,17 @@ //! wrapper around valueAgainst() //! @note added in 1.4 - bool getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node, - const QgsFieldMap& fields, QgsFeature &f ); + bool getValue( QgsSearchTreeValue& value, + QgsSearchTreeNode* node, + const QgsFieldMap& fields, + QgsFeature &f ); //! @note deprecated - bool getValue( QgsSearchTreeValue& value, QgsSearchTreeNode* node, - const QMap& fields, const QMap& attributes, QgsGeometry* geom = 0 ); + bool getValue( QgsSearchTreeValue& value, + QgsSearchTreeNode* node, + const QgsFieldMap &fields, + const QgsAttributeMap &attributes, + QgsGeometry* geom = 0 ); //! return a list of referenced columns in the tree //! @note added in 1.5 @@ -202,7 +207,7 @@ QgsSearchTreeValue valueAgainst( const QgsFieldMap& fields, QgsFeature &f ); //! @note deprecated - QgsSearchTreeValue valueAgainst( const QMap& fields, const QMap& attributes, QgsGeometry* geom = 0 ); + QgsSearchTreeValue valueAgainst( const QgsFieldMap& fields, const QgsAttributeMap& attributes, QgsGeometry* geom = 0 ); //! strips mText when node is of string type void stripText();