00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <qpainter.h>
00030 #include <qregion.h>
00031 #include <qpalette.h>
00032 #include <qpoint.h>
00033 #include <qsimplerichtext.h>
00034 #include <qpaintdevicemetrics.h>
00035
00036 #include <KDChartCustomBox.h>
00037 #include <KDXMLTools.h>
00038 #include <KDFrame.h>
00039
00040
00041
00042 KDChartCustomBox::~KDChartCustomBox()
00043 {
00044
00045 }
00046
00047
00048 void KDChartCustomBox::deepCopy( const KDChartCustomBox* source )
00049 {
00050 if( !source || this == source )
00051 return;
00052 _rotation = source->_rotation;
00053 _content.deepCopy( &source->_content);
00054 _fontSize = source->_fontSize;
00055 _fontScaleGlobal = source->_fontScaleGlobal;
00056 _deltaX = source->_deltaX;
00057 _deltaY = source->_deltaY;
00058 _width = source->_width;
00059 _height = source->_height;
00060 _color = source->_color;
00061 _paper = source->_paper;
00062 _anchorArea = source->_anchorArea;
00063 _anchorPos = source->_anchorPos;
00064 _anchorAlign = source->_anchorAlign;
00065 _dataRow = source->_dataRow;
00066 _dataCol = source->_dataCol;
00067 _data3rd = source->_data3rd;
00068 _deltaAlign = source->_deltaAlign;
00069 _deltaScaleGlobal = source->_deltaScaleGlobal;
00070 _anchorBeingCalculated = source->_anchorBeingCalculated;
00071 _parentAxisArea = source->_parentAxisArea;
00072 }
00073
00074 const KDChartCustomBox* KDChartCustomBox::clone() const
00075 {
00076 KDChartCustomBox* newBox = new KDChartCustomBox();
00077 newBox->deepCopy( this );
00078 return newBox;
00079 }
00080
00081
00082 float KDChartCustomBox::trueFontSize( double areaWidthP1000,
00083 double areaHeightP1000,
00084 int rectHeight ) const
00085 {
00086 float size;
00087 if( 0 > _fontSize ) {
00088 if( _fontScaleGlobal ) {
00089
00090 size = _fontSize * QMIN(areaWidthP1000, areaHeightP1000) * -1.0;
00091
00092 } else {
00093
00094
00095 float targetLineSpacing = (_fontSize * rectHeight)/ -1000;
00096 size = targetLineSpacing;
00097
00098 QFont font( content().font() );
00099 font.setPointSizeFloat( size );
00100 QFontMetrics fm( font );
00101
00102
00103
00104 size *= targetLineSpacing / fm.lineSpacing();
00105
00106
00107 font.setPointSizeFloat( size );
00108 QFontMetrics fm2( font );
00109 size *= targetLineSpacing / fm2.lineSpacing();
00110
00111
00112
00113 }
00114 }
00115 else {
00116
00117 if( _fontSize )
00118 size = _fontSize;
00119 else{
00120 size = content().font().pointSize();
00121 if( -1 == size )
00122 size = content().font().pixelSize();
00123 if( -1 == size )
00124 size = 10;
00125 }
00126 }
00127 return size;
00128 }
00129
00130
00131 int KDChartCustomBox::trueFontLineSpacing( double areaWidthP1000,
00132 double areaHeightP1000,
00133 int rectHeight ) const
00134 {
00135 QFont font( content().font() );
00136 font.setPointSizeFloat( trueFontSize( areaWidthP1000,areaHeightP1000, rectHeight ) );
00137 QFontMetrics fm( font );
00138 return fm.lineSpacing();
00139 }
00140
00141
00142 void KDChartCustomBox::getTrueShift( double areaWidthP1000,
00143 double areaHeightP1000,
00144 int rectHeight,
00145 int& dX,
00146 int& dY ) const
00147 {
00148 int x, y;
00149 if( _deltaScaleGlobal ){
00150 x = (0 > _deltaX) ? static_cast < int > ( -areaWidthP1000 * _deltaX ) : _deltaX;
00151 y = (0 > _deltaY) ? static_cast < int > ( -areaHeightP1000 * _deltaY ) : _deltaY;
00152 }else{
00153 int fontHeight = trueFontLineSpacing( areaWidthP1000, areaHeightP1000, rectHeight );
00154
00155 x = (0 > _deltaX) ? static_cast < int > ( fontHeight * _deltaX / -100.0 ) : _deltaX;
00156 y = (0 > _deltaY) ? static_cast < int > ( fontHeight * _deltaY / -100.0 ) : _deltaY;
00157
00158 }
00159 uint deltaAlign = (KDCHART_AlignAuto == _deltaAlign) ? _anchorAlign : _deltaAlign;
00160 if ( Qt::AlignLeft == (Qt::AlignLeft & deltaAlign) )
00161 dX = x;
00162 else if ( Qt::AlignRight == (Qt::AlignRight & deltaAlign) )
00163 dX = -x;
00164 else
00165 dX = 0;
00166
00167 if ( Qt::AlignTop == (Qt::AlignTop & deltaAlign) )
00168 dY = y;
00169 else if ( Qt::AlignBottom == (Qt::AlignBottom & deltaAlign) )
00170 dY = -y;
00171 else
00172 dY = 0;
00173 }
00174
00175 QRect KDChartCustomBox::trueRect( QPainter * , QPoint , double , double ) const
00176 {
00177
00178 qDebug( "Sorry, not implemented yet: KDChartCustomBox::trueRect()" );
00179 return QRect( 1, 1, 2, 2 );
00180 }
00181
00182
00183
00184
00185
00186 QRect KDChartCustomBox::trueRect( QPoint anchor, double areaWidthP1000, double areaHeightP1000 ) const
00187 {
00188 int w = (0 > _width ) ? static_cast < int > ( -areaWidthP1000 * _width ) : _width;
00189 int h = (0 > _height) ? static_cast < int > ( -areaHeightP1000 * _height ) : _height;
00190
00191
00192
00193 if( _fontScaleGlobal && 0 == w && 0 == h ){
00194
00195 QFont font( content().font() );
00196 if ( _fontSize ) {
00197 font.setPointSizeFloat(
00198 (0 > _fontSize)
00199 ? (_fontSize * QMIN(areaWidthP1000, areaHeightP1000) * -1.0)
00200 : _fontSize );
00201
00202 }
00203 QString txt( content().text() );
00204 QString txtTest( txt.stripWhiteSpace().lower() );
00205 #if QT_VERSION >= 200 && QT_VERSION < 300
00206
00207 if( !(txtTest.left(4) == "<qt>") )
00208 txt.prepend( "<qt>" );
00209 if( !(txtTest.right(5)== "</qt>"))
00210 txt.append( "</qt>");
00211 #else
00212 if( !txtTest.startsWith("<qt>" ) )
00213 txt.prepend( "<qt>" );
00214 if( !txtTest.endsWith( "</qt>") )
00215 txt.append( "</qt>");
00216 #endif
00217
00218
00219 QSimpleRichText tmpContent( txt, font );
00220
00221
00222
00223
00224
00225
00226
00227 w = tmpContent.widthUsed();
00228 h = tmpContent.height();
00229
00230
00231 }
00232
00233
00234 int x,y;
00235 if ( Qt::AlignLeft == (Qt::AlignLeft & _anchorAlign) )
00236 x = 0;
00237 else if ( Qt::AlignRight == (Qt::AlignRight & _anchorAlign) )
00238 x = - w + 1;
00239 else
00240 x = - w / 2;
00241
00242 if ( Qt::AlignTop == (Qt::AlignTop & _anchorAlign) )
00243 y = 0;
00244 else if ( Qt::AlignBottom == (Qt::AlignBottom & _anchorAlign) )
00245 y = - h + 1;
00246 else
00247 y = - h / 2;
00248 int dX,dY;
00249 getTrueShift( areaWidthP1000, areaHeightP1000, h,
00250 dX, dY );
00251
00252
00253 return QRect( anchor.x()+x+dX, anchor.y()+y+dY, w, h );
00254 }
00255
00256
00257 int KDChartCustomBox::trueRectAlignX(const QRect& rect) const
00258 {
00259 int ret = rect.center().x();
00260 if ( Qt::AlignLeft == (Qt::AlignLeft & _anchorAlign) )
00261 ret -= rect.width();
00262 else if ( Qt::AlignRight == (Qt::AlignRight & _anchorAlign) )
00263 ret += rect.width();
00264 return ret;
00265 }
00266 int KDChartCustomBox::trueRectAlignY(const QRect& rect) const
00267 {
00268 int ret = rect.center().y();
00269 if ( Qt::AlignTop == (Qt::AlignTop & _anchorAlign) )
00270 ret -= rect.height();
00271 else if ( Qt::AlignBottom == (Qt::AlignBottom & _anchorAlign) )
00272 ret += rect.height();
00273 return ret;
00274 }
00275
00276 void KDChartCustomBox::paint( QPainter* painter,
00277 QPoint anchor,
00278 double areaWidthP1000,
00279 double areaHeightP1000,
00280 const KDFrame* frame,
00281 const QRect& frameRect,
00282 const QColor * color,
00283 const QBrush * paper ) const
00284 {
00285 painter->save();
00286 int rotDX = 0;
00287 int rotDY = 0;
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 QRect myRect( trueRect( anchor, areaWidthP1000, areaHeightP1000 ) );
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 QRect myFrameRect( frameRect );
00312 if ( myRect.isValid() ) {
00313
00314 if( _rotation ){
00315 getTrueShift( areaWidthP1000, areaHeightP1000, myRect.height(),
00316 rotDX, rotDY );
00317 myRect.moveBy( -rotDX, -rotDY );
00318 if( frame )
00319 myFrameRect.moveBy( -rotDX, -rotDY );
00320
00321
00322 myRect.moveCenter( QPoint( anchor.x() - trueRectAlignX(myRect),
00323 anchor.y() - trueRectAlignY(myRect) ) );
00324 if( frame )
00325 myFrameRect.moveCenter( QPoint( anchor.x() - trueRectAlignX(myFrameRect),
00326 anchor.y() - trueRectAlignY(myFrameRect) ) );
00327
00328 painter->translate( anchor.x(), anchor.y() );
00329 painter->rotate( _rotation );
00330 painter->translate( rotDX, rotDY );
00331 }
00332 if( frame )
00333 frame->paint( painter, KDFrame::PaintAll, myFrameRect );
00334 if ( _fontSize ) {
00335 QFont font( content().font() );
00336
00337 float trueSize = trueFontSize(areaWidthP1000,areaHeightP1000, myRect.height() );
00338 font.setPointSizeFloat( trueSize );
00339
00340 myRect.setHeight( (int)(trueSize )+ (int)(trueSize*0.5));
00341 const KDChartTextPiece tmpTextPiece( painter, content().text(), font );
00342
00343 tmpTextPiece.draw( painter, myRect.x(), myRect.y(), myRect,
00344 color ? *color : _color,
00345 paper ? paper : &_paper );
00346 }else{
00347
00348 content().draw( painter, myRect.x(), myRect.y(), myRect,
00349 color ? *color : _color,
00350 paper ? paper : &_paper );
00351 }
00352 }
00353 painter->restore();
00354 }
00355
00356
00357 void KDChartCustomBox::createCustomBoxNode( QDomDocument& document,
00358 QDomNode& parent,
00359 const QString& elementName,
00360 const KDChartCustomBox* custombox )
00361 {
00362 QDomElement customBoxElement = document.createElement( elementName );
00363 parent.appendChild( customBoxElement );
00364 KDXML::createIntNode( document, customBoxElement, "Rotation", custombox->_rotation );
00365 KDXML::createStringNode( document, customBoxElement, "ContentText",
00366 custombox->_content.text() );
00367 KDXML::createFontNode( document, customBoxElement, "ContentFont",
00368 custombox->_content.font() );
00369 KDXML::createIntNode( document, customBoxElement, "FontSize", custombox->_fontSize );
00370 KDXML::createBoolNode( document, customBoxElement, "FontScaleGlobal",
00371 custombox->_fontScaleGlobal );
00372 KDXML::createIntNode( document, customBoxElement, "DeltaX", custombox->_deltaX );
00373 KDXML::createIntNode( document, customBoxElement, "DeltaY", custombox->_deltaY );
00374 KDXML::createIntNode( document, customBoxElement, "Width", custombox->_width );
00375 KDXML::createIntNode( document, customBoxElement, "Height", custombox->_height );
00376 KDXML::createColorNode( document, customBoxElement, "Color", custombox->_color );
00377 KDXML::createBrushNode( document, customBoxElement, "Paper", custombox->_paper );
00378 KDXML::createIntNode( document, customBoxElement, "AnchorArea",
00379 custombox->_anchorArea );
00380 KDXML::createStringNode( document, customBoxElement, "AnchorPos",
00381 KDChartEnums::positionFlagToString( custombox->_anchorPos ) );
00382 KDXML::createIntNode( document, customBoxElement, "AnchorAlign",
00383 custombox->_anchorAlign );
00384 KDXML::createIntNode( document, customBoxElement, "DataRow",
00385 custombox->_dataRow );
00386 KDXML::createIntNode( document, customBoxElement, "DataCol",
00387 custombox->_dataCol );
00388 KDXML::createIntNode( document, customBoxElement, "Data3rd",
00389 custombox->_data3rd );
00390 KDXML::createIntNode( document, customBoxElement, "DeltaAlign",
00391 custombox->_deltaAlign );
00392 KDXML::createBoolNode( document, customBoxElement, "DeltaScaleGlobal",
00393 custombox->_deltaScaleGlobal );
00394 KDXML::createIntNode( document, customBoxElement, "ParentAxisArea",
00395 custombox->_parentAxisArea );
00396 }
00397
00398
00399 bool KDChartCustomBox::readCustomBoxNode( const QDomElement& element,
00400 KDChartCustomBox& custombox )
00401 {
00402 bool ok = true;
00403 QString tempContentText;
00404 QFont tempContentFont;
00405 int tempRotation = 0;
00406 int tempDeltaAlign = KDCHART_AlignAuto;
00407 bool tempDeltaScaleGlobal = true;
00408 int tempFontSize, tempDeltaX, tempDeltaY,
00409 tempWidth, tempHeight, tempAnchorArea, tempParentAxisArea, tempAnchorAlign,
00410 tempDataRow, tempDataCol, tempData3rd;
00411 bool tempFontScaleGlobal;
00412 QColor tempColor;
00413 QBrush tempPaper;
00414 KDChartEnums::PositionFlag tempAnchorPos = KDChartEnums::PosTopLeft;
00415 QDomNode node = element.firstChild();
00416 while( !node.isNull() ) {
00417 QDomElement element = node.toElement();
00418 if( !element.isNull() ) {
00419 QString tagName = element.tagName();
00420 if( tagName == "Rotation" ) {
00421 ok = ok & KDXML::readIntNode( element, tempRotation );
00422 } else if( tagName == "ContentText" ) {
00423 ok = ok & KDXML::readStringNode( element, tempContentText );
00424 } else if( tagName == "ContentFont" ) {
00425 ok = ok & KDXML::readFontNode( element, tempContentFont );
00426 } else if( tagName == "FontSize" ) {
00427 ok = ok & KDXML::readIntNode( element, tempFontSize );
00428 } else if( tagName == "FontScaleGlobal" ) {
00429 ok = ok & KDXML::readBoolNode( element, tempFontScaleGlobal );
00430 } else if( tagName == "DeltaX" ) {
00431 ok = ok & KDXML::readIntNode( element, tempDeltaX );
00432 } else if( tagName == "DeltaY" ) {
00433 ok = ok & KDXML::readIntNode( element, tempDeltaY );
00434 } else if( tagName == "Width" ) {
00435 ok = ok & KDXML::readIntNode( element, tempWidth );
00436 } else if( tagName == "Height" ) {
00437 ok = ok & KDXML::readIntNode( element, tempHeight );
00438 } else if( tagName == "Color" ) {
00439 ok = ok & KDXML::readColorNode( element, tempColor );
00440 } else if( tagName == "Paper" ) {
00441 ok = ok & KDXML::readBrushNode( element, tempPaper );
00442 } else if( tagName == "AnchorArea" ) {
00443 ok = ok & KDXML::readIntNode( element, tempAnchorArea );
00444 } else if( tagName == "AnchorPos" ) {
00445 QString value;
00446 ok = ok & KDXML::readStringNode( element, value );
00447 tempAnchorPos = KDChartEnums::stringToPositionFlag( value );
00448 } else if( tagName == "AnchorAlign" ) {
00449 ok = ok & KDXML::readIntNode( element, tempAnchorAlign );
00450 } else if( tagName == "DataRow" ) {
00451 ok = ok & KDXML::readIntNode( element, tempDataRow );
00452 } else if( tagName == "DataCol" ) {
00453 ok = ok & KDXML::readIntNode( element, tempDataCol );
00454 } else if( tagName == "Data3rd" ) {
00455 ok = ok & KDXML::readIntNode( element, tempData3rd );
00456 } else if( tagName == "DeltaAlign" ) {
00457 ok = ok & KDXML::readIntNode( element, tempDeltaAlign );
00458 } else if( tagName == "DeltaScaleGlobal" ) {
00459 ok = ok & KDXML::readBoolNode( element, tempDeltaScaleGlobal );
00460 } else if ( tagName == "ParentAxisArea" ) {
00461 ok = ok & KDXML::readIntNode( element, tempParentAxisArea );
00462 } else {
00463 qDebug( "Unknown tag in custom box" );
00464 }
00465 }
00466 node = node.nextSibling();
00467 }
00468
00469 if( ok ) {
00470 const KDChartTextPiece piece( 0, tempContentText, tempContentFont );
00471 custombox._content.deepCopy( &piece );
00472 custombox._rotation = tempRotation;
00473 custombox._fontSize = tempFontSize;
00474 custombox._fontScaleGlobal = tempFontScaleGlobal;
00475 custombox._deltaX = tempDeltaX;
00476 custombox._deltaY = tempDeltaY;
00477 custombox._width = tempWidth;
00478 custombox._height = tempHeight;
00479 custombox._color = tempColor;
00480 custombox._paper = tempPaper;
00481 custombox._anchorArea = tempAnchorArea;
00482 custombox._anchorPos = tempAnchorPos;
00483 custombox._anchorAlign = tempAnchorAlign;
00484 custombox._dataRow = tempDataRow;
00485 custombox._dataCol = tempDataCol;
00486 custombox._data3rd = tempData3rd;
00487 custombox._deltaAlign = tempDeltaAlign;
00488 custombox._deltaScaleGlobal = tempDeltaScaleGlobal;
00489 custombox._parentAxisArea = tempParentAxisArea;
00490 }
00491
00492 return ok;
00493 }
00494
00495 #include "KDChartCustomBox.moc"