lib Library API Documentation

fractionelement.cc

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 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <qpainter.h> 00022 00023 #include <kdebug.h> 00024 #include <klocale.h> 00025 00026 #include "elementvisitor.h" 00027 #include "formulaelement.h" 00028 #include "formulacursor.h" 00029 #include "fractionelement.h" 00030 #include "sequenceelement.h" 00031 00032 KFORMULA_NAMESPACE_BEGIN 00033 using namespace std; 00034 00035 FractionElement::FractionElement(BasicElement* parent) 00036 : BasicElement(parent), withLine(true) 00037 { 00038 numerator = new SequenceElement(this); 00039 denominator = new SequenceElement(this); 00040 } 00041 00042 FractionElement::~FractionElement() 00043 { 00044 delete denominator; 00045 delete numerator; 00046 } 00047 00048 FractionElement::FractionElement( const FractionElement& other ) 00049 : BasicElement( other ), withLine( other.withLine ) 00050 { 00051 numerator = new SequenceElement( *( other.numerator ) ); 00052 denominator = new SequenceElement( *( other.denominator ) ); 00053 numerator->setParent( this ); 00054 denominator->setParent( this ); 00055 } 00056 00057 00058 bool FractionElement::accept( ElementVisitor* visitor ) 00059 { 00060 return visitor->visit( this ); 00061 } 00062 00063 void FractionElement::entered( SequenceElement* child ) 00064 { 00065 if ( child == numerator ) { 00066 formula()->tell( i18n( "Numerator" ) ); 00067 } 00068 else { 00069 formula()->tell( i18n( "Denominator" ) ); 00070 } 00071 } 00072 00073 00074 BasicElement* FractionElement::goToPos( FormulaCursor* cursor, bool& handled, 00075 const LuPixelPoint& point, const LuPixelPoint& parentOrigin ) 00076 { 00077 BasicElement* e = BasicElement::goToPos(cursor, handled, point, parentOrigin); 00078 if (e != 0) { 00079 LuPixelPoint myPos(parentOrigin.x() + getX(), 00080 parentOrigin.y() + getY()); 00081 e = numerator->goToPos(cursor, handled, point, myPos); 00082 if (e != 0) { 00083 return e; 00084 } 00085 e = denominator->goToPos(cursor, handled, point, myPos); 00086 if (e != 0) { 00087 return e; 00088 } 00089 00090 luPixel dx = point.x() - myPos.x(); 00091 luPixel dy = point.y() - myPos.y(); 00092 00093 // the positions after the numerator / denominator 00094 if ((dx > numerator->getX()) && 00095 (dy < numerator->getHeight())) { 00096 numerator->moveLeft(cursor, this); 00097 handled = true; 00098 return numerator; 00099 } 00100 else if ((dx > denominator->getX()) && 00101 (dy > denominator->getY())) { 00102 denominator->moveLeft(cursor, this); 00103 handled = true; 00104 return denominator; 00105 } 00106 00107 return this; 00108 } 00109 return 0; 00110 } 00111 00112 00117 void FractionElement::calcSizes(const ContextStyle& style, ContextStyle::TextStyle tstyle, ContextStyle::IndexStyle istyle) 00118 { 00119 ContextStyle::TextStyle i_tstyle = style.convertTextStyleFraction( tstyle ); 00120 ContextStyle::IndexStyle u_istyle = style.convertIndexStyleUpper( istyle ); 00121 ContextStyle::IndexStyle l_istyle = style.convertIndexStyleLower( istyle ); 00122 00123 numerator->calcSizes( style, i_tstyle, u_istyle ); 00124 denominator->calcSizes( style, i_tstyle, l_istyle ); 00125 00126 luPixel distY = style.ptToPixelY( style.getThinSpace( tstyle ) ); 00127 00128 setWidth( QMAX( numerator->getWidth(), denominator->getWidth() ) ); 00129 setHeight( numerator->getHeight() + denominator->getHeight() + 00130 2*distY + style.getLineWidth() ); 00131 setBaseline( qRound( numerator->getHeight() + distY + .5*style.getLineWidth() + 00132 style.axisHeight( tstyle ) ) ); 00133 00134 numerator->setX( ( getWidth() - numerator->getWidth() ) / 2 ); 00135 denominator->setX( ( getWidth() - denominator->getWidth() ) / 2 ); 00136 00137 numerator->setY( 0 ); 00138 denominator->setY( getHeight() - denominator->getHeight() ); 00139 } 00140 00141 00147 void FractionElement::draw( QPainter& painter, const LuPixelRect& r, 00148 const ContextStyle& style, 00149 ContextStyle::TextStyle tstyle, 00150 ContextStyle::IndexStyle istyle, 00151 const LuPixelPoint& parentOrigin ) 00152 { 00153 LuPixelPoint myPos( parentOrigin.x()+getX(), parentOrigin.y()+getY() ); 00154 //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) ) 00155 // return; 00156 00157 numerator->draw(painter, r, style, 00158 style.convertTextStyleFraction( tstyle ), 00159 style.convertIndexStyleUpper( istyle ), myPos); 00160 if (denominator) { // Can be temporarily 0 see FractionElement::remove 00161 denominator->draw(painter, r, style, 00162 style.convertTextStyleFraction( tstyle ), 00163 style.convertIndexStyleLower( istyle ), myPos); 00164 } 00165 00166 if ( withLine ) { 00167 painter.setPen( QPen( style.getDefaultColor(), 00168 style.layoutUnitToPixelY( style.getLineWidth() ) ) ); 00169 painter.drawLine( style.layoutUnitToPixelX( myPos.x() ), 00170 style.layoutUnitToPixelY( myPos.y() + axis( style, tstyle ) ), 00171 style.layoutUnitToPixelX( myPos.x() + getWidth() ), 00172 style.layoutUnitToPixelY( myPos.y() + axis( style, tstyle ) ) ); 00173 } 00174 } 00175 00176 00177 void FractionElement::dispatchFontCommand( FontCommand* cmd ) 00178 { 00179 numerator->dispatchFontCommand( cmd ); 00180 denominator->dispatchFontCommand( cmd ); 00181 } 00182 00188 void FractionElement::moveLeft(FormulaCursor* cursor, BasicElement* from) 00189 { 00190 if (cursor->isSelectionMode()) { 00191 getParent()->moveLeft(cursor, this); 00192 } 00193 else { 00194 bool linear = cursor->getLinearMovement(); 00195 if (from == getParent()) { 00196 if (linear) { 00197 denominator->moveLeft(cursor, this); 00198 } 00199 else { 00200 numerator->moveLeft(cursor, this); 00201 } 00202 } 00203 else if (from == denominator) { 00204 numerator->moveLeft(cursor, this); 00205 } 00206 else { 00207 getParent()->moveLeft(cursor, this); 00208 } 00209 } 00210 } 00211 00212 00218 void FractionElement::moveRight(FormulaCursor* cursor, BasicElement* from) 00219 { 00220 if (cursor->isSelectionMode()) { 00221 getParent()->moveRight(cursor, this); 00222 } 00223 else { 00224 bool linear = cursor->getLinearMovement(); 00225 if (from == getParent()) { 00226 numerator->moveRight(cursor, this); 00227 } 00228 else if (from == numerator) { 00229 if (linear) { 00230 denominator->moveRight(cursor, this); 00231 } 00232 else { 00233 getParent()->moveRight(cursor, this); 00234 } 00235 } 00236 else { 00237 getParent()->moveRight(cursor, this); 00238 } 00239 } 00240 } 00241 00242 00248 void FractionElement::moveUp(FormulaCursor* cursor, BasicElement* from) 00249 { 00250 if (cursor->isSelectionMode()) { 00251 getParent()->moveUp(cursor, this); 00252 } 00253 else { 00254 if (from == getParent()) { 00255 denominator->moveRight(cursor, this); 00256 } 00257 else if (from == denominator) { 00258 numerator->moveRight(cursor, this); 00259 } 00260 else { 00261 getParent()->moveUp(cursor, this); 00262 } 00263 } 00264 } 00265 00266 00272 void FractionElement::moveDown(FormulaCursor* cursor, BasicElement* from) 00273 { 00274 if (cursor->isSelectionMode()) { 00275 getParent()->moveDown(cursor, this); 00276 } 00277 else { 00278 if (from == getParent()) { 00279 numerator->moveRight(cursor, this); 00280 } 00281 else if (from == numerator) { 00282 denominator->moveRight(cursor, this); 00283 } 00284 else { 00285 getParent()->moveDown(cursor, this); 00286 } 00287 } 00288 } 00289 00290 00294 void FractionElement::insert(FormulaCursor* cursor, 00295 QPtrList<BasicElement>& newChildren, 00296 Direction direction) 00297 { 00298 if (cursor->getPos() == denominatorPos) { 00299 denominator = static_cast<SequenceElement*>(newChildren.take(0)); 00300 denominator->setParent(this); 00301 00302 if (direction == beforeCursor) { 00303 denominator->moveLeft(cursor, this); 00304 } 00305 else { 00306 denominator->moveRight(cursor, this); 00307 } 00308 cursor->setSelection(false); 00309 formula()->changed(); 00310 } 00311 } 00312 00313 00323 void FractionElement::remove(FormulaCursor* cursor, 00324 QPtrList<BasicElement>& removedChildren, 00325 Direction direction) 00326 { 00327 switch (cursor->getPos()) { 00328 case numeratorPos: 00329 getParent()->selectChild(cursor, this); 00330 getParent()->remove(cursor, removedChildren, direction); 00331 break; 00332 case denominatorPos: 00333 removedChildren.append(denominator); 00334 formula()->elementRemoval(denominator); 00335 denominator = 0; 00336 cursor->setTo(this, denominatorPos); 00337 formula()->changed(); 00338 break; 00339 } 00340 } 00341 00342 00348 bool FractionElement::isSenseless() 00349 { 00350 return denominator == 0; 00351 } 00352 00353 00354 // main child 00355 // 00356 // If an element has children one has to become the main one. 00357 00358 SequenceElement* FractionElement::getMainChild() 00359 { 00360 return numerator; 00361 } 00362 00363 // void FractionElement::setMainChild(SequenceElement* child) 00364 // { 00365 // formula()->elementRemoval(numerator); 00366 // numerator = child; 00367 // numerator->setParent(this); 00368 // formula()->changed(); 00369 // } 00370 00371 00376 void FractionElement::selectChild(FormulaCursor* cursor, BasicElement* child) 00377 { 00378 if (child == numerator) { 00379 cursor->setTo(this, numeratorPos); 00380 } 00381 else if (child == denominator) { 00382 cursor->setTo(this, denominatorPos); 00383 } 00384 } 00385 00386 00390 void FractionElement::writeDom(QDomElement element) 00391 { 00392 BasicElement::writeDom(element); 00393 00394 QDomDocument doc = element.ownerDocument(); 00395 if (!withLine) element.setAttribute("NOLINE", 1); 00396 00397 QDomElement num = doc.createElement("NUMERATOR"); 00398 num.appendChild(numerator->getElementDom(doc)); 00399 element.appendChild(num); 00400 00401 QDomElement den = doc.createElement("DENOMINATOR"); 00402 den.appendChild(denominator->getElementDom(doc)); 00403 element.appendChild(den); 00404 } 00405 00410 bool FractionElement::readAttributesFromDom(QDomElement element) 00411 { 00412 if (!BasicElement::readAttributesFromDom(element)) { 00413 return false; 00414 } 00415 QString lineStr = element.attribute("NOLINE"); 00416 if(!lineStr.isNull()) { 00417 withLine = lineStr.toInt() == 0; 00418 } 00419 return true; 00420 } 00421 00427 bool FractionElement::readContentFromDom(QDomNode& node) 00428 { 00429 if (!BasicElement::readContentFromDom(node)) { 00430 return false; 00431 } 00432 00433 if ( !buildChild( numerator, node, "NUMERATOR" ) ) { 00434 kdWarning( DEBUGID ) << "Empty numerator in FractionElement." << endl; 00435 return false; 00436 } 00437 node = node.nextSibling(); 00438 00439 if ( !buildChild( denominator, node, "DENOMINATOR" ) ) { 00440 kdWarning( DEBUGID ) << "Empty denominator in FractionElement." << endl; 00441 return false; 00442 } 00443 node = node.nextSibling(); 00444 00445 return true; 00446 } 00447 00448 QString FractionElement::toLatex() 00449 { 00450 if ( withLine ) { 00451 return "\\frac" + numerator->toLatex() + denominator->toLatex(); 00452 } 00453 else { 00454 return "{" + numerator->toLatex() + "\\atop " + denominator->toLatex() + "}"; 00455 } 00456 } 00457 00458 QString FractionElement::formulaString() 00459 { 00460 return "(" + numerator->formulaString() + ")/(" + denominator->formulaString() + ")"; 00461 } 00462 00463 void FractionElement::writeMathML( QDomDocument doc, QDomNode parent ) 00464 { 00465 QDomElement de = doc.createElement( "mfrac" ); 00466 if ( !withLine ) // why is this no function? 00467 de.setAttribute( "linethickness", 0 ); 00468 numerator->writeMathML( doc, de ); 00469 denominator->writeMathML( doc, de ); 00470 parent.appendChild( de ); 00471 } 00472 00473 KFORMULA_NAMESPACE_END
KDE Logo
This file is part of the documentation for lib Library Version 1.3.5.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Nov 17 06:54:14 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003