1
/* This file is part of the KDE project
2
Copyright (C) 2006 Martin Pfeiffer <hubipete@gmx.net>
3
2009 Jeremias Epperlein <jeeree@web.de>
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public
7
License as published by the Free Software Foundation; either
8
version 2 of the License, or (at your option) any later version.
10
This library is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public License
16
along with this library; see the file COPYING.LIB. If not, write to
17
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18
Boston, MA 02110-1301, USA.
21
#include "SubSupElement.h"
22
#include "FormulaCursor.h"
23
#include "AttributeManager.h"
24
#include <KoXmlWriter.h>
25
#include <KoXmlReader.h>
29
SubSupElement::SubSupElement( BasicElement* parent, ElementType elementType ) : FixedElement( parent )
31
m_baseElement = new RowElement( this );
32
if (elementType!=SupScript) {
33
m_subScript = new RowElement( this );
37
if (elementType!=SubScript) {
38
m_superScript = new RowElement( this );
42
m_elementType = elementType;
45
SubSupElement::~SubSupElement()
56
void SubSupElement::paint( QPainter& painter, AttributeManager* am )
60
/*do nothing as this element has no visual representation*/
63
void SubSupElement::layout( const AttributeManager* am )
65
// Get the minimum amount of shifting
66
double subscriptshift = am->doubleOf( "subscriptshift", this );
67
double superscriptshift = am->doubleOf( "superscriptshift", this );
68
double halfthinSpace = 0;
70
if(m_elementType == SubSupScript) {
71
//Add half a thin space between both sup and superscript, so there is a minimum
72
//of a whole thin space between them.
73
halfthinSpace = am->layoutSpacing( this )/2.0;
76
// The yOffset is the amount the base element is moved down to make
77
// room for the superscript
80
yOffset = m_superScript->height() - m_baseElement->height()/2 + halfthinSpace;
81
yOffset = qMax( yOffset, superscriptshift );
83
double largestWidth = 0;
85
largestWidth = m_subScript->width();
88
largestWidth = qMax( largestWidth, m_superScript->width());
89
m_superScript->setOrigin( QPointF( m_baseElement->width(), 0) );
92
setWidth( m_baseElement->width() + largestWidth );
93
setBaseLine( yOffset + m_baseElement->baseLine() );
94
m_baseElement->setOrigin( QPointF( 0, yOffset ) );
98
double yPos = yOffset +
99
qMax( m_baseElement->height()/2 + halfthinSpace,
100
m_baseElement->height() - m_subScript->baseLine()
102
m_subScript->setOrigin( QPointF( m_baseElement->width(), yPos ) );
103
setHeight( yPos + m_subScript->height() );
105
setHeight( yOffset + m_baseElement->height() );
109
const QList<BasicElement*> SubSupElement::childElements() const
111
QList<BasicElement*> tmp;
112
tmp << m_baseElement;
114
tmp << m_superScript;
121
QString SubSupElement::attributesDefaultValue( const QString& attribute ) const
123
Q_UNUSED( attribute )
127
ElementType SubSupElement::elementType() const
129
return m_elementType;
132
bool SubSupElement::readMathMLContent( const KoXmlElement& parent )
136
forEachElement( tmp, parent ) {
138
loadElement(tmp,&m_baseElement);
139
} else if (counter==1 && m_elementType != SupScript) {
140
loadElement(tmp,&m_subScript);
141
} else if ((counter==2 && m_elementType==SubSupScript) || (counter==1 && m_elementType==SupScript)) {
142
loadElement(tmp,&m_superScript);
143
} else if ((counter==3 && m_elementType==SubSupScript) || (counter==2)) {
144
kDebug(39001) << "Too many arguments to " << ElementFactory::elementName(m_elementType);
148
if ((counter<3 && m_elementType==SubSupScript) || (counter<2)) {
149
kDebug(39001) << "Not enough arguments to "<< ElementFactory::elementName(m_elementType);
155
void SubSupElement::writeMathMLContent( KoXmlWriter* writer ) const
157
// just save the children in the right order
158
m_baseElement->writeMathML( writer );
160
if( m_elementType!= SupScript)
161
m_subScript->writeMathML( writer );
163
if( m_elementType!= SubScript )
164
m_superScript->writeMathML( writer );
168
int SubSupElement::endPosition() const
170
return (m_elementType==SubSupScript ? 5 : 3);
174
bool SubSupElement::setCursorTo(FormulaCursor& cursor, QPointF point)
176
if (cursor.isSelecting()) {
179
if (m_subScript && m_subScript->boundingRect().contains(point)) {
180
return m_subScript->setCursorTo(cursor,point-m_subScript->origin());
181
} else if (m_superScript && m_superScript->boundingRect().contains(point)) {
182
return m_superScript->setCursorTo(cursor,point-m_superScript->origin());
184
return m_baseElement->setCursorTo(cursor,point-m_baseElement->origin());
190
bool SubSupElement::moveCursor ( FormulaCursor& newcursor, FormulaCursor& oldcursor )
193
int childpos=newcursor.position()/2;
195
switch( newcursor.direction()) {
198
if (m_elementType==SubScript) {
199
return moveHorSituation(newcursor,oldcursor,1,0);
200
} else if (m_elementType==SupScript) {
201
return moveHorSituation(newcursor,oldcursor,0,1);
206
return moveVertSituation(newcursor,oldcursor,1,2);
208
if (newcursor.direction()==MoveDown) {
209
return moveHorSituation(newcursor,oldcursor,1,0);
211
return moveHorSituation(newcursor,oldcursor,0,2);
220
return moveHorSituation(newcursor,oldcursor,0,1);
222
return moveHorSituation(newcursor,oldcursor,0,1);
224
return moveHorSituation(newcursor,oldcursor,0,2);