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