F:/KPlato/koffice/libs/kformula/FormulaContainer.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
00003                       Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
00004                  2006 Martin Pfeiffer <hubipete@gmx.net>
00005                       
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015 
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.LIB.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <QApplication>
00023 #include <QEvent>
00024 #include <QFile>
00025 #include <QClipboard>
00026 #include <QPainter>
00027 #include <QPixmap>
00028 #include <QString>
00029 #include <QTextStream>
00030 #include <QList>
00031 #include <QKeyEvent>
00032 
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 
00036 #include "KoGlobal.h"
00037 #include "BracketElement.h"
00038 #include "contextstyle.h"
00039 #include "FormulaCursor.h"
00040 #include "FormulaElement.h"
00041 #include "FractionElement.h"
00042 #include "kformulacommand.h"
00043 #include "kformulacompatibility.h"
00044 #include "FormulaContainer.h"
00045 #include "MatrixElement.h"
00046 #include "RootElement.h"
00047 #include "SequenceElement.h"
00048 #include "symboltable.h"
00049 #include "SpaceElement.h"
00050 #include "TextElement.h"
00051 
00052 #include <assert.h>
00053 
00054 KFORMULA_NAMESPACE_BEGIN
00055 using namespace std;
00056 
00057 
00058 struct Container::Container_Impl {
00059 
00060     Container_Impl( /*Document* doc*/ )
00061             : dirty( true ), cursorMoved( false )//, document( doc )
00062     {
00063     }
00064 
00065     ~Container_Impl()
00066     {
00067         delete internCursor;
00068 //        delete m_formulaElement;
00069 //        document = 0;
00070     }
00071 
00075     bool dirty;
00076 
00080     bool cursorMoved;
00081 
00085 //    FormulaElement* rootElement;
00086 
00090     FormulaCursor* activeCursor;
00091 
00095     FormulaCursor* internCursor;
00096 
00100 //    Document* document;
00101 };
00102 
00103 //Document* Container::document() const { return impl->document; }
00104 
00105 Container::Container( /*Document* doc,*/ int pos, bool registerMe )
00106 {
00107 //    impl = new Container_Impl( doc );
00108     m_formulaElement = 0;
00109     if ( registerMe ) {
00110         registerFormula( pos );
00111     }
00112 }
00113 
00114 Container::~Container()
00115 {
00116     unregisterFormula();
00117     delete impl;
00118     impl = 0;
00119 }
00120 
00121 
00122 void Container::initialize()
00123 {
00124     m_formulaElement = new FormulaElement( ); 
00125     impl->activeCursor = impl->internCursor = createCursor();
00126     recalcLayout();
00127 }
00128 
00129 
00130 FormulaCursor* Container::createCursor()
00131 {
00132     return new FormulaCursor( m_formulaElement );
00133 }
00134 
00135 /*
00136 KCommandHistory* Container::getHistory() const
00137 {
00138     return document()->getHistory();
00139 }
00140 */
00141 
00146 void Container::elementRemoval(BasicElement* child)
00147 {
00148     emit elementWillVanish(child);
00149 }
00150 
00155 void Container::changed()
00156 {
00157     impl->dirty = true;
00158 }
00159 
00160 void Container::cursorHasMoved( FormulaCursor* )
00161 {
00162     impl->cursorMoved = true;
00163 }
00164 
00165 void Container::moveOutLeft( FormulaCursor* cursor )
00166 {
00167     emit leaveFormula( this, cursor, EXIT_LEFT );
00168 }
00169 
00170 void Container::moveOutRight( FormulaCursor* cursor )
00171 {
00172     emit leaveFormula( this, cursor, EXIT_RIGHT );
00173 }
00174 
00175 void Container::moveOutAbove( FormulaCursor* cursor )
00176 {
00177     emit leaveFormula( this, cursor, EXIT_ABOVE );
00178 }
00179 
00180 void Container::moveOutBelow( FormulaCursor* cursor )
00181 {
00182     emit leaveFormula( this, cursor, EXIT_BELOW );
00183 }
00184 
00185 void Container::tell( const QString& msg )
00186 {
00187     emit statusMsg( msg );
00188 }
00189 
00190 void Container::removeFormula( FormulaCursor* cursor )
00191 {
00192     emit leaveFormula( this, cursor, REMOVE_FORMULA );
00193 }
00194 
00195 
00196 void Container::registerFormula( int pos )
00197 {
00198 //    document()->registerFormula( this, pos );
00199 }
00200 
00201 void Container::unregisterFormula()
00202 {
00203 //    document()->unregisterFormula( this );
00204 }
00205 
00206 
00207 void Container::baseSizeChanged( int size, bool owned )
00208 {
00209 /*    if ( owned ) {
00210         emit baseSizeChanged( size );
00211     }
00212     else {
00213         const ContextStyle& context = document()->getContextStyle();
00214         emit baseSizeChanged( context.baseSize() );
00215     }*/
00216 }
00217 
00218 FormulaCursor* Container::activeCursor()
00219 {
00220     return impl->activeCursor;
00221 }
00222 
00223 const FormulaCursor* Container::activeCursor() const
00224 {
00225     return impl->activeCursor;
00226 }
00227 
00228 
00233 void Container::setActiveCursor(FormulaCursor* cursor)
00234 {
00235 //    document()->activate(this);
00236     if (cursor != 0) {
00237         impl->activeCursor = cursor;
00238     }
00239     else {
00240         *(impl->internCursor) = *(impl->activeCursor);
00241         impl->activeCursor = impl->internCursor;
00242     }
00243 }
00244 
00245 
00246 bool Container::hasValidCursor() const
00247 {
00248     return (impl->activeCursor != 0) /*&& !impl->activeCursor->isReadOnly()*/;
00249 }
00250 
00251 void Container::testDirty()
00252 {
00253     if (impl->dirty) {
00254         recalcLayout();
00255     }
00256 }
00257 
00258 void Container::recalcLayout()
00259 {
00260 //    m_formulaElement->layout();
00261 /*    impl->dirty = false;
00262     ContextStyle& context = impl->document->getContextStyle();
00263     m_formulaElement->calcSizes( context );
00264 
00265     emit formulaChanged( context.layoutUnitToPixelX( m_formulaElement->getWidth() ),
00266                          context.layoutUnitToPixelY( m_formulaElement->getHeight() ) );
00267     emit formulaChanged( context.layoutUnitPtToPt( context.pixelXToPt( m_formulaElement->getWidth() ) ),
00268                          context.layoutUnitPtToPt( context.pixelYToPt( m_formulaElement->getHeight() ) ) );
00269     emit cursorMoved( activeCursor() );*/
00270 }
00271 
00272 bool Container::isEmpty()
00273 {
00274     return m_formulaElement->childElements().isEmpty();
00275 }
00276 
00277 
00278 const SymbolTable& Container::getSymbolTable() const
00279 {
00280     static SymbolTable s;
00281     return s;
00282 }
00283 
00284 
00285 void Container::draw( QPainter& painter, const QRectF& r, const QPalette& palette, bool edit )
00286 {
00287     painter.fillRect( r, palette.base() );
00288     draw( painter, r, edit );
00289 }
00290 
00291 
00292 void Container::draw( QPainter& painter, const QRectF& r, bool edit )
00293 {
00294 //    ContextStyle& context = document()->getContextStyle( edit );
00295 //    m_formulaElement->draw( painter, context.pixelToLayoutUnit( r ), context );
00296 }
00297 
00298 
00299 void Container::checkCursor()
00300 {
00301     if ( impl->cursorMoved ) {
00302         impl->cursorMoved = false;
00303         emit cursorMoved( activeCursor() );
00304     }
00305 }
00306 
00307 void Container::input( QKeyEvent* event )
00308 {
00309     //if ( !hasValidCursor() )
00310     if ( impl->activeCursor == 0 ) {
00311         return;
00312     }
00313 //    execute( activeCursor()->getElement()->input( this, event ) );
00314     checkCursor();
00315 }
00316 
00317 
00318 void Container::performRequest( Request* request )
00319 {
00320     if ( !hasValidCursor() )
00321         return;
00322 //    execute( activeCursor()->getElement()->buildCommand( this, request ) );
00323     checkCursor();
00324 }
00325 
00326 
00327 void Container::paste()
00328 {
00329 /*    if (!hasValidCursor())
00330         return;
00331     QClipboard* clipboard = QApplication::clipboard();
00332     const QMimeData* source = clipboard->mimeData();
00333     if (source->hasFormat( MimeSource::selectionMimeType() ))
00334     {
00335         QByteArray data = source->data( MimeSource::selectionMimeType() );
00336         QDomDocument formula;
00337         formula.setContent(data);
00338         paste( formula, i18n("Paste") );
00339     }*/
00340 }
00341 
00342 void Container::paste( const QDomDocument& document, const QString& desc )
00343 {
00344 /*    FormulaCursor* cursor = activeCursor();
00345     QList<BasicElement*> list;
00346 //    list.setAutoDelete( true );
00347     if ( cursor->buildElementsFromDom( document.documentElement(), list ) ) {
00348         uint count = list.count();
00349         // You must not execute an add command that adds nothing.
00350         if (count > 0) {
00351             KFCReplace* command = new KFCReplace( desc, this );
00352             for (uint i = 0; i < count; i++) {
00353                 command->addElement(list.takeAt(0));
00354             }
00355             //execute(command);
00356         }
00357     }*/
00358 }
00359 
00360 void Container::copy()
00361 {
00362 /*    // read-only cursors are fine for copying.
00363     FormulaCursor* cursor = activeCursor();
00364     if (cursor != 0)
00365     {
00366         QDomDocument formula;// = document()->createDomDocument();
00367         cursor->copy( formula );
00368         QClipboard* clipboard = QApplication::clipboard();
00369         QMimeData* data = new QMimeData();
00370         data->setData(MimeSource::selectionMimeType(), formula.toByteArray() );
00371         clipboard->setMimeData( data );
00372     }*/
00373 }
00374 
00375 void Container::cut()
00376 {
00377     if (!hasValidCursor())
00378         return;
00379     FormulaCursor* cursor = activeCursor();
00380     if (cursor->hasSelection()) {
00381         copy();
00382         DirectedRemove r( req_remove, beforeCursor );
00383         performRequest( &r );
00384     }
00385 }
00386 
00387 void Container::emitErrorMsg( const QString& msg )
00388 {
00389     emit errorMsg( msg );
00390 }
00391 
00392 const QRectF& Container::boundingRect() const
00393 {
00394  //   const ContextStyle& context = document()->getContextStyle();
00395     static QRectF r;
00396 /*    r = QRectF( context.layoutUnitToPixelX( m_formulaElement->getX() ),
00397                    context.layoutUnitToPixelY( m_formulaElement->getY() ),
00398                    context.layoutUnitToPixelX( m_formulaElement->getWidth() ),
00399                    context.layoutUnitToPixelY( m_formulaElement->getHeight() ) );*/
00400     return r;
00401 }
00402 
00403 const QRectF& Container::coveredRect() const
00404 {/*
00405     if ( impl->activeCursor != 0 ) {
00406         const ContextStyle& context = document()->getContextStyle();
00407         const LuPixelRect& cursorRect = impl->activeCursor->getCursorSize();
00408         return QRectF( context.layoutUnitToPixelX( m_formulaElement->getX() ),
00409                       context.layoutUnitToPixelY( m_formulaElement->getY() ),
00410                       context.layoutUnitToPixelX( m_formulaElement->getWidth() ),
00411                       context.layoutUnitToPixelY( m_formulaElement->getHeight() ) ) |
00412             QRectF( context.layoutUnitToPixelX( cursorRect.x() ),
00413                    context.layoutUnitToPixelY( cursorRect.y() ),
00414                    context.layoutUnitToPixelX( cursorRect.width() ),
00415                    context.layoutUnitToPixelY( cursorRect.height() ) );
00416     }
00417     */
00418     return boundingRect();
00419 }
00420 /*
00421 double Container::width() const
00422 {
00423     const ContextStyle& context = document()->getContextStyle();
00424     return context.layoutUnitPtToPt( context.pixelXToPt( m_formulaElement->getWidth() ) );
00425 }
00426 
00427 double Container::height() const
00428 {
00429     const ContextStyle& context = document()->getContextStyle();
00430     return context.layoutUnitPtToPt( context.pixelYToPt( m_formulaElement->getHeight() ) );
00431 }*/
00432 
00433 double Container::baseline() const
00434 {
00435 /*    const ContextStyle& context = document()->getContextStyle();
00436     //return context.layoutUnitToPixelY( rootElement()->getBaseline() );
00437     return context.layoutUnitPtToPt( context.pixelYToPt( m_formulaElement->getBaseline() ) );*/
00438     return 0.0;
00439 }
00440 
00441 void Container::moveTo( int x, int y )
00442 {
00443 /*    const ContextStyle& context = document()->getContextStyle();
00444     m_formulaElement->setX( context.pixelToLayoutUnitX( x ) );
00445     m_formulaElement->setY( context.pixelToLayoutUnitY( y ) );*/
00446 }
00447 
00448 int Container::fontSize() const
00449 {
00450     if ( m_formulaElement->hasOwnBaseSize() ) {
00451         return m_formulaElement->getBaseSize();
00452     }
00453     else {
00454 //        const ContextStyle& context = document()->getContextStyle();
00455 //        return qRound( context.baseSize() );
00456     }
00457 
00458     return 0;
00459 }
00460 
00461 void Container::setFontSize( int pointSize, bool /*forPrint*/ )
00462 {
00463     if ( m_formulaElement->getBaseSize() != pointSize ) {
00465     }
00466 }
00467 
00468 void Container::setFontSizeDirect( int pointSize )
00469 {
00470     m_formulaElement->setBaseSize( pointSize );
00471     recalcLayout();
00472 }
00473 
00474 void Container::updateMatrixActions()
00475 {
00476 /*    BasicElement *currentElement = activeCursor()->getElement();
00477     if ( ( currentElement = currentElement->getParent() ) != 0 )
00478         document()->wrapper()->enableMatrixActions( dynamic_cast<MatrixElement*>(currentElement) );
00479     else
00480         document()->wrapper()->enableMatrixActions( false );*/
00481 }
00482 
00483 void Container::save( QDomElement &root )
00484 {
00485     QDomDocument ownerDoc = root.ownerDocument();
00486     root.appendChild(m_formulaElement->getElementDom(ownerDoc));
00487 }
00488 
00489 
00493 bool Container::load( const QDomElement &fe )
00494 {
00495     if( fe.isNull() ) {
00496         kWarning( DEBUGID ) << "Empty element." << endl;
00497         return false;
00498     }
00499     
00500     FormulaElement* root = new FormulaElement( );
00501     if (root->buildFromDom(fe)) {
00502         delete m_formulaElement;
00503         m_formulaElement = root;
00504         emit formulaLoaded(m_formulaElement);
00505 
00506         recalcLayout();
00507         return true;
00508     }
00509 
00510     delete root;
00511     kWarning( DEBUGID ) << "Error constructing element tree." << endl;
00512     return false;
00513 }
00514 
00515 
00516 void Container::saveMathML( QTextStream& stream, bool oasisFormat )
00517 {
00518 /*    if ( !oasisFormat )
00519     {
00520         // ### TODO: Are we really using MathML 2.0 or would be MathMl 1.01 enough (like for OO)?
00521         QDomDocumentType dt = QDomImplementation().createDocumentType( "math",
00522                                                                        "-//W3C//DTD MathML 2.0//EN",
00523                                                                        "http://www.w3.org/TR/MathML2/dtd/mathml2.dtd");
00524         QDomDocument doc( dt );
00525         doc.insertBefore( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ), doc.documentElement() );
00526         m_formulaElement->writeMathML( doc, doc, oasisFormat );
00527         stream << doc;
00528     }
00529     else
00530     {
00531         QDomDocument doc;
00532         m_formulaElement->writeMathML( doc, doc, oasisFormat );
00533         stream << doc;
00534     }*/
00535 }
00536 
00537 bool Container::loadMathML( const QDomDocument &doc, bool oasisFormat )
00538 {
00539     return loadMathML( doc.documentElement(), oasisFormat );
00540 }
00541 
00542 bool Container::loadMathML( const QDomElement &element, bool oasisFormat )
00543 {
00544 /*    const ContextStyle& context = document()->getContextStyle();
00545     MathML2KFormula filter( element, context, oasisFormat );
00546     filter.startConversion();
00547     if (filter.m_error) {
00548         return false;
00549     }
00550 
00551     if ( load( filter.getKFormulaDom().documentElement() ) ) {
00552         getHistory()->clear();
00553         return true;
00554     }
00555     */
00556     return false;
00557 }
00558 
00559 /*
00560 QImage Container::drawImage( int width, int height )
00561 {
00562     ContextStyle& context = document()->getContextStyle( false );
00563     QRectF rect( m_formulaElement->getX(), m_formulaElement->getY(),
00564                 m_formulaElement->getWidth(), m_formulaElement->getHeight());
00565 
00566     int realWidth = context.layoutUnitToPixelX( m_formulaElement->getWidth() );
00567     int realHeight = context.layoutUnitToPixelY( m_formulaElement->getHeight() );
00568 
00569     double f = qMax( static_cast<double>( width )/static_cast<double>( realWidth ),
00570                      static_cast<double>( height )/static_cast<double>( realHeight ) );
00571 
00572     int oldZoom = context.zoomInPercent();
00573     context.setZoomAndResolution( qRound( oldZoom*f ), KoGlobal::dpiX(), KoGlobal::dpiY() );
00574 
00575     QPixmap pm( context.layoutUnitToPixelX( m_formulaElement->getWidth() ),
00576                 context.layoutUnitToPixelY( m_formulaElement->getHeight() ) );
00577     pm.fill();
00578     QPainter paint(&pm);
00579     m_formulaElement->draw(paint, rect.toRect(), context);
00580     paint.end();
00581     // FIXME store and reset zoomedResolution as well as zoom. This is lossy
00582     context.setZoomAndResolution( oldZoom, KoGlobal::dpiX(), KoGlobal::dpiY() );
00583     return pm.toImage();
00584 }*/
00585 
00586 } // namespace KFormula
00587 
00588 using namespace KFormula;
00589 #include "FormulaContainer.moc"

Généré le Wed Nov 22 23:41:00 2006 pour KPlato par  doxygen 1.5.1-p1