kspread

kspread_object.cc

00001 /* This file is part of the KDE project
00002    Copyright (C) 2006 Fredrik Edemar <f_edemar@linux.se>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017    Boston, MA 02110-1301, USA.
00018 */
00019 #include "kspread_object.h"
00020 #include "kspread_canvas.h"
00021 #include "kspread_doc.h"
00022 #include "kspread_sheet.h"
00023 #include "kspread_view.h"
00024 
00025 #include <assert.h>
00026 #include <kapplication.h>
00027 #include <kdebug.h>
00028 #include <kimageeffect.h>
00029 #include <kparts/partmanager.h>
00030 #include <koChart.h>
00031 
00032 #include <qbitmap.h>
00033 #include <qbuffer.h>
00034 #include <qcursor.h>
00035 #include <qdom.h>
00036 #include <qfileinfo.h>
00037 #include <qimage.h>
00038 #include <qpainter.h>
00039 #include <qpixmap.h>
00040 #include <qwmatrix.h>
00041 
00042 #include <KoDocument.h>
00043 #include <KoDocumentChild.h>
00044 #include <KoDom.h>
00045 #include <KoXmlWriter.h>
00046 #include <KoZoomHandler.h>
00047 
00048 using namespace KSpread;
00049 
00050 class Sheet;
00051 class View;
00052 
00053 /**********************************************************
00054  *
00055  * EmbeddedObject
00056  *
00057  **********************************************************/
00058 EmbeddedObject::EmbeddedObject( Sheet *_sheet, const KoRect& _geometry )
00059   : m_geometry( _geometry), m_sheet(_sheet), m_objectName(""), m_selected(false), m_protect(false), m_keepRatio(false), pen( Qt::black, 1, QPen::SolidLine )
00060 {
00061   angle = 0.0;
00062   inObjList = true;
00063   cmds = 0;
00064 }
00065 
00066 EmbeddedObject::~EmbeddedObject()
00067 {
00068 }
00069 KoRect EmbeddedObject::geometry()
00070 {
00071     return m_geometry;
00072 }
00073 void EmbeddedObject::setGeometry( const KoRect &rect )
00074 {
00075     m_geometry = rect;
00076 }
00077 
00078 void EmbeddedObject::moveBy( const KoPoint &_point )
00079 {
00080   m_geometry.moveTopLeft( m_geometry.topLeft() + _point );
00081 }
00082 
00083 void EmbeddedObject::moveBy( double _dx, double _dy )
00084 {
00085   m_geometry.moveTopLeft( m_geometry.topLeft() + KoPoint( _dx, _dy ) );
00086 }
00087 
00088 void EmbeddedObject::resizeBy( const KoSize & _size )
00089 {
00090   resizeBy( _size.width(), _size.height() );
00091 }
00092 
00093 void EmbeddedObject::resizeBy( double _dx, double _dy)
00094 {
00095   m_geometry.setSize( KoSize( m_geometry.width()+_dx, m_geometry.height()+_dy) );
00096 } // call (possibly reimplemented) setSize
00097 
00098 bool EmbeddedObject::load( const QDomElement& /*element*/ )
00099 {
00100     kdDebug() << "Loading EmbeddedObject" << endl;
00101     return false;
00102 }
00103 
00104 void EmbeddedObject::loadOasis(const QDomElement &element, KoOasisLoadingContext & context )
00105 {
00106   if(element.hasAttributeNS( KoXmlNS::draw, "name" ))
00107     m_objectName = element.attributeNS( KoXmlNS::draw, "name", QString::null);
00108   m_geometry.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", QString::null ) ) );
00109   m_geometry.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", QString::null ) ) );
00110   m_geometry.setWidth(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", QString::null )) );
00111   m_geometry.setHeight(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", QString::null ) ) );
00112     //kdDebug()<<" orig.x() :"<<orig.x() <<" orig.y() :"<<orig.y() <<"ext.width() :"<<ext.width()<<" ext.height(): "<<ext.height()<<endl;
00113   KoStyleStack &styleStack = context.styleStack();
00114 
00115   styleStack.setTypeProperties( "" ); //no type default type
00116 }
00117 
00118 
00119 QDomElement EmbeddedObject::save( QDomDocument& /*doc*/ )
00120 {
00121     kdDebug() << "Saving EmbeddedObject..." << endl;
00122     return QDomElement();
00123 }
00124 
00125 void EmbeddedObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
00126 {
00127     xmlWriter.addAttribute( "draw:id", "object" + QString::number( indexObj ) );
00128     //save all into pt
00129     xmlWriter.addAttributePt( "svg:x", sheet()->doc()->savingWholeDocument() ? m_geometry.x() : m_geometry.x() + 20.0 );
00130     xmlWriter.addAttributePt( "svg:y", sheet()->doc()->savingWholeDocument() ? m_geometry.y() : m_geometry.y() + 20.0 );
00131     xmlWriter.addAttributePt( "svg:width", m_geometry.width() );
00132     xmlWriter.addAttributePt( "svg:height", m_geometry.height() );
00133 
00134 //     if ( kAbs( angle ) > 1E-6 )
00135 //     {
00136 //         double value = -1 * ( ( double )angle* M_PI )/180.0;
00137 //         QString str=QString( "rotate (%1)" ).arg( value );
00138 //         xmlWriter.addAttribute( "draw:transform", str );
00139 //     }
00140 }
00141 
00142 bool EmbeddedObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &/* sc */ ) const
00143 {
00144     kdDebug() << "bool saveOasisObjectAttributes not implemented";
00145     return true;
00146 }
00147 
00148 bool EmbeddedObject::saveOasisObject( KSpreadOasisSaveContext &sc ) const
00149 {
00150     sc.xmlWriter.startElement( getOasisElementName() );
00151     //sc.xmlWriter.addAttribute( "draw:style-name", getStyle( sc ) );
00152     saveOasisPosObject( sc.xmlWriter, sc.indexObj );
00153     if( !getObjectName().isEmpty())
00154         sc.xmlWriter.addAttribute( "draw:name", getObjectName() );
00155 
00156     saveOasisObjectAttributes( sc );
00157 
00158     sc.xmlWriter.endElement();
00159     return true;
00160 }
00161 
00162 void EmbeddedObject::draw( QPainter *_painter )
00163 {
00164   paintSelection(_painter, SM_MOVERESIZE );
00165 }
00166 
00167 QPixmap EmbeddedObject::toPixmap()
00168 {
00169     return toPixmap( 1.0 , 1.0 );
00170 }
00171 
00172 QPixmap EmbeddedObject::toPixmap(QSize size)
00173 {
00174     double xZoom;
00175     double yZoom;
00176 
00177     calculateRequiredZoom( size , xZoom , yZoom );
00178 
00179     return toPixmap(xZoom,yZoom);
00180 }
00181 
00182 QPixmap EmbeddedObject::toPixmap(double /*xZoom*/ , double /*yZoom*/)
00183 {
00184     return QPixmap();
00185 
00186 }
00187 
00188 void EmbeddedObject::calculateRequiredZoom( QSize desiredSize, double& xZoom, double& yZoom)
00189 {
00190     QSize actualSize = geometry().size().toQSize();
00191 
00192     xZoom = (double) desiredSize.width() / (double)actualSize.width();
00193     yZoom = (double) desiredSize.height() / (double)actualSize.height();
00194 }
00195 
00196 void EmbeddedObject::paintSelection( QPainter *_painter, SelectionMode mode )
00197 {
00198   if ( !m_selected || mode == SM_NONE )
00199     return;
00200 
00201   _painter->save();
00202   KoRect bound( geometry().left(), geometry().top(),
00203                 geometry().width() , geometry().height() );
00204   QRect zoomedBound = sheet()->doc()->zoomRect( bound ) ;
00205 
00206   //_painter->setPen( QPen( Qt::black, 1, QPen::SolidLine ) );
00207   _painter->setPen( pen );
00208   _painter->setBrush( kapp->palette().color( QPalette::Active, QColorGroup::Highlight ) );
00209 
00210   //KoRect r = rotateRectObject(); // TODO: rotation
00211   KoRect r = /*KoRect::fromQRect*/( bound );
00212   int x = sheet()->doc()->zoomItX( r.left() /*- orig.x()*/);
00213   int y = sheet()->doc()->zoomItY( r.top() /*- orig.y()*/);
00214   int zX6 = /*sheet()->doc()->zoomItX*/( 6 );
00215   int zY6 = /*sheet()->doc()->zoomItY*/( 6 );
00216   int w = sheet()->doc()->zoomItX(r.width()) - 6;
00217   int h = sheet()->doc()->zoomItY(r.height()) - 6;
00218 
00219   if ( mode == SM_MOVERESIZE ) {
00220     _painter->drawRect( x, y,  zX6, zY6 );
00221     _painter->drawRect( x, y + h / 2, zX6, zY6 );
00222     _painter->drawRect( x, y + h, zX6, zY6 );
00223     _painter->drawRect( x + w, y, zX6, zY6 );
00224     _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
00225     _painter->drawRect( x + w, y + h, zX6, zY6 );
00226     _painter->drawRect( x + w / 2, y,zX6, zY6 );
00227     _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
00228   }
00229   else if ( mode == SM_PROTECT) {
00230     _painter->drawRect( x, y,  zX6, zY6 );
00231     _painter->drawRect( x, y + h / 2, zX6, zY6 );
00232     _painter->drawRect( x, y + h, zX6, zY6 );
00233     _painter->drawRect( x + w, y, zX6, zY6 );
00234     _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
00235     _painter->drawRect( x + w, y + h, zX6, zY6 );
00236     _painter->drawRect( x + w / 2, y,zX6, zY6 );
00237     _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
00238 
00239     x= x + 1;
00240     y= y + 1;
00241     zX6=zX6-2;
00242     zY6=zY6-2;
00243 
00244     QBrush brush=kapp->palette().color( QPalette::Active,QColorGroup::Base );
00245     _painter->fillRect( x, y,  zX6, zY6, brush );
00246     _painter->fillRect( x, y + h / 2, zX6, zY6, brush);
00247     _painter->fillRect( x, y + h, zX6, zY6, brush );
00248     _painter->fillRect( x + w, y, zX6, zY6, brush );
00249     _painter->fillRect( x + w, y + h / 2, zX6, zY6, brush );
00250     _painter->fillRect( x + w  , y + h , zX6 , zY6 , brush );
00251     _painter->fillRect( x + w / 2 , y ,zX6 , zY6 , brush );
00252     _painter->fillRect( x + w / 2, y + h , zX6 , zY6 , brush );
00253   }
00254   else if ( mode == SM_ROTATE ) {
00255     _painter->drawEllipse( x, y,  zX6, zY6 );
00256     _painter->drawEllipse( x, y + h, zX6, zY6 );
00257     _painter->drawEllipse( x + w, y, zX6, zY6 );
00258     _painter->drawEllipse( x + w, y + h, zX6, zY6 );
00259   }
00260 
00261   _painter->restore();
00262 }
00263 
00264 QCursor EmbeddedObject::getCursor( const QPoint &_point, ModifyType &_modType, QRect &geometry) const
00265 {
00266     int px = /*sheet()->doc()->zoomItX*/(_point.x());
00267     int py = /*sheet()->doc()->zoomItY*/(_point.y());
00268     int ox = /*sheet()->doc()->zoomItX*/(/*orig*/geometry.x());
00269     int oy = /*sheet()->doc()->zoomItY*/(/*orig*/geometry.y());
00270     int ow = /*sheet()->doc()->zoomItX*/(/*ext*/geometry.width());
00271     int oh = /*sheet()->doc()->zoomItY*/(/*ext*/geometry.height());
00272 
00273 //     if ( angle != 0.0 )
00274 //     {
00275 //         QRect rr = sheet()->doc()->zoomRect( rotateRectObject() );
00276 //         ox = rr.x();
00277 //         oy = rr.y();
00278 //         ow = rr.width();
00279 //         oh = rr.height();
00280 //     }
00281 
00282     int sz = 4;
00283     if ( px >= ox && py >= oy && px <= ox + QMIN( ow / 3, sz ) && py <= oy + QMIN( oh / 3, sz ) )
00284     {
00285         _modType = MT_RESIZE_LU;
00286         if ( m_protect )
00287             return Qt::ForbiddenCursor;
00288         return Qt::sizeFDiagCursor;
00289     }
00290 
00291     if ( px >= ox && py >= oy + oh / 2 - QMIN( oh / 6, sz / 2 )
00292          && px <= ox + QMIN( ow / 3, sz)
00293          && py <= oy + oh / 2 + QMIN( oh / 6, sz / 2 ) )
00294     {
00295         _modType = MT_RESIZE_LF;
00296         if ( m_protect)
00297             return Qt::ForbiddenCursor;
00298         return Qt::sizeHorCursor;
00299     }
00300 
00301     if ( px >= ox && py >= oy + oh - QMIN( oh / 3, sz ) && px <= ox + QMIN( ow / 3, sz ) && py <= oy + oh )
00302     {
00303         _modType = MT_RESIZE_LD;
00304         if ( m_protect )
00305             return Qt::ForbiddenCursor;
00306         return Qt::sizeBDiagCursor;
00307     }
00308 
00309     if ( px >= ox + ow / 2 - QMIN( ow / 6, sz / 2 ) && py >= oy
00310          && px <= ox + ow / 2 + QMIN( ow / 6, sz / 2 )
00311          && py <= oy + QMIN( oh / 3, sz ) )
00312     {
00313         _modType = MT_RESIZE_UP;
00314         if ( m_protect )
00315             return Qt::ForbiddenCursor;
00316         return Qt::sizeVerCursor;
00317     }
00318 
00319     if ( px >= ox + ow / 2 - QMIN( ow / 6, sz / 2 ) && py >= oy + oh - QMIN( oh / 3, sz )
00320          && px <= ox + ow / 2 + QMIN( ow / 6, sz / 2 ) && py <= oy + oh )
00321     {
00322         _modType = MT_RESIZE_DN;
00323         if ( m_protect )
00324             return Qt::ForbiddenCursor;
00325         return Qt::sizeVerCursor;
00326     }
00327 
00328     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy && px <= ox + ow && py <= oy + QMIN( oh / 3, sz) )
00329     {
00330         _modType = MT_RESIZE_RU;
00331         if ( m_protect )
00332             return Qt::ForbiddenCursor;
00333         return Qt::sizeBDiagCursor;
00334     }
00335 
00336     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy + oh / 2 - QMIN( oh / 6, sz / 2 )
00337          && px <= ox + ow && py <= oy + oh / 2 + QMIN( oh / 6, sz / 2) )
00338     {
00339         _modType = MT_RESIZE_RT;
00340         if ( m_protect )
00341             return Qt::ForbiddenCursor;
00342         return Qt::sizeHorCursor;
00343     }
00344 
00345     if ( px >= ox + ow - QMIN( ow / 3, sz ) && py >= oy + oh - QMIN( oh / 3, sz)
00346          && px <= ox + ow && py <= oy + oh )
00347     {
00348         _modType = MT_RESIZE_RD;
00349         if ( m_protect )
00350             return Qt::ForbiddenCursor;
00351         return Qt::sizeFDiagCursor;
00352     }
00353 
00354     _modType = MT_MOVE;
00355     return Qt::sizeAllCursor;
00356 }
00357 
00358 
00359 void EmbeddedObject::doDelete()
00360 {
00361     if ( cmds == 0 && !inObjList )
00362         delete this;
00363 }
00364 
00365 /**********************************************************
00366  *
00367  * EmbeddedKOfficeObject
00368  *
00369  **********************************************************/
00370 EmbeddedKOfficeObject::EmbeddedKOfficeObject( Doc *parent, Sheet *_sheet, KoDocument* doc, const KoRect& geometry )
00371     : EmbeddedObject( _sheet, geometry ), m_parent(parent)
00372 {
00373     m_embeddedObject = new KoDocumentChild(parent, doc, geometry.toQRect() );
00374 }
00375 
00376 EmbeddedKOfficeObject::EmbeddedKOfficeObject( Doc *parent, Sheet *_sheet )
00377     : EmbeddedObject( _sheet, KoRect() ), m_parent(parent)
00378 {
00379     m_embeddedObject = new KoDocumentChild( parent );
00380 }
00381 
00382 EmbeddedKOfficeObject::~EmbeddedKOfficeObject()
00383 {
00384   delete m_embeddedObject;
00385 }
00386 
00387 Doc* EmbeddedKOfficeObject::parent()
00388 {
00389     return m_parent;
00390 }
00391 
00392 KoDocumentChild* EmbeddedKOfficeObject::embeddedObject()
00393 {
00394     return m_embeddedObject;
00395 }
00396 
00397 bool EmbeddedKOfficeObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
00398 {
00399     kdDebug() << "EmbeddedKOfficeObject::saveOasisPart " << sc.partIndexObj << endl;
00400 
00401     sc.xmlWriter.startElement( "draw:object" );
00402     const QString name = QString( "Object_%1" ).arg( sc.partIndexObj + 1 );
00403     ++sc.partIndexObj;
00404     m_embeddedObject->saveOasisAttributes( sc.xmlWriter, name );
00405 
00406     if ( getType() != OBJECT_CHART )
00407         sc.xmlWriter.endElement();
00408     return true;
00409 }
00410 
00411 const char * EmbeddedKOfficeObject::getOasisElementName() const
00412 {
00413     return "draw:frame";
00414 }
00415 
00416 bool EmbeddedKOfficeObject::load( const QDomElement& element )
00417 {
00418     kdDebug() << "Loading EmbeddedKOfficeObject" << endl;
00419     bool result = embeddedObject()->load( element );
00420     setGeometry( KoRect::fromQRect( embeddedObject()->geometry() ) );
00421     return result;
00422 }
00423 
00424 void EmbeddedKOfficeObject::loadOasis(const QDomElement &element, KoOasisLoadingContext &context/*, KPRLoadingInfo *info*/)
00425 {
00426     kdDebug()<<"void EmbeddedKOfficeObject::loadOasis(const QDomElement &element)******************\n";
00427     EmbeddedObject::loadOasis( element, context );
00428 
00429     QDomElement objectElement = KoDom::namedItemNS( element, KoXmlNS::draw, "object" );
00430     m_embeddedObject->loadOasis( element, objectElement );
00431     if( element.hasAttributeNS( KoXmlNS::draw, "name" ) )
00432         m_objectName = element.attributeNS( KoXmlNS::draw, "name", QString::null);
00433     (void)m_embeddedObject->loadOasisDocument( context.store(), context.manifestDocument() );
00434 }
00435 
00436 QDomElement EmbeddedKOfficeObject::save( QDomDocument& doc )
00437 {
00438     kdDebug() << "Saving EmbeddedKOfficeObject" << endl;
00439     embeddedObject()->setGeometry( geometry().toQRect() );
00440     return m_embeddedObject->save( doc );
00441 }
00442 
00443 void EmbeddedKOfficeObject::draw( QPainter *_painter )
00444 {
00445   kdDebug() << "Painting..." << endl;
00446 
00447   int const penw = pen.width() ;
00448   KoRect bound( 0, 0,
00449                 geometry().width() - ( 2 * penw ), geometry().height() - ( 2 * penw ) );
00450   QRect const zoomedBound = sheet()->doc()->zoomRect( bound );
00451 
00452   _painter->save();
00453   int const xOffset = sheet()->doc()->zoomItX( geometry().left() + penw);
00454   int const yOffset = sheet()->doc()->zoomItY( geometry().top() + penw );
00455 
00456   QRect new_geometry = zoomedBound;
00457 
00458   //if ( translate )
00459   //{
00460     _painter->translate( xOffset , yOffset );
00461 
00462     new_geometry.moveBy(  xOffset , yOffset );
00463     new_geometry.moveBy( -_painter->window().x(), -_painter->window().y() );
00464   //}
00465 
00466   _painter->setClipRect( zoomedBound, QPainter::CoordPainter );
00467 
00468    assert( embeddedObject()->document() != 0 );
00469 
00470    double zoomX = static_cast<double>( sheet()->doc()->zoom() ) / 100;
00471    double zoomY = static_cast<double>( sheet()->doc()->zoom() ) / 100;
00472    embeddedObject()->document()->paintEverything( *_painter,
00473         zoomedBound,
00474         embeddedObject()->isTransparent(),
00475         0 /* View isn't known from here - is that a problem? */,
00476         zoomX,
00477         zoomY );
00478 
00479 
00480    embeddedObject()->setGeometry( new_geometry );
00481   _painter->restore();
00482 
00483   EmbeddedObject::draw( _painter );
00484 }
00485 
00486 QPixmap EmbeddedKOfficeObject::toPixmap( double xZoom , double yZoom )
00487 {
00488     QPixmap pixmap( (int)( geometry().width()*xZoom ), (int)( geometry().height()*yZoom ) );
00489 
00490     QPainter painter(&pixmap);
00491     QRect  bound( 0,0,(int)( geometry().width()*xZoom ), (int)(geometry().height()*yZoom) );
00492     embeddedObject()->document()->paintEverything(painter,bound,
00493                     embeddedObject()->isTransparent(),
00494                     0,
00495                     xZoom,
00496                     yZoom);
00497     return pixmap;
00498 }
00499 
00500 void EmbeddedKOfficeObject::activate( View *_view, Canvas* /* canvas */ )
00501 {
00502     KoDocument* part = embeddedObject()->document();
00503     if ( !part )
00504         return;
00505     kdDebug() << "Activating..." << endl;
00506 
00507     _view->partManager()->addPart( part, false );
00508     _view->partManager()->setActivePart( part, _view );
00509 }
00510 
00511 void EmbeddedKOfficeObject::deactivate()
00512 {
00513 }
00514 
00515 
00516 void EmbeddedKOfficeObject::updateChildGeometry()
00517 {
00518 //   KoZoomHandler* zh = m_sheet->doc();
00519 //   embeddedObject()->setGeometry( zh->zoomRect( geometry() ), true );
00520 
00521 //   return;
00522 //   QRect r = sheet()->doc()->zoomRect( geometry() );
00523 //   if ( _canvas )
00524 //   {
00525 //     kdDebug() << "_canvas->xOffset():" << _canvas->xOffset() << endl;
00526 //     kdDebug() << "         _canvas->xOffset()*_canvas->doc()->zoomedResolutionX():" << _canvas->xOffset() * _canvas->doc()->zoomedResolutionX() << endl;
00527 //     kdDebug() << "_canvas->yOffset():" << _canvas->yOffset() << endl;
00528 //     kdDebug() << "         _canvas->yOffset()*_canvas->doc()->zoomedResolutionY():" << _canvas->yOffset() * _canvas->doc()->zoomedResolutionY() << endl;
00529 //     r.moveBy( -_canvas->xOffset() / _canvas->doc()->zoomedResolutionX() , -_canvas->yOffset() / _canvas->doc()->zoomedResolutionY() );
00530 //   }
00531 //   embeddedObject()->setGeometry( r , true );
00532 }
00533 
00534 /**********************************************************
00535  *
00536  * EmbeddedChart
00537  *
00538  **********************************************************/
00539 
00540 EmbeddedChart::EmbeddedChart( Doc *_spread, Sheet *_sheet, KoDocument* doc, const KoRect& geometry )
00541   : EmbeddedKOfficeObject( _spread, _sheet, doc, geometry )
00542 {
00543     m_pBinding = 0;
00544 }
00545 
00546 EmbeddedChart::EmbeddedChart( Doc *_spread, Sheet *_sheet )
00547   : EmbeddedKOfficeObject( _spread, _sheet )
00548 {
00549     m_pBinding = 0;
00550 }
00551 
00552 EmbeddedChart::~EmbeddedChart()
00553 {
00554   if ( m_embeddedObject->isDeleted() )
00555     delete m_pBinding;
00556 }
00557 
00558 void EmbeddedChart::setDataArea( const QRect& _data )
00559 {
00560     if ( m_pBinding == 0L )
00561         m_pBinding = new ChartBinding( m_sheet, _data, this );
00562     else
00563         m_pBinding->setDataArea( _data );
00564 }
00565 
00566 void EmbeddedChart::update()
00567 {
00568     if ( m_pBinding )
00569         m_pBinding->cellChanged( 0 );
00570 }
00571 
00572 const char * EmbeddedChart::getOasisElementName() const
00573 {
00574     return "draw:frame";
00575 }
00576 
00577 bool EmbeddedChart::load( const QDomElement& element )
00578 {
00579     kdDebug() << "Loading EmbeddedChart" << endl;
00580     if ( !EmbeddedKOfficeObject::load( element ) )
00581         return false;
00582 
00583     if ( element.hasAttribute( "left-cell" ) &&
00584          element.hasAttribute( "top-cell" ) &&
00585          element.hasAttribute( "right-cell" ) &&
00586          element.hasAttribute( "bottom-cell" ) )
00587     {
00588         QRect r;
00589         r.setCoords( element.attribute( "left-cell" ).toInt(),
00590                      element.attribute( "top-cell" ).toInt(),
00591                      element.attribute( "right-cell" ).toInt(),
00592                      element.attribute( "bottom-cell" ).toInt() );
00593 
00594         setDataArea( r );
00595     }
00596 
00597     return true;
00598 }
00599 
00600 void EmbeddedChart::loadOasis(const QDomElement &element, KoOasisLoadingContext &context/*, KPRLoadingInfo *info*/)
00601 {
00602     kdDebug()<<"void EmbeddedChart::loadOasis(const QDomElement &element)******************\n";
00603     EmbeddedKOfficeObject::loadOasis( element, context );
00604 
00605     QDomElement objectElement = KoDom::namedItemNS( element, KoXmlNS::draw, "object" );
00606     QString str_range = objectElement.attributeNS( KoXmlNS::draw, "notify-on-update-of-ranges", QString::null);
00607 
00608     if ( !str_range.isNull() )
00609     {
00610       str_range = Oasis::decodeFormula( str_range );
00611       Range range( str_range );
00612       if ( range.isValid() )
00613         setDataArea( range.range() );
00614     }
00615 
00616     chart()->setCanChangeValue( false  );
00617 }
00618 
00619 
00620 bool EmbeddedChart::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
00621 {
00622     kdDebug() << "EmbeddedChart::saveOasisPart " << sc.partIndexObj << endl;
00623 
00624     EmbeddedKOfficeObject::saveOasisObjectAttributes( sc );
00625 
00626     if(m_pBinding) { // see http://bugs.kde.org/show_bug.cgi?id=120395
00627         QRect dataArea = m_pBinding->dataArea();
00628         QString rangeName = util_rangeName( dataArea);
00629         rangeName.insert( rangeName.find(':') +1, sheet()->sheetName() + "." );
00630         rangeName.prepend( sheet()->sheetName() + "." );
00631         sc.xmlWriter.addAttribute( "draw:notify-on-update-of-ranges", rangeName );
00632     }
00633     else {
00634         kdDebug() << "EmbeddedChart::saveOasisPart m_pBinding is NULL" << endl;
00635     }
00636     sc.xmlWriter.endElement();
00637 
00638     return true;
00639 }
00640 
00641 QDomElement EmbeddedChart::save( QDomDocument& doc )
00642 {
00643     kdDebug() << "Saving EmbeddedChart" << endl;
00644     QDomElement element = EmbeddedKOfficeObject::save( doc );
00645     element.setTagName( "chart" );
00646 
00647     element.setAttribute( "left-cell", m_pBinding->dataArea().left() );
00648     element.setAttribute( "right-cell", m_pBinding->dataArea().right() );
00649     element.setAttribute( "top-cell", m_pBinding->dataArea().top() );
00650     element.setAttribute( "bottom-cell", m_pBinding->dataArea().bottom() );
00651 
00652     return element;
00653 }
00654 void EmbeddedChart::draw( QPainter *_painter )
00655 {
00656   EmbeddedKOfficeObject::draw( _painter );
00657 }
00658 
00659 bool EmbeddedChart::loadDocument( KoStore* _store )
00660 {
00661     bool res = /*EmbeddedKOfficeObject::*/m_embeddedObject->loadDocument( _store );
00662     if ( !res )
00663         return res;
00664 
00665     // Did we see a cell rectangle ?
00666     if ( !m_pBinding )
00667         return true;
00668 
00669     update();
00670 
00671     chart()->setCanChangeValue( false  );
00672     return true;
00673 }
00674 
00675 KoChart::Part* EmbeddedChart::chart()
00676 {
00677     assert( m_embeddedObject->document()->inherits( "KoChart::Part" ) );
00678     return static_cast<KoChart::Part *>( m_embeddedObject->document() );
00679 }
00680 
00681 /**********************************************************
00682  *
00683  * EmbeddedPictureObject
00684  *
00685  **********************************************************/
00686 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection )
00687    : EmbeddedObject( _sheet, _geometry )
00688 {
00689     imageCollection = _imageCollection;
00690     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00691     mirrorType = PM_NORMAL;
00692     depth = 0;
00693     swapRGB = false;
00694     grayscal = false;
00695     bright = 0;
00696     m_effect = IE_NONE;
00697     m_ie_par1 = QVariant();
00698     m_ie_par2 = QVariant();
00699     m_ie_par3 = QVariant();
00700     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00701     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00702 }
00703 
00704 
00705 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection, const KoPictureKey & key )
00706     : EmbeddedObject( _sheet, _geometry )
00707 {
00708     imageCollection = _imageCollection;
00709 
00710     //ext = KoSize(); // invalid size means unset
00711     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00712     mirrorType = PM_NORMAL;
00713     depth = 0;
00714     swapRGB = false;
00715     grayscal = false;
00716     bright = 0;
00717     m_effect = IE_NONE;
00718     m_ie_par1 = QVariant();
00719     m_ie_par2 = QVariant();
00720     m_ie_par3 = QVariant();
00721     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00722     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00723 
00724     setPicture( key );
00725 }
00726 
00727 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, KoPictureCollection *_imageCollection )
00728   : EmbeddedObject( _sheet, KoRect(0,0,0,0) )
00729 {
00730   imageCollection = _imageCollection;
00731 
00732   //ext = KoSize(); // invalid size means unset
00733   pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00734   mirrorType = PM_NORMAL;
00735   depth = 0;
00736   swapRGB = false;
00737   grayscal = false;
00738   bright = 0;
00739   m_effect = IE_NONE;
00740   m_ie_par1 = QVariant();
00741   m_ie_par2 = QVariant();
00742   m_ie_par3 = QVariant();
00743     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00744   m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00745 }
00746 
00747 EmbeddedPictureObject::~EmbeddedPictureObject()
00748 {
00749 }
00750 
00751 bool EmbeddedPictureObject::load( const QDomElement& /*element*/ )
00752 {
00753     return false;
00754 }
00755 
00756 QDomElement EmbeddedPictureObject::save( QDomDocument& /*doc*/ )
00757 {
00758     kdDebug() << "Saving EmbeddedPictureObject" << endl;
00759     return QDomElement();
00760 }
00761 
00762 QString EmbeddedPictureObject::convertValueToPercent( int val ) const
00763 {
00764    return QString::number( val )+"%";
00765 }
00766 
00767 void EmbeddedPictureObject::saveOasisPictureElement( KoGenStyle &styleobjectauto ) const
00768 {
00769 
00770     if ( bright != 0 )
00771     {
00772         styleobjectauto.addProperty( "draw:luminance", convertValueToPercent( bright ) );
00773     }
00774     if ( grayscal )
00775     {
00776         styleobjectauto.addProperty( "draw:color-mode","greyscale" );
00777     }
00778 
00779     switch (m_effect)
00780     {
00781     case IE_NONE:
00782         //nothing
00783         break;
00784     case IE_CHANNEL_INTENSITY:
00785     {
00786         //for the moment kpresenter support just one channel
00787         QString percent = convertValueToPercent( m_ie_par1.toInt() );
00788         KImageEffect::RGBComponent channel = static_cast<KImageEffect::RGBComponent>( m_ie_par2.toInt() );
00789         switch( channel )
00790         {
00791         case KImageEffect::Red:
00792             styleobjectauto.addProperty( "draw:red", percent );
00793             styleobjectauto.addProperty( "draw:blue", "0%" );
00794             styleobjectauto.addProperty( "draw:green", "0%" );
00795             break;
00796         case KImageEffect::Green:
00797             styleobjectauto.addProperty( "draw:green", percent );
00798             styleobjectauto.addProperty( "draw:red", "0%" );
00799             styleobjectauto.addProperty( "draw:blue", "0%" );
00800             break;
00801         case KImageEffect::Blue:
00802             styleobjectauto.addProperty( "draw:blue", percent );
00803             styleobjectauto.addProperty( "draw:red", "0%" );
00804             styleobjectauto.addProperty( "draw:green", "0%" );
00805             break;
00806         case KImageEffect::Gray:
00807             break;
00808         case KImageEffect::All:
00809             break;
00810         }
00811     }
00812     break;
00813     case IE_FADE:
00814         break;
00815     case IE_FLATTEN:
00816         break;
00817     case IE_INTENSITY:
00818         break;
00819     case IE_DESATURATE:
00820         break;
00821     case IE_CONTRAST:
00822     {
00823         //kpresenter use value between -255 and 255
00824         //oo impress between -100% and 100%
00825         int val =  m_ie_par1.toInt();
00826         val = ( int )( ( double )val*100.0/255.0 );
00827         styleobjectauto.addProperty( "draw:contrast", convertValueToPercent( val ) );
00828     }
00829     break;
00830     case IE_NORMALIZE:
00831         break;
00832     case IE_EQUALIZE:
00833         break;
00834     case IE_THRESHOLD:
00835         break;
00836     case IE_SOLARIZE:
00837         break;
00838     case IE_EMBOSS:
00839         break;
00840     case IE_DESPECKLE:
00841         break;
00842     case IE_CHARCOAL:
00843         break;
00844     case IE_NOISE:
00845         break;
00846     case IE_BLUR:
00847         break;
00848     case IE_EDGE:
00849         break;
00850     case IE_IMPLODE:
00851         break;
00852     case IE_OIL_PAINT:
00853         break;
00854     case IE_SHARPEN:
00855         break;
00856     case IE_SPREAD:
00857         break;
00858     case IE_SHADE:
00859         break;
00860     case IE_SWIRL:
00861         break;
00862     case IE_WAVE:
00863         break;
00864     }
00865 }
00866 
00867 bool EmbeddedPictureObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
00868 {
00869     sc.xmlWriter.startElement( "draw:image" );
00870     sc.xmlWriter.addAttribute( "xlink:type", "simple" );
00871     sc.xmlWriter.addAttribute( "xlink:show", "embed" );
00872     sc.xmlWriter.addAttribute( "xlink:actuate", "onLoad" );
00873     sc.xmlWriter.addAttribute( "xlink:href", imageCollection->getOasisFileName( image ) );
00874     sc.xmlWriter.endElement();
00875 
00876     return true;
00877 }
00878 
00879 const char * EmbeddedPictureObject::getOasisElementName() const
00880 {
00881     return "draw:frame";
00882 }
00883 
00884 
00885 void EmbeddedPictureObject::loadPicture( const QString & fileName )
00886 {
00887     image = imageCollection->loadPicture( fileName );
00888 }
00889 
00890 EmbeddedPictureObject &EmbeddedPictureObject::operator=( const EmbeddedPictureObject & )
00891 {
00892     return *this;
00893 }
00894 
00895 void EmbeddedPictureObject::setPicture( const KoPictureKey & key )
00896 {
00897     image = imageCollection->findPicture( key );
00898 }
00899 
00900 void EmbeddedPictureObject::reload( void )
00901 {
00902     // ### FIXME: this seems wrong, KoPictureCollection will never reload it (or perhaps it is the function name that is wrong)
00903     setPicture( image.getKey() );
00904 }
00905 
00906 // KSpread doesn't support pictures in it's old XML file format.
00907 // QDomDocumentFragment EmbeddedPictureObject::save( QDomDocument& doc, double offset )
00908 // {
00909 //     QDomDocumentFragment fragment=KP2DObject::save(doc, offset);
00910 //     QDomElement elem=doc.createElement("KEY");
00911 //     image.getKey().saveAttributes(elem);
00912 //     fragment.appendChild(elem);
00913 //
00914 //     QDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
00915 //
00916 //     elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
00917 //     elemSettings.setAttribute( "depth", depth );
00918 //     elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
00919 //     elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
00920 //     elemSettings.setAttribute( "bright", bright );
00921 //     fragment.appendChild( elemSettings );
00922 //
00923 //     if (m_effect!=IE_NONE) {
00924 //         QDomElement imageEffects = doc.createElement("EFFECTS");
00925 //         imageEffects.setAttribute("type", static_cast<int>(m_effect));
00926 //         if (m_ie_par1.isValid())
00927 //             imageEffects.setAttribute("param1", m_ie_par1.toString());
00928 //         if (m_ie_par2.isValid())
00929 //             imageEffects.setAttribute("param2", m_ie_par2.toString());
00930 //         if (m_ie_par3.isValid())
00931 //             imageEffects.setAttribute("param3", m_ie_par3.toString());
00932 //         fragment.appendChild( imageEffects );
00933 //     }
00934 //
00935 //     return fragment;
00936 // }
00937 
00938 void EmbeddedPictureObject::loadOasisPictureEffect(KoOasisLoadingContext & context )
00939 {
00940     KoStyleStack &styleStack = context.styleStack();
00941     styleStack.setTypeProperties( "graphic" );
00942     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) &&  ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
00943     {
00944         grayscal = true;
00945     }
00946 
00947     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
00948     {
00949         QString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
00950         str = str.remove( '%' );
00951         int val = str.toInt();
00952         m_effect = IE_CONTRAST;
00953         val = ( int )( 255.0 *val/100.0 );
00954         m_ie_par1 = QVariant(val);
00955     }
00956     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
00957     {
00958         QString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
00959         str = str.remove( '%' );
00960         int val = str.toInt();
00961         m_effect = IE_CHANNEL_INTENSITY;
00962         m_ie_par1 = QVariant(val);
00963         m_ie_par2 = QVariant( ( int )KImageEffect::Red );
00964     }
00965     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
00966     {
00967         QString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
00968         str = str.remove( '%' );
00969         int val = str.toInt();
00970         m_effect = IE_CHANNEL_INTENSITY;
00971         m_ie_par1 = QVariant(val);
00972         m_ie_par2 = QVariant( ( int )KImageEffect::Green );
00973     }
00974     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
00975     {
00976         QString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
00977         str = str.remove( '%' );
00978         int val = str.toInt();
00979         m_effect = IE_CHANNEL_INTENSITY;
00980         m_ie_par1 = QVariant(val);
00981         m_ie_par2 = QVariant( ( int )KImageEffect::Blue );
00982     }
00983     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
00984     {
00985        QString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
00986        str = str.remove( '%' );
00987        bright = str.toInt();
00988     }
00989 }
00990 
00991 void EmbeddedPictureObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& /*mainStyles*/ ) const
00992 {
00993      //KP2DObject::fillStyle( styleObjectAuto, mainStyles );
00994      saveOasisPictureElement( styleObjectAuto );
00995 }
00996 
00997 void EmbeddedPictureObject::loadOasis(const QDomElement &element, KoOasisLoadingContext & context/*, KPRLoadingInfo *info*/)
00998 {
00999     //load it into kpresenter_doc
01000     EmbeddedObject::loadOasis( element, context );
01001     loadOasisPictureEffect( context );
01002     QDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
01003     const QString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", QString::null) );
01004     kdDebug()<<" href: "<<href<<endl;
01005     if ( !href.isEmpty() /*&& href[0] == '#'*/ )
01006     {
01007         QString strExtension;
01008         const int result=href.findRev(".");
01009         if (result>=0)
01010         {
01011             strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
01012         }
01013         QString filename(href/*.mid(1)*/);
01014         const KoPictureKey key(filename, QDateTime::currentDateTime(Qt::UTC));
01015         image.setKey(key);
01016 
01017         KoStore* store = context.store();
01018         if ( store->open( filename ) )
01019         {
01020             KoStoreDevice dev(store);
01021             if ( !image.load( &dev, strExtension ) )
01022                 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
01023             store->close();
01024         }
01025         imageCollection->insertPicture( key, image );
01026     }
01027     // ### TODO: load remote file
01028 }
01029 
01030 
01031 // double EmbeddedPictureObject::load(const QDomElement &element)
01032 // {
01033 //     double offset=KP2DObject::load(element);
01034 //     QDomElement e=element.namedItem("KEY").toElement();
01035 //     if(!e.isNull()) {
01036 //         KoPictureKey key;
01037 //         key.loadAttributes( e );
01038 //         image.clear();
01039 //         image.setKey(key);
01040 //     }
01041 //     else {
01042 //         // try to find a PIXMAP tag if the KEY is not available...
01043 //         e=element.namedItem("PIXMAP").toElement();
01044 //         if (e.isNull()) {
01045 //             // try to find a FILENAME tag (old cliparts...)
01046 //             e=element.namedItem("FILENAME").toElement();
01047 //             if(!e.isNull()) {
01048 //                 // Loads from the disk directly (unless it's in the collection already?)
01049 //                 image = imageCollection->loadPicture( e.attribute("filename") );
01050 //             }
01051 //         } else {
01052 //             bool openPic = true;
01053 //             QString _data;
01054 //             QString _fileName;
01055 //             if(e.hasAttribute("data"))
01056 //                 _data=e.attribute("data");
01057 //             if ( _data.isEmpty() )
01058 //                 openPic = true;
01059 //             else
01060 //                 openPic = false;
01061 //             if(e.hasAttribute("filename"))
01062 //                 _fileName=e.attribute("filename");
01063 //             if ( !_fileName.isEmpty() )
01064 //             {
01065 //                 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
01066 //                 {
01067 //                     int _envVarE = _fileName.find( '/', _envVarB );
01068 //                     // ### FIXME: it should be QString::local8Bit instead of QFile::encodeName, shouldn't it?
01069 //                     QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
01070 //                     _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
01071 //                 }
01072 //             }
01073 //
01074 //             if ( openPic )
01075 //                 // !! this loads it from the disk (unless it's in the image collection already)
01076 //                 image = imageCollection->loadPicture( _fileName );
01077 //             else
01078 //             {
01079 //                 KoPictureKey key( _fileName );
01080 //                 image.clear();
01081 //                 image.setKey(key);
01082 //                 QByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
01083 //                 rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
01084 //                 QBuffer buffer(rawData); // ### TODO: open?
01085 //                 image.loadXpm(&buffer);
01086 //             }
01087 //         }
01088 //     }
01089 //
01090 //     e = element.namedItem( "PICTURESETTINGS" ).toElement();
01091 //     if ( !e.isNull() ) {
01092 //         PictureMirrorType _mirrorType = PM_NORMAL;
01093 //         int _depth = 0;
01094 //         bool _swapRGB = false;
01095 //         bool _grayscal = false;
01096 //         int _bright = 0;
01097 //
01098 //         if ( e.hasAttribute( "mirrorType" ) )
01099 //             _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
01100 //         if ( e.hasAttribute( "depth" ) )
01101 //             _depth = e.attribute( "depth" ).toInt();
01102 //         if ( e.hasAttribute( "swapRGB" ) )
01103 //             _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
01104 //         if ( e.hasAttribute( "grayscal" ) )
01105 //             _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
01106 //         if ( e.hasAttribute( "bright" ) )
01107 //             _bright = e.attribute( "bright" ).toInt();
01108 //
01109 //         mirrorType = _mirrorType;
01110 //         depth = _depth;
01111 //         swapRGB = _swapRGB;
01112 //         grayscal = _grayscal;
01113 //         bright = _bright;
01114 //     }
01115 //     else {
01116 //         mirrorType = PM_NORMAL;
01117 //         depth = 0;
01118 //         swapRGB = false;
01119 //         grayscal = false;
01120 //         bright = 0;
01121 //     }
01122 //
01123 //     e = element.namedItem( "EFFECTS" ).toElement();
01124 //     if (!e.isNull()) {
01125 //         if (e.hasAttribute("type"))
01126 //             m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
01127 //         if (e.hasAttribute("param1"))
01128 //             m_ie_par1 = QVariant(e.attribute("param1"));
01129 //         else
01130 //             m_ie_par1 = QVariant();
01131 //         if (e.hasAttribute("param2"))
01132 //             m_ie_par2 = QVariant(e.attribute("param2"));
01133 //         else
01134 //             m_ie_par2 = QVariant();
01135 //         if (e.hasAttribute("param3"))
01136 //             m_ie_par3 = QVariant(e.attribute("param3"));
01137 //         else
01138 //             m_ie_par3 = QVariant();
01139 //     }
01140 //     else
01141 //         m_effect = IE_NONE;
01142 //
01143 //     return offset;
01144 // }
01145 
01146 void EmbeddedPictureObject::drawShadow( QPainter* /*_painter*/,  KoZoomHandler* /*_zoomHandler*/)
01147 {
01148 //     const double ox = /*orig*/m_geometry.x();
01149 //     const double oy = /*orig*/m_geometry.y();
01150 //     const double ow = /*ext*/m_geometry.width();
01151 //     const double oh = /*ext*/m_geometry.height();
01152 //
01153 //     _painter->save();
01154 //
01155 //     QPen pen2 = pen.zoomedPen( _zoomHandler );
01156 //     _painter->setPen( pen2 );
01157 //     _painter->setBrush( getBrush() );
01158 //
01159 //     double sx = 0;
01160 //     double sy = 0;
01161 //
01162 //     getShadowCoords( sx, sy );
01163 //
01164 //     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
01165 //     _painter->setPen( QPen( shadowColor ) );
01166 //     _painter->setBrush( shadowColor );
01167 //     if ( kAbs(angle) <= DBL_EPSILON )
01168 //         _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
01169 //                             _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
01170 //     else
01171 //     {
01172 //         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
01173 //         QRect br = QRect( 0, 0, bs.width(), bs.height() );
01174 //         int pw = br.width();
01175 //         int ph = br.height();
01176 //         QRect rr = br;
01177 //         int pixYPos = -rr.y();
01178 //         int pixXPos = -rr.x();
01179 //         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
01180 //         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
01181 //
01182 //         QWMatrix m;
01183 //         m.translate( pw / 2, ph / 2 );
01184 //         m.rotate( angle );
01185 //         m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
01186 //                      rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
01187 //
01188 //         _painter->setWorldMatrix( m, true );
01189 //
01190 //         _painter->drawRect( 0, 0, bs.width(), bs.height() );
01191 //     }
01192 //
01193 //     _painter->restore();
01194 }
01195 
01196 QPixmap EmbeddedPictureObject::toPixmap( double xZoom , double yZoom )
01197 {
01198     KoZoomHandler zoomHandler;
01199     zoomHandler.setZoomedResolution( xZoom /* *zoomHandler.resolutionX()*/ , yZoom /* *zoomHandler.resolutionY()*/ );
01200     return generatePixmap( &zoomHandler );
01201 }
01202 
01203 QPixmap EmbeddedPictureObject::generatePixmap(KoZoomHandler*_zoomHandler)
01204 {
01205     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1 : pen.width() ) / 2.0 );
01206 
01207     QSize size( _zoomHandler->zoomSize( m_geometry.size() /*ext*/ ) );
01208     //kdDebug(33001) << "EmbeddedPictureObject::generatePixmap size= " << size << endl;
01209     QPixmap pixmap(size);
01210     QPainter paint;
01211 
01212     paint.begin( &pixmap );
01213     pixmap.fill( Qt::white );
01214 
01215     // Draw background
01216     paint.setPen( Qt::NoPen );
01217     paint.setBrush( getBrush() );
01218 
01219     QRect rect( (int)( penw ), (int)( penw ),
01220                  (int)( _zoomHandler->zoomItX( /*ext*/m_geometry.width() ) - 2.0 * penw ),
01221                  (int)( _zoomHandler->zoomItY( /*ext*/m_geometry.height() ) - 2.0 * penw ) );
01222 
01223 //      if ( getFillType() == FT_BRUSH || !gradient )
01224          paint.drawRect( rect );
01225 //     else {
01226         // ### TODO: this was also drawn for drawContour==true, but why?
01227 //         gradient->setSize( size );
01228 //         paint.drawPixmap( (int)( penw ), (int)( penw ),
01229 //                           gradient->pixmap(), 0, 0,
01230 //                           (int)( _zoomHandler->zoomItX( m_geometry/*ext*/.width() ) - 2 * penw ),
01231 //                           (int)( _zoomHandler->zoomItY( m_geometry/*ext*/.height() ) - 2 * penw ) );
01232 //    }
01233 
01234 
01235     image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
01236     image.clearCache(); // Release the memoy of the picture cache
01237 
01238 //     image.setAlphaBuffer(true);
01239 //     QBitmap tmpMask;
01240 //     tmpMask = image.createAlphaMask().scale(size);
01241 //     pixmap.setMask(tmpMask);
01242 
01243     paint.end();
01244     return pixmap;
01245 }
01246 
01247 void EmbeddedPictureObject::draw( QPainter *_painter/*, KoZoomHandler*_zoomHandler,
01248                            int pageNum, SelectionMode selectionMode, bool drawContour*/ )
01249 {
01250     bool drawContour = false;
01251     KoZoomHandler*_zoomHandler = sheet()->doc();
01252 
01253 
01254     if ( image.isNull() ) return;
01255 
01256 //     if ( shadowDistance > 0 && !drawContour )
01257 //         drawShadow(_painter, _zoomHandler);
01258 
01259     const double ox = /*orig*/m_geometry.x();
01260     const double oy = /*orig*/m_geometry.y();
01261     const double ow = /*ext*/m_geometry.width();
01262     const double oh = /*ext*/m_geometry.height();
01263     //const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
01264 
01265     _painter->save();
01266 
01267     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
01268 
01269     if ( kAbs(angle)> DBL_EPSILON ) {
01270         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
01271         QRect br = QRect( 0, 0, bs.width(), bs.height() );
01272         int pw = br.width();
01273         int ph = br.height();
01274         QRect rr = br;
01275         int pixYPos = -rr.y();
01276         int pixXPos = -rr.x();
01277         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
01278         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
01279 
01280         QWMatrix m;
01281         m.translate( pw / 2, ph / 2 );
01282         m.rotate( angle );
01283         m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
01284         _painter->setWorldMatrix( m, true );
01285     }
01286 
01287     if ( !drawContour )
01288     {
01289         QRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
01290                     (int)( _zoomHandler->zoomItY(  oh ) ) );
01291         // ### HACK QT seems not to be able to correctly compare QVariant
01292         bool variants1;
01293         if (m_ie_par1.isNull())
01294             variants1=m_cachedPar1.isNull();
01295         else
01296             variants1=(m_ie_par1 == m_cachedPar1);
01297         bool variants2;
01298         if (m_ie_par2.isNull())
01299             variants2=m_cachedPar2.isNull();
01300         else
01301             variants2=(m_ie_par2 == m_cachedPar2);
01302         bool variants3;
01303         if (m_ie_par3.isNull())
01304             variants3=m_cachedPar3.isNull();
01305         else
01306             variants3=(m_ie_par3 == m_cachedPar3);
01307 
01308         if (m_cachedRect == rect
01309             // All what EmbeddedPictureObject::changePictureSettings needs
01310             && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
01311             && m_cachedBright == bright && m_cachedEffect == m_effect
01312             // Who needs it?
01313             && m_cachedDepth == depth
01314 #if 0
01315             && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
01316 #else
01317             && variants1 && variants2 && variants3
01318 #endif
01319             )
01320         {
01321             //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
01322         }
01323         else
01324         {
01325             if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
01326                 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
01327             else
01328                 m_cachedPixmap = generatePixmap( _zoomHandler );
01329             m_cachedRect = rect;
01330             m_cachedMirrorType = mirrorType;
01331             m_cachedSwapRGB = swapRGB;
01332             m_cachedGrayscal = grayscal;
01333             m_cachedBright = bright;
01334             m_cachedEffect = m_effect;
01335             m_cachedDepth = depth;
01336             m_cachedPar1 = m_ie_par1;
01337             m_cachedPar2 = m_ie_par2;
01338             m_cachedPar3 = m_ie_par3;
01339             //kdDebug(33001) <<  "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
01340         }
01341         _painter->eraseRect( rect );
01342         _painter->drawPixmap( rect, m_cachedPixmap);
01343     }
01344 
01345     // Draw border
01346     // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
01347 //     QPen pen2;
01348 //     if ( drawContour ) {
01349 //         pen2 = QPen( Qt::black, 1, Qt::DotLine );
01350 //         _painter->setRasterOp( Qt::NotXorROP );
01351 //     }
01352 //     else {
01353 //         pen2 = pen;
01354 //         pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == Qt::NoPen ) ? 1.0 : (double)pen.width() ) );
01355 //     }
01356 //     _painter->setPen( pen2 );
01357 //     _painter->setBrush( Qt::NoBrush );
01358 //     _painter->drawRect( (int)( penw ), (int)( penw ),
01359 //                         (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
01360 //                         (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
01361 
01362 
01363     _painter->restore();
01364 
01365     //KPObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
01366     EmbeddedObject::draw( _painter );
01367 }
01368 
01369 QPixmap EmbeddedPictureObject::getOriginalPixmap()
01370 {
01371     QSize _pixSize = image.getOriginalSize();
01372     kdDebug(33001) << "EmbeddedPictureObject::getOriginalPixmap size= " << _pixSize << endl;
01373     QPixmap _pixmap = image.generatePixmap( _pixSize, true );
01374     image.clearCache(); // Release the memoy of the picture cache
01375 
01376     return _pixmap;
01377 }
01378 
01379 QPixmap EmbeddedPictureObject::changePictureSettings( QPixmap _tmpPixmap )
01380 {
01381     QImage _tmpImage = _tmpPixmap.convertToImage();
01382 
01383     if (_tmpImage.isNull())
01384         return _tmpPixmap;
01385 
01386     bool _horizontal = false;
01387     bool _vertical = false;
01388     if ( mirrorType == PM_HORIZONTAL )
01389         _horizontal = true;
01390     else if ( mirrorType == PM_VERTICAL )
01391         _vertical = true;
01392     else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
01393         _horizontal = true;
01394         _vertical = true;
01395     }
01396 
01397     _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
01398 
01399     if ( depth != 0 ) {
01400         QImage tmpImg = _tmpImage.convertDepth( depth );
01401         if ( !tmpImg.isNull() )
01402             _tmpImage = tmpImg;
01403     }
01404 
01405     if ( swapRGB )
01406         _tmpImage = _tmpImage.swapRGB();
01407 
01408     if ( grayscal ) {
01409         if ( depth == 1 || depth == 8 ) {
01410             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
01411                 QRgb rgb = _tmpImage.color( i );
01412                 int gray = qGray( rgb );
01413                 rgb = qRgb( gray, gray, gray );
01414                 _tmpImage.setColor( i, rgb );
01415             }
01416         }
01417         else {
01418             int _width = _tmpImage.width();
01419             int _height = _tmpImage.height();
01420             int _x = 0;
01421             int _y = 0;
01422 
01423             for ( _x = 0; _x < _width; ++_x ) {
01424                 for ( _y = 0; _y < _height; ++_y ) {
01425                     if ( _tmpImage.valid( _x, _y ) ) {
01426                         QRgb rgb = _tmpImage.pixel( _x, _y );
01427                         int gray = qGray( rgb );
01428                         rgb = qRgb( gray, gray, gray );
01429                         _tmpImage.setPixel( _x, _y, rgb );
01430                     }
01431                 }
01432             }
01433         }
01434     }
01435 
01436     if ( bright != 0 ) {
01437         if ( depth == 1 || depth == 8 ) {
01438             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
01439                 QRgb rgb = _tmpImage.color( i );
01440                 QColor c( rgb );
01441 
01442                 if ( bright > 0 )
01443                     rgb = c.light( 100 + bright ).rgb();
01444                 else
01445                     rgb = c.dark( 100 + abs( bright ) ).rgb();
01446 
01447                 _tmpImage.setColor( i, rgb );
01448             }
01449         }
01450         else {
01451             int _width = _tmpImage.width();
01452             int _height = _tmpImage.height();
01453             int _x = 0;
01454             int _y = 0;
01455 
01456             for ( _x = 0; _x < _width; ++_x ) {
01457                 for ( _y = 0; _y < _height; ++_y ) {
01458                     if ( _tmpImage.valid( _x, _y ) ) {
01459                         QRgb rgb = _tmpImage.pixel( _x, _y );
01460                         QColor c( rgb );
01461 
01462                         if ( bright > 0 )
01463                             rgb = c.light( 100 + bright ).rgb();
01464                         else
01465                             rgb = c.dark( 100 + abs( bright ) ).rgb();
01466 
01467                         _tmpImage.setPixel( _x, _y, rgb );
01468                     }
01469                 }
01470             }
01471         }
01472     }
01473 
01474     switch (m_effect) {
01475     case IE_CHANNEL_INTENSITY: {
01476         _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
01477                                                    static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
01478         break;
01479     }
01480     case IE_FADE: {
01481         _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
01482         break;
01483     }
01484     case IE_FLATTEN: {
01485         _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
01486         break;
01487     }
01488     case IE_INTENSITY: {
01489         _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
01490         break;
01491     }
01492     case IE_DESATURATE: {
01493         _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
01494         break;
01495     }
01496     case IE_CONTRAST: {
01497         _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
01498         break;
01499     }
01500     case IE_NORMALIZE: {
01501         KImageEffect::normalize(_tmpImage);
01502         break;
01503     }
01504     case IE_EQUALIZE: {
01505         KImageEffect::equalize(_tmpImage);
01506         break;
01507     }
01508     case IE_THRESHOLD: {
01509         KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
01510         break;
01511     }
01512     case IE_SOLARIZE: {
01513         KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
01514         break;
01515     }
01516     case IE_EMBOSS: {
01517         _tmpImage = KImageEffect::emboss(_tmpImage);
01518         break;
01519     }
01520     case IE_DESPECKLE: {
01521         _tmpImage = KImageEffect::despeckle(_tmpImage);
01522         break;
01523     }
01524     case IE_CHARCOAL: {
01525         _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
01526         break;
01527     }
01528     case IE_NOISE: {
01529         _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
01530         break;
01531     }
01532     case IE_BLUR: {
01533         _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
01534         break;
01535     }
01536     case IE_EDGE: {
01537         _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
01538         break;
01539     }
01540     case IE_IMPLODE: {
01541         _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
01542         break;
01543     }
01544     case IE_OIL_PAINT: {
01545         _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
01546         break;
01547     }
01548     case IE_SHARPEN: {
01549         _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
01550         break;
01551     }
01552     case IE_SPREAD: {
01553         _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
01554         break;
01555     }
01556     case IE_SHADE: {
01557         _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
01558         break;
01559     }
01560     case IE_SWIRL: {
01561         _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
01562         break;
01563     }
01564     case IE_WAVE: {
01565         _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
01566         break;
01567     }
01568     case IE_NONE:
01569     default:
01570         break;
01571     }
01572 
01573     _tmpPixmap.convertFromImage( _tmpImage );
01574 
01575     return _tmpPixmap;
01576 }
01577 
01578 void EmbeddedPictureObject::flip( bool /*horizontal*/ )
01579 {
01580 //     KP2DObject::flip( horizontal );
01581 //     if ( horizontal )
01582 //     {
01583 //         switch ( mirrorType )
01584 //         {
01585 //             case PM_NORMAL:
01586 //                 mirrorType = PM_HORIZONTAL;
01587 //                 break;
01588 //             case PM_HORIZONTAL:
01589 //                 mirrorType = PM_NORMAL;
01590 //                 break;
01591 //             case PM_VERTICAL:
01592 //                 mirrorType = PM_HORIZONTALANDVERTICAL;
01593 //                 break;
01594 //             case PM_HORIZONTALANDVERTICAL:
01595 //                 mirrorType = PM_VERTICAL;
01596 //                 break;
01597 //         }
01598 //     }
01599 //     else
01600 //     {
01601 //         switch ( mirrorType )
01602 //         {
01603 //             case PM_NORMAL:
01604 //                 mirrorType = PM_VERTICAL;
01605 //                 break;
01606 //             case PM_HORIZONTAL:
01607 //                 mirrorType = PM_HORIZONTALANDVERTICAL;
01608 //                 break;
01609 //             case PM_VERTICAL:
01610 //                 mirrorType = PM_NORMAL;
01611 //                 break;
01612 //             case PM_HORIZONTALANDVERTICAL:
01613 //                 mirrorType = PM_HORIZONTAL;
01614 //                 break;
01615 //         }
01616 //     }
01617 }
KDE Home | KDE Accessibility Home | Description of Access Keys