00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "KWDocument.h"
00021 #include "KWView.h"
00022 #include "KWViewMode.h"
00023 #include "KWCanvas.h"
00024 #include "KWFrame.h"
00025 #include "defs.h"
00026 #include "KWTextFrameSet.h"
00027
00028 #include <KoTextObject.h>
00029
00030 #include <kformulacontainer.h>
00031 #include <kformuladocument.h>
00032 #include <kformulaview.h>
00033
00034 #include <kcursor.h>
00035 #include <klocale.h>
00036 #include <kmessagebox.h>
00037 #include <kdebug.h>
00038 #include <float.h>
00039 #include "KWordFrameSetIface.h"
00040 #include <dcopobject.h>
00041 #include "KWordTextFrameSetEditIface.h"
00042 #include "KWordFormulaFrameSetIface.h"
00043 #include "KWordFormulaFrameSetEditIface.h"
00044 #include "KWordPictureFrameSetIface.h"
00045
00046 #include "KWFormulaFrameSet.h"
00047
00048 #include <assert.h>
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 KWFormulaFrameSet::KWFormulaFrameSet( KWDocument *doc, const QString & name )
00059 : KWFrameSet( doc ), m_changed( false ), m_edit( 0 )
00060 {
00061 kdDebug() << k_funcinfo << endl;
00062
00063
00064
00065 formula = doc->formulaDocument()->createFormula( -1, false );
00066
00067
00068
00069 formula->moveTo( 0, 0 );
00070
00071 connect( formula, SIGNAL( formulaChanged( double, double ) ),
00072 this, SLOT( slotFormulaChanged( double, double ) ) );
00073 connect( formula, SIGNAL( errorMsg( const QString& ) ),
00074 this, SLOT( slotErrorMessage( const QString& ) ) );
00075 if ( name.isEmpty() )
00076 m_name = doc->generateFramesetName( i18n( "Formula %1" ) );
00077 else
00078 m_name = name;
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 QRect rect = formula->boundingRect();
00092 slotFormulaChanged(rect.width(), rect.height());
00093 }
00094
00095 KWordFrameSetIface* KWFormulaFrameSet::dcopObject()
00096 {
00097 if ( !m_dcop )
00098 m_dcop = new KWordFormulaFrameSetIface( this );
00099
00100 return m_dcop;
00101 }
00102
00103 KWFormulaFrameSet::~KWFormulaFrameSet()
00104 {
00105 kdDebug() << k_funcinfo << endl;
00106 delete formula;
00107 }
00108
00109 void KWFormulaFrameSet::addFrame( KWFrame *frame, bool recalc )
00110 {
00111 kdDebug() << k_funcinfo << endl;
00112 if ( formula ) {
00113 frame->setWidth( formula->width() );
00114 frame->setHeight( formula->height() );
00115 }
00116 KWFrameSet::addFrame( frame, recalc );
00117 if ( formula ) {
00118 formula->registerFormula();
00119 }
00120 }
00121
00122 void KWFormulaFrameSet::deleteFrame( unsigned int num, bool remove, bool recalc )
00123 {
00124 kdDebug() << k_funcinfo << endl;
00125 assert( num == 0 );
00126 KWFrameSet::deleteFrame( num, remove, recalc );
00127 formula->unregisterFormula();
00128 }
00129
00130
00131 KWFrameSetEdit* KWFormulaFrameSet::createFrameSetEdit(KWCanvas* canvas)
00132 {
00133 return new KWFormulaFrameSetEdit(this, canvas);
00134 }
00135
00136 void KWFormulaFrameSet::drawFrameContents( KWFrame* ,
00137 QPainter* painter, const QRect& crect,
00138 const QColorGroup& cg, bool onlyChanged,
00139 bool resetChanged,
00140 KWFrameSetEdit* , KWViewMode * )
00141 {
00142 if ( m_changed || !onlyChanged )
00143 {
00144 if ( resetChanged )
00145 m_changed = false;
00146
00147 bool printing = painter->device()->devType() == QInternal::Printer;
00148 bool clipping = true;
00149 QPainter *p;
00150 QPixmap* pix = 0L;
00151 if ( printing ) {
00152 p = painter;
00153 clipping = painter->hasClipping();
00154
00155
00156
00157 painter->setClipping( false );
00158 }
00159 else {
00160 pix = doubleBufferPixmap( crect.size() );
00161 p = new QPainter( pix );
00162 p->translate( -crect.x(), -crect.y() );
00163 }
00164
00165 if ( m_edit ) {
00166
00167 if ( m_edit->getFormulaView() ) {
00168 m_edit->getFormulaView()->draw( *p, crect, cg );
00169 }
00170 else {
00171 formula->draw( *p, crect, cg );
00172 }
00173 }
00174 else {
00175 formula->draw( *p, crect, cg );
00176 }
00177
00178 if ( !printing ) {
00179 p->end();
00180 delete p;
00181 painter->drawPixmap( crect.topLeft(), *pix );
00182 }
00183 else {
00184 painter->setClipping( clipping );
00185 }
00186 }
00187 }
00188
00189
00190 void KWFormulaFrameSet::slotFormulaChanged( double width, double height )
00191 {
00192 if ( m_frames.isEmpty() )
00193 return;
00194
00195 double oldWidth = m_frames.first()->width();
00196 double oldHeight = m_frames.first()->height();
00197
00198 m_frames.first()->setWidth( width );
00199 m_frames.first()->setHeight( height );
00200
00201 updateFrames();
00202 kWordDocument()->layout();
00203 if ( ( oldWidth != width ) || ( oldHeight != height ) ) {
00204 kWordDocument()->repaintAllViews( false );
00205 kWordDocument()->updateRulerFrameStartEnd();
00206 }
00207
00208 m_changed = true;
00209
00210 if ( !m_edit ) {
00211
00212
00213 formula->startEvaluation();
00214 }
00215 }
00216
00217 void KWFormulaFrameSet::slotErrorMessage( const QString& msg )
00218 {
00219 KMessageBox::error( 0, msg );
00220 }
00221
00222 MouseMeaning KWFormulaFrameSet::getMouseMeaningInsideFrame( const KoPoint& )
00223 {
00224 return MEANING_MOUSE_INSIDE_TEXT;
00225 }
00226
00227 QDomElement KWFormulaFrameSet::save(QDomElement& parentElem, bool saveFrames)
00228 {
00229 if ( m_frames.isEmpty() )
00230 return QDomElement();
00231 QDomElement framesetElem = parentElem.ownerDocument().createElement("FRAMESET");
00232 parentElem.appendChild(framesetElem);
00233
00234 KWFrameSet::saveCommon(framesetElem, saveFrames);
00235
00236 QDomElement formulaElem = parentElem.ownerDocument().createElement("FORMULA");
00237 framesetElem.appendChild(formulaElem);
00238 formula->save(formulaElem);
00239 return framesetElem;
00240 }
00241
00242 void KWFormulaFrameSet::saveOasis(KoXmlWriter&, KoSavingContext&, bool) const
00243 {
00244
00245 }
00246
00247 void KWFormulaFrameSet::load(QDomElement& attributes, bool loadFrames)
00248 {
00249 KWFrameSet::load(attributes, loadFrames);
00250 QDomElement formulaElem = attributes.namedItem("FORMULA").toElement();
00251 paste( formulaElem );
00252 }
00253
00254 void KWFormulaFrameSet::paste( QDomNode& formulaElem )
00255 {
00256 if (!formulaElem.isNull()) {
00257 if (formula == 0) {
00258 formula = m_doc->formulaDocument()->createFormula( -1, false );
00259 connect(formula, SIGNAL(formulaChanged(double, double)),
00260 this, SLOT(slotFormulaChanged(double, double)));
00261 connect( formula, SIGNAL( errorMsg( const QString& ) ),
00262 this, SLOT( slotErrorMessage( const QString& ) ) );
00263 }
00264 if ( !formula->load( formulaElem.firstChild().toElement() ) ) {
00265 kdError(32001) << "Error loading formula" << endl;
00266 }
00267 }
00268 else {
00269 kdError(32001) << "Missing FORMULA tag in FRAMESET" << endl;
00270 }
00271 }
00272
00273 void KWFormulaFrameSet::moveFloatingFrame( int frameNum, const KoPoint &position )
00274 {
00275 kdDebug() << k_funcinfo << endl;
00276 KWFrameSet::moveFloatingFrame( frameNum, position );
00277 if ( !m_frames.isEmpty() ) {
00278 formula->setDocumentPosition( position.x(), position.y()+formula->baseline() );
00279 }
00280 }
00281
00282 int KWFormulaFrameSet::floatingFrameBaseline( int )
00283 {
00284 if ( !m_frames.isEmpty() )
00285 {
00286 return m_doc->ptToLayoutUnitPixY( formula->baseline() );
00287 }
00288 return -1;
00289 }
00290
00291 void KWFormulaFrameSet::setAnchorFormat( KoTextFormat* format, int )
00292 {
00293 if ( !m_frames.isEmpty() ) {
00294 formula->setFontSizeDirect( format->pointSize() );
00295 }
00296 }
00297
00298
00299 QPixmap* KWFormulaFrameSet::m_bufPixmap = 0;
00300
00301
00302
00303
00304 QPixmap* KWFormulaFrameSet::doubleBufferPixmap( const QSize& s )
00305 {
00306 if ( !m_bufPixmap ) {
00307 int w = QABS( s.width() );
00308 int h = QABS( s.height() );
00309 m_bufPixmap = new QPixmap( w, h );
00310 } else {
00311 if ( m_bufPixmap->width() < s.width() ||
00312 m_bufPixmap->height() < s.height() ) {
00313 m_bufPixmap->resize( QMAX( s.width(), m_bufPixmap->width() ),
00314 QMAX( s.height(), m_bufPixmap->height() ) );
00315 }
00316 }
00317
00318 return m_bufPixmap;
00319 }
00320
00321
00322 KWFormulaFrameSetEdit::KWFormulaFrameSetEdit(KWFormulaFrameSet* fs, KWCanvas* canvas)
00323 : KWFrameSetEdit(fs, canvas)
00324 {
00325 formulaView = new KFormula::View( fs->getFormula() );
00326
00327 connect( formulaView, SIGNAL( cursorChanged( bool, bool ) ),
00328 this, SLOT( cursorChanged( bool, bool ) ) );
00329 connect( fs->getFormula(), SIGNAL( leaveFormula( Container*, FormulaCursor*, int ) ),
00330 this, SLOT( slotLeaveFormula( Container*, FormulaCursor*, int ) ) );
00331
00332 fs->m_edit = this;
00333
00334 m_canvas->gui()->getView()->showFormulaToolbar(true);
00335 focusInEvent();
00336 dcop=0;
00337 }
00338
00339 DCOPObject* KWFormulaFrameSetEdit::dcopObject()
00340 {
00341 if ( !dcop )
00342 dcop = new KWordFormulaFrameSetEditIface( this );
00343 return dcop;
00344 }
00345
00346 KWFormulaFrameSetEdit::~KWFormulaFrameSetEdit()
00347 {
00348 formulaFrameSet()->m_edit = 0;
00349 focusOutEvent();
00350
00351 m_canvas->gui()->getView()->showFormulaToolbar(false);
00352 delete formulaView;
00353 formulaView = 0;
00354 formulaFrameSet()->getFormula()->startEvaluation();
00355 formulaFrameSet()->setChanged();
00356 m_canvas->repaintChanged( formulaFrameSet(), true );
00357 delete dcop;
00358 }
00359
00360 const KFormula::View* KWFormulaFrameSetEdit::getFormulaView() const { return formulaView; }
00361 KFormula::View* KWFormulaFrameSetEdit::getFormulaView() { return formulaView; }
00362
00363 void KWFormulaFrameSetEdit::keyPressEvent( QKeyEvent* event )
00364 {
00365
00366 formulaView->keyPressEvent( event );
00367 }
00368
00369 void KWFormulaFrameSetEdit::mousePressEvent( QMouseEvent* event,
00370 const QPoint&,
00371 const KoPoint& pos )
00372 {
00373
00374 KoPoint tl = m_currentFrame->topLeft();
00375 formulaView->mousePressEvent( event, pos-tl );
00376 }
00377
00378 void KWFormulaFrameSetEdit::mouseMoveEvent( QMouseEvent* event,
00379 const QPoint&,
00380 const KoPoint& pos )
00381 {
00382 KoPoint tl = m_currentFrame->topLeft();
00383 formulaView->mouseMoveEvent( event, pos-tl );
00384 }
00385
00386 void KWFormulaFrameSetEdit::mouseReleaseEvent( QMouseEvent* event,
00387 const QPoint&,
00388 const KoPoint& pos )
00389 {
00390 KoPoint tl = m_currentFrame->topLeft();
00391 formulaView->mouseReleaseEvent( event, pos-tl );
00392 }
00393
00394 void KWFormulaFrameSetEdit::focusInEvent()
00395 {
00396
00397 if ( formulaView != 0 ) {
00398 formulaView->focusInEvent(0);
00399 }
00400 }
00401
00402 void KWFormulaFrameSetEdit::focusOutEvent()
00403 {
00404
00405
00406 if ( formulaView != 0 ) {
00407 formulaView->focusOutEvent(0);
00408 }
00409 }
00410
00411 void KWFormulaFrameSetEdit::copy()
00412 {
00413 formulaView->getDocument()->copy();
00414 }
00415
00416 void KWFormulaFrameSetEdit::cut()
00417 {
00418 formulaView->getDocument()->cut();
00419 }
00420
00421 void KWFormulaFrameSetEdit::paste()
00422 {
00423 formulaView->getDocument()->paste();
00424 }
00425
00426 void KWFormulaFrameSetEdit::pasteData( QMimeSource* , int , bool )
00427 {
00428 paste();
00429 }
00430
00431 void KWFormulaFrameSetEdit::selectAll()
00432 {
00433 formulaView->slotSelectAll();
00434 }
00435
00436 void KWFormulaFrameSetEdit::moveHome()
00437 {
00438 formulaView->moveHome( KFormula::WordMovement );
00439 }
00440 void KWFormulaFrameSetEdit::moveEnd()
00441 {
00442 formulaView->moveEnd( KFormula::WordMovement );
00443 }
00444
00445 void KWFormulaFrameSetEdit::removeFormula()
00446 {
00447 if ( formulaFrameSet()->isFloating() ) {
00448 KWCanvas* canvas = m_canvas;
00449
00450
00451 exitRight();
00452
00453 QKeyEvent keyEvent( QEvent::KeyPress, Key_Backspace, 0, 0 );
00454 canvas->currentFrameSetEdit()->keyPressEvent( &keyEvent );
00455 }
00456 }
00457
00458 void KWFormulaFrameSetEdit::cursorChanged( bool visible, bool )
00459 {
00460 if ( visible ) {
00461 if ( m_currentFrame )
00462 {
00463
00464 QPoint nPoint = frameSet()->kWordDocument()->zoomPoint( m_currentFrame->topLeft() );
00465 nPoint += formulaView->getCursorPoint();
00466
00467 QPoint p = m_canvas->viewMode()->normalToView( nPoint );
00468 m_canvas->ensureVisible( p.x(), p.y() );
00469 }
00470 }
00471 formulaFrameSet()->setChanged();
00472 m_canvas->repaintChanged( formulaFrameSet(), true );
00473 }
00474
00475 void KWFormulaFrameSetEdit::slotLeaveFormula( KFormula::Container*,
00476 KFormula::FormulaCursor* cursor,
00477 int cmd )
00478 {
00479 kdDebug() << k_funcinfo << endl;
00480
00481 if ( cursor == formulaView->getCursor() ) {
00482 switch ( cmd ) {
00483 case KFormula::Container::EXIT_LEFT:
00484 exitLeft();
00485 break;
00486 case KFormula::Container::EXIT_RIGHT:
00487 exitRight();
00488 break;
00489 case KFormula::Container::EXIT_ABOVE:
00490 exitLeft();
00491 break;
00492 case KFormula::Container::EXIT_BELOW:
00493 exitRight();
00494 break;
00495 case KFormula::Container::REMOVE_FORMULA:
00496 removeFormula();
00497 break;
00498 }
00499 }
00500 }
00501
00502 #include "KWFormulaFrameSet.moc"