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:
jef 2008-07-14 20:21:57 +00:00
parent 3c13ecf648
commit b5948bde31
8 changed files with 151 additions and 53 deletions

View File

@ -30,13 +30,14 @@ public:
YOffset,
Angle,
Alignment,
BufferEnabled,
BufferEnabled,
BufferSize,
BufferColor,
BufferBrush,
BorderWidth,
BorderColor,
BorderStyle,
MultilineEnabled,
LabelFieldCount
};
@ -46,7 +47,7 @@ public:
void renderLabel ( QPainter* painter, QgsRect& viewExtent,
QgsCoordinateTransform* coordTransform,
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
@param rnode the DOM node to read

View File

@ -101,6 +101,8 @@ public:
void setBorderStyle ( Qt::PenStyle style );
bool borderStyleIsSet ( ) const;
Qt::PenStyle borderStyle ( ) const;
bool multilineEnabled() const;
void setMultilineEnabled( bool useMultiline );
};

View File

@ -239,6 +239,8 @@ void QgsLabelDialog::init ( )
{
spinBufferSize->setValue(1);
}
//set the state of the multiline enabled checkbox
chkUseMultiline->setChecked(myLabelAttributes->multilineEnabled());
//set the state of the buffer enabled checkbox
chkUseBuffer->setChecked(myLabelAttributes->bufferEnabled());
@ -360,6 +362,7 @@ void QgsLabelDialog::apply()
if (radioBelow->isChecked()) myLabelAttributes->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
if (radioOver->isChecked()) myLabelAttributes->setAlignment(Qt::AlignCenter);
myLabelAttributes->setMultilineEnabled(chkUseMultiline->isChecked());
myLabelAttributes->setBufferEnabled(chkUseBuffer->isChecked());
myLabelAttributes->setBufferColor(mBufferColor);
myTypeInt = 0;

View File

@ -71,7 +71,7 @@ QString QgsLabel::fieldValue ( int attr, QgsFeature &feature )
const QgsAttributeMap& attrs = feature.attributeMap();
QgsAttributeMap::const_iterator it = attrs.find(mLabelFieldIdx[attr]);
if (it != attrs.end())
{
return it->toString();
@ -86,7 +86,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
const QgsCoordinateTransform* coordTransform,
const QgsMapToPixel *transform,
QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes,
double sizeScale )
double sizeScale )
{
QPen pen;
@ -137,20 +137,20 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
int sizeType;
value = fieldValue ( SizeType, feature );
if( value.isEmpty() )
sizeType = mLabelAttributes->sizeType();
sizeType = mLabelAttributes->sizeType();
else
{
value = value.toLower();
if( value.compare("mapunits") == 0 )
sizeType = QgsLabelAttributes::MapUnits;
else
sizeType = QgsLabelAttributes::PointUnits;
value = value.toLower();
if( value.compare("mapunits") == 0 )
sizeType = QgsLabelAttributes::MapUnits;
else
sizeType = QgsLabelAttributes::PointUnits;
}
if ( sizeType == QgsLabelAttributes::MapUnits )
{
size *= scale;
} else {
size *= sizeScale;
size *= sizeScale;
}
if(size>0.0)
font.setPointSizeF ( size );
@ -214,8 +214,26 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
/* Alignment */
int alignment;
QFontMetrics fm ( font );
int width = fm.width ( text );
int height = fm.height();
int width, 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 dy = 0;
@ -226,23 +244,23 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
}
else
{
value = value.toLower();
value = value.toLower();
alignment=0;
alignment=0;
if ( value.contains("left") )
alignment |= Qt::AlignLeft;
else if( value.contains("right") )
alignment |= Qt::AlignRight;
else
alignment |= Qt::AlignHCenter;
if ( value.contains("left") )
alignment |= Qt::AlignLeft;
else if( value.contains("right") )
alignment |= Qt::AlignRight;
else
alignment |= Qt::AlignHCenter;
if( value.contains("bottom") )
alignment |= Qt::AlignBottom;
else if( value.contains("top") )
alignment |= Qt::AlignTop;
else
alignment |= Qt::AlignVCenter;
if( value.contains("bottom") )
alignment |= Qt::AlignBottom;
else if( value.contains("top") )
alignment |= Qt::AlignTop;
else
alignment |= Qt::AlignVCenter;
}
if ( alignment & Qt::AlignLeft )
@ -319,7 +337,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
{
renderLabel(painter, overridePoint, coordTransform,
transform, text, font, pen, dx, dy,
xoffset, yoffset, ang);
xoffset, yoffset, ang, width, height, alignment);
}
else
{
@ -329,7 +347,7 @@ void QgsLabel::renderLabel( QPainter * painter, const QgsRect& viewExtent,
{
renderLabel(painter, points[i], coordTransform,
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,
int dx, int dy,
double xoffset, double yoffset,
double ang)
double ang,
int width, int height, int alignment)
{
// Convert point to projected units
if (coordTransform)
@ -372,31 +391,38 @@ void QgsLabel::renderLabel(QPainter* painter, QgsPoint point,
painter->setFont ( font );
painter->translate ( x, y );
painter->rotate ( -ang );
//
// Draw a buffer behind the text if one is desired
//
if (mLabelAttributes->bufferSizeIsSet() && mLabelAttributes->bufferEnabled())
{
int myBufferSize = static_cast<int>(mLabelAttributes->bufferSize());
if (mLabelAttributes->bufferColorIsSet())
int myBufferSize = static_cast<int>(mLabelAttributes->bufferSize());
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());
}
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->drawText( i ,j, text);
}
if( mLabelAttributes->multilineEnabled() )
painter->drawText( i , j-height, width, height, alignment, text);
else
painter->drawText( i , j, text);
}
}
}
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();
}
@ -882,6 +908,20 @@ void QgsLabel::readXML( const QDomNode& node )
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()
@ -1158,6 +1198,26 @@ void QgsLabel::writeXML(std::ostream& xml)
{
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";
}

View File

@ -73,6 +73,7 @@ public:
BorderWidth,
BorderColor,
BorderStyle,
MultilineEnabled,
LabelFieldCount
};
@ -127,7 +128,8 @@ private:
QString text, QFont font, QPen pen,
int dx, int dy,
double xoffset, double yoffset,
double ang);
double ang,
int width, int height, int alignment);
/** Get label point for simple feature in map units */
void labelPoint ( std::vector<QgsPoint>&, QgsFeature & feature );

View File

@ -51,7 +51,8 @@ QgsLabelAttributes::QgsLabelAttributes( bool def )
mBufferStyleIsSet( false ),
mBorderColorIsSet( false ),
mBorderWidthIsSet( false ),
mBorderStyleIsSet( false )
mBorderStyleIsSet( false ),
mMultilineEnabledFlag( false )
{
if ( def ) { // set defaults
@ -388,13 +389,25 @@ Qt::PenStyle QgsLabelAttributes::borderStyle ( void ) const
return mBorderPen.style();
}
/* Multiline */
bool QgsLabelAttributes::multilineEnabled() const
{
return mMultilineEnabledFlag;
}
void QgsLabelAttributes::setMultilineEnabled(bool useMultilineFlag)
{
mMultilineEnabledFlag=useMultilineFlag;
}
/* units */
QString QgsLabelAttributes::unitsName ( int units )
{
if ( units == MapUnits ){
return QString("mu");
}
return QString("pt");
if ( units == MapUnits )
{
return QString("mu");
}
return QString("pt");
}
int QgsLabelAttributes::unitsCode ( const QString &name )
@ -406,6 +419,7 @@ int QgsLabelAttributes::unitsCode ( const QString &name )
return PointUnits;
}
/* alignment */
QString QgsLabelAttributes::alignmentName ( int alignment )
{
std::cout << "QString QgsLabelAttributes::alignmentName (" << alignment << ")" << std::endl;

View File

@ -171,6 +171,9 @@ public:
void setBorderStyle ( Qt::PenStyle style );
bool borderStyleIsSet ( void ) const;
Qt::PenStyle borderStyle ( void ) const;
bool multilineEnabled() const;
void setMultilineEnabled( bool useMultiline );
protected:
/* Text */
@ -224,6 +227,9 @@ public:
bool mBorderColorIsSet;
bool mBorderWidthIsSet;
bool mBorderStyleIsSet;
/** Multiline enablement */
bool mMultilineEnabledFlag;
};
#endif

View File

@ -449,6 +449,16 @@
</widget>
</item>
<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>
<property name="orientation" >
<enum>Qt::Vertical</enum>