QGIS/src/core/composer/qgscomposerpolyline.cpp
Nyall Dawson aed6c735a6 Swap QScopedPointer to std::unique_ptr
Why?
- no benefits to QScopedPointer over std::unique_ptr
- unlike QScopedPointer, std::unique_ptr has no overhead
over regular pointers
- using standard language features makes it more likely that
compilers can optimise this use and static analysers can
correctly handle code using unique_ptrs
- QScopedPointer has an (IMO) uncertain future (given that
Qt is dropping features which have become part of the c++
standard). Better to port now before wider use of QScopedPointer
in the codebase!
2017-02-07 12:08:57 +10:00

137 lines
4.5 KiB
C++

/***************************************************************************
qgscomposerpolyline.cpp
begin : March 2016
copyright : (C) 2016 Paul Blottiere, Oslandia
email : paul dot blottiere at oslandia dot com
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgscomposerpolyline.h"
#include "qgscomposition.h"
#include "qgscomposerutils.h"
#include "qgssymbollayerutils.h"
#include "qgssymbol.h"
#include "qgsmapsettings.h"
#include <limits>
QgsComposerPolyline::QgsComposerPolyline( QgsComposition* c )
: QgsComposerNodesItem( QStringLiteral( "ComposerPolyline" ), c )
, mPolylineStyleSymbol( nullptr )
{
createDefaultPolylineStyleSymbol();
}
QgsComposerPolyline::QgsComposerPolyline( const QPolygonF& polyline, QgsComposition* c )
: QgsComposerNodesItem( QStringLiteral( "ComposerPolyline" ), polyline, c )
, mPolylineStyleSymbol( nullptr )
{
createDefaultPolylineStyleSymbol();
}
bool QgsComposerPolyline::_addNode( const int indexPoint,
QPointF newPoint,
const double radius )
{
const double distStart = computeDistance( newPoint, mPolygon[0] );
const double distEnd = computeDistance( newPoint, mPolygon[mPolygon.size()-1] );
if ( indexPoint == ( mPolygon.size() - 1 ) )
{
if ( distEnd < radius )
mPolygon.append( newPoint );
else if ( distStart < radius )
mPolygon.insert( 0, newPoint );
}
else
mPolygon.insert( indexPoint + 1, newPoint );
return true;
}
bool QgsComposerPolyline::_removeNode( const int index )
{
if ( index < 0 || index >= mPolygon.size() )
return false;
mPolygon.remove( index );
if ( mPolygon.size() < 2 )
mPolygon.clear();
else
{
int newSelectNode = index;
if ( index >= mPolygon.size() )
newSelectNode = mPolygon.size() - 1;
setSelectedNode( newSelectNode );
}
return true;
}
void QgsComposerPolyline::createDefaultPolylineStyleSymbol()
{
QgsStringMap properties;
properties.insert( QStringLiteral( "color" ), QStringLiteral( "0,0,0,255" ) );
properties.insert( QStringLiteral( "width" ), QStringLiteral( "0.3" ) );
properties.insert( QStringLiteral( "capstyle" ), QStringLiteral( "square" ) );
mPolylineStyleSymbol.reset( QgsLineSymbol::createSimple( properties ) );
emit frameChanged();
}
QString QgsComposerPolyline::displayName() const
{
if ( !id().isEmpty() )
return id();
return tr( "<polyline>" );
}
void QgsComposerPolyline::_draw( QPainter *painter )
{
double dotsPerMM = painter->device()->logicalDpiX() / 25.4;
QgsRenderContext context = QgsComposerUtils::createRenderContextForComposition( mComposition, painter );
context.setForceVectorOutput( true );
QgsExpressionContext expressionContext = createExpressionContext();
context.setExpressionContext( expressionContext );
painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
QTransform t = QTransform::fromScale( dotsPerMM, dotsPerMM );
mPolylineStyleSymbol->startRender( context );
mPolylineStyleSymbol->renderPolyline( t.map( mPolygon ), nullptr, context );
mPolylineStyleSymbol->stopRender( context );
painter->scale( dotsPerMM, dotsPerMM );
}
void QgsComposerPolyline::_readXmlStyle( const QDomElement &elmt )
{
mPolylineStyleSymbol.reset( QgsSymbolLayerUtils::loadSymbol<QgsLineSymbol>( elmt ) );
}
void QgsComposerPolyline::setPolylineStyleSymbol( QgsLineSymbol* symbol )
{
mPolylineStyleSymbol.reset( static_cast<QgsLineSymbol*>( symbol->clone() ) );
update();
emit frameChanged();
}
void QgsComposerPolyline::_writeXmlStyle( QDomDocument &doc, QDomElement &elmt ) const
{
const QDomElement pe = QgsSymbolLayerUtils::saveSymbol( QString(),
mPolylineStyleSymbol.get(),
doc );
elmt.appendChild( pe );
}