kformula/flake
FractionElement.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "FractionElement.h"
00024 #include "FormulaCursor.h"
00025 #include "AttributeManager.h"
00026 #include <KoXmlWriter.h>
00027 #include <KoXmlReader.h>
00028 #include <QPainter>
00029 #include <kdebug.h>
00030
00031 FractionElement::FractionElement( BasicElement* parent ) : FixedElement( parent )
00032 {
00033 m_numerator = new RowElement( this );
00034 m_denominator = new RowElement( this );
00035 m_lineThickness = 1.0;
00036 }
00037
00038 FractionElement::~FractionElement()
00039 {
00040 delete m_numerator;
00041 delete m_denominator;
00042 }
00043
00044 void FractionElement::paint( QPainter& painter, AttributeManager* am )
00045 {
00046 Q_UNUSED( am )
00047
00048 if( m_lineThickness == 0.0 )
00049 return;
00050
00051
00052 QPen pen;
00053 pen.setWidthF( m_lineThickness );
00054 painter.setPen( pen );
00055 painter.drawLine( m_fractionLine );
00056 }
00057
00058 void FractionElement::layout( const AttributeManager* am )
00059 {
00060
00061 QString value = am->findValue( "linethickness", this );
00062 Length length;
00063 if(value == "thick")
00064 length.value = 2;
00065 else if(value == "medium")
00066 length.value = 1;
00067 else if(value == "thin")
00068 length.value = 0.5;
00069 else
00070 length = am->parseUnit( value, this );
00071
00072 if(length.unit == Length::None)
00073 m_lineThickness = am->lineThickness(this) * length.value;
00074 else
00075 m_lineThickness = am->lengthToPixels(length, this, "linethickness");
00076
00077
00078 if( am->boolOf( "bevelled", this ) )
00079 {
00080 layoutBevelledFraction( am );
00081 return;
00082 }
00083
00084 double distY = am->layoutSpacing( this );
00085 Align numalign = am->alignOf( "numalign", this );
00086 Align denomalign = am->alignOf( "denomalign", this );
00087
00088
00089 QPointF numeratorOrigin;
00090 QPointF denominatorOrigin( 0.0, m_numerator->height() + m_lineThickness + 2*distY );
00091 setWidth( qMax( m_numerator->width(), m_denominator->width() ) + m_lineThickness*2 );
00092
00093 if( numalign == Right )
00094 numeratorOrigin.setX( width() - m_numerator->width() - m_lineThickness );
00095 else if( numalign == Center )
00096 numeratorOrigin.setX( ( width() - m_numerator->width() ) / 2 );
00097
00098 if( denomalign == Right )
00099 denominatorOrigin.setX( width() - m_denominator->width() - m_lineThickness );
00100 else if( numalign == Center )
00101 denominatorOrigin.setX( ( width() - m_denominator->width() ) / 2 );
00102
00103 m_numerator->setOrigin( numeratorOrigin );
00104 m_denominator->setOrigin( denominatorOrigin );
00105
00106
00107 double fractionLineY = m_numerator->height() + m_lineThickness/2 + distY;
00108 m_fractionLine = QLineF( QPointF( m_lineThickness, fractionLineY ),
00109 QPointF( width()-m_lineThickness, fractionLineY ) );
00110
00111 setHeight( m_numerator->height() + m_denominator->height() +
00112 m_lineThickness + 2*distY );
00113 setBaseLine( denominatorOrigin.y() );
00114 }
00115
00116 void FractionElement::layoutBevelledFraction( const AttributeManager* am )
00117 {
00118
00119
00120
00121 double borderY = am->layoutSpacing( this );
00122 setHeight( m_numerator->height() + m_denominator->height() + 2*borderY );
00123 setWidth( m_numerator->width() + m_denominator->width() + height()/3 );
00124 setBaseLine( height()/2 );
00125
00126 m_numerator->setOrigin( QPointF( 0.0, borderY ) );
00127 m_denominator->setOrigin( QPointF( width()-m_denominator->width(),
00128 borderY+m_numerator->height() ) );
00129 m_fractionLine = QLineF( QPointF( m_numerator->width(), height() ),
00130 QPointF( width()-m_denominator->width(), 0.0 ) );
00131 }
00132
00133 const QList<BasicElement*> FractionElement::childElements() const
00134 {
00135 QList<BasicElement*> list;
00136 list << m_numerator<<m_denominator;
00137 return list;
00138 }
00139
00140 int FractionElement::endPosition() const {
00141 return 3;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 QList< BasicElement* > FractionElement::elementsBetween ( int pos1, int pos2 ) const
00172 {
00173 QList<BasicElement*> tmp;
00174 if (pos1==0 && pos2 >0) {
00175 tmp.append(m_numerator);
00176 }
00177 if (pos1<3 && pos2==3) {
00178 tmp.append(m_denominator);
00179 }
00180 return tmp;
00181 }
00182
00183
00184 int FractionElement::positionOfChild(BasicElement* child) const {
00185 if (m_numerator==child){
00186 return 0;
00187 }
00188 else if (m_denominator==child) {
00189 return 2;
00190 }
00191 return -1;
00192 }
00193
00194 bool FractionElement::moveCursor(FormulaCursor& newcursor, FormulaCursor& oldcursor) {
00195 if (newcursor.isSelecting()) {
00196 return false;
00197 } else {
00198
00199
00200
00201
00202 return moveVertSituation(newcursor,oldcursor,0,1);
00203 }
00204 }
00205
00206 bool FractionElement::setCursorTo( FormulaCursor& cursor, QPointF point )
00207 {
00208
00209 bool inNumerator=point.y() < (m_numerator->boundingRect().bottom() + m_denominator->boundingRect().top())/2 ;
00210 if (cursor.isSelecting()) {
00211 return false;
00212 } else {
00213 if (point.x() > width()) {
00214 cursor.moveTo(this,inNumerator? 1 : 3);
00215 return true;
00216 }
00217 if (point.x() < 0) {
00218 cursor.moveTo(this,inNumerator? 0 : 2);
00219 return true;
00220 }
00221 if ( inNumerator ) {
00222 point-=m_numerator->origin();
00223
00224 return m_numerator->setCursorTo(cursor,point);
00225 } else {
00226 point-=m_denominator->origin();
00227 return m_denominator->setCursorTo(cursor,point);
00228 }
00229 }
00230 }
00231
00232 bool FractionElement::replaceChild ( BasicElement* oldelement, BasicElement* newelement )
00233 {
00234
00235 if (newelement->elementType()==Row) {
00236 RowElement* newrow=static_cast<RowElement*>(newelement);
00237 if( oldelement == m_numerator ) {
00238 m_numerator = newrow;
00239 return true;
00240 } else if( oldelement == m_denominator ) {
00241 m_denominator = newrow;
00242 return true;
00243 }
00244 }
00245 return false;
00246 }
00247
00248 QString FractionElement::attributesDefaultValue( const QString& attribute ) const
00249 {
00250 if( attribute == "linethickness" )
00251 return "1";
00252 else if( attribute == "numalign" || attribute == "denomalign" )
00253 return "center";
00254 else if( attribute == "bevelled" )
00255 return "false";
00256 else
00257 return QString();
00258 }
00259
00260 bool FractionElement::readMathMLContent( const KoXmlElement& parent )
00261 {
00262 KoXmlElement tmp;
00263 int counter=0;
00264 forEachElement( tmp, parent ) {
00265 if (counter==0) {
00266 loadElement(tmp,&m_numerator);
00267 } else if (counter==1) {
00268 loadElement(tmp,&m_denominator);
00269 } else {
00270 kDebug(39001) << "Too many arguments to mfrac";
00271 }
00272 counter++;
00273 }
00274 if (counter<2) {
00275 kDebug(39001) << "Not enough arguments to mfrac";
00276 }
00277 return true;
00278 }
00279
00280 void FractionElement::writeMathMLContent( KoXmlWriter* writer ) const
00281 {
00282 m_numerator->writeMathML( writer );
00283 m_denominator->writeMathML( writer );
00284 }
00285
00286 ElementType FractionElement::elementType() const
00287 {
00288 return Fraction;
00289 }
|