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