Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'master' of https://github.com/qgis/Quantum-GIS
Conflicts:
	python/plugins/sextante/grass/ext/CMakeLists.txt
  • Loading branch information
volaya committed Dec 15, 2012
2 parents 33e3925 + 3a59fd4 commit 0c2fef4
Show file tree
Hide file tree
Showing 17 changed files with 480 additions and 46 deletions.
Expand Up @@ -92,7 +92,9 @@ def run(item, action, mainwindow):
prevRenderFlagState = iface.mapCanvas().renderFlag()
iface.mapCanvas().setRenderFlag( False )
try:
group = legend.addGroup(u'%s topology' % toponame)
# NOTE: -1 parent is an attempt to always add to the root, but
# it is currently broken: http://hub.qgis.org/issues/6879
group = legend.addGroup(u'%s topology' % toponame, False, -1)

provider = db.dbplugin().providerName()
uri = db.uri();
Expand Down
22 changes: 22 additions & 0 deletions python/plugins/sextante/ftools/ConvexHull.py
Expand Up @@ -184,6 +184,28 @@ def processAlgorithm(self, progress):
if not FEATURE_EXCEPT:
SextanteLog.addToLog(SextanteLog.LOG_WARNING, "Feature exception while computing convex hull")

def simpleMeasure(self, inGeom ):
measure = QgsDistanceArea()
attr1 = measure.measure(inGeom)
if inGeom.type() == QGis.Polygon:
attr2 = self.perimMeasure( inGeom, measure )
else:
attr2 = attr1
return ( attr1, attr2 )

def perimMeasure(self, inGeom, measure ):
value = 0.00
if inGeom.isMultipart():
poly = inGeom.asMultiPolygon()
for k in poly:
for j in k:
value = value + measure.measureLine( j )
else:
poly = inGeom.asPolygon()
for k in poly:
value = value + measure.measureLine( k )
return value

def defineCharacteristics(self):
self.name = "Convex hull"
self.group = "Geoprocessing tools"
Expand Down
13 changes: 12 additions & 1 deletion src/app/legend/qgslegend.cpp
Expand Up @@ -230,7 +230,18 @@ int QgsLegend::addGroup( QString name, bool expand, QTreeWidgetItem* parent )

emit itemAdded( groupIndex );

return groupIndex.row();
// TODO: use QModelIndex::iternalId for an identifier instead of this mess ?
int itemCount = 0;
for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
{
QgsLegendItem* legendItem = dynamic_cast<QgsLegendItem *>( theItem );
if ( legendItem->type() == QgsLegendItem::LEGEND_GROUP )
{
if ( legendItem == group ) return itemCount;
else itemCount++;
}
}
return itemCount; // bogus return
}

int QgsLegend::addGroup( QString name, bool expand, int groupIndex )
Expand Down
8 changes: 7 additions & 1 deletion src/app/qgisapp.cpp
Expand Up @@ -5238,7 +5238,8 @@ bool QgisApp::toggleEditing( QgsMapLayer *layer, bool allowCancel )
res = false;
}

vlayer->triggerRepaint();
// canvas refreshes handled in QgsUndoWidget::indexChanged
//vlayer->triggerRepaint();
break;

default:
Expand Down Expand Up @@ -7215,11 +7216,16 @@ void QgisApp::activateDeactivateLayerRelatedActions( QgsMapLayer* layer )
mActionToggleEditing->setEnabled( canChangeAttributes && !vlayer->isReadOnly() );
mActionToggleEditing->setChecked( vlayer->isEditable() );
mActionSaveEdits->setEnabled( canChangeAttributes && vlayer->isEditable() );
mUndoWidget->dockContents()->setEnabled( vlayer->isEditable() );
updateUndoActions();
}
else
{
mActionToggleEditing->setEnabled( false );
mActionSaveEdits->setEnabled( false );
mUndoWidget->dockContents()->setEnabled( false );
mActionUndo->setEnabled( false );
mActionRedo->setEnabled( false );
}

if ( dprovider->capabilities() & QgsVectorDataProvider::AddFeatures )
Expand Down
41 changes: 27 additions & 14 deletions src/app/qgsundowidget.cpp
Expand Up @@ -37,6 +37,8 @@ QgsUndoWidget::QgsUndoWidget( QWidget * parent, QgsMapCanvas * mapCanvas )
mMapCanvas = mapCanvas;
mUndoView = NULL;
mUndoStack = NULL;
mPreviousIndex = 0;
mPreviousCount = 0;
}


Expand Down Expand Up @@ -80,13 +82,25 @@ void QgsUndoWidget::redoChanged( bool value )
emit undoStackChanged();
}


void QgsUndoWidget::indexChanged( int value )
void QgsUndoWidget::indexChanged( int curIndx )
{
Q_UNUSED( value );
//redoButton->setDisabled( !value );
//canvas refresh
mMapCanvas->refresh();
// this is called twice when a non-current command is clicked in QUndoView
// first call has offset, second call will have offset of 0
int curCount = 0;
if ( mUndoStack )
{
curCount = mUndoStack->count();
}
bool cmdAdded = ( curIndx == curCount && mPreviousCount == ( curCount - 1 ) );
int offset = qAbs( mPreviousIndex - curIndx );
// avoid refresh when only a command was added to stack (i.e. no undo/redo action)
if ( offset > 1 || ( offset == 1 && !cmdAdded ) )
{
mMapCanvas->refresh();
}

mPreviousIndex = curIndx;
mPreviousCount = curCount;
}

void QgsUndoWidget::undo( )
Expand All @@ -111,20 +125,19 @@ void QgsUndoWidget::setUndoStack( QUndoStack* undoStack )
}

mUndoStack = undoStack;
mPreviousIndex = mUndoStack->index();
mPreviousCount = mUndoStack->count();

mUndoView = new QUndoView( dockWidgetContents );
mUndoView->setStack( undoStack );
mUndoView->setObjectName( "undoView" );
gridLayout->addWidget( mUndoView, 0, 0, 1, 2 );
setWidget( dockWidgetContents );
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );

// indexChanged() triggers a refresh. but it gets triggered also when a new action
// is done, resulting in two refreshes. For now let's trigger the refresh from
// vector layer: it causes potentially multiple refreshes when moving more commands
// back, but avoids double refresh in common case when adding commands to the stack
//connect(mUndoStack, SIGNAL(indexChanged(int)), this, SLOT(indexChanged(int)));
connect( mUndoStack, SIGNAL( canUndoChanged( bool ) ), this, SLOT( undoChanged( bool ) ) );
connect( mUndoStack, SIGNAL( canRedoChanged( bool ) ), this, SLOT( redoChanged( bool ) ) );

// gets triggered also when a new command is added to stack, and twice when clicking a command in QUndoView
connect( mUndoStack, SIGNAL( indexChanged( int ) ), this, SLOT( indexChanged( int ) ) );

undoButton->setDisabled( !mUndoStack->canUndo() );
redoButton->setDisabled( !mUndoStack->canRedo() );
Expand Down
10 changes: 9 additions & 1 deletion src/app/qgsundowidget.h
Expand Up @@ -58,6 +58,12 @@ class QgsUndoWidget : public QDockWidget
*/
void destroyStack();

/**
* Access to dock's contents
* @note added in 1.9
*/
QWidget* dockContents() { return dockWidgetContents; }

public slots:
/**
* Changes undo stack which is displayed by undo view
Expand All @@ -77,7 +83,7 @@ class QgsUndoWidget : public QDockWidget
/**
* Slot to handle index changed signal
*/
void indexChanged( int value );
void indexChanged( int curIndx );

/**
* Undo operation called from button push
Expand All @@ -97,6 +103,8 @@ class QgsUndoWidget : public QDockWidget
QUndoStack * mUndoStack;
QgsMapCanvas* mMapCanvas;

int mPreviousIndex;
int mPreviousCount;
};


Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsexpression.h
Expand Up @@ -358,7 +358,7 @@ class CORE_EXPORT QgsExpression
static const int HOUR = 60 * 60;
static const int MINUTE = 60;
public:
Interval( double seconds = 0 ) { mSeconds = seconds; }
Interval( double seconds = 0 ): mSeconds(seconds), mValid(true) { }
~Interval();
double years() { return mSeconds / YEARS;}
double months() { return mSeconds / MONTHS; }
Expand Down
13 changes: 7 additions & 6 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -4256,10 +4256,9 @@ bool QgsVectorLayer::rollBack()

if ( isModified() )
{
while ( undoStack()->canUndo() )
{
undoStack()->undo();
}
// new undo stack roll back method
// old method of calling every undo could cause many canvas refreshes
undoStack()->setIndex( 0 );

Q_ASSERT( mAddedAttributeIds.isEmpty() );
Q_ASSERT( mDeletedAttributeIds.isEmpty() );
Expand Down Expand Up @@ -5240,7 +5239,8 @@ void QgsVectorLayer::redoEditCommand( QgsUndoCommand* cmd )
setModified( true );

// it's not ideal to trigger refresh from here
triggerRepaint();
// canvas refreshes handled in QgsUndoWidget::indexChanged
//triggerRepaint();
}

void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
Expand Down Expand Up @@ -5363,7 +5363,8 @@ void QgsVectorLayer::undoEditCommand( QgsUndoCommand* cmd )
setModified( true );

// it's not ideal to trigger refresh from here
triggerRepaint();
// canvas refreshes handled in QgsUndoWidget::indexChanged
//triggerRepaint();
}

void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )
Expand Down
18 changes: 18 additions & 0 deletions src/core/raster/qgsrasterblock.cpp
Expand Up @@ -410,6 +410,24 @@ bool QgsRasterBlock::convert( QgsRasterBlock::DataType destDataType )
return true;
}

void QgsRasterBlock::applyNodataValues( const QList<Range>& rangeList )
{
if ( rangeList.isEmpty() )
{
return;
}

size_t size = mWidth * mHeight;
for ( size_t i = 0; i < size; ++i )
{
double val = value( i );
if ( valueInRange( val, rangeList ) )
{
setValue( i, mNoDataValue );
}
}
}

QImage QgsRasterBlock::image() const
{
if ( mImage )
Expand Down
2 changes: 2 additions & 0 deletions src/core/raster/qgsrasterblock.h
Expand Up @@ -304,6 +304,8 @@ class CORE_EXPORT QgsRasterBlock

inline static void writeValue( void *data, QgsRasterBlock::DataType type, size_t index, double value );

void applyNodataValues( const QList<Range>& rangeList );

private:

static QImage::Format imageFormat( QgsRasterBlock::DataType theDataType );
Expand Down
17 changes: 1 addition & 16 deletions src/core/raster/qgsrasterdataprovider.cpp
Expand Up @@ -194,22 +194,7 @@ QgsRasterBlock * QgsRasterDataProvider::block( int theBandNo, QgsRectangle cons

// apply user no data values
// TODO: there are other readBlock methods where no data are not applied
QList<QgsRasterBlock::Range> myNoDataRangeList = userNoDataValue( theBandNo );
if ( !myNoDataRangeList.isEmpty() )
{
double myNoDataValue = noDataValue( theBandNo );
size_t size = theWidth * theHeight;
for ( size_t i = 0; i < size; i++ )
{
double value = block->value( i );

if ( QgsRasterBlock::valueInRange( value, myNoDataRangeList ) )
{
block->setValue( i, myNoDataValue );
}
}
}

block->applyNodataValues( userNoDataValue( theBandNo ) );
return block;
}

Expand Down
1 change: 1 addition & 0 deletions src/gui/qgsrubberband.cpp
Expand Up @@ -29,6 +29,7 @@
*/
QgsRubberBand::QgsRubberBand( QgsMapCanvas* mapCanvas, QGis::GeometryType geometryType )
: QgsMapCanvasItem( mapCanvas )
, mWidth( 1 )
, mGeometryType( geometryType )
, mTranslationOffsetX( 0.0 )
, mTranslationOffsetY( 0.0 )
Expand Down
13 changes: 13 additions & 0 deletions src/providers/gdal/qgsgdalprovider.cpp
Expand Up @@ -363,6 +363,19 @@ QImage* QgsGdalProvider::draw( QgsRectangle const & viewExtent, int pixelWidth,
return image;
}

QgsRasterBlock* QgsGdalProvider::block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight )
{
QgsRasterBlock *block = new QgsRasterBlock( dataType( theBandNo ), theWidth, theHeight, noDataValue( theBandNo ) );

if ( block->isEmpty() )
{
return block;
}

readBlock( theBandNo, theExtent, theWidth, theHeight, block->data() );
block->applyNodataValues( userNoDataValue( theBandNo ) );
return block;
}

void QgsGdalProvider::readBlock( int theBandNo, int xBlock, int yBlock, void *block )
{
Expand Down
2 changes: 2 additions & 0 deletions src/providers/gdal/qgsgdalprovider.h
Expand Up @@ -166,6 +166,8 @@ class QgsGdalProvider : public QgsRasterDataProvider, QgsGdalProviderBase
int xSize() const;
int ySize() const;

/**Reimplemented from QgsRasterDataProvider to bypass second resampling (more efficient for local file based sources)*/
QgsRasterBlock *block( int theBandNo, const QgsRectangle &theExtent, int theWidth, int theHeight );

void readBlock( int bandNo, int xBlock, int yBlock, void *data );
void readBlock( int bandNo, QgsRectangle const & viewExtent, int width, int height, void *data );
Expand Down

0 comments on commit 0c2fef4

Please sign in to comment.