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     KoChart::Part* chartPart = chart();
00617     if ( chartPart )
00618         chartPart->setCanChangeValue( false  );
00619 }
00620 
00621 
00622 bool EmbeddedChart::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
00623 {
00624     kdDebug() << "EmbeddedChart::saveOasisPart " << sc.partIndexObj << endl;
00625 
00626     EmbeddedKOfficeObject::saveOasisObjectAttributes( sc );
00627 
00628     if(m_pBinding) { // see http://bugs.kde.org/show_bug.cgi?id=120395
00629         QRect dataArea = m_pBinding->dataArea();
00630         QString rangeName = util_rangeName( dataArea);
00631         rangeName.insert( rangeName.find(':') +1, sheet()->sheetName() + "." );
00632         rangeName.prepend( sheet()->sheetName() + "." );
00633         sc.xmlWriter.addAttribute( "draw:notify-on-update-of-ranges", rangeName );
00634     }
00635     else {
00636         kdDebug() << "EmbeddedChart::saveOasisPart m_pBinding is NULL" << endl;
00637     }
00638     sc.xmlWriter.endElement();
00639 
00640     return true;
00641 }
00642 
00643 QDomElement EmbeddedChart::save( QDomDocument& doc )
00644 {
00645     kdDebug() << "Saving EmbeddedChart" << endl;
00646     QDomElement element = EmbeddedKOfficeObject::save( doc );
00647     element.setTagName( "chart" );
00648 
00649     element.setAttribute( "left-cell", m_pBinding->dataArea().left() );
00650     element.setAttribute( "right-cell", m_pBinding->dataArea().right() );
00651     element.setAttribute( "top-cell", m_pBinding->dataArea().top() );
00652     element.setAttribute( "bottom-cell", m_pBinding->dataArea().bottom() );
00653 
00654     return element;
00655 }
00656 void EmbeddedChart::draw( QPainter *_painter )
00657 {
00658   EmbeddedKOfficeObject::draw( _painter );
00659 }
00660 
00661 bool EmbeddedChart::loadDocument( KoStore* _store )
00662 {
00663     bool res = /*EmbeddedKOfficeObject::*/m_embeddedObject->loadDocument( _store );
00664     if ( !res )
00665         return res;
00666 
00667     // Did we see a cell rectangle ?
00668     if ( !m_pBinding )
00669         return true;
00670 
00671     update();
00672 
00673     KoChart::Part* chartPart = chart();
00674     if ( chartPart )
00675         chartPart->setCanChangeValue( false  );
00676     return true;
00677 }
00678 
00679 KoChart::Part* EmbeddedChart::chart()
00680 {
00681     // Returns 0 when the chart couldn't be loaded and we get KoUnavailPart instead.
00682     return qt_cast<KoChart::Part *>( m_embeddedObject->document() );
00683 }
00684 
00685 /**********************************************************
00686  *
00687  * EmbeddedPictureObject
00688  *
00689  **********************************************************/
00690 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection )
00691    : EmbeddedObject( _sheet, _geometry )
00692 {
00693     imageCollection = _imageCollection;
00694     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00695     mirrorType = PM_NORMAL;
00696     depth = 0;
00697     swapRGB = false;
00698     grayscal = false;
00699     bright = 0;
00700     m_effect = IE_NONE;
00701     m_ie_par1 = QVariant();
00702     m_ie_par2 = QVariant();
00703     m_ie_par3 = QVariant();
00704     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00705     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00706 }
00707 
00708 
00709 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection, const KoPictureKey & key )
00710     : EmbeddedObject( _sheet, _geometry )
00711 {
00712     imageCollection = _imageCollection;
00713 
00714     //ext = KoSize(); // invalid size means unset
00715     pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00716     mirrorType = PM_NORMAL;
00717     depth = 0;
00718     swapRGB = false;
00719     grayscal = false;
00720     bright = 0;
00721     m_effect = IE_NONE;
00722     m_ie_par1 = QVariant();
00723     m_ie_par2 = QVariant();
00724     m_ie_par3 = QVariant();
00725     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00726     m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00727 
00728     setPicture( key );
00729 }
00730 
00731 EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, KoPictureCollection *_imageCollection )
00732   : EmbeddedObject( _sheet, KoRect(0,0,0,0) )
00733 {
00734   imageCollection = _imageCollection;
00735 
00736   //ext = KoSize(); // invalid size means unset
00737   pen = KoPen( Qt::black, 1.0, Qt::NoPen );
00738   mirrorType = PM_NORMAL;
00739   depth = 0;
00740   swapRGB = false;
00741   grayscal = false;
00742   bright = 0;
00743   m_effect = IE_NONE;
00744   m_ie_par1 = QVariant();
00745   m_ie_par2 = QVariant();
00746   m_ie_par3 = QVariant();
00747     // Forbid QPixmap to cache the X-Window resources (Yes, it is slower!)
00748   m_cachedPixmap.setOptimization(QPixmap::MemoryOptim);
00749 }
00750 
00751 EmbeddedPictureObject::~EmbeddedPictureObject()
00752 {
00753 }
00754 
00755 bool EmbeddedPictureObject::load( const QDomElement& /*element*/ )
00756 {
00757     return false;
00758 }
00759 
00760 QDomElement EmbeddedPictureObject::save( QDomDocument& /*doc*/ )
00761 {
00762     kdDebug() << "Saving EmbeddedPictureObject" << endl;
00763     return QDomElement();
00764 }
00765 
00766 QString EmbeddedPictureObject::convertValueToPercent( int val ) const
00767 {
00768    return QString::number( val )+"%";
00769 }
00770 
00771 void EmbeddedPictureObject::saveOasisPictureElement( KoGenStyle &styleobjectauto ) const
00772 {
00773 
00774     if ( bright != 0 )
00775     {
00776         styleobjectauto.addProperty( "draw:luminance", convertValueToPercent( bright ) );
00777     }
00778     if ( grayscal )
00779     {
00780         styleobjectauto.addProperty( "draw:color-mode","greyscale" );
00781     }
00782 
00783     switch (m_effect)
00784     {
00785     case IE_NONE:
00786         //nothing
00787         break;
00788     case IE_CHANNEL_INTENSITY:
00789     {
00790         //for the moment kpresenter support just one channel
00791         QString percent = convertValueToPercent( m_ie_par1.toInt() );
00792         KImageEffect::RGBComponent channel = static_cast<KImageEffect::RGBComponent>( m_ie_par2.toInt() );
00793         switch( channel )
00794         {
00795         case KImageEffect::Red:
00796             styleobjectauto.addProperty( "draw:red", percent );
00797             styleobjectauto.addProperty( "draw:blue", "0%" );
00798             styleobjectauto.addProperty( "draw:green", "0%" );
00799             break;
00800         case KImageEffect::Green:
00801             styleobjectauto.addProperty( "draw:green", percent );
00802             styleobjectauto.addProperty( "draw:red", "0%" );
00803             styleobjectauto.addProperty( "draw:blue", "0%" );
00804             break;
00805         case KImageEffect::Blue:
00806             styleobjectauto.addProperty( "draw:blue", percent );
00807             styleobjectauto.addProperty( "draw:red", "0%" );
00808             styleobjectauto.addProperty( "draw:green", "0%" );
00809             break;
00810         case KImageEffect::Gray:
00811             break;
00812         case KImageEffect::All:
00813             break;
00814         }
00815     }
00816     break;
00817     case IE_FADE:
00818         break;
00819     case IE_FLATTEN:
00820         break;
00821     case IE_INTENSITY:
00822         break;
00823     case IE_DESATURATE:
00824         break;
00825     case IE_CONTRAST:
00826     {
00827         //kpresenter use value between -255 and 255
00828         //oo impress between -100% and 100%
00829         int val =  m_ie_par1.toInt();
00830         val = ( int )( ( double )val*100.0/255.0 );
00831         styleobjectauto.addProperty( "draw:contrast", convertValueToPercent( val ) );
00832     }
00833     break;
00834     case IE_NORMALIZE:
00835         break;
00836     case IE_EQUALIZE:
00837         break;
00838     case IE_THRESHOLD:
00839         break;
00840     case IE_SOLARIZE:
00841         break;
00842     case IE_EMBOSS:
00843         break;
00844     case IE_DESPECKLE:
00845         break;
00846     case IE_CHARCOAL:
00847         break;
00848     case IE_NOISE:
00849         break;
00850     case IE_BLUR:
00851         break;
00852     case IE_EDGE:
00853         break;
00854     case IE_IMPLODE:
00855         break;
00856     case IE_OIL_PAINT:
00857         break;
00858     case IE_SHARPEN:
00859         break;
00860     case IE_SPREAD:
00861         break;
00862     case IE_SHADE:
00863         break;
00864     case IE_SWIRL:
00865         break;
00866     case IE_WAVE:
00867         break;
00868     }
00869 }
00870 
00871 bool EmbeddedPictureObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
00872 {
00873     sc.xmlWriter.startElement( "draw:image" );
00874     sc.xmlWriter.addAttribute( "xlink:type", "simple" );
00875     sc.xmlWriter.addAttribute( "xlink:show", "embed" );
00876     sc.xmlWriter.addAttribute( "xlink:actuate", "onLoad" );
00877     sc.xmlWriter.addAttribute( "xlink:href", imageCollection->getOasisFileName( image ) );
00878     sc.xmlWriter.endElement();
00879 
00880     return true;
00881 }
00882 
00883 const char * EmbeddedPictureObject::getOasisElementName() const
00884 {
00885     return "draw:frame";
00886 }
00887 
00888 
00889 void EmbeddedPictureObject::loadPicture( const QString & fileName )
00890 {
00891     image = imageCollection->loadPicture( fileName );
00892 }
00893 
00894 EmbeddedPictureObject &EmbeddedPictureObject::operator=( const EmbeddedPictureObject & )
00895 {
00896     return *this;
00897 }
00898 
00899 void EmbeddedPictureObject::setPicture( const KoPictureKey & key )
00900 {
00901     image = imageCollection->findPicture( key );
00902 }
00903 
00904 void EmbeddedPictureObject::reload( void )
00905 {
00906     // ### FIXME: this seems wrong, KoPictureCollection will never reload it (or perhaps it is the function name that is wrong)
00907     setPicture( image.getKey() );
00908 }
00909 
00910 // KSpread doesn't support pictures in it's old XML file format.
00911 // QDomDocumentFragment EmbeddedPictureObject::save( QDomDocument& doc, double offset )
00912 // {
00913 //     QDomDocumentFragment fragment=KP2DObject::save(doc, offset);
00914 //     QDomElement elem=doc.createElement("KEY");
00915 //     image.getKey().saveAttributes(elem);
00916 //     fragment.appendChild(elem);
00917 //
00918 //     QDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
00919 //
00920 //     elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
00921 //     elemSettings.setAttribute( "depth", depth );
00922 //     elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
00923 //     elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
00924 //     elemSettings.setAttribute( "bright", bright );
00925 //     fragment.appendChild( elemSettings );
00926 //
00927 //     if (m_effect!=IE_NONE) {
00928 //         QDomElement imageEffects = doc.createElement("EFFECTS");
00929 //         imageEffects.setAttribute("type", static_cast<int>(m_effect));
00930 //         if (m_ie_par1.isValid())
00931 //             imageEffects.setAttribute("param1", m_ie_par1.toString());
00932 //         if (m_ie_par2.isValid())
00933 //             imageEffects.setAttribute("param2", m_ie_par2.toString());
00934 //         if (m_ie_par3.isValid())
00935 //             imageEffects.setAttribute("param3", m_ie_par3.toString());
00936 //         fragment.appendChild( imageEffects );
00937 //     }
00938 //
00939 //     return fragment;
00940 // }
00941 
00942 void EmbeddedPictureObject::loadOasisPictureEffect(KoOasisLoadingContext & context )
00943 {
00944     KoStyleStack &styleStack = context.styleStack();
00945     styleStack.setTypeProperties( "graphic" );
00946     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) &&  ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
00947     {
00948         grayscal = true;
00949     }
00950 
00951     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
00952     {
00953         QString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
00954         str = str.remove( '%' );
00955         int val = str.toInt();
00956         m_effect = IE_CONTRAST;
00957         val = ( int )( 255.0 *val/100.0 );
00958         m_ie_par1 = QVariant(val);
00959     }
00960     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
00961     {
00962         QString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
00963         str = str.remove( '%' );
00964         int val = str.toInt();
00965         m_effect = IE_CHANNEL_INTENSITY;
00966         m_ie_par1 = QVariant(val);
00967         m_ie_par2 = QVariant( ( int )KImageEffect::Red );
00968     }
00969     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
00970     {
00971         QString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
00972         str = str.remove( '%' );
00973         int val = str.toInt();
00974         m_effect = IE_CHANNEL_INTENSITY;
00975         m_ie_par1 = QVariant(val);
00976         m_ie_par2 = QVariant( ( int )KImageEffect::Green );
00977     }
00978     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
00979     {
00980         QString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
00981         str = str.remove( '%' );
00982         int val = str.toInt();
00983         m_effect = IE_CHANNEL_INTENSITY;
00984         m_ie_par1 = QVariant(val);
00985         m_ie_par2 = QVariant( ( int )KImageEffect::Blue );
00986     }
00987     if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
00988     {
00989        QString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
00990        str = str.remove( '%' );
00991        bright = str.toInt();
00992     }
00993 }
00994 
00995 void EmbeddedPictureObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& /*mainStyles*/ ) const
00996 {
00997      //KP2DObject::fillStyle( styleObjectAuto, mainStyles );
00998      saveOasisPictureElement( styleObjectAuto );
00999 }
01000 
01001 void EmbeddedPictureObject::loadOasis(const QDomElement &element, KoOasisLoadingContext & context/*, KPRLoadingInfo *info*/)
01002 {
01003     //load it into kpresenter_doc
01004     EmbeddedObject::loadOasis( element, context );
01005     loadOasisPictureEffect( context );
01006     QDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
01007     const QString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", QString::null) );
01008     kdDebug()<<" href: "<<href<<endl;
01009     if ( !href.isEmpty() /*&& href[0] == '#'*/ )
01010     {
01011         QString strExtension;
01012         const int result=href.findRev(".");
01013         if (result>=0)
01014         {
01015             strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
01016         }
01017         QString filename(href/*.mid(1)*/);
01018         const KoPictureKey key(filename, QDateTime::currentDateTime(Qt::UTC));
01019         image.setKey(key);
01020 
01021         KoStore* store = context.store();
01022         if ( store->open( filename ) )
01023         {
01024             KoStoreDevice dev(store);
01025             if ( !image.load( &dev, strExtension ) )
01026                 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
01027             store->close();
01028         }
01029         imageCollection->insertPicture( key, image );
01030     }
01031     // ### TODO: load remote file
01032 }
01033 
01034 
01035 // double EmbeddedPictureObject::load(const QDomElement &element)
01036 // {
01037 //     double offset=KP2DObject::load(element);
01038 //     QDomElement e=element.namedItem("KEY").toElement();
01039 //     if(!e.isNull()) {
01040 //         KoPictureKey key;
01041 //         key.loadAttributes( e );
01042 //         image.clear();
01043 //         image.setKey(key);
01044 //     }
01045 //     else {
01046 //         // try to find a PIXMAP tag if the KEY is not available...
01047 //         e=element.namedItem("PIXMAP").toElement();
01048 //         if (e.isNull()) {
01049 //             // try to find a FILENAME tag (old cliparts...)
01050 //             e=element.namedItem("FILENAME").toElement();
01051 //             if(!e.isNull()) {
01052 //                 // Loads from the disk directly (unless it's in the collection already?)
01053 //                 image = imageCollection->loadPicture( e.attribute("filename") );
01054 //             }
01055 //         } else {
01056 //             bool openPic = true;
01057 //             QString _data;
01058 //             QString _fileName;
01059 //             if(e.hasAttribute("data"))
01060 //                 _data=e.attribute("data");
01061 //             if ( _data.isEmpty() )
01062 //                 openPic = true;
01063 //             else
01064 //                 openPic = false;
01065 //             if(e.hasAttribute("filename"))
01066 //                 _fileName=e.attribute("filename");
01067 //             if ( !_fileName.isEmpty() )
01068 //             {
01069 //                 if ( int _envVarB = _fileName.find( '$' ) >= 0 )
01070 //                 {
01071 //                     int _envVarE = _fileName.find( '/', _envVarB );
01072 //                     // ### FIXME: it should be QString::local8Bit instead of QFile::encodeName, shouldn't it?
01073 //                     QString path = getenv( QFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
01074 //                     _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
01075 //                 }
01076 //             }
01077 //
01078 //             if ( openPic )
01079 //                 // !! this loads it from the disk (unless it's in the image collection already)
01080 //                 image = imageCollection->loadPicture( _fileName );
01081 //             else
01082 //             {
01083 //                 KoPictureKey key( _fileName );
01084 //                 image.clear();
01085 //                 image.setKey(key);
01086 //                 QByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
01087 //                 rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
01088 //                 QBuffer buffer(rawData); // ### TODO: open?
01089 //                 image.loadXpm(&buffer);
01090 //             }
01091 //         }
01092 //     }
01093 //
01094 //     e = element.namedItem( "PICTURESETTINGS" ).toElement();
01095 //     if ( !e.isNull() ) {
01096 //         PictureMirrorType _mirrorType = PM_NORMAL;
01097 //         int _depth = 0;
01098 //         bool _swapRGB = false;
01099 //         bool _grayscal = false;
01100 //         int _bright = 0;
01101 //
01102 //         if ( e.hasAttribute( "mirrorType" ) )
01103 //             _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
01104 //         if ( e.hasAttribute( "depth" ) )
01105 //             _depth = e.attribute( "depth" ).toInt();
01106 //         if ( e.hasAttribute( "swapRGB" ) )
01107 //             _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
01108 //         if ( e.hasAttribute( "grayscal" ) )
01109 //             _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
01110 //         if ( e.hasAttribute( "bright" ) )
01111 //             _bright = e.attribute( "bright" ).toInt();
01112 //
01113 //         mirrorType = _mirrorType;
01114 //         depth = _depth;
01115 //         swapRGB = _swapRGB;
01116 //         grayscal = _grayscal;
01117 //         bright = _bright;
01118 //     }
01119 //     else {
01120 //         mirrorType = PM_NORMAL;
01121 //         depth = 0;
01122 //         swapRGB = false;
01123 //         grayscal = false;
01124 //         bright = 0;
01125 //     }
01126 //
01127 //     e = element.namedItem( "EFFECTS" ).toElement();
01128 //     if (!e.isNull()) {
01129 //         if (e.hasAttribute("type"))
01130 //             m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
01131 //         if (e.hasAttribute("param1"))
01132 //             m_ie_par1 = QVariant(e.attribute("param1"));
01133 //         else
01134 //             m_ie_par1 = QVariant();
01135 //         if (e.hasAttribute("param2"))
01136 //             m_ie_par2 = QVariant(e.attribute("param2"));
01137 //         else
01138 //             m_ie_par2 = QVariant();
01139 //         if (e.hasAttribute("param3"))
01140 //             m_ie_par3 = QVariant(e.attribute("param3"));
01141 //         else
01142 //             m_ie_par3 = QVariant();
01143 //     }
01144 //     else
01145 //         m_effect = IE_NONE;
01146 //
01147 //     return offset;
01148 // }
01149 
01150 void EmbeddedPictureObject::drawShadow( QPainter* /*_painter*/,  KoZoomHandler* /*_zoomHandler*/)
01151 {
01152 //     const double ox = /*orig*/m_geometry.x();
01153 //     const double oy = /*orig*/m_geometry.y();
01154 //     const double ow = /*ext*/m_geometry.width();
01155 //     const double oh = /*ext*/m_geometry.height();
01156 //
01157 //     _painter->save();
01158 //
01159 //     QPen pen2 = pen.zoomedPen( _zoomHandler );
01160 //     _painter->setPen( pen2 );
01161 //     _painter->setBrush( getBrush() );
01162 //
01163 //     double sx = 0;
01164 //     double sy = 0;
01165 //
01166 //     getShadowCoords( sx, sy );
01167 //
01168 //     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
01169 //     _painter->setPen( QPen( shadowColor ) );
01170 //     _painter->setBrush( shadowColor );
01171 //     if ( kAbs(angle) <= DBL_EPSILON )
01172 //         _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
01173 //                             _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
01174 //     else
01175 //     {
01176 //         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
01177 //         QRect br = QRect( 0, 0, bs.width(), bs.height() );
01178 //         int pw = br.width();
01179 //         int ph = br.height();
01180 //         QRect rr = br;
01181 //         int pixYPos = -rr.y();
01182 //         int pixXPos = -rr.x();
01183 //         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
01184 //         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
01185 //
01186 //         QWMatrix m;
01187 //         m.translate( pw / 2, ph / 2 );
01188 //         m.rotate( angle );
01189 //         m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
01190 //                      rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
01191 //
01192 //         _painter->setWorldMatrix( m, true );
01193 //
01194 //         _painter->drawRect( 0, 0, bs.width(), bs.height() );
01195 //     }
01196 //
01197 //     _painter->restore();
01198 }
01199 
01200 QPixmap EmbeddedPictureObject::toPixmap( double xZoom , double yZoom )
01201 {
01202     KoZoomHandler zoomHandler;
01203     zoomHandler.setZoomedResolution( xZoom /* *zoomHandler.resolutionX()*/ , yZoom /* *zoomHandler.resolutionY()*/ );
01204     return generatePixmap( &zoomHandler );
01205 }
01206 
01207 QPixmap EmbeddedPictureObject::generatePixmap(KoZoomHandler*_zoomHandler)
01208 {
01209     const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1 : pen.width() ) / 2.0 );
01210 
01211     QSize size( _zoomHandler->zoomSize( m_geometry.size() /*ext*/ ) );
01212     //kdDebug(33001) << "EmbeddedPictureObject::generatePixmap size= " << size << endl;
01213     QPixmap pixmap(size);
01214     QPainter paint;
01215 
01216     paint.begin( &pixmap );
01217     pixmap.fill( Qt::white );
01218 
01219     // Draw background
01220     paint.setPen( Qt::NoPen );
01221     paint.setBrush( getBrush() );
01222 
01223     QRect rect( (int)( penw ), (int)( penw ),
01224                  (int)( _zoomHandler->zoomItX( /*ext*/m_geometry.width() ) - 2.0 * penw ),
01225                  (int)( _zoomHandler->zoomItY( /*ext*/m_geometry.height() ) - 2.0 * penw ) );
01226 
01227 //      if ( getFillType() == FT_BRUSH || !gradient )
01228          paint.drawRect( rect );
01229 //     else {
01230         // ### TODO: this was also drawn for drawContour==true, but why?
01231 //         gradient->setSize( size );
01232 //         paint.drawPixmap( (int)( penw ), (int)( penw ),
01233 //                           gradient->pixmap(), 0, 0,
01234 //                           (int)( _zoomHandler->zoomItX( m_geometry/*ext*/.width() ) - 2 * penw ),
01235 //                           (int)( _zoomHandler->zoomItY( m_geometry/*ext*/.height() ) - 2 * penw ) );
01236 //    }
01237 
01238 
01239     image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
01240     image.clearCache(); // Release the memoy of the picture cache
01241 
01242 //     image.setAlphaBuffer(true);
01243 //     QBitmap tmpMask;
01244 //     tmpMask = image.createAlphaMask().scale(size);
01245 //     pixmap.setMask(tmpMask);
01246 
01247     paint.end();
01248     return pixmap;
01249 }
01250 
01251 void EmbeddedPictureObject::draw( QPainter *_painter/*, KoZoomHandler*_zoomHandler,
01252                            int pageNum, SelectionMode selectionMode, bool drawContour*/ )
01253 {
01254     bool drawContour = false;
01255     KoZoomHandler*_zoomHandler = sheet()->doc();
01256 
01257 
01258     if ( image.isNull() ) return;
01259 
01260 //     if ( shadowDistance > 0 && !drawContour )
01261 //         drawShadow(_painter, _zoomHandler);
01262 
01263     const double ox = /*orig*/m_geometry.x();
01264     const double oy = /*orig*/m_geometry.y();
01265     const double ow = /*ext*/m_geometry.width();
01266     const double oh = /*ext*/m_geometry.height();
01267     //const double penw = _zoomHandler->zoomItX( ( ( pen.style() == Qt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
01268 
01269     _painter->save();
01270 
01271     _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
01272 
01273     if ( kAbs(angle)> DBL_EPSILON ) {
01274         QSize bs = QSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
01275         QRect br = QRect( 0, 0, bs.width(), bs.height() );
01276         int pw = br.width();
01277         int ph = br.height();
01278         QRect rr = br;
01279         int pixYPos = -rr.y();
01280         int pixXPos = -rr.x();
01281         br.moveTopLeft( QPoint( -br.width() / 2, -br.height() / 2 ) );
01282         rr.moveTopLeft( QPoint( -rr.width() / 2, -rr.height() / 2 ) );
01283 
01284         QWMatrix m;
01285         m.translate( pw / 2, ph / 2 );
01286         m.rotate( angle );
01287         m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
01288         _painter->setWorldMatrix( m, true );
01289     }
01290 
01291     if ( !drawContour )
01292     {
01293         QRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
01294                     (int)( _zoomHandler->zoomItY(  oh ) ) );
01295         // ### HACK QT seems not to be able to correctly compare QVariant
01296         bool variants1;
01297         if (m_ie_par1.isNull())
01298             variants1=m_cachedPar1.isNull();
01299         else
01300             variants1=(m_ie_par1 == m_cachedPar1);
01301         bool variants2;
01302         if (m_ie_par2.isNull())
01303             variants2=m_cachedPar2.isNull();
01304         else
01305             variants2=(m_ie_par2 == m_cachedPar2);
01306         bool variants3;
01307         if (m_ie_par3.isNull())
01308             variants3=m_cachedPar3.isNull();
01309         else
01310             variants3=(m_ie_par3 == m_cachedPar3);
01311 
01312         if (m_cachedRect == rect
01313             // All what EmbeddedPictureObject::changePictureSettings needs
01314             && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
01315             && m_cachedBright == bright && m_cachedEffect == m_effect
01316             // Who needs it?
01317             && m_cachedDepth == depth
01318 #if 0
01319             && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
01320 #else
01321             && variants1 && variants2 && variants3
01322 #endif
01323             )
01324         {
01325             //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
01326         }
01327         else
01328         {
01329             if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
01330                 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
01331             else
01332                 m_cachedPixmap = generatePixmap( _zoomHandler );
01333             m_cachedRect = rect;
01334             m_cachedMirrorType = mirrorType;
01335             m_cachedSwapRGB = swapRGB;
01336             m_cachedGrayscal = grayscal;
01337             m_cachedBright = bright;
01338             m_cachedEffect = m_effect;
01339             m_cachedDepth = depth;
01340             m_cachedPar1 = m_ie_par1;
01341             m_cachedPar2 = m_ie_par2;
01342             m_cachedPar3 = m_ie_par3;
01343             //kdDebug(33001) <<  "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
01344         }
01345         _painter->eraseRect( rect );
01346         _painter->drawPixmap( rect, m_cachedPixmap);
01347     }
01348 
01349     // Draw border
01350     // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
01351 //     QPen pen2;
01352 //     if ( drawContour ) {
01353 //         pen2 = QPen( Qt::black, 1, Qt::DotLine );
01354 //         _painter->setRasterOp( Qt::NotXorROP );
01355 //     }
01356 //     else {
01357 //         pen2 = pen;
01358 //         pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == Qt::NoPen ) ? 1.0 : (double)pen.width() ) );
01359 //     }
01360 //     _painter->setPen( pen2 );
01361 //     _painter->setBrush( Qt::NoBrush );
01362 //     _painter->drawRect( (int)( penw ), (int)( penw ),
01363 //                         (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
01364 //                         (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
01365 
01366 
01367     _painter->restore();
01368 
01369     //KPObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
01370     EmbeddedObject::draw( _painter );
01371 }
01372 
01373 QPixmap EmbeddedPictureObject::getOriginalPixmap()
01374 {
01375     QSize _pixSize = image.getOriginalSize();
01376     kdDebug(33001) << "EmbeddedPictureObject::getOriginalPixmap size= " << _pixSize << endl;
01377     QPixmap _pixmap = image.generatePixmap( _pixSize, true );
01378     image.clearCache(); // Release the memoy of the picture cache
01379 
01380     return _pixmap;
01381 }
01382 
01383 QPixmap EmbeddedPictureObject::changePictureSettings( QPixmap _tmpPixmap )
01384 {
01385     QImage _tmpImage = _tmpPixmap.convertToImage();
01386 
01387     if (_tmpImage.isNull())
01388         return _tmpPixmap;
01389 
01390     bool _horizontal = false;
01391     bool _vertical = false;
01392     if ( mirrorType == PM_HORIZONTAL )
01393         _horizontal = true;
01394     else if ( mirrorType == PM_VERTICAL )
01395         _vertical = true;
01396     else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
01397         _horizontal = true;
01398         _vertical = true;
01399     }
01400 
01401     _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
01402 
01403     if ( depth != 0 ) {
01404         QImage tmpImg = _tmpImage.convertDepth( depth );
01405         if ( !tmpImg.isNull() )
01406             _tmpImage = tmpImg;
01407     }
01408 
01409     if ( swapRGB )
01410         _tmpImage = _tmpImage.swapRGB();
01411 
01412     if ( grayscal ) {
01413         if ( depth == 1 || depth == 8 ) {
01414             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
01415                 QRgb rgb = _tmpImage.color( i );
01416                 int gray = qGray( rgb );
01417                 rgb = qRgb( gray, gray, gray );
01418                 _tmpImage.setColor( i, rgb );
01419             }
01420         }
01421         else {
01422             int _width = _tmpImage.width();
01423             int _height = _tmpImage.height();
01424             int _x = 0;
01425             int _y = 0;
01426 
01427             for ( _x = 0; _x < _width; ++_x ) {
01428                 for ( _y = 0; _y < _height; ++_y ) {
01429                     if ( _tmpImage.valid( _x, _y ) ) {
01430                         QRgb rgb = _tmpImage.pixel( _x, _y );
01431                         int gray = qGray( rgb );
01432                         rgb = qRgb( gray, gray, gray );
01433                         _tmpImage.setPixel( _x, _y, rgb );
01434                     }
01435                 }
01436             }
01437         }
01438     }
01439 
01440     if ( bright != 0 ) {
01441         if ( depth == 1 || depth == 8 ) {
01442             for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
01443                 QRgb rgb = _tmpImage.color( i );
01444                 QColor c( rgb );
01445 
01446                 if ( bright > 0 )
01447                     rgb = c.light( 100 + bright ).rgb();
01448                 else
01449                     rgb = c.dark( 100 + abs( bright ) ).rgb();
01450 
01451                 _tmpImage.setColor( i, rgb );
01452             }
01453         }
01454         else {
01455             int _width = _tmpImage.width();
01456             int _height = _tmpImage.height();
01457             int _x = 0;
01458             int _y = 0;
01459 
01460             for ( _x = 0; _x < _width; ++_x ) {
01461                 for ( _y = 0; _y < _height; ++_y ) {
01462                     if ( _tmpImage.valid( _x, _y ) ) {
01463                         QRgb rgb = _tmpImage.pixel( _x, _y );
01464                         QColor c( rgb );
01465 
01466                         if ( bright > 0 )
01467                             rgb = c.light( 100 + bright ).rgb();
01468                         else
01469                             rgb = c.dark( 100 + abs( bright ) ).rgb();
01470 
01471                         _tmpImage.setPixel( _x, _y, rgb );
01472                     }
01473                 }
01474             }
01475         }
01476     }
01477 
01478     switch (m_effect) {
01479     case IE_CHANNEL_INTENSITY: {
01480         _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
01481                                                    static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
01482         break;
01483     }
01484     case IE_FADE: {
01485         _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
01486         break;
01487     }
01488     case IE_FLATTEN: {
01489         _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
01490         break;
01491     }
01492     case IE_INTENSITY: {
01493         _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
01494         break;
01495     }
01496     case IE_DESATURATE: {
01497         _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
01498         break;
01499     }
01500     case IE_CONTRAST: {
01501         _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
01502         break;
01503     }
01504     case IE_NORMALIZE: {
01505         KImageEffect::normalize(_tmpImage);
01506         break;
01507     }
01508     case IE_EQUALIZE: {
01509         KImageEffect::equalize(_tmpImage);
01510         break;
01511     }
01512     case IE_THRESHOLD: {
01513         KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
01514         break;
01515     }
01516     case IE_SOLARIZE: {
01517         KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
01518         break;
01519     }
01520     case IE_EMBOSS: {
01521         _tmpImage = KImageEffect::emboss(_tmpImage);
01522         break;
01523     }
01524     case IE_DESPECKLE: {
01525         _tmpImage = KImageEffect::despeckle(_tmpImage);
01526         break;
01527     }
01528     case IE_CHARCOAL: {
01529         _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
01530         break;
01531     }
01532     case IE_NOISE: {
01533         _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
01534         break;
01535     }
01536     case IE_BLUR: {
01537         _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
01538         break;
01539     }
01540     case IE_EDGE: {
01541         _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
01542         break;
01543     }
01544     case IE_IMPLODE: {
01545         _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
01546         break;
01547     }
01548     case IE_OIL_PAINT: {
01549         _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
01550         break;
01551     }
01552     case IE_SHARPEN: {
01553         _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
01554         break;
01555     }
01556     case IE_SPREAD: {
01557         _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
01558         break;
01559     }
01560     case IE_SHADE: {
01561         _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
01562         break;
01563     }
01564     case IE_SWIRL: {
01565         _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
01566         break;
01567     }
01568     case IE_WAVE: {
01569         _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
01570         break;
01571     }
01572     case IE_NONE:
01573     default:
01574         break;
01575     }
01576 
01577     _tmpPixmap.convertFromImage( _tmpImage );
01578 
01579     return _tmpPixmap;
01580 }
01581 
01582 void EmbeddedPictureObject::flip( bool /*horizontal*/ )
01583 {
01584 //     KP2DObject::flip( horizontal );
01585 //     if ( horizontal )
01586 //     {
01587 //         switch ( mirrorType )
01588 //         {
01589 //             case PM_NORMAL:
01590 //                 mirrorType = PM_HORIZONTAL;
01591 //                 break;
01592 //             case PM_HORIZONTAL:
01593 //                 mirrorType = PM_NORMAL;
01594 //                 break;
01595 //             case PM_VERTICAL:
01596 //                 mirrorType = PM_HORIZONTALANDVERTICAL;
01597 //                 break;
01598 //             case PM_HORIZONTALANDVERTICAL:
01599 //                 mirrorType = PM_VERTICAL;
01600 //                 break;
01601 //         }
01602 //     }
01603 //     else
01604 //     {
01605 //         switch ( mirrorType )
01606 //         {
01607 //             case PM_NORMAL:
01608 //                 mirrorType = PM_VERTICAL;
01609 //                 break;
01610 //             case PM_HORIZONTAL:
01611 //                 mirrorType = PM_HORIZONTALANDVERTICAL;
01612 //                 break;
01613 //             case PM_VERTICAL:
01614 //                 mirrorType = PM_NORMAL;
01615 //                 break;
01616 //             case PM_HORIZONTALANDVERTICAL:
01617 //                 mirrorType = PM_HORIZONTAL;
01618 //                 break;
01619 //         }
01620 //     }
01621 }
KDE Home | KDE Accessibility Home | Description of Access Keys