1
/* This file is part of the KDE project
2
Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
3
Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.de>
4
2006 Martin Pfeiffer <hubipete@gmx.net>
5
Copyright (C) 2007 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
6
2009 Jeremias Epperlein <jeeree@web.de>
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Library General Public
10
License as published by the Free Software Foundation; either
11
version 2 of the License, or (at your option) any later version.
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Library General Public License for more details.
18
You should have received a copy of the GNU Library General Public License
19
along with this library; see the file COPYING.LIB. If not, write to
20
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21
Boston, MA 02110-1301, USA.
24
#include "RootElement.h"
25
#include "AttributeManager.h"
26
#include "FormulaCursor.h"
27
#include "RowElement.h"
28
#include <KoXmlReader.h>
33
RootElement::RootElement( BasicElement* parent ) : FixedElement( parent )
35
m_radicand = new RowElement( this );
36
m_exponent = new RowElement( this );
39
RootElement::~RootElement()
45
void RootElement::paint( QPainter& painter, AttributeManager* am )
49
pen.setWidth( m_lineThickness );
50
painter.setPen( pen );
51
painter.drawPath( m_rootSymbol );
54
void RootElement::layout( const AttributeManager* am )
56
// Calculate values to layout the root symbol
57
double thinSpace = am->layoutSpacing( this );
58
double symbolHeight = m_radicand->baseLine();
59
if( m_radicand->height() > symbolHeight*1.3 ) symbolHeight = m_radicand->height();
60
symbolHeight += thinSpace;
61
double tickWidth = symbolHeight / 3.0; // The width of the root symbol's tick part
63
m_lineThickness = am->lineThickness(this);
65
// The root symbol an xOffset and yOffset due to the exponent.
66
double xOffset = m_exponent->width() - tickWidth/2;
67
xOffset = xOffset < 0 ? 0 : xOffset; // no negative offset for the root symbol
68
double yOffset = m_exponent->height() - 2.0*symbolHeight/5.0;
69
yOffset = yOffset < 0 ? 0 : yOffset;
71
// Set the roots dimensions
72
setBaseLine( yOffset + thinSpace + m_radicand->baseLine() );
73
setHeight( yOffset + thinSpace + m_radicand->height() );
74
setWidth( xOffset + tickWidth + m_radicand->width() + thinSpace );
76
// Place the children in the correct place
77
m_radicand->setOrigin( QPointF( xOffset+tickWidth+thinSpace, yOffset+thinSpace ) );
78
m_exponent->setOrigin( QPointF( 0.0, 0.0 ) );
80
// Draw the actual root symbol to a path as buffer
81
m_rootSymbol = QPainterPath();
82
m_rootSymbol.moveTo( xOffset+m_lineThickness, yOffset + 2.0 * symbolHeight / 3.0 );
83
m_rootSymbol.lineTo( m_rootSymbol.currentPosition().x()+tickWidth*0.5, yOffset + symbolHeight - m_lineThickness/2 );
84
m_rootSymbol.lineTo( m_rootSymbol.currentPosition().x()+tickWidth*0.5, yOffset + m_lineThickness/2 );
85
m_rootSymbol.lineTo( width()-m_lineThickness/2, yOffset + m_lineThickness/2);
88
const QList<BasicElement*> RootElement::childElements() const
90
QList<BasicElement*> tmp;
91
tmp << m_exponent << m_radicand;
96
// QList< BasicElement* > RootElement::elementsBetween(int pos1, int pos2) const
98
// QList<BasicElement*> tmp;
99
// if (pos1==0 && pos2 >0) {
100
// tmp.append(m_exponent);
102
// if (pos1<3 && pos2==3) {
103
// tmp.append(m_radicand);
108
// int RootElement::positionOfChild(BasicElement* child) const
110
// if (child==m_exponent) {
112
// } else if (child==m_radicand) {
118
bool RootElement::setCursorTo(FormulaCursor& cursor, QPointF point)
120
if (cursor.isSelecting()) {
123
if (m_exponent->boundingRect().contains(point)) {
124
return m_exponent->setCursorTo(cursor, point-m_exponent->origin());
126
return m_radicand->setCursorTo(cursor, point-m_radicand->origin());
130
bool RootElement::moveCursor(FormulaCursor& newcursor, FormulaCursor& oldcursor)
132
if (newcursor.isSelecting()) {
135
return moveHorSituation(newcursor,oldcursor,0,1);
140
int RootElement::endPosition() const
146
bool RootElement::replaceChild ( BasicElement* oldelement, BasicElement* newelement )
148
if (oldelement==m_exponent) {
149
m_exponent=newelement;
151
} else if (oldelement==m_radicand) {
152
m_radicand=newelement;
158
ElementType RootElement::elementType() const
163
bool RootElement::readMathMLContent( const KoXmlElement& element )
165
BasicElement* tmpElement = 0;
167
bool radicand = true;
168
bool exponent = true;
170
forEachElement( tmp, element ) {
171
tmpElement = ElementFactory::createElement( tmp.tagName(), this );
172
if( !tmpElement->readMathML( tmp ) ) {
177
m_radicand = tmpElement;
179
} else if( exponent ) {
181
m_exponent = tmpElement;
184
kDebug(39001) << "Too many arguments to mroot";
191
void RootElement::writeMathMLContent( KoXmlWriter* writer ) const
193
Q_ASSERT( m_radicand );
194
Q_ASSERT( m_exponent );
195
m_radicand->writeMathML( writer );
196
m_exponent->writeMathML( writer );