Skip to content

Commit

Permalink
add support for multiline labels (applies #1138)
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@8775 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
jef committed Jul 14, 2008
1 parent 928d63c commit ba4948a
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 53 deletions.
5 changes: 3 additions & 2 deletions python/core/qgslabel.sip
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ public:
YOffset,
Angle,
Alignment,
BufferEnabled,
BufferEnabled,
BufferSize,
BufferColor,
BufferBrush,
BorderWidth,
BorderColor,
BorderStyle,
MultilineEnabled,
LabelFieldCount
};

Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion python/core/qgslabelattributes.sip
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ public:
void setBorderStyle ( Qt::PenStyle style );
bool borderStyleIsSet ( ) const;
Qt::PenStyle borderStyle ( ) const;


bool multilineEnabled() const;
void setMultilineEnabled( bool useMultiline );
};

3 changes: 3 additions & 0 deletions src/app/qgslabeldialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand Down Expand Up @@ -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;
Expand Down
146 changes: 103 additions & 43 deletions src/core/qgslabel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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;
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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;

Expand All @@ -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 )
Expand Down Expand Up @@ -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
{
Expand All @@ -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);
}
}
}
Expand All @@ -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)
Expand Down Expand Up @@ -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())
{
painter->setPen( mLabelAttributes->bufferColor());
}
else //default to a white buffer
{
painter->setPen( Qt::white);
}
for (int i = dx-myBufferSize; i <= dx+myBufferSize; i++)
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++)
{
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();
}

Expand Down Expand Up @@ -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()


Expand Down Expand Up @@ -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";
}

4 changes: 3 additions & 1 deletion src/core/qgslabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class CORE_EXPORT QgsLabel
BorderWidth,
BorderColor,
BorderStyle,
MultilineEnabled,
LabelFieldCount
};

Expand Down Expand Up @@ -127,7 +128,8 @@ class CORE_EXPORT QgsLabel
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 );
Expand Down
26 changes: 20 additions & 6 deletions src/core/qgslabelattributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ QgsLabelAttributes::QgsLabelAttributes( bool def )
mBufferStyleIsSet( false ),
mBorderColorIsSet( false ),
mBorderWidthIsSet( false ),
mBorderStyleIsSet( false )
mBorderStyleIsSet( false ),
mMultilineEnabledFlag( false )
{

if ( def ) { // set defaults
Expand Down Expand Up @@ -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 )
Expand All @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions src/core/qgslabelattributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class CORE_EXPORT QgsLabelAttributes
void setBorderStyle ( Qt::PenStyle style );
bool borderStyleIsSet ( void ) const;
Qt::PenStyle borderStyle ( void ) const;

bool multilineEnabled() const;
void setMultilineEnabled( bool useMultiline );

protected:
/* Text */
Expand Down Expand Up @@ -224,6 +227,9 @@ class CORE_EXPORT QgsLabelAttributes
bool mBorderColorIsSet;
bool mBorderWidthIsSet;
bool mBorderStyleIsSet;

/** Multiline enablement */
bool mMultilineEnabledFlag;
};

#endif
10 changes: 10 additions & 0 deletions src/ui/qgslabeldialogbase.ui
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down

0 comments on commit ba4948a

Please sign in to comment.