00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "KPrBackground.h"
00023 #include "KPrDocument.h"
00024 #include <kapplication.h>
00025 #include "KPrGradientCollection.h"
00026 #include "KPrTextObject.h"
00027 #include "KPrPage.h"
00028 #include "KPrUtils.h"
00029 #include "KPrBrush.h"
00030
00031 #include <qpainter.h>
00032 #include <qpicture.h>
00033 #include <qfileinfo.h>
00034
00035 #include <KoRichText.h>
00036 #include <KoTextObject.h>
00037
00038 #include <stdlib.h>
00039 using namespace std;
00040 #include <kdebug.h>
00041 #include <kglobalsettings.h>
00042 #include <KoStore.h>
00043 #include <KoStoreDevice.h>
00044 #include <KoGenStyles.h>
00045 #include <KoXmlNS.h>
00046
00047 KPrBackGround::KPrBackGround( KPrPage *_page )
00048
00049 {
00050 backType = BT_COLOR;
00051 backView = BV_CENTER;
00052 backColor1 = Qt::white;
00053 backColor2 = Qt::white;
00054 bcType = BCT_PLAIN;
00055 unbalanced = false;
00056 xfactor = 100;
00057 yfactor = 100;
00058
00059 gradientPixmap = 0L;
00060 m_page=_page;
00061 }
00062
00063 void KPrBackGround::setBackPicture( const KoPicture& picture )
00064 {
00065 if ( backType != BT_PICTURE )
00066 return;
00067 backPicture = pictureCollection()->insertPicture(picture);
00068 }
00069
00070 void KPrBackGround::setBackPicture ( const KoPictureKey& key )
00071 {
00072 if ( backType != BT_PICTURE )
00073 return;
00074 backPicture = pictureCollection()->findOrLoad(key.filename(), key.lastModified() );
00075 }
00076
00077 void KPrBackGround::drawBackground( QPainter *_painter, const KoTextZoomHandler* zoomHandler,
00078 const QRect& _crect, bool _drawBorders )
00079 {
00080 QRect pageRect = zoomHandler->zoomRect( m_page->getPageRect() );
00081 QRect crect = pageRect.intersect( _crect );
00082 if ( crect.isEmpty() )
00083 return;
00084 QSize ext = pageRect.size();
00085 drawBackground( _painter, ext, crect, _drawBorders );
00086 }
00087
00088 void KPrBackGround::drawBackground( QPainter *_painter, const QSize& ext, const QRect& crect, bool _drawBorders )
00089 {
00090 if ( m_page->displayBackground() )
00091 {
00092 _painter->save();
00093 switch ( backType )
00094 {
00095 case BT_COLOR:
00096 drawBackColor( _painter, ext, crect );
00097 break;
00098 case BT_CLIPART:
00099 case BT_PICTURE:
00100 {
00101 if ( backView == BV_CENTER )
00102 drawBackColor( _painter, ext, crect );
00103 drawBackPix( _painter, ext, crect );
00104 break;
00105 }
00106 default:
00107 break;
00108 }
00109
00110 if ( _drawBorders )
00111 drawBorders( _painter, ext, crect );
00112
00113 _painter->restore();
00114 }
00115 }
00116
00117 void KPrBackGround::reload()
00118 {
00119 if ( backType == BT_PICTURE || backType == BT_CLIPART )
00120 backPicture = pictureCollection()->insertPicture(backPicture);
00121 else
00122 backPicture.clear();
00123 }
00124
00125
00126 QDomElement KPrBackGround::save( QDomDocument &doc )
00127 {
00128 QString tag = m_page->masterPage() == 0 ? "MASTERPAGE" : "PAGE";
00129 QDomElement page=doc.createElement( tag );
00130 QDomElement element;
00131
00132 element=doc.createElement("BACKMASTER");
00133 element.setAttribute( "useMasterBackground", static_cast<int>(m_page->useMasterBackground() ) );
00134 element.setAttribute( "displayMasterPageObject", static_cast<int>( m_page->displayObjectFromMasterPage() ));
00135 element.setAttribute( "displayBackground", static_cast<int>( m_page->displayBackground() ));
00136 page.appendChild(element);
00137 if ( !m_page->useMasterBackground() )
00138 {
00139
00140 if (backType!=BT_COLOR) {
00141 element=doc.createElement("BACKTYPE");
00142 element.setAttribute("value", static_cast<int>( backType ));
00143 page.appendChild(element);
00144 }
00145
00146 if (backView!=BV_CENTER) {
00147 element=doc.createElement("BACKVIEW");
00148 element.setAttribute("value", static_cast<int>( backView ));
00149 page.appendChild(element);
00150 }
00151
00152 if (backColor1!=Qt::white) {
00153 element=doc.createElement("BACKCOLOR1");
00154 element.setAttribute("color", backColor1.name());
00155 page.appendChild(element);
00156 }
00157
00158 if (backColor2!=Qt::white) {
00159 element=doc.createElement("BACKCOLOR2");
00160 element.setAttribute("color", backColor2.name());
00161 page.appendChild(element);
00162 }
00163
00164 if (bcType!=BCT_PLAIN) {
00165 element=doc.createElement("BCTYPE");
00166 element.setAttribute("value", static_cast<int>( bcType ));
00167 page.appendChild(element);
00168 }
00169
00170 if (xfactor!=100 || yfactor!=100 || unbalanced) {
00171 element=doc.createElement("BGRADIENT");
00172 element.setAttribute("unbalanced", static_cast<int>( unbalanced ));
00173 element.setAttribute("xfactor", xfactor);
00174 element.setAttribute("yfactor", yfactor);
00175 page.appendChild(element);
00176 }
00177
00178 if ( !backPicture.isNull() && ( ( backType == BT_PICTURE ) || ( backType == BT_CLIPART ) ) )
00179 {
00180 element = doc.createElement( "BACKPICTUREKEY" );
00181
00182 backPicture.getKey().saveAttributes( element );
00183 page.appendChild( element );
00184 }
00185 }
00186
00187 return page;
00188 }
00189
00190
00191 void KPrBackGround::saveOasisBackgroundPageStyle( KoGenStyle& stylepageauto, KoGenStyles& mainStyles )
00192 {
00193 switch ( backType )
00194 {
00195 case BT_COLOR:
00196 {
00197 QBrush qbrush( backColor1 );
00198 KPrBrush brush( qbrush, backColor1, backColor2, bcType,
00199 bcType == BCT_PLAIN ? FT_BRUSH : FT_GRADIENT,
00200 unbalanced, xfactor, yfactor );
00201 brush.saveOasisFillStyle( stylepageauto, mainStyles );
00202 } break;
00203 case BT_BRUSH:
00204 case BT_CLIPART:
00205 case BT_PICTURE:
00206 {
00207 stylepageauto.addProperty("draw:fill", "bitmap" );
00208 stylepageauto.addProperty("draw:fill-image-name", saveOasisPictureStyle( mainStyles ) );
00209 QString repeat = "repeat";
00210 switch ( backView )
00211 {
00212 case BV_ZOOM:
00213 repeat = "stretch";
00214 break;
00215 case BV_CENTER:
00216 repeat = "no-repeat";
00217 break;
00218 case BV_TILED:
00219 repeat = "repeat";
00220 break;
00221 }
00222 stylepageauto.addProperty( "style:repeat", repeat );
00223 } break;
00224 }
00225 }
00226
00227
00228 QString KPrBackGround::saveOasisPictureStyle( KoGenStyles& mainStyles )
00229 {
00230
00231 KoGenStyle pictureStyle( KPrDocument::STYLE_PICTURE );
00232 pictureStyle.addAttribute( "xlink:show", "embed" );
00233 pictureStyle.addAttribute( "xlink:actuate", "onLoad" );
00234 pictureStyle.addAttribute( "xlink:type", "simple" );
00235 pictureStyle.addAttribute( "xlink:href", pictureCollection()->getOasisFileName(backPicture ) );
00236 return mainStyles.lookup( pictureStyle, "picture" );
00237 }
00238
00239
00240 void KPrBackGround::loadOasis(KoOasisContext & context )
00241 {
00242 KoStyleStack& styleStack = context.styleStack();
00243 kdDebug()<<"KPrBackGround::loadOasis()\n";
00244 styleStack.setTypeProperties( "drawing-page" );
00245 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "fill" ) )
00246 {
00247 const QString fill = styleStack.attributeNS( KoXmlNS::draw, "fill" );
00248 kdDebug(33001) <<"fill page type :" << fill << endl;
00249 if ( fill == "solid" || fill == "gradient" )
00250 {
00251 KPrBrush brush;
00252 brush.loadOasisFillStyle( context, "drawing-page" );
00253 if ( brush.getFillType() == FT_BRUSH )
00254 {
00255 setBackColor1( brush.getBrush().color() );
00256 setBackColorType( BCT_PLAIN );
00257 }
00258 else
00259 {
00260 setBackColor1( brush.getGColor1() );
00261 setBackColor2( brush.getGColor2() );
00262 setBackColorType( brush.getGType() );
00263 setBackUnbalanced( brush.getGUnbalanced() );
00264 setBackXFactor( brush.getGXFactor() );
00265 setBackYFactor( brush.getGYFactor() );
00266 }
00267 setBackType( BT_COLOR );
00268 }
00269 else if ( fill == "bitmap" )
00270 {
00271 QString style = styleStack.attributeNS( KoXmlNS::draw, "fill-image-name" );
00272 QDomElement* draw =context.oasisStyles().drawStyles()[style];
00273
00274 const QString href( draw->attributeNS( KoXmlNS::xlink, "href", QString::null) );
00275 kdDebug()<<" href: "<<href<<endl;
00276 if ( !href.isEmpty() )
00277 {
00278 QString strExtension;
00279 const int result=href.findRev(".");
00280 if (result>=0)
00281 {
00282 strExtension=href.mid(result+1);
00283 }
00284 QString filename(href);
00285 const KoPictureKey key(filename, QDateTime::currentDateTime(Qt::UTC));
00286 backPicture.setKey(key);
00287
00288 KoStore* store = context.store();
00289 if ( store->open( filename ) )
00290 {
00291 KoStoreDevice dev(store);
00292 if ( !backPicture.load( &dev, strExtension ) )
00293 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
00294 store->close();
00295 }
00296 pictureCollection()->insertPicture( key, backPicture );
00297 }
00298
00299 if ( styleStack.hasAttributeNS( KoXmlNS::style, "repeat" ) )
00300 {
00301 QString repeat = styleStack.attributeNS( KoXmlNS::style, "repeat" );
00302 if ( repeat == "stretch" )
00303 setBackView( BV_ZOOM );
00304 else if ( repeat == "no-repeat" )
00305 setBackView( BV_CENTER );
00306 else
00307 setBackView( BV_TILED );
00308 }
00309 else
00310 setBackView( BV_TILED );;
00311
00312 setBackType(BT_PICTURE);
00313 }
00314 }
00315 }
00316
00317 void KPrBackGround::load( const QDomElement &element )
00318 {
00319
00320 QDomElement e=element.namedItem("BACKMASTER").toElement();
00321 if ( !e.isNull() )
00322 {
00323 if ( e.hasAttribute( "useMasterBackground" ) )
00324 {
00325 m_page->setUseMasterBackground( (bool)e.attribute("useMasterBackground").toInt());
00326 }
00327 else
00328 m_page->setUseMasterBackground( true );
00329
00330 if(e.hasAttribute("displayMasterPageObject"))
00331 {
00332 m_page->setDisplayObjectFromMasterPage( (bool)e.attribute("displayMasterPageObject").toInt());
00333 }
00334 if(e.hasAttribute("displayBackground"))
00335 {
00336 m_page->setDisplayBackground( (bool)e.attribute("displayBackground").toInt());
00337 }
00338 }
00339 else
00340 m_page->setUseMasterBackground( false );
00341
00342 e=element.namedItem("BACKTYPE").toElement();
00343 if(!e.isNull()) {
00344 int tmp=0;
00345 if(e.hasAttribute("value"))
00346 tmp=e.attribute("value").toInt();
00347 setBackType(static_cast<BackType>(tmp));
00348 }
00349 e=element.namedItem("BACKVIEW").toElement();
00350 if(!e.isNull()) {
00351 int tmp=0;
00352 if(e.hasAttribute("value"))
00353 tmp=e.attribute("value").toInt();
00354 setBackView(static_cast<BackView>(tmp));
00355 }
00356 e=element.namedItem("BACKCOLOR1").toElement();
00357 if(!e.isNull()) {
00358 int red=0, green=0, blue=0;
00359 if(e.hasAttribute("red"))
00360 red=e.attribute("red").toInt();
00361 if(e.hasAttribute("green"))
00362 green=e.attribute("green").toInt();
00363 if(e.hasAttribute("blue"))
00364 blue=e.attribute("blue").toInt();
00365 if(e.hasAttribute("color"))
00366 setBackColor1(QColor(e.attribute("color")));
00367 else
00368 setBackColor1(QColor(red, green, blue));
00369 }
00370 e=element.namedItem("BACKCOLOR2").toElement();
00371 if(!e.isNull()) {
00372 int red=0, green=0, blue=0;
00373 if(e.hasAttribute("red"))
00374 red=e.attribute("red").toInt();
00375 if(e.hasAttribute("green"))
00376 green=e.attribute("green").toInt();
00377 if(e.hasAttribute("blue"))
00378 blue=e.attribute("blue").toInt();
00379 if(e.hasAttribute("color"))
00380 setBackColor2(QColor(e.attribute("color")));
00381 else
00382 setBackColor2(QColor(red, green, blue));
00383 }
00384 e=element.namedItem("BGRADIENT").toElement();
00385 if(!e.isNull()) {
00386 int xf=0, yf=0, unbalanced=0;
00387 if(e.hasAttribute("xfactor"))
00388 xf=e.attribute("xfactor").toInt();
00389 setBackXFactor(xf);
00390 if(e.hasAttribute("yfactor"))
00391 yf=e.attribute("yfactor").toInt();
00392 setBackYFactor(yf);
00393 if(e.hasAttribute("unbalanced"))
00394 unbalanced=e.attribute("unbalanced").toInt();
00395 setBackUnbalanced(static_cast<bool>(unbalanced));
00396 }
00397 e=element.namedItem("BCTYPE").toElement();
00398 if(!e.isNull()) {
00399 int tmp=0;
00400 if(e.hasAttribute("value"))
00401 tmp=e.attribute("value").toInt();
00402 setBackColorType(static_cast<BCType>(tmp));
00403 }
00404 e=element.namedItem("BACKPICTUREKEY").toElement();
00405 if(!e.isNull()) {
00406 KoPictureKey key;
00407 key.loadAttributes( e );
00408 backPicture.clear();
00409 backPicture.setKey( key );
00410
00411 }
00412 e=element.namedItem("BACKPIXKEY").toElement();
00413 if(!e.isNull()) {
00414 KoPictureKey key;
00415 key.loadAttributes( e );
00416 backPicture.clear();
00417 backPicture.setKey( key );
00418
00419 }
00420 else {
00421
00422 KoPictureKey key;
00423 e=element.namedItem("BACKPIX").toElement();
00424 if(!e.isNull()) {
00425 bool openPic = true;
00426 QString _data;
00427 QString _fileName;
00428 if(e.hasAttribute("data"))
00429 _data=e.attribute("data");
00430 if ( _data.isEmpty() )
00431 openPic = true;
00432 else
00433 openPic = false;
00434 if(e.hasAttribute("filename"))
00435 _fileName=e.attribute("filename");
00436 if ( !_fileName.isEmpty() )
00437 {
00438 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
00439 {
00440 int _envVarE = _fileName.find( '/', _envVarB );
00441 QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
00442 _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
00443 }
00444 }
00445 if ( openPic )
00446
00447 backPicture = pictureCollection()->loadPicture( _fileName );
00448 else
00449 {
00450 KoPictureKey key( _fileName );
00451 backPicture.clear();
00452 backPicture.setKey(key);
00453 QByteArray rawData=_data.utf8();
00454 rawData[rawData.size()-1]=char(10);
00455 QBuffer buffer(rawData);
00456 backPicture.loadXpm(&buffer);
00457 }
00458
00459 #if 0
00460 if ( ext == orig_size.toQSize() )
00461 ext = backPicture.size();
00462
00463 backPicture = backPicture.scale( ext );
00464 #endif
00465 }
00466 }
00467 e=element.namedItem("BACKCLIPKEY").toElement();
00468 if(!e.isNull()) {
00469 KoPictureKey clipKey;
00470 clipKey.loadAttributes( e );
00471 backPicture.clear();
00472 backPicture.setKey(clipKey);
00473
00474 }
00475 else {
00476
00477 e=element.namedItem("BACKCLIP").toElement();
00478 if(!e.isNull()) {
00479 QString _fileName;
00480 if(e.hasAttribute("filename"))
00481 _fileName=e.attribute("filename");
00482 if ( !_fileName.isEmpty() )
00483 {
00484 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
00485 {
00486 int _envVarE = _fileName.find( '/', _envVarB );
00487 QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
00488 _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
00489 }
00490 }
00491
00492
00493 backPicture = pictureCollection()->loadPicture( _fileName );
00494 }
00495 }
00496 }
00497
00498 void KPrBackGround::drawBackColor( QPainter *_painter, const QSize& ext, const QRect& crect )
00499 {
00500 if ( (backType == BT_COLOR && bcType == BCT_PLAIN) || backColor1 == backColor2 )
00501 {
00502
00503 _painter->fillRect( crect, QBrush( getBackColor1() ) );
00504 }
00505 else if (backType == BT_COLOR && bcType != BCT_PLAIN) {
00506 if ( !gradientPixmap || gradientPixmap->size() != ext )
00507 generateGradient( ext );
00508 _painter->drawPixmap( crect.topLeft(), *gradientPixmap, crect );
00509 }
00510 else
00511 _painter->fillRect( crect, QBrush( Qt::white ) );
00512 return;
00513 }
00514
00515 void KPrBackGround::drawBackPix( QPainter *_painter, const QSize& ext, const QRect& )
00516 {
00517
00518
00519
00520 if ( !backPicture.isNull() )
00521 {
00522
00523 const QSize _origSize = backPicture.getOriginalSize();
00524
00525 double w = _origSize.width();
00526 w *= ext.width();
00527 #if KDE_IS_VERSION(3,1,90)
00528 QRect desk = KGlobalSettings::desktopGeometry(kapp->activeWindow());
00529 #else
00530 QRect desk = QApplication::desktop()->screenGeometry();
00531 #endif
00532 w /= desk.width();
00533 double h = _origSize.height();
00534 h *= ext.height();
00535 h /= desk.height();
00536 const QSize _pixSize = QSize( (int)w, (int)h );
00537 QPixmap backPix;
00538
00539 switch ( backView )
00540 {
00541 case BV_ZOOM:
00542 backPix=backPicture.generatePixmap( ext, true );
00543 _painter->drawPixmap( QRect( 0, 0, ext.width(), ext.height() ), backPix );
00544 break;
00545 case BV_TILED:
00546 backPix=backPicture.generatePixmap( _pixSize, true );
00547 _painter->drawTiledPixmap( 0, 0, ext.width(), ext.height(), backPix );
00548 break;
00549 case BV_CENTER:
00550 {
00551 backPix=backPicture.generatePixmap( _pixSize, true );
00552
00553 QPixmap *pix = new QPixmap( ext.width(), ext.height() );
00554 bool delPix = true;
00555 int _x = 0, _y = 0;
00556
00557 if ( backPix.width() > pix->width() && backPix.height() > pix->height() )
00558 bitBlt( pix, 0, 0, &backPix, backPix.width() - pix->width(), backPix.height() - pix->height(),
00559 pix->width(), pix->height() );
00560 else if ( backPix.width() > pix->width() )
00561 {
00562 bitBlt( pix, 0, 0, &backPix, backPix.width() - pix->width(), 0,
00563 pix->width(), backPix.height() );
00564 _y = ( pix->height() - backPix.height() ) / 2;
00565 }
00566 else if ( backPix.height() > pix->height() )
00567 {
00568 bitBlt( pix, 0, 0, &backPix, 0, backPix.height() - pix->height(),
00569 backPix.width(), pix->height() );
00570 _x = ( pix->width() - backPix.width() ) / 2;
00571 }
00572 else
00573 {
00574 _x = ( pix->width() - backPix.width() ) / 2;
00575 _y = ( pix->height() - backPix.height() ) / 2;
00576 delPix = false;
00577 delete pix;
00578 pix = &backPix;
00579 }
00580
00581 if ( pix && !pix->isNull() )
00582 _painter->drawPixmap( _x, _y, *pix );
00583 if ( delPix ) delete pix;
00584 }
00585 break;
00586 }
00587 }
00588 }
00589
00590 void KPrBackGround::drawBorders( QPainter *_painter, const QSize& , const QRect& )
00591 {
00592 _painter->setPen( QApplication::palette().active().color( QColorGroup::Dark ) );
00593 _painter->setBrush( Qt::NoBrush );
00594
00595 QRect rect = m_page->getZoomPageRect();
00596
00597 _painter->drawRect( rect.x()-1,rect.y()-1,rect.width()+1,rect.height()+1 );
00598 }
00599
00600 void KPrBackGround::generateGradient( const QSize& size )
00601 {
00602 if ( backType == BT_COLOR || backType == BT_CLIPART ||
00603 backType == BT_PICTURE && backView == BV_CENTER ) {
00604 removeGradient();
00605 gradientPixmap = &gradientCollection()->getGradient( backColor1, backColor2, bcType, size,
00606 unbalanced, xfactor, yfactor );
00607 }
00608
00609
00610 if ( (backType == BT_PICTURE || backType==BT_CLIPART) && gradientPixmap )
00611 removeGradient();
00612 }
00613
00614 void KPrBackGround::removeGradient()
00615 {
00616 if ( gradientPixmap ) {
00617 gradientCollection()->removeRef( backColor1, backColor2, bcType, gradientPixmap->size(),
00618 unbalanced, xfactor, yfactor);
00619 gradientPixmap = 0;
00620 }
00621 }
00622
00623 KoPictureCollection * KPrBackGround::pictureCollection() const
00624 {
00625 return m_page->kPresenterDoc()->pictureCollection();
00626 }
00627
00628 KPrGradientCollection * KPrBackGround::gradientCollection() const
00629 {
00630 return m_page->kPresenterDoc()->gradientCollection();
00631 }
00632
00633 void KPrBackGround::setBackGround( const struct Settings &settings )
00634 {
00635 backType = settings.m_backType;
00636 backColor1 = settings.m_backColor1;
00637 backColor2 = settings.m_backColor2;
00638 bcType = settings.m_bcType;
00639 unbalanced = settings.m_unbalanced;
00640 xfactor = settings.m_xfactor;
00641 yfactor = settings.m_yfactor;
00642 removeGradient();
00643 setBackPicture( settings.m_backPictureKey );
00644 backView = settings.m_backView;
00645
00646 }
00647
00648 struct KPrBackGround::Settings KPrBackGround::getBackGround() const
00649 {
00650 return Settings( backType, backColor1, backColor2,
00651 bcType, unbalanced, xfactor, yfactor,
00652 backPicture.getKey(), backView);
00653 }