mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-18 00:03:05 -04:00
add support for multiline labels (applies #1138)
git-svn-id: http://svn.osgeo.org/qgis/trunk@8775 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
3c13ecf648
commit
b5948bde31
@ -30,13 +30,14 @@ public:
|
|||||||
YOffset,
|
YOffset,
|
||||||
Angle,
|
Angle,
|
||||||
Alignment,
|
Alignment,
|
||||||
BufferEnabled,
|
BufferEnabled,
|
||||||
BufferSize,
|
BufferSize,
|
||||||
BufferColor,
|
BufferColor,
|
||||||
BufferBrush,
|
BufferBrush,
|
||||||
BorderWidth,
|
BorderWidth,
|
||||||
BorderColor,
|
BorderColor,
|
||||||
BorderStyle,
|
BorderStyle,
|
||||||
|
MultilineEnabled,
|
||||||
LabelFieldCount
|
LabelFieldCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ public:
|
|||||||
void renderLabel ( QPainter* painter, QgsRect& viewExtent,
|
void renderLabel ( QPainter* painter, QgsRect& viewExtent,
|
||||||
QgsCoordinateTransform* coordTransform,
|
QgsCoordinateTransform* coordTransform,
|
||||||
QgsMapToPixel *transform,
|
QgsMapToPixel *transform,
|
||||||
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0, double sizeScale = 1);
|
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0, double sizeScale = 1);
|
||||||
|
|
||||||
/** Reads the renderer configuration from an XML file
|
/** Reads the renderer configuration from an XML file
|
||||||
@param rnode the DOM node to read
|
@param rnode the DOM node to read
|
||||||
|
@ -101,6 +101,8 @@ public:
|
|||||||
void setBorderStyle ( Qt::PenStyle style );
|
void setBorderStyle ( Qt::PenStyle style );
|
||||||
bool borderStyleIsSet ( ) const;
|
bool borderStyleIsSet ( ) const;
|
||||||
Qt::PenStyle borderStyle ( ) const;
|
Qt::PenStyle borderStyle ( ) const;
|
||||||
|
|
||||||
|
bool multilineEnabled() const;
|
||||||
|
void setMultilineEnabled( bool useMultiline );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -239,6 +239,8 @@ void QgsLabelDialog::init ( )
|
|||||||
{
|
{
|
||||||
spinBufferSize->setValue(1);
|
spinBufferSize->setValue(1);
|
||||||
}
|
}
|
||||||
|
//set the state of the multiline enabled checkbox
|
||||||
|
chkUseMultiline->setChecked(myLabelAttributes->multilineEnabled());
|
||||||
//set the state of the buffer enabled checkbox
|
//set the state of the buffer enabled checkbox
|
||||||
chkUseBuffer->setChecked(myLabelAttributes->bufferEnabled());
|
chkUseBuffer->setChecked(myLabelAttributes->bufferEnabled());
|
||||||
|
|
||||||
@ -360,6 +362,7 @@ void QgsLabelDialog::apply()
|
|||||||
if (radioBelow->isChecked()) myLabelAttributes->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
if (radioBelow->isChecked()) myLabelAttributes->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||||
if (radioOver->isChecked()) myLabelAttributes->setAlignment(Qt::AlignCenter);
|
if (radioOver->isChecked()) myLabelAttributes->setAlignment(Qt::AlignCenter);
|
||||||
|
|
||||||
|
myLabelAttributes->setMultilineEnabled(chkUseMultiline->isChecked());
|
||||||
myLabelAttributes->setBufferEnabled(chkUseBuffer->isChecked());
|
myLabelAttributes->setBufferEnabled(chkUseBuffer->isChecked());
|
||||||
myLabelAttributes->setBufferColor(mBufferColor);
|
myLabelAttributes->setBufferColor(mBufferColor);
|
||||||
myTypeInt = 0;
|
myTypeInt = 0;
|
||||||
|
@ -71,7 +71,7 @@ QString QgsLabel::fieldValue ( int attr, QgsFeature &feature )
|
|||||||
|
|
||||||
const QgsAttributeMap& attrs = feature.attributeMap();
|
const QgsAttributeMap& attrs = feature.attributeMap();
|
||||||
QgsAttributeMap::const_iterator it = attrs.find(mLabelFieldIdx[attr]);
|
QgsAttributeMap::const_iterator it = attrs.find(mLabelFieldIdx[attr]);
|
||||||
|
|
||||||
if (it != attrs.end())
|
if (it != attrs.end())
|
||||||
{
|
{
|
||||||
return it->toString();
|
return it->toString();
|
||||||
@ -86,7 +86,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
const QgsCoordinateTransform* coordTransform,
|
const QgsCoordinateTransform* coordTransform,
|
||||||
const QgsMapToPixel *transform,
|
const QgsMapToPixel *transform,
|
||||||
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes,
|
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes,
|
||||||
double sizeScale )
|
double sizeScale )
|
||||||
{
|
{
|
||||||
|
|
||||||
QPen pen;
|
QPen pen;
|
||||||
@ -137,20 +137,20 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
int sizeType;
|
int sizeType;
|
||||||
value = fieldValue ( SizeType, feature );
|
value = fieldValue ( SizeType, feature );
|
||||||
if( value.isEmpty() )
|
if( value.isEmpty() )
|
||||||
sizeType = mLabelAttributes->sizeType();
|
sizeType = mLabelAttributes->sizeType();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = value.toLower();
|
value = value.toLower();
|
||||||
if( value.compare("mapunits") == 0 )
|
if( value.compare("mapunits") == 0 )
|
||||||
sizeType = QgsLabelAttributes::MapUnits;
|
sizeType = QgsLabelAttributes::MapUnits;
|
||||||
else
|
else
|
||||||
sizeType = QgsLabelAttributes::PointUnits;
|
sizeType = QgsLabelAttributes::PointUnits;
|
||||||
}
|
}
|
||||||
if ( sizeType == QgsLabelAttributes::MapUnits )
|
if ( sizeType == QgsLabelAttributes::MapUnits )
|
||||||
{
|
{
|
||||||
size *= scale;
|
size *= scale;
|
||||||
} else {
|
} else {
|
||||||
size *= sizeScale;
|
size *= sizeScale;
|
||||||
}
|
}
|
||||||
if(size>0.0)
|
if(size>0.0)
|
||||||
font.setPointSizeF ( size );
|
font.setPointSizeF ( size );
|
||||||
@ -214,8 +214,26 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
/* Alignment */
|
/* Alignment */
|
||||||
int alignment;
|
int alignment;
|
||||||
QFontMetrics fm ( font );
|
QFontMetrics fm ( font );
|
||||||
int width = fm.width ( text );
|
int width, height;
|
||||||
int height = fm.height();
|
|
||||||
|
if( mLabelAttributes->multilineEnabled() )
|
||||||
|
{
|
||||||
|
QStringList texts = text.split("\n");
|
||||||
|
|
||||||
|
width=0;
|
||||||
|
for(int i=0; i<texts.size(); i++) {
|
||||||
|
int w = fm.width(texts[i]);
|
||||||
|
if(w>width)
|
||||||
|
width=w;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = fm.height()*texts.size();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
width = fm.width ( text );
|
||||||
|
height = fm.height();
|
||||||
|
}
|
||||||
int dx = 0;
|
int dx = 0;
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
|
|
||||||
@ -226,23 +244,23 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = value.toLower();
|
value = value.toLower();
|
||||||
|
|
||||||
alignment=0;
|
alignment=0;
|
||||||
|
|
||||||
if ( value.contains("left") )
|
if ( value.contains("left") )
|
||||||
alignment |= Qt::AlignLeft;
|
alignment |= Qt::AlignLeft;
|
||||||
else if( value.contains("right") )
|
else if( value.contains("right") )
|
||||||
alignment |= Qt::AlignRight;
|
alignment |= Qt::AlignRight;
|
||||||
else
|
else
|
||||||
alignment |= Qt::AlignHCenter;
|
alignment |= Qt::AlignHCenter;
|
||||||
|
|
||||||
if( value.contains("bottom") )
|
if( value.contains("bottom") )
|
||||||
alignment |= Qt::AlignBottom;
|
alignment |= Qt::AlignBottom;
|
||||||
else if( value.contains("top") )
|
else if( value.contains("top") )
|
||||||
alignment |= Qt::AlignTop;
|
alignment |= Qt::AlignTop;
|
||||||
else
|
else
|
||||||
alignment |= Qt::AlignVCenter;
|
alignment |= Qt::AlignVCenter;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( alignment & Qt::AlignLeft )
|
if ( alignment & Qt::AlignLeft )
|
||||||
@ -319,7 +337,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
{
|
{
|
||||||
renderLabel(painter, overridePoint, coordTransform,
|
renderLabel(painter, overridePoint, coordTransform,
|
||||||
transform, text, font, pen, dx, dy,
|
transform, text, font, pen, dx, dy,
|
||||||
xoffset, yoffset, ang);
|
xoffset, yoffset, ang, width, height, alignment);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -329,7 +347,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
|
|||||||
{
|
{
|
||||||
renderLabel(painter, points[i], coordTransform,
|
renderLabel(painter, points[i], coordTransform,
|
||||||
transform, text, font, pen, dx, dy,
|
transform, text, font, pen, dx, dy,
|
||||||
xoffset, yoffset, ang);
|
xoffset, yoffset, ang, width, height, alignment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -340,7 +358,8 @@ void QgsLabel::renderLabel(QPainter* painter, QgsPoint point,
|
|||||||
QString text, QFont font, QPen pen,
|
QString text, QFont font, QPen pen,
|
||||||
int dx, int dy,
|
int dx, int dy,
|
||||||
double xoffset, double yoffset,
|
double xoffset, double yoffset,
|
||||||
double ang)
|
double ang,
|
||||||
|
int width, int height, int alignment)
|
||||||
{
|
{
|
||||||
// Convert point to projected units
|
// Convert point to projected units
|
||||||
if (coordTransform)
|
if (coordTransform)
|
||||||
@ -372,31 +391,38 @@ void QgsLabel::renderLabel(QPainter* painter, QgsPoint point,
|
|||||||
painter->setFont ( font );
|
painter->setFont ( font );
|
||||||
painter->translate ( x, y );
|
painter->translate ( x, y );
|
||||||
painter->rotate ( -ang );
|
painter->rotate ( -ang );
|
||||||
|
|
||||||
//
|
//
|
||||||
// Draw a buffer behind the text if one is desired
|
// Draw a buffer behind the text if one is desired
|
||||||
//
|
//
|
||||||
if (mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled())
|
if (mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled())
|
||||||
{
|
{
|
||||||
int myBufferSize = static_cast<int>(mLabelAttributes->bufferSize());
|
int myBufferSize = static_cast<int>(mLabelAttributes->bufferSize());
|
||||||
if (mLabelAttributes->bufferColorIsSet())
|
if (mLabelAttributes->bufferColorIsSet())
|
||||||
|
{
|
||||||
|
painter->setPen( mLabelAttributes->bufferColor());
|
||||||
|
}
|
||||||
|
else //default to a white buffer
|
||||||
|
{
|
||||||
|
painter->setPen( Qt::white);
|
||||||
|
}
|
||||||
|
for (int i = dx-myBufferSize; i <= dx+myBufferSize; i++)
|
||||||
|
{
|
||||||
|
for (int j = dy-myBufferSize; j <= dy+myBufferSize; j++)
|
||||||
{
|
{
|
||||||
painter->setPen( mLabelAttributes->bufferColor());
|
if( mLabelAttributes->multilineEnabled() )
|
||||||
}
|
painter->drawText( i , j-height, width, height, alignment, text);
|
||||||
else //default to a white buffer
|
else
|
||||||
{
|
painter->drawText( i , j, text);
|
||||||
painter->setPen( Qt::white);
|
|
||||||
}
|
|
||||||
for (int i = dx-myBufferSize; i <= dx+myBufferSize; i++)
|
|
||||||
{
|
|
||||||
for (int j = dy-myBufferSize; j <= dy+myBufferSize; j++)
|
|
||||||
{
|
|
||||||
painter->drawText( i ,j, text);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->setPen ( pen );
|
painter->setPen ( pen );
|
||||||
painter->drawText ( dx, dy, text );
|
if( mLabelAttributes->multilineEnabled() )
|
||||||
|
painter->drawText ( dx, dy-height, width, height, alignment, text );
|
||||||
|
else
|
||||||
|
painter->drawText ( dx, dy, text );
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -882,6 +908,20 @@ void QgsLabel::readXML( const QDomNode& node )
|
|||||||
setLabelField ( BufferEnabled, _elementFieldIndex(el) );
|
setLabelField ( BufferEnabled, _elementFieldIndex(el) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scratchNode = node.namedItem("multilineenabled");
|
||||||
|
|
||||||
|
if ( scratchNode.isNull() )
|
||||||
|
{
|
||||||
|
QgsDebugMsg("couldn't find QgsLabel ``multilineenabled'' attribute");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
el = scratchNode.toElement();
|
||||||
|
|
||||||
|
mLabelAttributes->setMultilineEnabled ( (bool)el.attribute("on","0").toInt() );
|
||||||
|
setLabelField ( MultilineEnabled, _elementFieldIndex(el) );
|
||||||
|
}
|
||||||
|
|
||||||
} // QgsLabel::readXML()
|
} // QgsLabel::readXML()
|
||||||
|
|
||||||
|
|
||||||
@ -1158,6 +1198,26 @@ void QgsLabel::writeXML(std::ostream& xml)
|
|||||||
{
|
{
|
||||||
xml << "\t\t\t<bufferenabled on=\"" << "\" field=\"" << "\" />\n";
|
xml << "\t\t\t<bufferenabled on=\"" << "\" field=\"" << "\" />\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// multiline enabled
|
||||||
|
if (mLabelAttributes->multilineEnabled())
|
||||||
|
{
|
||||||
|
if (mLabelFieldIdx[MultilineEnabled] != -1)
|
||||||
|
{
|
||||||
|
xml << "\t\t\t<multilineenabled on=\"" << mLabelAttributes->multilineEnabled()
|
||||||
|
<< "\" field=\"" << mLabelFieldIdx[MultilineEnabled] << "\" />\n";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml << "\t\t\t<multilineenabled on=\"" << mLabelAttributes->multilineEnabled()
|
||||||
|
<< "\" field=\"\" />\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xml << "\t\t\t<multilineenabled on=\"" << "\" field=\"" << "\" />\n";
|
||||||
|
}
|
||||||
|
|
||||||
xml << "\t\t</labelattributes>\n";
|
xml << "\t\t</labelattributes>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,6 +73,7 @@ public:
|
|||||||
BorderWidth,
|
BorderWidth,
|
||||||
BorderColor,
|
BorderColor,
|
||||||
BorderStyle,
|
BorderStyle,
|
||||||
|
MultilineEnabled,
|
||||||
LabelFieldCount
|
LabelFieldCount
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +128,8 @@ private:
|
|||||||
QString text, QFont font, QPen pen,
|
QString text, QFont font, QPen pen,
|
||||||
int dx, int dy,
|
int dx, int dy,
|
||||||
double xoffset, double yoffset,
|
double xoffset, double yoffset,
|
||||||
double ang);
|
double ang,
|
||||||
|
int width, int height, int alignment);
|
||||||
|
|
||||||
/** Get label point for simple feature in map units */
|
/** Get label point for simple feature in map units */
|
||||||
void labelPoint ( std::vector<QgsPoint>&, QgsFeature & feature );
|
void labelPoint ( std::vector<QgsPoint>&, QgsFeature & feature );
|
||||||
|
@ -51,7 +51,8 @@ QgsLabelAttributes::QgsLabelAttributes( bool def )
|
|||||||
mBufferStyleIsSet( false ),
|
mBufferStyleIsSet( false ),
|
||||||
mBorderColorIsSet( false ),
|
mBorderColorIsSet( false ),
|
||||||
mBorderWidthIsSet( false ),
|
mBorderWidthIsSet( false ),
|
||||||
mBorderStyleIsSet( false )
|
mBorderStyleIsSet( false ),
|
||||||
|
mMultilineEnabledFlag( false )
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( def ) { // set defaults
|
if ( def ) { // set defaults
|
||||||
@ -388,13 +389,25 @@ Qt::PenStyle QgsLabelAttributes::borderStyle ( void ) const
|
|||||||
return mBorderPen.style();
|
return mBorderPen.style();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Multiline */
|
||||||
|
bool QgsLabelAttributes::multilineEnabled() const
|
||||||
|
{
|
||||||
|
return mMultilineEnabledFlag;
|
||||||
|
}
|
||||||
|
void QgsLabelAttributes::setMultilineEnabled(bool useMultilineFlag)
|
||||||
|
{
|
||||||
|
mMultilineEnabledFlag=useMultilineFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* units */
|
||||||
QString QgsLabelAttributes::unitsName ( int units )
|
QString QgsLabelAttributes::unitsName ( int units )
|
||||||
{
|
{
|
||||||
if ( units == MapUnits ){
|
if ( units == MapUnits )
|
||||||
return QString("mu");
|
{
|
||||||
}
|
return QString("mu");
|
||||||
|
}
|
||||||
return QString("pt");
|
|
||||||
|
return QString("pt");
|
||||||
}
|
}
|
||||||
|
|
||||||
int QgsLabelAttributes::unitsCode ( const QString &name )
|
int QgsLabelAttributes::unitsCode ( const QString &name )
|
||||||
@ -406,6 +419,7 @@ int QgsLabelAttributes::unitsCode ( const QString &name )
|
|||||||
return PointUnits;
|
return PointUnits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* alignment */
|
||||||
QString QgsLabelAttributes::alignmentName ( int alignment )
|
QString QgsLabelAttributes::alignmentName ( int alignment )
|
||||||
{
|
{
|
||||||
std::cout << "QString QgsLabelAttributes::alignmentName (" << alignment << ")" << std::endl;
|
std::cout << "QString QgsLabelAttributes::alignmentName (" << alignment << ")" << std::endl;
|
||||||
|
@ -171,6 +171,9 @@ public:
|
|||||||
void setBorderStyle ( Qt::PenStyle style );
|
void setBorderStyle ( Qt::PenStyle style );
|
||||||
bool borderStyleIsSet ( void ) const;
|
bool borderStyleIsSet ( void ) const;
|
||||||
Qt::PenStyle borderStyle ( void ) const;
|
Qt::PenStyle borderStyle ( void ) const;
|
||||||
|
|
||||||
|
bool multilineEnabled() const;
|
||||||
|
void setMultilineEnabled( bool useMultiline );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/* Text */
|
/* Text */
|
||||||
@ -224,6 +227,9 @@ public:
|
|||||||
bool mBorderColorIsSet;
|
bool mBorderColorIsSet;
|
||||||
bool mBorderWidthIsSet;
|
bool mBorderWidthIsSet;
|
||||||
bool mBorderStyleIsSet;
|
bool mBorderStyleIsSet;
|
||||||
|
|
||||||
|
/** Multiline enablement */
|
||||||
|
bool mMultilineEnabledFlag;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -449,6 +449,16 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" >
|
<item row="5" column="0" >
|
||||||
|
<widget class="QCheckBox" name="chkUseMultiline" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Multiline labels?</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked" >
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="6" column="0" >
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation" >
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user