29 #include <QDomDocument>
30 #include <QDomElement>
35 , mTitle(
tr(
"Legend" ) )
36 , mFontColor( QColor( 0, 0, 0 ) )
41 , mSplitLayer( false )
42 , mEqualColumnWidth( false )
76 Q_UNUSED( itemStyle );
84 QStandardItem* rootItem =
mLegendModel.invisibleRootItem();
85 if ( !rootItem )
return size;
91 painter->setPen( QPen( QColor( 0, 0, 0 ) ) );
98 qreal maxColumnWidth = 0;
101 foreach (
Atom atom, atomList )
103 maxColumnWidth = qMax( atom.
size.width(), maxColumnWidth );
111 bool firstInColumn =
true;
112 double columnMaxHeight = 0;
113 qreal columnWidth = 0;
115 foreach (
Atom atom, atomList )
117 if ( atom.
column > column )
128 point.ry() = columnTop;
131 firstInColumn =
true;
133 if ( !firstInColumn )
138 QSizeF atomSize =
drawAtom( atom, painter, point );
139 columnWidth = qMax( atomSize.width(), columnWidth );
141 point.ry() += atom.
size.height();
142 columnMaxHeight = qMax( point.y() - columnTop, columnMaxHeight );
144 firstInColumn =
false;
148 size.rheight() = columnTop + columnMaxHeight +
mBoxSpace;
149 size.rwidth() = point.x();
157 Qt::AlignmentFlag halignment;
158 if (
mColumnCount > 1 && titleSize.width() + 2 * mBoxSpace < size.width() )
160 halignment = Qt::AlignHCenter;
161 point.rx() = mBoxSpace + size.rwidth() / 2;
165 halignment = Qt::AlignLeft;
167 size.rwidth() = qMax( titleSize.width() + 2 *
mBoxSpace, size.width() );
174 if ( painter && size.height() > rect().height() )
176 setSceneRect( QRectF( transform().dx(), transform().dy(), rect().width(), size.height() ) );
178 if ( painter && size.width() > rect().width() )
180 setSceneRect( QRectF( transform().dx(), transform().dy(), size.width(), rect().height() ) );
201 if (
mTitle.isEmpty() )
return size;
205 double y = point.y();
209 for ( QStringList::Iterator titlePart = lines.begin(); titlePart != lines.end(); ++titlePart )
215 double left = halignment == Qt::AlignLeft ? point.x() : point.x() - width / 2;
217 QRectF rect( left, y, width, height );
221 size.rwidth() = qMax( width, size.width() );
224 if ( titlePart != lines.end() )
229 size.rheight() = y - point.y();
238 if ( !groupItem )
return size;
240 double y = point.y();
245 for ( QStringList::Iterator groupPart = lines.begin(); groupPart != lines.end(); ++groupPart )
250 size.rwidth() = qMax( width, size.width() );
251 if ( groupPart != lines.end() )
256 size.rheight() = y - point.y();
263 if ( !layerItem )
return size;
266 if ( layerItem->text().isEmpty() )
return size;
268 double y = point.y();
273 for ( QStringList::Iterator layerItemPart = lines.begin(); layerItemPart != lines.end(); ++layerItemPart )
278 size.rwidth() = qMax( width, size.width() );
279 if ( layerItemPart != lines.end() )
284 size.rheight() = y - point.y();
292 QgsDebugMsg( QString(
"width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) );
293 if ( size.isValid() )
295 setSceneRect( QRectF( transform().dx(), transform().dy(), size.width(), size.height() ) );
301 QSizeF symbolSize( 0, 0 );
302 QSizeF labelSize( 0, 0 );
303 if ( !symbolItem )
return Nucleon();
312 double realSymbolHeight;
323 opacity = currentLayer->getTransparency();
328 QString text = symbolItem->text();
336 symbolNg = symbolV2Item->
symbolV2();
340 double x = point.x();
345 symbolSize.rwidth() = qMax( x - point.x(),
mSymbolWidth );
346 symbolSize.rheight() = qMax( realSymbolHeight,
mSymbolHeight );
348 else if ( rasterItem )
352 painter->setBrush( rasterItem->
color() );
360 QIcon symbolIcon = symbolItem->icon();
361 if ( !symbolIcon.isNull() )
372 double labelX = point.x() + qMax((
double ) symbolSize.width(), labelXOffset );
378 labelSize.rheight() = lines.count() * textHeight + ( lines.count() - 1 ) *
mlineSpacing;
381 if ( labelSize.height() < symbolSize.height() )
383 labelY = point.y() + symbolSize.height() / 2 + textHeight / 2;
387 labelY = point.y() + textHeight;
390 for ( QStringList::Iterator itemPart = lines.begin(); itemPart != lines.end(); ++itemPart )
394 if ( itemPart != lines.end() )
401 nucleon.
item = symbolItem;
405 double width = qMax((
double ) symbolSize.width(), labelXOffset ) + labelSize.width();
406 double height = qMax( symbolSize.height(), labelSize.height() );
407 nucleon.
size = QSizeF( width, height );
422 QPaintDevice* paintDevice = p->device();
427 rasterScaleFactor = ( paintDevice->logicalDpiX() + paintDevice->logicalDpiY() ) / 2.0 / 25.4;
432 double mmPerMapUnit = 1;
444 double widthOffset = 0;
445 double heightOffset = 0;
449 size = markerSymbol->
size();
454 height *= mmPerMapUnit;
455 width *= mmPerMapUnit;
456 markerSymbol->
setSize( width );
471 p->translate( currentXPosition + widthOffset, currentYCoord + heightOffset );
472 p->scale( 1.0 / rasterScaleFactor, 1.0 / rasterScaleFactor );
474 if ( markerSymbol && sizeInMapUnits )
479 s->
drawPreviewIcon( p, QSize( width * rasterScaleFactor, height * rasterScaleFactor ) );
481 if ( markerSymbol && sizeInMapUnits )
488 currentXPosition += width;
489 currentXPosition += 2 * widthOffset;
490 symbolHeight = height + 2 * heightOffset;
505 return QStringList();
544 QDomElement composerLegendElem = doc.createElement(
"ComposerLegend" );
545 elem.appendChild( composerLegendElem );
548 composerLegendElem.setAttribute(
"title",
mTitle );
549 composerLegendElem.setAttribute(
"columnCount", QString::number(
mColumnCount ) );
550 composerLegendElem.setAttribute(
"splitLayer", QString::number(
mSplitLayer ) );
551 composerLegendElem.setAttribute(
"equalColumnWidth", QString::number(
mEqualColumnWidth ) );
553 composerLegendElem.setAttribute(
"boxSpace", QString::number(
mBoxSpace ) );
554 composerLegendElem.setAttribute(
"columnSpace", QString::number(
mColumnSpace ) );
556 composerLegendElem.setAttribute(
"symbolWidth", QString::number(
mSymbolWidth ) );
557 composerLegendElem.setAttribute(
"symbolHeight", QString::number(
mSymbolHeight ) );
558 composerLegendElem.setAttribute(
"wrapChar",
mWrapChar );
559 composerLegendElem.setAttribute(
"fontColor",
mFontColor.name() );
566 QDomElement composerLegendStyles = doc.createElement(
"styles" );
567 composerLegendElem.appendChild( composerLegendStyles );
578 return _writeXML( composerLegendElem, doc );
583 if ( itemElem.isNull() )
589 mTitle = itemElem.attribute(
"title" );
590 mColumnCount = itemElem.attribute(
"columnCount",
"1" ).toInt();
592 mSplitLayer = itemElem.attribute(
"splitLayer",
"0" ).toInt() == 1;
595 QDomNodeList stylesNodeList = itemElem.elementsByTagName(
"styles" );
596 if ( stylesNodeList.size() > 0 )
598 QDomNode stylesNode = stylesNodeList.at( 0 );
599 for (
int i = 0; i < stylesNode.childNodes().size(); i++ )
601 QDomElement styleElem = stylesNode.childNodes().at( i ).toElement();
603 style.
readXML( styleElem, doc );
604 QString name = styleElem.attribute(
"name" );
617 mFontColor.setNamedColor( itemElem.attribute(
"fontColor",
"#000000" ) );
620 mBoxSpace = itemElem.attribute(
"boxSpace",
"2.0" ).toDouble();
621 mColumnSpace = itemElem.attribute(
"columnSpace",
"2.0" ).toDouble();
623 mSymbolWidth = itemElem.attribute(
"symbolWidth",
"7.0" ).toDouble();
624 mSymbolHeight = itemElem.attribute(
"symbolHeight",
"14.0" ).toDouble();
626 mWrapChar = itemElem.attribute(
"wrapChar" );
629 if ( !itemElem.attribute(
"map" ).isEmpty() )
635 QDomNodeList modelNodeList = itemElem.elementsByTagName(
"Model" );
636 if ( modelNodeList.size() > 0 )
638 QDomElement modelElem = modelNodeList.at( 0 ).toElement();
643 QDomNodeList composerItemList = itemElem.elementsByTagName(
"ComposerItem" );
644 if ( composerItemList.size() > 0 )
646 QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
652 QString titleFontString = itemElem.attribute(
"titleFont" );
653 if ( !titleFontString.isEmpty() )
658 QString groupFontString = itemElem.attribute(
"groupFont" );
659 if ( !groupFontString.isEmpty() )
665 QString layerFontString = itemElem.attribute(
"layerFont" );
666 if ( !layerFontString.isEmpty() )
671 QString itemFontString = itemElem.attribute(
"itemFont" );
672 if ( !itemFontString.isEmpty() )
677 if ( !itemElem.attribute(
"groupSpace" ).isEmpty() )
681 if ( !itemElem.attribute(
"layerSpace" ).isEmpty() )
685 if ( !itemElem.attribute(
"symbolSpace" ).isEmpty() )
719 list << stringToSplt;
729 if ( !rootItem )
return atoms;
733 for (
int i = 0; i < rootItem->rowCount(); i++ )
735 QStandardItem* currentLayerItem = rootItem->child( i );
737 if ( !currentLegendItem )
continue;
743 QList<Atom> groupAtoms =
createAtomList( currentLayerItem, splitLayer );
746 nucleon.
item = currentLegendItem;
749 if ( groupAtoms.size() > 0 )
754 groupAtoms[0].nucleons.prepend( nucleon );
755 groupAtoms[0].size.rheight() += nucleon.
size.height();
756 groupAtoms[0].size.rwidth() = qMax( nucleon.
size.width(), groupAtoms[0].size.width() );
763 atom.
size.rwidth() += nucleon.
size.width();
764 atom.
size.rheight() += nucleon.
size.height();
765 atom.
size.rwidth() = qMax( nucleon.
size.width(), atom.
size.width() );
766 groupAtoms.append( atom );
768 atoms.append( groupAtoms );
777 nucleon.
item = currentLegendItem;
780 atom.
size.rwidth() = nucleon.
size.width();
781 atom.
size.rheight() = nucleon.
size.height();
784 QList<Atom> layerAtoms;
786 for (
int j = 0; j < currentLegendItem->rowCount(); j++ )
789 if ( !symbolItem )
continue;
797 atom.
size.rwidth() = qMax( symbolNucleon.
size.width(), atom.
size.width() );
805 atom.
size.rheight() += symbolNucleon.
size.height();
806 atom.
nucleons.append( symbolNucleon );
811 symbolAtom.
nucleons.append( symbolNucleon );
812 symbolAtom.
size.rwidth() = symbolNucleon.
size.width();
813 symbolAtom.
size.rheight() = symbolNucleon.
size.height();
814 layerAtoms.append( symbolAtom );
817 layerAtoms.prepend( atom );
818 atoms.append( layerAtoms );
834 if ( !item )
continue;
839 if ( !groupItem )
continue;
852 if ( !layerItem )
continue;
872 size.rwidth() = qMax( symbolNucleon.
size.width(), size.width() );
874 point.ry() += nucleon.
size.height();
882 if ( atom.
nucleons.size() == 0 )
return 0;
887 if ( !item )
return 0;
914 double totalHeight = 0;
916 qreal maxAtomHeight = 0;
917 foreach (
Atom atom, atomList )
923 totalHeight += atom.
size.height();
924 maxAtomHeight = qMax( atom.
size.height(), maxAtomHeight );
935 int currentColumn = 0;
936 int currentColumnAtomCount = 0;
937 double currentColumnHeight = 0;
938 double maxColumnHeight = 0;
939 double closedColumnsHeight = 0;
941 for (
int i = 0; i < atomList.size(); i++ )
943 Atom atom = atomList[i];
944 double currentHeight = currentColumnHeight;
949 currentHeight += atom.
size.height();
952 avgColumnHeight = ( totalHeight - closedColumnsHeight ) / (
mColumnCount - currentColumn );
953 if (( currentHeight - avgColumnHeight ) > atom.
size.height() / 2
954 && currentColumnAtomCount > 0
955 && currentHeight > maxAtomHeight
956 && currentHeight > maxColumnHeight
961 currentColumnAtomCount = 0;
962 closedColumnsHeight += currentColumnHeight;
963 currentColumnHeight = atom.
size.height();
967 currentColumnHeight = currentHeight;
969 atomList[i].column = currentColumn;
970 currentColumnAtomCount++;
971 maxColumnHeight = qMax( currentColumnHeight, maxColumnHeight );
977 QMap<QString, qreal> maxSymbolWidth;
978 for (
int i = 0; i < atomList.size(); i++ )
980 for (
int j = 0; j < atomList[i].nucleons.size(); j++ )
983 if ( !item )
continue;
988 QString key = QString(
"%1-%2" ).arg(( qulonglong )item->parent() ).arg( atomList[i].column );
989 maxSymbolWidth[key] = qMax( atomList[i].nucleons[j].symbolSize.width(), maxSymbolWidth[key] );
993 for (
int i = 0; i < atomList.size(); i++ )
995 for (
int j = 0; j < atomList[i].nucleons.size(); j++ )
998 if ( !item )
continue;
1003 QString key = QString(
"%1-%2" ).arg(( qulonglong )item->parent() ).arg( atomList[i].column );
1006 atomList[i].nucleons[j].labelXOffset = maxSymbolWidth[key] + space;
1007 atomList[i].nucleons[j].size.rwidth() = maxSymbolWidth[key] + space + atomList[i].nucleons[j].labelSize.width();