kspread

kspread_object.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2006 Fredrik Edemar <f_edemar@linux.se>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18*/
19#include "kspread_object.h"
20#include "kspread_canvas.h"
21#include "kspread_doc.h"
22#include "kspread_sheet.h"
23#include "kspread_view.h"
24
25#include <assert.h>
26#include <tdeapplication.h>
27#include <kdebug.h>
28#include <kimageeffect.h>
29#include <tdeparts/partmanager.h>
30#include <koChart.h>
31
32#include <tqbitmap.h>
33#include <tqbuffer.h>
34#include <tqcursor.h>
35#include <tqdom.h>
36#include <tqfileinfo.h>
37#include <tqimage.h>
38#include <tqpainter.h>
39#include <tqpixmap.h>
40#include <tqwmatrix.h>
41
42#include <KoDocument.h>
43#include <KoDocumentChild.h>
44#include <KoDom.h>
45#include <KoXmlWriter.h>
46#include <KoZoomHandler.h>
47
48using namespace KSpread;
49
50class Sheet;
51class View;
52
53/**********************************************************
54 *
55 * EmbeddedObject
56 *
57 **********************************************************/
58EmbeddedObject::EmbeddedObject( Sheet *_sheet, const KoRect& _geometry )
59 : m_geometry( _geometry), m_sheet(_sheet), m_objectName(""), m_selected(false), m_protect(false), m_keepRatio(false), pen( TQt::black, 1, TQt::SolidLine )
60{
61 angle = 0.0;
62 inObjList = true;
63 cmds = 0;
64}
65
66EmbeddedObject::~EmbeddedObject()
67{
68}
69KoRect EmbeddedObject::geometry()
70{
71 return m_geometry;
72}
73void EmbeddedObject::setGeometry( const KoRect &rect )
74{
75 m_geometry = rect;
76}
77
78void EmbeddedObject::moveBy( const KoPoint &_point )
79{
80 m_geometry.moveTopLeft( m_geometry.topLeft() + _point );
81}
82
83void EmbeddedObject::moveBy( double _dx, double _dy )
84{
85 m_geometry.moveTopLeft( m_geometry.topLeft() + KoPoint( _dx, _dy ) );
86}
87
88void EmbeddedObject::resizeBy( const KoSize & _size )
89{
90 resizeBy( _size.width(), _size.height() );
91}
92
93void EmbeddedObject::resizeBy( double _dx, double _dy)
94{
95 m_geometry.setSize( KoSize( m_geometry.width()+_dx, m_geometry.height()+_dy) );
96} // call (possibly reimplemented) setSize
97
98bool EmbeddedObject::load( const TQDomElement& /*element*/ )
99{
100 kdDebug() << "Loading EmbeddedObject" << endl;
101 return false;
102}
103
104void EmbeddedObject::loadOasis(const TQDomElement &element, KoOasisLoadingContext & context )
105{
106 if(element.hasAttributeNS( KoXmlNS::draw, "name" ))
107 m_objectName = element.attributeNS( KoXmlNS::draw, "name", TQString());
108 m_geometry.setX( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "x", TQString() ) ) );
109 m_geometry.setY( KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "y", TQString() ) ) );
110 m_geometry.setWidth(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "width", TQString() )) );
111 m_geometry.setHeight(KoUnit::parseValue( element.attributeNS( KoXmlNS::svg, "height", TQString() ) ) );
112 //kdDebug()<<" orig.x() :"<<orig.x() <<" orig.y() :"<<orig.y() <<"ext.width() :"<<ext.width()<<" ext.height(): "<<ext.height()<<endl;
113 KoStyleStack &styleStack = context.styleStack();
114
115 styleStack.setTypeProperties( "" ); //no type default type
116}
117
118
119TQDomElement EmbeddedObject::save( TQDomDocument& /*doc*/ )
120{
121 kdDebug() << "Saving EmbeddedObject..." << endl;
122 return TQDomElement();
123}
124
125void EmbeddedObject::saveOasisPosObject( KoXmlWriter &xmlWriter, int indexObj ) const
126{
127 xmlWriter.addAttribute( "draw:id", "object" + TQString::number( indexObj ) );
128 //save all into pt
129 xmlWriter.addAttributePt( "svg:x", sheet()->doc()->savingWholeDocument() ? m_geometry.x() : m_geometry.x() + 20.0 );
130 xmlWriter.addAttributePt( "svg:y", sheet()->doc()->savingWholeDocument() ? m_geometry.y() : m_geometry.y() + 20.0 );
131 xmlWriter.addAttributePt( "svg:width", m_geometry.width() );
132 xmlWriter.addAttributePt( "svg:height", m_geometry.height() );
133
134// if ( kAbs( angle ) > 1E-6 )
135// {
136// double value = -1 * ( ( double )angle* M_PI )/180.0;
137// TQString str=TQString( "rotate (%1)" ).arg( value );
138// xmlWriter.addAttribute( "draw:transform", str );
139// }
140}
141
142bool EmbeddedObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &/* sc */ ) const
143{
144 kdDebug() << "bool saveOasisObjectAttributes not implemented";
145 return true;
146}
147
148bool EmbeddedObject::saveOasisObject( KSpreadOasisSaveContext &sc ) const
149{
150 sc.xmlWriter.startElement( getOasisElementName() );
151 //sc.xmlWriter.addAttribute( "draw:style-name", getStyle( sc ) );
152 saveOasisPosObject( sc.xmlWriter, sc.indexObj );
153 if( !getObjectName().isEmpty())
154 sc.xmlWriter.addAttribute( "draw:name", getObjectName() );
155
156 saveOasisObjectAttributes( sc );
157
158 sc.xmlWriter.endElement();
159 return true;
160}
161
162void EmbeddedObject::draw( TQPainter *_painter )
163{
164 paintSelection(_painter, SM_MOVERESIZE );
165}
166
168{
169 return toPixmap( 1.0 , 1.0 );
170}
171
172TQPixmap EmbeddedObject::toPixmap(TQSize size)
173{
174 double xZoom;
175 double yZoom;
176
177 calculateRequiredZoom( size , xZoom , yZoom );
178
179 return toPixmap(xZoom,yZoom);
180}
181
182TQPixmap EmbeddedObject::toPixmap(double /*xZoom*/ , double /*yZoom*/)
183{
184 return TQPixmap();
185
186}
187
188void EmbeddedObject::calculateRequiredZoom( TQSize desiredSize, double& xZoom, double& yZoom)
189{
190 TQSize actualSize = geometry().size().toTQSize();
191
192 xZoom = (double) desiredSize.width() / (double)actualSize.width();
193 yZoom = (double) desiredSize.height() / (double)actualSize.height();
194}
195
196void EmbeddedObject::paintSelection( TQPainter *_painter, SelectionMode mode )
197{
198 if ( !m_selected || mode == SM_NONE )
199 return;
200
201 _painter->save();
202 KoRect bound( geometry().left(), geometry().top(),
203 geometry().width() , geometry().height() );
204 TQRect zoomedBound = sheet()->doc()->zoomRect( bound ) ;
205
206 //_painter->setPen( TQPen( TQt::black, 1, TQPen::SolidLine ) );
207 _painter->setPen( pen );
208 _painter->setBrush( kapp->palette().color( TQPalette::Active, TQColorGroup::Highlight ) );
209
210 //KoRect r = rotateRectObject(); // TODO: rotation
211 KoRect r = /*KoRect::fromTQRect*/( bound );
212 int x = sheet()->doc()->zoomItX( r.left() /*- orig.x()*/);
213 int y = sheet()->doc()->zoomItY( r.top() /*- orig.y()*/);
214 int zX6 = /*sheet()->doc()->zoomItX*/( 6 );
215 int zY6 = /*sheet()->doc()->zoomItY*/( 6 );
216 int w = sheet()->doc()->zoomItX(r.width()) - 6;
217 int h = sheet()->doc()->zoomItY(r.height()) - 6;
218
219 if ( mode == SM_MOVERESIZE ) {
220 _painter->drawRect( x, y, zX6, zY6 );
221 _painter->drawRect( x, y + h / 2, zX6, zY6 );
222 _painter->drawRect( x, y + h, zX6, zY6 );
223 _painter->drawRect( x + w, y, zX6, zY6 );
224 _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
225 _painter->drawRect( x + w, y + h, zX6, zY6 );
226 _painter->drawRect( x + w / 2, y,zX6, zY6 );
227 _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
228 }
229 else if ( mode == SM_PROTECT) {
230 _painter->drawRect( x, y, zX6, zY6 );
231 _painter->drawRect( x, y + h / 2, zX6, zY6 );
232 _painter->drawRect( x, y + h, zX6, zY6 );
233 _painter->drawRect( x + w, y, zX6, zY6 );
234 _painter->drawRect( x + w, y + h / 2, zX6, zY6 );
235 _painter->drawRect( x + w, y + h, zX6, zY6 );
236 _painter->drawRect( x + w / 2, y,zX6, zY6 );
237 _painter->drawRect( x + w / 2, y + h, zX6, zY6 );
238
239 x= x + 1;
240 y= y + 1;
241 zX6=zX6-2;
242 zY6=zY6-2;
243
244 TQBrush brush=kapp->palette().color( TQPalette::Active,TQColorGroup::Base );
245 _painter->fillRect( x, y, zX6, zY6, brush );
246 _painter->fillRect( x, y + h / 2, zX6, zY6, brush);
247 _painter->fillRect( x, y + h, zX6, zY6, brush );
248 _painter->fillRect( x + w, y, zX6, zY6, brush );
249 _painter->fillRect( x + w, y + h / 2, zX6, zY6, brush );
250 _painter->fillRect( x + w , y + h , zX6 , zY6 , brush );
251 _painter->fillRect( x + w / 2 , y ,zX6 , zY6 , brush );
252 _painter->fillRect( x + w / 2, y + h , zX6 , zY6 , brush );
253 }
254 else if ( mode == SM_ROTATE ) {
255 _painter->drawEllipse( x, y, zX6, zY6 );
256 _painter->drawEllipse( x, y + h, zX6, zY6 );
257 _painter->drawEllipse( x + w, y, zX6, zY6 );
258 _painter->drawEllipse( x + w, y + h, zX6, zY6 );
259 }
260
261 _painter->restore();
262}
263
264TQCursor EmbeddedObject::getCursor( const TQPoint &_point, ModifyType &_modType, TQRect &geometry) const
265{
266 int px = /*sheet()->doc()->zoomItX*/(_point.x());
267 int py = /*sheet()->doc()->zoomItY*/(_point.y());
268 int ox = /*sheet()->doc()->zoomItX*/(/*orig*/geometry.x());
269 int oy = /*sheet()->doc()->zoomItY*/(/*orig*/geometry.y());
270 int ow = /*sheet()->doc()->zoomItX*/(/*ext*/geometry.width());
271 int oh = /*sheet()->doc()->zoomItY*/(/*ext*/geometry.height());
272
273// if ( angle != 0.0 )
274// {
275// TQRect rr = sheet()->doc()->zoomRect( rotateRectObject() );
276// ox = rr.x();
277// oy = rr.y();
278// ow = rr.width();
279// oh = rr.height();
280// }
281
282 int sz = 4;
283 if ( px >= ox && py >= oy && px <= ox + TQMIN( ow / 3, sz ) && py <= oy + TQMIN( oh / 3, sz ) )
284 {
285 _modType = MT_RESIZE_LU;
286 if ( m_protect )
287 return TQt::ForbiddenCursor;
288 return TQt::sizeFDiagCursor;
289 }
290
291 if ( px >= ox && py >= oy + oh / 2 - TQMIN( oh / 6, sz / 2 )
292 && px <= ox + TQMIN( ow / 3, sz)
293 && py <= oy + oh / 2 + TQMIN( oh / 6, sz / 2 ) )
294 {
295 _modType = MT_RESIZE_LF;
296 if ( m_protect)
297 return TQt::ForbiddenCursor;
298 return TQt::sizeHorCursor;
299 }
300
301 if ( px >= ox && py >= oy + oh - TQMIN( oh / 3, sz ) && px <= ox + TQMIN( ow / 3, sz ) && py <= oy + oh )
302 {
303 _modType = MT_RESIZE_LD;
304 if ( m_protect )
305 return TQt::ForbiddenCursor;
306 return TQt::sizeBDiagCursor;
307 }
308
309 if ( px >= ox + ow / 2 - TQMIN( ow / 6, sz / 2 ) && py >= oy
310 && px <= ox + ow / 2 + TQMIN( ow / 6, sz / 2 )
311 && py <= oy + TQMIN( oh / 3, sz ) )
312 {
313 _modType = MT_RESIZE_UP;
314 if ( m_protect )
315 return TQt::ForbiddenCursor;
316 return TQt::sizeVerCursor;
317 }
318
319 if ( px >= ox + ow / 2 - TQMIN( ow / 6, sz / 2 ) && py >= oy + oh - TQMIN( oh / 3, sz )
320 && px <= ox + ow / 2 + TQMIN( ow / 6, sz / 2 ) && py <= oy + oh )
321 {
322 _modType = MT_RESIZE_DN;
323 if ( m_protect )
324 return TQt::ForbiddenCursor;
325 return TQt::sizeVerCursor;
326 }
327
328 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy && px <= ox + ow && py <= oy + TQMIN( oh / 3, sz) )
329 {
330 _modType = MT_RESIZE_RU;
331 if ( m_protect )
332 return TQt::ForbiddenCursor;
333 return TQt::sizeBDiagCursor;
334 }
335
336 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy + oh / 2 - TQMIN( oh / 6, sz / 2 )
337 && px <= ox + ow && py <= oy + oh / 2 + TQMIN( oh / 6, sz / 2) )
338 {
339 _modType = MT_RESIZE_RT;
340 if ( m_protect )
341 return TQt::ForbiddenCursor;
342 return TQt::sizeHorCursor;
343 }
344
345 if ( px >= ox + ow - TQMIN( ow / 3, sz ) && py >= oy + oh - TQMIN( oh / 3, sz)
346 && px <= ox + ow && py <= oy + oh )
347 {
348 _modType = MT_RESIZE_RD;
349 if ( m_protect )
350 return TQt::ForbiddenCursor;
351 return TQt::sizeFDiagCursor;
352 }
353
354 _modType = MT_MOVE;
355 return TQt::sizeAllCursor;
356}
357
358
359void EmbeddedObject::doDelete()
360{
361 if ( cmds == 0 && !inObjList )
362 delete this;
363}
364
365/**********************************************************
366 *
367 * EmbeddedKOfficeObject
368 *
369 **********************************************************/
370EmbeddedKOfficeObject::EmbeddedKOfficeObject( Doc *parent, Sheet *_sheet, KoDocument* doc, const KoRect& geometry )
371 : EmbeddedObject( _sheet, geometry ), m_parent(parent)
372{
373 m_embeddedObject = new KoDocumentChild(parent, doc, geometry.toTQRect() );
374}
375
376EmbeddedKOfficeObject::EmbeddedKOfficeObject( Doc *parent, Sheet *_sheet )
377 : EmbeddedObject( _sheet, KoRect() ), m_parent(parent)
378{
379 m_embeddedObject = new KoDocumentChild( parent );
380}
381
382EmbeddedKOfficeObject::~EmbeddedKOfficeObject()
383{
384 delete m_embeddedObject;
385}
386
387Doc* EmbeddedKOfficeObject::parent()
388{
389 return m_parent;
390}
391
392KoDocumentChild* EmbeddedKOfficeObject::embeddedObject()
393{
394 return m_embeddedObject;
395}
396
397bool EmbeddedKOfficeObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
398{
399 kdDebug() << "EmbeddedKOfficeObject::saveOasisPart " << sc.partIndexObj << endl;
400
401 sc.xmlWriter.startElement( "draw:object" );
402 const TQString name = TQString( "Object_%1" ).arg( sc.partIndexObj + 1 );
403 ++sc.partIndexObj;
404 m_embeddedObject->saveOasisAttributes( sc.xmlWriter, name );
405
406 if ( getType() != OBJECT_CHART )
407 sc.xmlWriter.endElement();
408 return true;
409}
410
412{
413 return "draw:frame";
414}
415
416bool EmbeddedKOfficeObject::load( const TQDomElement& element )
417{
418 kdDebug() << "Loading EmbeddedKOfficeObject" << endl;
419 bool result = embeddedObject()->load( element );
420 setGeometry( KoRect::fromTQRect( embeddedObject()->geometry() ) );
421 return result;
422}
423
424void EmbeddedKOfficeObject::loadOasis(const TQDomElement &element, KoOasisLoadingContext &context/*, KPRLoadingInfo *info*/)
425{
426 kdDebug()<<"void EmbeddedKOfficeObject::loadOasis(const TQDomElement &element)******************\n";
427 EmbeddedObject::loadOasis( element, context );
428
429 TQDomElement objectElement = KoDom::namedItemNS( element, KoXmlNS::draw, "object" );
430 m_embeddedObject->loadOasis( element, objectElement );
431 if( element.hasAttributeNS( KoXmlNS::draw, "name" ) )
432 m_objectName = element.attributeNS( KoXmlNS::draw, "name", TQString());
433 (void)m_embeddedObject->loadOasisDocument( context.store(), context.manifestDocument() );
434}
435
436TQDomElement EmbeddedKOfficeObject::save( TQDomDocument& doc )
437{
438 kdDebug() << "Saving EmbeddedKOfficeObject" << endl;
439 embeddedObject()->setGeometry( geometry().toTQRect() );
440 return m_embeddedObject->save( doc );
441}
442
443void EmbeddedKOfficeObject::draw( TQPainter *_painter )
444{
445 kdDebug() << "Painting..." << endl;
446
447 int const penw = pen.width() ;
448 KoRect bound( 0, 0,
449 geometry().width() - ( 2 * penw ), geometry().height() - ( 2 * penw ) );
450 TQRect const zoomedBound = sheet()->doc()->zoomRect( bound );
451
452 _painter->save();
453 int const xOffset = sheet()->doc()->zoomItX( geometry().left() + penw);
454 int const yOffset = sheet()->doc()->zoomItY( geometry().top() + penw );
455
456 TQRect new_geometry = zoomedBound;
457
458 //if ( translate )
459 //{
460 _painter->translate( xOffset , yOffset );
461
462 new_geometry.moveBy( xOffset , yOffset );
463 new_geometry.moveBy( -_painter->window().x(), -_painter->window().y() );
464 //}
465
466 _painter->setClipRect( zoomedBound, TQPainter::CoordPainter );
467
468 assert( embeddedObject()->document() != 0 );
469
470 double zoomX = static_cast<double>( sheet()->doc()->zoom() ) / 100;
471 double zoomY = static_cast<double>( sheet()->doc()->zoom() ) / 100;
472 embeddedObject()->document()->paintEverything( *_painter,
473 zoomedBound,
474 embeddedObject()->isTransparent(),
475 0 /* View isn't known from here - is that a problem? */,
476 zoomX,
477 zoomY );
478
479
480 embeddedObject()->setGeometry( new_geometry );
481 _painter->restore();
482
483 EmbeddedObject::draw( _painter );
484}
485
486TQPixmap EmbeddedKOfficeObject::toPixmap( double xZoom , double yZoom )
487{
488 TQPixmap pixmap( (int)( geometry().width()*xZoom ), (int)( geometry().height()*yZoom ) );
489
490 TQPainter painter(&pixmap);
491 TQRect bound( 0,0,(int)( geometry().width()*xZoom ), (int)(geometry().height()*yZoom) );
492 embeddedObject()->document()->paintEverything(painter,bound,
493 embeddedObject()->isTransparent(),
494 0,
495 xZoom,
496 yZoom);
497 return pixmap;
498}
499
500void EmbeddedKOfficeObject::activate( View *_view, Canvas* /* canvas */ )
501{
502 KoDocument* part = embeddedObject()->document();
503 if ( !part )
504 return;
505 kdDebug() << "Activating..." << endl;
506
507 _view->partManager()->addPart( part, false );
508 _view->partManager()->setActivePart( part, _view );
509}
510
511void EmbeddedKOfficeObject::deactivate()
512{
513}
514
515
516void EmbeddedKOfficeObject::updateChildGeometry()
517{
518// KoZoomHandler* zh = m_sheet->doc();
519// embeddedObject()->setGeometry( zh->zoomRect( geometry() ), true );
520
521// return;
522// TQRect r = sheet()->doc()->zoomRect( geometry() );
523// if ( _canvas )
524// {
525// kdDebug() << "_canvas->xOffset():" << _canvas->xOffset() << endl;
526// kdDebug() << " _canvas->xOffset()*_canvas->doc()->zoomedResolutionX():" << _canvas->xOffset() * _canvas->doc()->zoomedResolutionX() << endl;
527// kdDebug() << "_canvas->yOffset():" << _canvas->yOffset() << endl;
528// kdDebug() << " _canvas->yOffset()*_canvas->doc()->zoomedResolutionY():" << _canvas->yOffset() * _canvas->doc()->zoomedResolutionY() << endl;
529// r.moveBy( -_canvas->xOffset() / _canvas->doc()->zoomedResolutionX() , -_canvas->yOffset() / _canvas->doc()->zoomedResolutionY() );
530// }
531// embeddedObject()->setGeometry( r , true );
532}
533
534/**********************************************************
535 *
536 * EmbeddedChart
537 *
538 **********************************************************/
539
540EmbeddedChart::EmbeddedChart( Doc *_spread, Sheet *_sheet, KoDocument* doc, const KoRect& geometry )
541 : EmbeddedKOfficeObject( _spread, _sheet, doc, geometry )
542{
543 m_pBinding = 0;
544}
545
546EmbeddedChart::EmbeddedChart( Doc *_spread, Sheet *_sheet )
547 : EmbeddedKOfficeObject( _spread, _sheet )
548{
549 m_pBinding = 0;
550}
551
552EmbeddedChart::~EmbeddedChart()
553{
554 if ( m_embeddedObject->isDeleted() )
555 delete m_pBinding;
556}
557
558void EmbeddedChart::setDataArea( const TQRect& _data )
559{
560 if ( m_pBinding == 0L )
561 m_pBinding = new ChartBinding( m_sheet, _data, this );
562 else
563 m_pBinding->setDataArea( _data );
564}
565
566void EmbeddedChart::update()
567{
568 if ( m_pBinding )
569 m_pBinding->cellChanged( 0 );
570}
571
573{
574 return "draw:frame";
575}
576
577bool EmbeddedChart::load( const TQDomElement& element )
578{
579 kdDebug() << "Loading EmbeddedChart" << endl;
580 if ( !EmbeddedKOfficeObject::load( element ) )
581 return false;
582
583 if ( element.hasAttribute( "left-cell" ) &&
584 element.hasAttribute( "top-cell" ) &&
585 element.hasAttribute( "right-cell" ) &&
586 element.hasAttribute( "bottom-cell" ) )
587 {
588 TQRect r;
589 r.setCoords( element.attribute( "left-cell" ).toInt(),
590 element.attribute( "top-cell" ).toInt(),
591 element.attribute( "right-cell" ).toInt(),
592 element.attribute( "bottom-cell" ).toInt() );
593
594 setDataArea( r );
595 }
596
597 return true;
598}
599
600void EmbeddedChart::loadOasis(const TQDomElement &element, KoOasisLoadingContext &context/*, KPRLoadingInfo *info*/)
601{
602 kdDebug()<<"void EmbeddedChart::loadOasis(const TQDomElement &element)******************\n";
603 EmbeddedKOfficeObject::loadOasis( element, context );
604
605 TQDomElement objectElement = KoDom::namedItemNS( element, KoXmlNS::draw, "object" );
606 TQString str_range = objectElement.attributeNS( KoXmlNS::draw, "notify-on-update-of-ranges", TQString());
607
608 if ( !str_range.isNull() )
609 {
610 str_range = Oasis::decodeFormula( str_range );
611 Range range( str_range );
612 if ( range.isValid() )
613 setDataArea( range.range() );
614 }
615
616 KoChart::Part* chartPart = chart();
617 if ( chartPart )
618 chartPart->setCanChangeValue( false );
619}
620
621
622bool EmbeddedChart::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
623{
624 kdDebug() << "EmbeddedChart::saveOasisPart " << sc.partIndexObj << endl;
625
626 EmbeddedKOfficeObject::saveOasisObjectAttributes( sc );
627
628 if(m_pBinding) { // see http://bugs.kde.org/show_bug.cgi?id=120395
629 TQRect dataArea = m_pBinding->dataArea();
630 TQString rangeName = util_rangeName( dataArea);
631 rangeName.insert( rangeName.find(':') +1, sheet()->sheetName() + "." );
632 rangeName.prepend( sheet()->sheetName() + "." );
633 sc.xmlWriter.addAttribute( "draw:notify-on-update-of-ranges", rangeName );
634 }
635 else {
636 kdDebug() << "EmbeddedChart::saveOasisPart m_pBinding is NULL" << endl;
637 }
638 sc.xmlWriter.endElement();
639
640 return true;
641}
642
643TQDomElement EmbeddedChart::save( TQDomDocument& doc )
644{
645 kdDebug() << "Saving EmbeddedChart" << endl;
646 TQDomElement element = EmbeddedKOfficeObject::save( doc );
647 element.setTagName( "chart" );
648
649 element.setAttribute( "left-cell", m_pBinding->dataArea().left() );
650 element.setAttribute( "right-cell", m_pBinding->dataArea().right() );
651 element.setAttribute( "top-cell", m_pBinding->dataArea().top() );
652 element.setAttribute( "bottom-cell", m_pBinding->dataArea().bottom() );
653
654 return element;
655}
656void EmbeddedChart::draw( TQPainter *_painter )
657{
658 EmbeddedKOfficeObject::draw( _painter );
659}
660
661bool EmbeddedChart::loadDocument( KoStore* _store )
662{
663 bool res = /*EmbeddedKOfficeObject::*/m_embeddedObject->loadDocument( _store );
664 if ( !res )
665 return res;
666
667 // Did we see a cell rectangle ?
668 if ( !m_pBinding )
669 return true;
670
671 update();
672
673 KoChart::Part* chartPart = chart();
674 if ( chartPart )
675 chartPart->setCanChangeValue( false );
676 return true;
677}
678
679KoChart::Part* EmbeddedChart::chart()
680{
681 // Returns 0 when the chart couldn't be loaded and we get KoUnavailPart instead.
682 return ::tqt_cast<KoChart::Part *>( m_embeddedObject->document() );
683}
684
685/**********************************************************
686 *
687 * EmbeddedPictureObject
688 *
689 **********************************************************/
690EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection )
691 : EmbeddedObject( _sheet, _geometry )
692{
693 imageCollection = _imageCollection;
694 pen = KoPen( TQt::black, 1.0, TQt::NoPen );
695 mirrorType = PM_NORMAL;
696 depth = 0;
697 swapRGB = false;
698 grayscal = false;
699 bright = 0;
700 m_effect = IE_NONE;
701 m_ie_par1 = TQVariant();
702 m_ie_par2 = TQVariant();
703 m_ie_par3 = TQVariant();
704 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
705 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
706}
707
708
709EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, const KoRect& _geometry, KoPictureCollection *_imageCollection, const KoPictureKey & key )
710 : EmbeddedObject( _sheet, _geometry )
711{
712 imageCollection = _imageCollection;
713
714 //ext = KoSize(); // invalid size means unset
715 pen = KoPen( TQt::black, 1.0, TQt::NoPen );
716 mirrorType = PM_NORMAL;
717 depth = 0;
718 swapRGB = false;
719 grayscal = false;
720 bright = 0;
721 m_effect = IE_NONE;
722 m_ie_par1 = TQVariant();
723 m_ie_par2 = TQVariant();
724 m_ie_par3 = TQVariant();
725 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
726 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
727
728 setPicture( key );
729}
730
731EmbeddedPictureObject::EmbeddedPictureObject( Sheet *_sheet, KoPictureCollection *_imageCollection )
732 : EmbeddedObject( _sheet, KoRect(0,0,0,0) )
733{
734 imageCollection = _imageCollection;
735
736 //ext = KoSize(); // invalid size means unset
737 pen = KoPen( TQt::black, 1.0, TQt::NoPen );
738 mirrorType = PM_NORMAL;
739 depth = 0;
740 swapRGB = false;
741 grayscal = false;
742 bright = 0;
743 m_effect = IE_NONE;
744 m_ie_par1 = TQVariant();
745 m_ie_par2 = TQVariant();
746 m_ie_par3 = TQVariant();
747 // Forbid TQPixmap to cache the X-Window resources (Yes, it is slower!)
748 m_cachedPixmap.setOptimization(TQPixmap::MemoryOptim);
749}
750
751EmbeddedPictureObject::~EmbeddedPictureObject()
752{
753}
754
755bool EmbeddedPictureObject::load( const TQDomElement& /*element*/ )
756{
757 return false;
758}
759
760TQDomElement EmbeddedPictureObject::save( TQDomDocument& /*doc*/ )
761{
762 kdDebug() << "Saving EmbeddedPictureObject" << endl;
763 return TQDomElement();
764}
765
766TQString EmbeddedPictureObject::convertValueToPercent( int val ) const
767{
768 return TQString::number( val )+"%";
769}
770
771void EmbeddedPictureObject::saveOasisPictureElement( KoGenStyle &styleobjectauto ) const
772{
773
774 if ( bright != 0 )
775 {
776 styleobjectauto.addProperty( "draw:luminance", convertValueToPercent( bright ) );
777 }
778 if ( grayscal )
779 {
780 styleobjectauto.addProperty( "draw:color-mode","greyscale" );
781 }
782
783 switch (m_effect)
784 {
785 case IE_NONE:
786 //nothing
787 break;
788 case IE_CHANNEL_INTENSITY:
789 {
790 //for the moment kpresenter support just one channel
791 TQString percent = convertValueToPercent( m_ie_par1.toInt() );
792 KImageEffect::RGBComponent channel = static_cast<KImageEffect::RGBComponent>( m_ie_par2.toInt() );
793 switch( channel )
794 {
795 case KImageEffect::Red:
796 styleobjectauto.addProperty( "draw:red", percent );
797 styleobjectauto.addProperty( "draw:blue", "0%" );
798 styleobjectauto.addProperty( "draw:green", "0%" );
799 break;
800 case KImageEffect::Green:
801 styleobjectauto.addProperty( "draw:green", percent );
802 styleobjectauto.addProperty( "draw:red", "0%" );
803 styleobjectauto.addProperty( "draw:blue", "0%" );
804 break;
805 case KImageEffect::Blue:
806 styleobjectauto.addProperty( "draw:blue", percent );
807 styleobjectauto.addProperty( "draw:red", "0%" );
808 styleobjectauto.addProperty( "draw:green", "0%" );
809 break;
810 case KImageEffect::Gray:
811 break;
812 case KImageEffect::All:
813 break;
814 }
815 }
816 break;
817 case IE_FADE:
818 break;
819 case IE_FLATTEN:
820 break;
821 case IE_INTENSITY:
822 break;
823 case IE_DESATURATE:
824 break;
825 case IE_CONTRAST:
826 {
827 //kpresenter use value between -255 and 255
828 //oo impress between -100% and 100%
829 int val = m_ie_par1.toInt();
830 val = ( int )( ( double )val*100.0/255.0 );
831 styleobjectauto.addProperty( "draw:contrast", convertValueToPercent( val ) );
832 }
833 break;
834 case IE_NORMALIZE:
835 break;
836 case IE_EQUALIZE:
837 break;
838 case IE_THRESHOLD:
839 break;
840 case IE_SOLARIZE:
841 break;
842 case IE_EMBOSS:
843 break;
844 case IE_DESPECKLE:
845 break;
846 case IE_CHARCOAL:
847 break;
848 case IE_NOISE:
849 break;
850 case IE_BLUR:
851 break;
852 case IE_EDGE:
853 break;
854 case IE_IMPLODE:
855 break;
856 case IE_OIL_PAINT:
857 break;
858 case IE_SHARPEN:
859 break;
860 case IE_SPREAD:
861 break;
862 case IE_SHADE:
863 break;
864 case IE_SWIRL:
865 break;
866 case IE_WAVE:
867 break;
868 }
869}
870
871bool EmbeddedPictureObject::saveOasisObjectAttributes( KSpreadOasisSaveContext &sc ) const
872{
873 sc.xmlWriter.startElement( "draw:image" );
874 sc.xmlWriter.addAttribute( "xlink:type", "simple" );
875 sc.xmlWriter.addAttribute( "xlink:show", "embed" );
876 sc.xmlWriter.addAttribute( "xlink:actuate", "onLoad" );
877 sc.xmlWriter.addAttribute( "xlink:href", imageCollection->getOasisFileName( image ) );
878 sc.xmlWriter.endElement();
879
880 return true;
881}
882
884{
885 return "draw:frame";
886}
887
888
889void EmbeddedPictureObject::loadPicture( const TQString & fileName )
890{
891 image = imageCollection->loadPicture( fileName );
892}
893
894EmbeddedPictureObject &EmbeddedPictureObject::operator=( const EmbeddedPictureObject & )
895{
896 return *this;
897}
898
899void EmbeddedPictureObject::setPicture( const KoPictureKey & key )
900{
901 image = imageCollection->findPicture( key );
902}
903
904void EmbeddedPictureObject::reload( void )
905{
906 // ### FIXME: this seems wrong, KoPictureCollection will never reload it (or perhaps it is the function name that is wrong)
907 setPicture( image.getKey() );
908}
909
910// KSpread doesn't support pictures in it's old XML file format.
911// TQDomDocumentFragment EmbeddedPictureObject::save( TQDomDocument& doc, double offset )
912// {
913// TQDomDocumentFragment fragment=KP2DObject::save(doc, offset);
914// TQDomElement elem=doc.createElement("KEY");
915// image.getKey().saveAttributes(elem);
916// fragment.appendChild(elem);
917//
918// TQDomElement elemSettings = doc.createElement( "PICTURESETTINGS" );
919//
920// elemSettings.setAttribute( "mirrorType", static_cast<int>( mirrorType ) );
921// elemSettings.setAttribute( "depth", depth );
922// elemSettings.setAttribute( "swapRGB", static_cast<int>( swapRGB ) );
923// elemSettings.setAttribute( "grayscal", static_cast<int>( grayscal ) );
924// elemSettings.setAttribute( "bright", bright );
925// fragment.appendChild( elemSettings );
926//
927// if (m_effect!=IE_NONE) {
928// TQDomElement imageEffects = doc.createElement("EFFECTS");
929// imageEffects.setAttribute("type", static_cast<int>(m_effect));
930// if (m_ie_par1.isValid())
931// imageEffects.setAttribute("param1", m_ie_par1.toString());
932// if (m_ie_par2.isValid())
933// imageEffects.setAttribute("param2", m_ie_par2.toString());
934// if (m_ie_par3.isValid())
935// imageEffects.setAttribute("param3", m_ie_par3.toString());
936// fragment.appendChild( imageEffects );
937// }
938//
939// return fragment;
940// }
941
942void EmbeddedPictureObject::loadOasisPictureEffect(KoOasisLoadingContext & context )
943{
944 KoStyleStack &styleStack = context.styleStack();
945 styleStack.setTypeProperties( "graphic" );
946 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "color-mode" ) && ( styleStack.attributeNS( KoXmlNS::draw, "color-mode" )=="greyscale" ) )
947 {
948 grayscal = true;
949 }
950
951 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "contrast" ) )
952 {
953 TQString str( styleStack.attributeNS( KoXmlNS::draw, "contrast" ) );
954 str = str.remove( '%' );
955 int val = str.toInt();
956 m_effect = IE_CONTRAST;
957 val = ( int )( 255.0 *val/100.0 );
958 m_ie_par1 = TQVariant(val);
959 }
960 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "red" ) && styleStack.attributeNS( KoXmlNS::draw, "red" ) != "0%" )
961 {
962 TQString str( styleStack.attributeNS( KoXmlNS::draw, "red" ) );
963 str = str.remove( '%' );
964 int val = str.toInt();
965 m_effect = IE_CHANNEL_INTENSITY;
966 m_ie_par1 = TQVariant(val);
967 m_ie_par2 = TQVariant( ( int )KImageEffect::Red );
968 }
969 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "green" ) && styleStack.attributeNS( KoXmlNS::draw, "green" ) != "0%" )
970 {
971 TQString str( styleStack.attributeNS( KoXmlNS::draw, "green" ) );
972 str = str.remove( '%' );
973 int val = str.toInt();
974 m_effect = IE_CHANNEL_INTENSITY;
975 m_ie_par1 = TQVariant(val);
976 m_ie_par2 = TQVariant( ( int )KImageEffect::Green );
977 }
978 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "blue" ) && styleStack.attributeNS( KoXmlNS::draw, "blue" ) != "0%" )
979 {
980 TQString str( styleStack.attributeNS( KoXmlNS::draw, "blue" ) );
981 str = str.remove( '%' );
982 int val = str.toInt();
983 m_effect = IE_CHANNEL_INTENSITY;
984 m_ie_par1 = TQVariant(val);
985 m_ie_par2 = TQVariant( ( int )KImageEffect::Blue );
986 }
987 if ( styleStack.hasAttributeNS( KoXmlNS::draw, "luminance" ) )
988 {
989 TQString str( styleStack.attributeNS( KoXmlNS::draw, "luminance" ) );
990 str = str.remove( '%' );
991 bright = str.toInt();
992 }
993}
994
995void EmbeddedPictureObject::fillStyle( KoGenStyle& styleObjectAuto, KoGenStyles& /*mainStyles*/ ) const
996{
997 //KP2DObject::fillStyle( styleObjectAuto, mainStyles );
998 saveOasisPictureElement( styleObjectAuto );
999}
1000
1001void EmbeddedPictureObject::loadOasis(const TQDomElement &element, KoOasisLoadingContext & context/*, KPRLoadingInfo *info*/)
1002{
1003 //load it into kpresenter_doc
1004 EmbeddedObject::loadOasis( element, context );
1005 loadOasisPictureEffect( context );
1006 TQDomNode imageBox = KoDom::namedItemNS( element, KoXmlNS::draw, "image" );
1007 const TQString href( imageBox.toElement().attributeNS( KoXmlNS::xlink, "href", TQString()) );
1008 kdDebug()<<" href: "<<href<<endl;
1009 if ( !href.isEmpty() /*&& href[0] == '#'*/ )
1010 {
1011 TQString strExtension;
1012 const int result=href.findRev(".");
1013 if (result>=0)
1014 {
1015 strExtension=href.mid(result+1); // As we are using KoPicture, the extension should be without the dot.
1016 }
1017 TQString filename(href/*.mid(1)*/);
1018 const KoPictureKey key(filename, TQDateTime::currentDateTime(TQt::UTC));
1019 image.setKey(key);
1020
1021 KoStore* store = context.store();
1022 if ( store->open( filename ) )
1023 {
1024 KoStoreDevice dev(store);
1025 if ( !image.load( &dev, strExtension ) )
1026 kdWarning() << "Cannot load picture: " << filename << " " << href << endl;
1027 store->close();
1028 }
1029 imageCollection->insertPicture( key, image );
1030 }
1031 // ### TODO: load remote file
1032}
1033
1034
1035// double EmbeddedPictureObject::load(const TQDomElement &element)
1036// {
1037// double offset=KP2DObject::load(element);
1038// TQDomElement e=element.namedItem("KEY").toElement();
1039// if(!e.isNull()) {
1040// KoPictureKey key;
1041// key.loadAttributes( e );
1042// image.clear();
1043// image.setKey(key);
1044// }
1045// else {
1046// // try to find a PIXMAP tag if the KEY is not available...
1047// e=element.namedItem("PIXMAP").toElement();
1048// if (e.isNull()) {
1049// // try to find a FILENAME tag (old cliparts...)
1050// e=element.namedItem("FILENAME").toElement();
1051// if(!e.isNull()) {
1052// // Loads from the disk directly (unless it's in the collection already?)
1053// image = imageCollection->loadPicture( e.attribute("filename") );
1054// }
1055// } else {
1056// bool openPic = true;
1057// TQString _data;
1058// TQString _fileName;
1059// if(e.hasAttribute("data"))
1060// _data=e.attribute("data");
1061// if ( _data.isEmpty() )
1062// openPic = true;
1063// else
1064// openPic = false;
1065// if(e.hasAttribute("filename"))
1066// _fileName=e.attribute("filename");
1067// if ( !_fileName.isEmpty() )
1068// {
1069// if ( int _envVarB = _fileName.find( '$' ) >= 0 )
1070// {
1071// int _envVarE = _fileName.find( '/', _envVarB );
1072// // ### FIXME: it should be TQString::local8Bit instead of TQFile::encodeName, shouldn't it?
1073// TQString path = getenv( TQFile::encodeName(_fileName.mid( _envVarB, _envVarE-_envVarB )) );
1074// _fileName.replace( _envVarB-1, _envVarE-_envVarB+1, path );
1075// }
1076// }
1077//
1078// if ( openPic )
1079// // !! this loads it from the disk (unless it's in the image collection already)
1080// image = imageCollection->loadPicture( _fileName );
1081// else
1082// {
1083// KoPictureKey key( _fileName );
1084// image.clear();
1085// image.setKey(key);
1086// TQByteArray rawData=_data.utf8(); // XPM is normally ASCII, therefore UTF-8
1087// rawData[rawData.size()-1]=char(10); // Replace the NULL character by a LINE FEED
1088// TQBuffer buffer(rawData); // ### TODO: open?
1089// image.loadXpm(&buffer);
1090// }
1091// }
1092// }
1093//
1094// e = element.namedItem( "PICTURESETTINGS" ).toElement();
1095// if ( !e.isNull() ) {
1096// PictureMirrorType _mirrorType = PM_NORMAL;
1097// int _depth = 0;
1098// bool _swapRGB = false;
1099// bool _grayscal = false;
1100// int _bright = 0;
1101//
1102// if ( e.hasAttribute( "mirrorType" ) )
1103// _mirrorType = static_cast<PictureMirrorType>( e.attribute( "mirrorType" ).toInt() );
1104// if ( e.hasAttribute( "depth" ) )
1105// _depth = e.attribute( "depth" ).toInt();
1106// if ( e.hasAttribute( "swapRGB" ) )
1107// _swapRGB = static_cast<bool>( e.attribute( "swapRGB" ).toInt() );
1108// if ( e.hasAttribute( "grayscal" ) )
1109// _grayscal = static_cast<bool>( e.attribute( "grayscal" ).toInt() );
1110// if ( e.hasAttribute( "bright" ) )
1111// _bright = e.attribute( "bright" ).toInt();
1112//
1113// mirrorType = _mirrorType;
1114// depth = _depth;
1115// swapRGB = _swapRGB;
1116// grayscal = _grayscal;
1117// bright = _bright;
1118// }
1119// else {
1120// mirrorType = PM_NORMAL;
1121// depth = 0;
1122// swapRGB = false;
1123// grayscal = false;
1124// bright = 0;
1125// }
1126//
1127// e = element.namedItem( "EFFECTS" ).toElement();
1128// if (!e.isNull()) {
1129// if (e.hasAttribute("type"))
1130// m_effect = static_cast<ImageEffect>(e.attribute("type").toInt());
1131// if (e.hasAttribute("param1"))
1132// m_ie_par1 = TQVariant(e.attribute("param1"));
1133// else
1134// m_ie_par1 = TQVariant();
1135// if (e.hasAttribute("param2"))
1136// m_ie_par2 = TQVariant(e.attribute("param2"));
1137// else
1138// m_ie_par2 = TQVariant();
1139// if (e.hasAttribute("param3"))
1140// m_ie_par3 = TQVariant(e.attribute("param3"));
1141// else
1142// m_ie_par3 = TQVariant();
1143// }
1144// else
1145// m_effect = IE_NONE;
1146//
1147// return offset;
1148// }
1149
1150void EmbeddedPictureObject::drawShadow( TQPainter* /*_painter*/, KoZoomHandler* /*_zoomHandler*/)
1151{
1152// const double ox = /*orig*/m_geometry.x();
1153// const double oy = /*orig*/m_geometry.y();
1154// const double ow = /*ext*/m_geometry.width();
1155// const double oh = /*ext*/m_geometry.height();
1156//
1157// _painter->save();
1158//
1159// TQPen pen2 = pen.zoomedPen( _zoomHandler );
1160// _painter->setPen( pen2 );
1161// _painter->setBrush( getBrush() );
1162//
1163// double sx = 0;
1164// double sy = 0;
1165//
1166// getShadowCoords( sx, sy );
1167//
1168// _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
1169// _painter->setPen( TQPen( shadowColor ) );
1170// _painter->setBrush( shadowColor );
1171// if ( kAbs(angle) <= DBL_EPSILON )
1172// _painter->drawRect( _zoomHandler->zoomItX( sx ), _zoomHandler->zoomItY( sy ),
1173// _zoomHandler->zoomItX( ext.width() ), _zoomHandler->zoomItY( ext.height() ) );
1174// else
1175// {
1176// TQSize bs = TQSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
1177// TQRect br = TQRect( 0, 0, bs.width(), bs.height() );
1178// int pw = br.width();
1179// int ph = br.height();
1180// TQRect rr = br;
1181// int pixYPos = -rr.y();
1182// int pixXPos = -rr.x();
1183// br.moveTopLeft( TQPoint( -br.width() / 2, -br.height() / 2 ) );
1184// rr.moveTopLeft( TQPoint( -rr.width() / 2, -rr.height() / 2 ) );
1185//
1186// TQWMatrix m;
1187// m.translate( pw / 2, ph / 2 );
1188// m.rotate( angle );
1189// m.translate( rr.left() + pixXPos + _zoomHandler->zoomItX( sx ),
1190// rr.top() + pixYPos + _zoomHandler->zoomItY( sy ) );
1191//
1192// _painter->setWorldMatrix( m, true );
1193//
1194// _painter->drawRect( 0, 0, bs.width(), bs.height() );
1195// }
1196//
1197// _painter->restore();
1198}
1199
1200TQPixmap EmbeddedPictureObject::toPixmap( double xZoom , double yZoom )
1201{
1202 KoZoomHandler zoomHandler;
1203 zoomHandler.setZoomedResolution( xZoom /* *zoomHandler.resolutionX()*/ , yZoom /* *zoomHandler.resolutionY()*/ );
1204 return generatePixmap( &zoomHandler );
1205}
1206
1207TQPixmap EmbeddedPictureObject::generatePixmap(KoZoomHandler*_zoomHandler)
1208{
1209 const double penw = _zoomHandler->zoomItX( ( ( pen.style() == TQt::NoPen ) ? 1 : pen.width() ) / 2.0 );
1210
1211 TQSize size( _zoomHandler->zoomSize( m_geometry.size() /*ext*/ ) );
1212 //kdDebug(33001) << "EmbeddedPictureObject::generatePixmap size= " << size << endl;
1213 TQPixmap pixmap(size);
1214 TQPainter paint;
1215
1216 paint.begin( &pixmap );
1217 pixmap.fill( TQt::white );
1218
1219 // Draw background
1220 paint.setPen( TQt::NoPen );
1221 paint.setBrush( getBrush() );
1222
1223 TQRect rect( (int)( penw ), (int)( penw ),
1224 (int)( _zoomHandler->zoomItX( /*ext*/m_geometry.width() ) - 2.0 * penw ),
1225 (int)( _zoomHandler->zoomItY( /*ext*/m_geometry.height() ) - 2.0 * penw ) );
1226
1227// if ( getFillType() == FT_BRUSH || !gradient )
1228 paint.drawRect( rect );
1229// else {
1230 // ### TODO: this was also drawn for drawContour==true, but why?
1231// gradient->setSize( size );
1232// paint.drawPixmap( (int)( penw ), (int)( penw ),
1233// gradient->pixmap(), 0, 0,
1234// (int)( _zoomHandler->zoomItX( m_geometry/*ext*/.width() ) - 2 * penw ),
1235// (int)( _zoomHandler->zoomItY( m_geometry/*ext*/.height() ) - 2 * penw ) );
1236// }
1237
1238
1239 image.draw(paint, 0, 0, size.width(), size.height(), 0, 0, -1, -1, false); // Always slow mode!
1240 image.clearCache(); // Release the memoy of the picture cache
1241
1242// image.setAlphaBuffer(true);
1243// TQBitmap tmpMask;
1244// tmpMask = image.createAlphaMask().scale(size);
1245// pixmap.setMask(tmpMask);
1246
1247 paint.end();
1248 return pixmap;
1249}
1250
1251void EmbeddedPictureObject::draw( TQPainter *_painter/*, KoZoomHandler*_zoomHandler,
1252 int pageNum, SelectionMode selectionMode, bool drawContour*/ )
1253{
1254 bool drawContour = false;
1255 KoZoomHandler*_zoomHandler = sheet()->doc();
1256
1257
1258 if ( image.isNull() ) return;
1259
1260// if ( shadowDistance > 0 && !drawContour )
1261// drawShadow(_painter, _zoomHandler);
1262
1263 const double ox = /*orig*/m_geometry.x();
1264 const double oy = /*orig*/m_geometry.y();
1265 const double ow = /*ext*/m_geometry.width();
1266 const double oh = /*ext*/m_geometry.height();
1267 //const double penw = _zoomHandler->zoomItX( ( ( pen.style() == TQt::NoPen ) ? 1.0 : pen.width() ) / 2.0 );
1268
1269 _painter->save();
1270
1271 _painter->translate( _zoomHandler->zoomItX( ox ), _zoomHandler->zoomItY( oy ) );
1272
1273 if ( kAbs(angle)> DBL_EPSILON ) {
1274 TQSize bs = TQSize( _zoomHandler->zoomItX( ow ), _zoomHandler->zoomItY( oh ) );
1275 TQRect br = TQRect( 0, 0, bs.width(), bs.height() );
1276 int pw = br.width();
1277 int ph = br.height();
1278 TQRect rr = br;
1279 int pixYPos = -rr.y();
1280 int pixXPos = -rr.x();
1281 br.moveTopLeft( TQPoint( -br.width() / 2, -br.height() / 2 ) );
1282 rr.moveTopLeft( TQPoint( -rr.width() / 2, -rr.height() / 2 ) );
1283
1284 TQWMatrix m;
1285 m.translate( pw / 2, ph / 2 );
1286 m.rotate( angle );
1287 m.translate( rr.left() + pixXPos, rr.top() + pixYPos );
1288 _painter->setWorldMatrix( m, true );
1289 }
1290
1291 if ( !drawContour )
1292 {
1293 TQRect rect( 0, 0, (int)( _zoomHandler->zoomItX( ow ) ),
1294 (int)( _zoomHandler->zoomItY( oh ) ) );
1295 // ### HACK TQt seems not to be able to correctly compare TQVariant
1296 bool variants1;
1297 if (m_ie_par1.isNull())
1298 variants1=m_cachedPar1.isNull();
1299 else
1300 variants1=(m_ie_par1 == m_cachedPar1);
1301 bool variants2;
1302 if (m_ie_par2.isNull())
1303 variants2=m_cachedPar2.isNull();
1304 else
1305 variants2=(m_ie_par2 == m_cachedPar2);
1306 bool variants3;
1307 if (m_ie_par3.isNull())
1308 variants3=m_cachedPar3.isNull();
1309 else
1310 variants3=(m_ie_par3 == m_cachedPar3);
1311
1312 if (m_cachedRect == rect
1313 // All what EmbeddedPictureObject::changePictureSettings needs
1314 && m_cachedMirrorType == mirrorType && m_cachedSwapRGB == swapRGB && m_cachedGrayscal == grayscal
1315 && m_cachedBright == bright && m_cachedEffect == m_effect
1316 // Who needs it?
1317 && m_cachedDepth == depth
1318#if 0
1319 && m_ie_par1 == m_cachedPar1 && m_ie_par2 == m_cachedPar2 && m_ie_par3 == m_cachedPar3
1320#else
1321 && variants1 && variants2 && variants3
1322#endif
1323 )
1324 {
1325 //kdDebug(33001) << "Drawing cached pixmap " << (void*) this << " " << k_funcinfo << endl;
1326 }
1327 else
1328 {
1329 if (mirrorType != PM_NORMAL || depth != 0 || swapRGB || grayscal || bright != 0 || m_effect!=IE_NONE)
1330 m_cachedPixmap = changePictureSettings( generatePixmap( _zoomHandler ) );
1331 else
1332 m_cachedPixmap = generatePixmap( _zoomHandler );
1333 m_cachedRect = rect;
1334 m_cachedMirrorType = mirrorType;
1335 m_cachedSwapRGB = swapRGB;
1336 m_cachedGrayscal = grayscal;
1337 m_cachedBright = bright;
1338 m_cachedEffect = m_effect;
1339 m_cachedDepth = depth;
1340 m_cachedPar1 = m_ie_par1;
1341 m_cachedPar2 = m_ie_par2;
1342 m_cachedPar3 = m_ie_par3;
1343 //kdDebug(33001) << "Drawing non-cached pixmap " << (void*) this << " " << k_funcinfo << endl;
1344 }
1345 _painter->eraseRect( rect );
1346 _painter->drawPixmap( rect, m_cachedPixmap);
1347 }
1348
1349 // Draw border
1350 // ### TODO port to KoBorder::drawBorders() (after writing a simplified version of it, that takes the same border on each size)
1351// TQPen pen2;
1352// if ( drawContour ) {
1353// pen2 = TQPen( TQt::black, 1, TQt::DotLine );
1354// _painter->setRasterOp( TQt::NotXorROP );
1355// }
1356// else {
1357// pen2 = pen;
1358// pen2.setWidth( _zoomHandler->zoomItX( ( pen.style() == TQt::NoPen ) ? 1.0 : (double)pen.width() ) );
1359// }
1360// _painter->setPen( pen2 );
1361// _painter->setBrush( TQt::NoBrush );
1362// _painter->drawRect( (int)( penw ), (int)( penw ),
1363// (int)( _zoomHandler->zoomItX( ow ) - 2.0 * penw ),
1364// (int)( _zoomHandler->zoomItY( oh ) - 2.0 * penw ) );
1365
1366
1367 _painter->restore();
1368
1369 //KPObject::draw( _painter, _zoomHandler, pageNum, selectionMode, drawContour );
1370 EmbeddedObject::draw( _painter );
1371}
1372
1373TQPixmap EmbeddedPictureObject::getOriginalPixmap()
1374{
1375 TQSize _pixSize = image.getOriginalSize();
1376 kdDebug(33001) << "EmbeddedPictureObject::getOriginalPixmap size= " << _pixSize << endl;
1377 TQPixmap _pixmap = image.generatePixmap( _pixSize, true );
1378 image.clearCache(); // Release the memoy of the picture cache
1379
1380 return _pixmap;
1381}
1382
1383TQPixmap EmbeddedPictureObject::changePictureSettings( TQPixmap _tmpPixmap )
1384{
1385 TQImage _tmpImage = _tmpPixmap.convertToImage();
1386
1387 if (_tmpImage.isNull())
1388 return _tmpPixmap;
1389
1390 bool _horizontal = false;
1391 bool _vertical = false;
1392 if ( mirrorType == PM_HORIZONTAL )
1393 _horizontal = true;
1394 else if ( mirrorType == PM_VERTICAL )
1395 _vertical = true;
1396 else if ( mirrorType == PM_HORIZONTALANDVERTICAL ) {
1397 _horizontal = true;
1398 _vertical = true;
1399 }
1400
1401 _tmpImage = _tmpImage.mirror( _horizontal, _vertical );
1402
1403 if ( depth != 0 ) {
1404 TQImage tmpImg = _tmpImage.convertDepth( depth );
1405 if ( !tmpImg.isNull() )
1406 _tmpImage = tmpImg;
1407 }
1408
1409 if ( swapRGB )
1410 _tmpImage = _tmpImage.swapRGB();
1411
1412 if ( grayscal ) {
1413 if ( depth == 1 || depth == 8 ) {
1414 for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
1415 TQRgb rgb = _tmpImage.color( i );
1416 int gray = tqGray( rgb );
1417 rgb = tqRgb( gray, gray, gray );
1418 _tmpImage.setColor( i, rgb );
1419 }
1420 }
1421 else {
1422 int _width = _tmpImage.width();
1423 int _height = _tmpImage.height();
1424 int _x = 0;
1425 int _y = 0;
1426
1427 for ( _x = 0; _x < _width; ++_x ) {
1428 for ( _y = 0; _y < _height; ++_y ) {
1429 if ( _tmpImage.valid( _x, _y ) ) {
1430 TQRgb rgb = _tmpImage.pixel( _x, _y );
1431 int gray = tqGray( rgb );
1432 rgb = tqRgb( gray, gray, gray );
1433 _tmpImage.setPixel( _x, _y, rgb );
1434 }
1435 }
1436 }
1437 }
1438 }
1439
1440 if ( bright != 0 ) {
1441 if ( depth == 1 || depth == 8 ) {
1442 for ( int i = 0; i < _tmpImage.numColors(); ++i ) {
1443 TQRgb rgb = _tmpImage.color( i );
1444 TQColor c( rgb );
1445
1446 if ( bright > 0 )
1447 rgb = c.light( 100 + bright ).rgb();
1448 else
1449 rgb = c.dark( 100 + abs( bright ) ).rgb();
1450
1451 _tmpImage.setColor( i, rgb );
1452 }
1453 }
1454 else {
1455 int _width = _tmpImage.width();
1456 int _height = _tmpImage.height();
1457 int _x = 0;
1458 int _y = 0;
1459
1460 for ( _x = 0; _x < _width; ++_x ) {
1461 for ( _y = 0; _y < _height; ++_y ) {
1462 if ( _tmpImage.valid( _x, _y ) ) {
1463 TQRgb rgb = _tmpImage.pixel( _x, _y );
1464 TQColor c( rgb );
1465
1466 if ( bright > 0 )
1467 rgb = c.light( 100 + bright ).rgb();
1468 else
1469 rgb = c.dark( 100 + abs( bright ) ).rgb();
1470
1471 _tmpImage.setPixel( _x, _y, rgb );
1472 }
1473 }
1474 }
1475 }
1476 }
1477
1478 switch (m_effect) {
1479 case IE_CHANNEL_INTENSITY: {
1480 _tmpImage = KImageEffect::channelIntensity(_tmpImage, m_ie_par1.toDouble()/100.0,
1481 static_cast<KImageEffect::RGBComponent>(m_ie_par2.toInt()));
1482 break;
1483 }
1484 case IE_FADE: {
1485 _tmpImage = KImageEffect::fade(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toColor());
1486 break;
1487 }
1488 case IE_FLATTEN: {
1489 _tmpImage = KImageEffect::flatten(_tmpImage, m_ie_par1.toColor(), m_ie_par2.toColor());
1490 break;
1491 }
1492 case IE_INTENSITY: {
1493 _tmpImage = KImageEffect::intensity(_tmpImage, m_ie_par1.toDouble()/100.0);
1494 break;
1495 }
1496 case IE_DESATURATE: {
1497 _tmpImage = KImageEffect::desaturate(_tmpImage, m_ie_par1.toDouble());
1498 break;
1499 }
1500 case IE_CONTRAST: {
1501 _tmpImage = KImageEffect::contrast(_tmpImage, m_ie_par1.toInt());
1502 break;
1503 }
1504 case IE_NORMALIZE: {
1505 KImageEffect::normalize(_tmpImage);
1506 break;
1507 }
1508 case IE_EQUALIZE: {
1509 KImageEffect::equalize(_tmpImage);
1510 break;
1511 }
1512 case IE_THRESHOLD: {
1513 KImageEffect::threshold(_tmpImage, m_ie_par1.toInt());
1514 break;
1515 }
1516 case IE_SOLARIZE: {
1517 KImageEffect::solarize(_tmpImage, m_ie_par1.toDouble());
1518 break;
1519 }
1520 case IE_EMBOSS: {
1521 _tmpImage = KImageEffect::emboss(_tmpImage);
1522 break;
1523 }
1524 case IE_DESPECKLE: {
1525 _tmpImage = KImageEffect::despeckle(_tmpImage);
1526 break;
1527 }
1528 case IE_CHARCOAL: {
1529 _tmpImage = KImageEffect::charcoal(_tmpImage, m_ie_par1.toDouble());
1530 break;
1531 }
1532 case IE_NOISE: {
1533 _tmpImage = KImageEffect::addNoise(_tmpImage, static_cast<KImageEffect::NoiseType>(m_ie_par1.toInt()));
1534 break;
1535 }
1536 case IE_BLUR: {
1537 _tmpImage = KImageEffect::blur(_tmpImage, m_ie_par1.toDouble());
1538 break;
1539 }
1540 case IE_EDGE: {
1541 _tmpImage = KImageEffect::edge(_tmpImage, m_ie_par1.toDouble());
1542 break;
1543 }
1544 case IE_IMPLODE: {
1545 _tmpImage = KImageEffect::implode(_tmpImage, m_ie_par1.toDouble());
1546 break;
1547 }
1548 case IE_OIL_PAINT: {
1549 _tmpImage = KImageEffect::oilPaint(_tmpImage, m_ie_par1.toInt());
1550 break;
1551 }
1552 case IE_SHARPEN: {
1553 _tmpImage = KImageEffect::sharpen(_tmpImage, m_ie_par1.toDouble());
1554 break;
1555 }
1556 case IE_SPREAD: {
1557 _tmpImage = KImageEffect::spread(_tmpImage, m_ie_par1.toInt());
1558 break;
1559 }
1560 case IE_SHADE: {
1561 _tmpImage = KImageEffect::shade(_tmpImage, m_ie_par1.toBool(), m_ie_par2.toDouble(), m_ie_par3.toDouble());
1562 break;
1563 }
1564 case IE_SWIRL: {
1565 _tmpImage = KImageEffect::swirl(_tmpImage, m_ie_par1.toDouble());
1566 break;
1567 }
1568 case IE_WAVE: {
1569 _tmpImage = KImageEffect::wave(_tmpImage, m_ie_par1.toDouble(), m_ie_par2.toDouble());
1570 break;
1571 }
1572 case IE_NONE:
1573 default:
1574 break;
1575 }
1576
1577 _tmpPixmap.convertFromImage( _tmpImage );
1578
1579 return _tmpPixmap;
1580}
1581
1582void EmbeddedPictureObject::flip( bool /*horizontal*/ )
1583{
1584// KP2DObject::flip( horizontal );
1585// if ( horizontal )
1586// {
1587// switch ( mirrorType )
1588// {
1589// case PM_NORMAL:
1590// mirrorType = PM_HORIZONTAL;
1591// break;
1592// case PM_HORIZONTAL:
1593// mirrorType = PM_NORMAL;
1594// break;
1595// case PM_VERTICAL:
1596// mirrorType = PM_HORIZONTALANDVERTICAL;
1597// break;
1598// case PM_HORIZONTALANDVERTICAL:
1599// mirrorType = PM_VERTICAL;
1600// break;
1601// }
1602// }
1603// else
1604// {
1605// switch ( mirrorType )
1606// {
1607// case PM_NORMAL:
1608// mirrorType = PM_VERTICAL;
1609// break;
1610// case PM_HORIZONTAL:
1611// mirrorType = PM_HORIZONTALANDVERTICAL;
1612// break;
1613// case PM_VERTICAL:
1614// mirrorType = PM_NORMAL;
1615// break;
1616// case PM_HORIZONTALANDVERTICAL:
1617// mirrorType = PM_HORIZONTAL;
1618// break;
1619// }
1620// }
1621}
The canvas builds a part of the GUI of KSpread.
This class holds the data that makes up a spreadsheet.
Definition kspread_doc.h:98
virtual const char * getOasisElementName() const
Get the element name for saving the object.
bool loadDocument(KoStore *_store)
Holds an embedded koffice object.
virtual const char * getOasisElementName() const
Get the element name for saving the object.
Contains basic information for every object.
TQPixmap toPixmap()
Renders the embedded object to a pixmap at 100% scale.
virtual const char * getOasisElementName() const =0
Get the element name for saving the object.
void calculateRequiredZoom(TQSize desiredSize, double &xZoom, double &yZoom)
Calculates the X and Y zoom factors required to render the embedded object at the given size.
Holds a picture object.
virtual const char * getOasisElementName() const
Get the element name for saving the object.
The View class displays a KSpread document.
The KSpread namespace.
Definition commands.h:39