29 #include <QDomDocument>
30 #include <QDomElement>
35 , mTitle(
tr(
"Legend" ) )
36 , mFontColor( QColor( 0, 0, 0 ) )
41 , mSplitLayer( false )
42 , mEqualColumnWidth( false )
78 Q_UNUSED( itemStyle );
86 QStandardItem* rootItem =
mLegendModel.invisibleRootItem();
87 if ( !rootItem )
return size;
93 painter->setPen( QPen( QColor( 0, 0, 0 ) ) );
100 qreal maxColumnWidth = 0;
103 foreach (
Atom atom, atomList )
105 maxColumnWidth = qMax( atom.
size.width(), maxColumnWidth );
113 bool firstInColumn =
true;
114 double columnMaxHeight = 0;
115 qreal columnWidth = 0;
117 foreach (
Atom atom, atomList )
119 if ( atom.
column > column )
130 point.ry() = columnTop;
133 firstInColumn =
true;
135 if ( !firstInColumn )
140 QSizeF atomSize =
drawAtom( atom, painter, point );
141 columnWidth = qMax( atomSize.width(), columnWidth );
143 point.ry() += atom.
size.height();
144 columnMaxHeight = qMax( point.y() - columnTop, columnMaxHeight );
146 firstInColumn =
false;
150 size.rheight() = columnTop + columnMaxHeight +
mBoxSpace;
151 size.rwidth() = point.x();
159 Qt::AlignmentFlag halignment;
160 if (
mColumnCount > 1 && titleSize.width() + 2 * mBoxSpace < size.width() )
162 halignment = Qt::AlignHCenter;
163 point.rx() = mBoxSpace + size.rwidth() / 2;
167 halignment = Qt::AlignLeft;
169 size.rwidth() = qMax( titleSize.width() + 2 *
mBoxSpace, size.width() );
176 if ( painter && size.height() > rect().height() )
178 setSceneRect( QRectF( pos().x(), pos().y(), rect().width(), size.height() ) );
180 if ( painter && size.width() > rect().width() )
182 setSceneRect( QRectF( pos().x(), pos().y(), size.width(), rect().height() ) );
203 if (
mTitle.isEmpty() )
return size;
207 double y = point.y();
211 for ( QStringList::Iterator titlePart = lines.begin(); titlePart != lines.end(); ++titlePart )
217 double left = halignment == Qt::AlignLeft ? point.x() : point.x() - width / 2;
219 QRectF rect( left, y, width, height );
223 size.rwidth() = qMax( width, size.width() );
226 if ( titlePart != lines.end() )
231 size.rheight() = y - point.y();
240 if ( !groupItem )
return size;
242 double y = point.y();
247 for ( QStringList::Iterator groupPart = lines.begin(); groupPart != lines.end(); ++groupPart )
252 size.rwidth() = qMax( width, size.width() );
253 if ( groupPart != lines.end() )
258 size.rheight() = y - point.y();
265 if ( !layerItem )
return size;
268 if ( layerItem->text().isEmpty() )
return size;
270 double y = point.y();
275 for ( QStringList::Iterator layerItemPart = lines.begin(); layerItemPart != lines.end(); ++layerItemPart )
280 size.rwidth() = qMax( width, size.width() );
281 if ( layerItemPart != lines.end() )
286 size.rheight() = y - point.y();
294 QgsDebugMsg( QString(
"width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) );
295 if ( size.isValid() )
297 setSceneRect( QRectF( pos().x(), pos().y(), size.width(), size.height() ) );
303 QSizeF symbolSize( 0, 0 );
304 QSizeF labelSize( 0, 0 );
305 if ( !symbolItem )
return Nucleon();
314 double realSymbolHeight;
325 opacity = currentLayer->getTransparency();
330 QString text = symbolItem->text();
338 symbolNg = symbolV2Item->
symbolV2();
342 double x = point.x();
347 symbolSize.rwidth() = qMax( x - point.x(),
mSymbolWidth );
348 symbolSize.rheight() = qMax( realSymbolHeight,
mSymbolHeight );
350 else if ( rasterItem )
354 QIcon symbolIcon = symbolItem->icon();
355 if ( !symbolIcon.isNull() && symbolItem->text().isEmpty() )
358 QList<QSize> sizes = symbolIcon.availableSizes();
360 double maxHeight = 0;
361 foreach ( QSize
size, sizes )
363 if ( maxWidth < size.width() ) maxWidth = size.width();
364 if ( maxHeight < size.height() ) maxHeight = size.height();
366 QSize maxSize( maxWidth, maxHeight );
369 QImage legend = symbolIcon.pixmap( maxWidth, maxHeight ).toImage();
381 painter->setBrush( rasterItem->
color() );
390 QIcon symbolIcon = symbolItem->icon();
391 if ( !symbolIcon.isNull() )
402 double labelX = point.x() + qMax((
double ) symbolSize.width(), labelXOffset );
408 labelSize.rheight() = lines.count() * textHeight + ( lines.count() - 1 ) *
mlineSpacing;
411 if ( labelSize.height() < symbolSize.height() )
413 labelY = point.y() + symbolSize.height() / 2 + textHeight / 2;
417 labelY = point.y() + textHeight;
420 for ( QStringList::Iterator itemPart = lines.begin(); itemPart != lines.end(); ++itemPart )
424 if ( itemPart != lines.end() )
431 nucleon.
item = symbolItem;
435 double width = qMax((
double ) symbolSize.width(), labelXOffset ) + labelSize.width();
436 double height = qMax( symbolSize.height(), labelSize.height() );
437 nucleon.
size = QSizeF( width, height );
452 QPaintDevice* paintDevice = p->device();
457 rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
462 double mmPerMapUnit = 1;
474 double widthOffset = 0;
475 double heightOffset = 0;
479 size = markerSymbol->
size();
484 height *= mmPerMapUnit;
485 width *= mmPerMapUnit;
486 markerSymbol->
setSize( width );
501 p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
502 p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
504 if ( markerSymbol && sizeInMapUnits )
509 s->
drawPreviewIcon( p, QSize( width * rasterScaleFactor, height * rasterScaleFactor ) );
511 if ( markerSymbol && sizeInMapUnits )
518 currentXPosition += width;
519 currentXPosition += 2 * widthOffset;
520 symbolHeight = height + 2 * heightOffset;
535 return QStringList();
574 QDomElement composerLegendElem = doc.createElement(
"ComposerLegend" );
575 elem.appendChild( composerLegendElem );
578 composerLegendElem.setAttribute(
"title",
mTitle );
579 composerLegendElem.setAttribute(
"columnCount", QString::number(
mColumnCount ) );
580 composerLegendElem.setAttribute(
"splitLayer", QString::number(
mSplitLayer ) );
581 composerLegendElem.setAttribute(
"equalColumnWidth", QString::number(
mEqualColumnWidth ) );
583 composerLegendElem.setAttribute(
"boxSpace", QString::number(
mBoxSpace ) );
584 composerLegendElem.setAttribute(
"columnSpace", QString::number(
mColumnSpace ) );
586 composerLegendElem.setAttribute(
"symbolWidth", QString::number(
mSymbolWidth ) );
587 composerLegendElem.setAttribute(
"symbolHeight", QString::number(
mSymbolHeight ) );
588 composerLegendElem.setAttribute(
"wmsLegendWidth", QString::number(
mWmsLegendWidth ) );
589 composerLegendElem.setAttribute(
"wmsLegendHeight", QString::number(
mWmsLegendHeight ) );
590 composerLegendElem.setAttribute(
"wrapChar",
mWrapChar );
591 composerLegendElem.setAttribute(
"fontColor",
mFontColor.name() );
598 QDomElement composerLegendStyles = doc.createElement(
"styles" );
599 composerLegendElem.appendChild( composerLegendStyles );
610 return _writeXML( composerLegendElem, doc );
615 if ( itemElem.isNull() )
621 mTitle = itemElem.attribute(
"title" );
622 mColumnCount = itemElem.attribute(
"columnCount",
"1" ).toInt();
624 mSplitLayer = itemElem.attribute(
"splitLayer",
"0" ).toInt() == 1;
627 QDomNodeList stylesNodeList = itemElem.elementsByTagName(
"styles" );
628 if ( stylesNodeList.size() > 0 )
630 QDomNode stylesNode = stylesNodeList.at( 0 );
631 for (
int i = 0; i < stylesNode.childNodes().size(); i++ )
633 QDomElement styleElem = stylesNode.childNodes().at( i ).toElement();
635 style.
readXML( styleElem, doc );
636 QString name = styleElem.attribute(
"name" );
649 mFontColor.setNamedColor( itemElem.attribute(
"fontColor",
"#000000" ) );
652 mBoxSpace = itemElem.attribute(
"boxSpace",
"2.0" ).toDouble();
653 mColumnSpace = itemElem.attribute(
"columnSpace",
"2.0" ).toDouble();
655 mSymbolWidth = itemElem.attribute(
"symbolWidth",
"7.0" ).toDouble();
656 mSymbolHeight = itemElem.attribute(
"symbolHeight",
"14.0" ).toDouble();
657 mWmsLegendWidth = itemElem.attribute(
"wmsLegendWidth",
"50" ).toDouble();
658 mWmsLegendHeight = itemElem.attribute(
"wmsLegendHeight",
"25" ).toDouble();
660 mWrapChar = itemElem.attribute(
"wrapChar" );
663 if ( !itemElem.attribute(
"map" ).isEmpty() )
669 QDomNodeList modelNodeList = itemElem.elementsByTagName(
"Model" );
670 if ( modelNodeList.size() > 0 )
672 QDomElement modelElem = modelNodeList.at( 0 ).toElement();
677 QDomNodeList composerItemList = itemElem.elementsByTagName(
"ComposerItem" );
678 if ( composerItemList.size() > 0 )
680 QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
686 QString titleFontString = itemElem.attribute(
"titleFont" );
687 if ( !titleFontString.isEmpty() )
692 QString groupFontString = itemElem.attribute(
"groupFont" );
693 if ( !groupFontString.isEmpty() )
699 QString layerFontString = itemElem.attribute(
"layerFont" );
700 if ( !layerFontString.isEmpty() )
705 QString itemFontString = itemElem.attribute(
"itemFont" );
706 if ( !itemFontString.isEmpty() )
711 if ( !itemElem.attribute(
"groupSpace" ).isEmpty() )
715 if ( !itemElem.attribute(
"layerSpace" ).isEmpty() )
719 if ( !itemElem.attribute(
"symbolSpace" ).isEmpty() )
753 list << stringToSplt;
763 if ( !rootItem )
return atoms;
767 for (
int i = 0; i < rootItem->rowCount(); i++ )
769 QStandardItem* currentLayerItem = rootItem->child( i );
771 if ( !currentLegendItem )
continue;
777 QList<Atom> groupAtoms =
createAtomList( currentLayerItem, splitLayer );
780 nucleon.
item = currentLegendItem;
783 if ( groupAtoms.size() > 0 )
788 groupAtoms[0].nucleons.prepend( nucleon );
789 groupAtoms[0].size.rheight() += nucleon.
size.height();
790 groupAtoms[0].size.rwidth() = qMax( nucleon.
size.width(), groupAtoms[0].size.width() );
797 atom.
size.rwidth() += nucleon.
size.width();
798 atom.
size.rheight() += nucleon.
size.height();
799 atom.
size.rwidth() = qMax( nucleon.
size.width(), atom.
size.width() );
800 groupAtoms.append( atom );
802 atoms.append( groupAtoms );
811 nucleon.
item = currentLegendItem;
814 atom.
size.rwidth() = nucleon.
size.width();
815 atom.
size.rheight() = nucleon.
size.height();
818 QList<Atom> layerAtoms;
820 for (
int j = 0; j < currentLegendItem->rowCount(); j++ )
823 if ( !symbolItem )
continue;
831 atom.
size.rwidth() = qMax( symbolNucleon.
size.width(), atom.
size.width() );
838 atom.
size.rheight() += symbolNucleon.
size.height();
839 atom.
nucleons.append( symbolNucleon );
844 symbolAtom.
nucleons.append( symbolNucleon );
845 symbolAtom.
size.rwidth() = symbolNucleon.
size.width();
846 symbolAtom.
size.rheight() = symbolNucleon.
size.height();
847 layerAtoms.append( symbolAtom );
850 layerAtoms.prepend( atom );
851 atoms.append( layerAtoms );
867 if ( !item )
continue;
872 if ( !groupItem )
continue;
885 if ( !layerItem )
continue;
905 size.rwidth() = qMax( symbolNucleon.
size.width(), size.width() );
907 point.ry() += nucleon.
size.height();
915 if ( atom.
nucleons.size() == 0 )
return 0;
920 if ( !item )
return 0;
947 double totalHeight = 0;
949 qreal maxAtomHeight = 0;
950 foreach (
Atom atom, atomList )
956 totalHeight += atom.
size.height();
957 maxAtomHeight = qMax( atom.
size.height(), maxAtomHeight );
968 int currentColumn = 0;
969 int currentColumnAtomCount = 0;
970 double currentColumnHeight = 0;
971 double maxColumnHeight = 0;
972 double closedColumnsHeight = 0;
974 for (
int i = 0; i < atomList.size(); i++ )
976 Atom atom = atomList[i];
977 double currentHeight = currentColumnHeight;
982 currentHeight += atom.
size.height();
985 avgColumnHeight = ( totalHeight - closedColumnsHeight ) / (
mColumnCount - currentColumn );
986 if (( currentHeight - avgColumnHeight ) > atom.
size.height() / 2
987 && currentColumnAtomCount > 0
988 && currentHeight > maxAtomHeight
989 && currentHeight > maxColumnHeight
994 currentColumnAtomCount = 0;
995 closedColumnsHeight += currentColumnHeight;
996 currentColumnHeight = atom.
size.height();
1000 currentColumnHeight = currentHeight;
1002 atomList[i].column = currentColumn;
1003 currentColumnAtomCount++;
1004 maxColumnHeight = qMax( currentColumnHeight, maxColumnHeight );
1010 QMap<QString, qreal> maxSymbolWidth;
1011 for (
int i = 0; i < atomList.size(); i++ )
1013 for (
int j = 0; j < atomList[i].nucleons.size(); j++ )
1016 if ( !item )
continue;
1021 QString key = QString(
"%1-%2" ).arg(( qulonglong )item->parent() ).arg( atomList[i].column );
1022 maxSymbolWidth[key] = qMax( atomList[i].nucleons[j].symbolSize.width(), maxSymbolWidth[key] );
1026 for (
int i = 0; i < atomList.size(); i++ )
1028 for (
int j = 0; j < atomList[i].nucleons.size(); j++ )
1031 if ( !item )
continue;
1036 QString key = QString(
"%1-%2" ).arg(( qulonglong )item->parent() ).arg( atomList[i].column );
1039 atomList[i].nucleons[j].labelXOffset = maxSymbolWidth[key] + space;
1040 atomList[i].nucleons[j].size.rwidth() = maxSymbolWidth[key] + space + atomList[i].nucleons[j].labelSize.width();