1 /* This file is part of the KDE project
2    Copyright (C) 2009 Jeremias Epperlein <jeeree@web.de>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this library; see the file COPYING.LIB.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17    Boston, MA 02110-1301, USA.
18 */
19 
20 #include "FixedElement.h"
21 
22 #include "FormulaCursor.h"
23 #include "FormulaDebug.h"
24 
25 #include <KoXmlReader.h>
26 
27 #include <QPainter>
28 #include <QPainterPath>
29 
30 
FixedElement(BasicElement * parent)31 FixedElement::FixedElement( BasicElement* parent ) : BasicElement( parent )
32 {
33 }
34 
~FixedElement()35 FixedElement::~FixedElement()
36 {
37 }
38 
39 
elementAfter(int position) const40 BasicElement* FixedElement::elementAfter ( int position ) const
41 {
42     if (position % 2 == 0) {
43         return elementNext(position);
44     } else {
45         return 0;
46     }
47 }
48 
elementBefore(int position) const49 BasicElement* FixedElement::elementBefore ( int position ) const
50 {
51     if (position % 2 == 1) {
52         return elementNext(position);
53     } else {
54         return 0;
55     }
56 }
57 
elementNext(int position) const58 BasicElement* FixedElement::elementNext ( int position ) const
59 {
60         return childElements()[position/2];
61 }
62 
63 
selectionRegion(const int pos1,const int pos2) const64 QPainterPath FixedElement::selectionRegion(const int pos1, const int pos2) const
65 {
66     QPainterPath temp;
67     Q_UNUSED(pos1);
68     Q_UNUSED(pos2);
69     return temp;
70 }
71 
moveHorSituation(FormulaCursor & newcursor,FormulaCursor & oldcursor,int pos1,int pos2)72 bool FixedElement::moveHorSituation(FormulaCursor& newcursor, FormulaCursor& oldcursor, int pos1, int pos2) {
73     if ((newcursor.position()/2==pos1 && newcursor.direction()==MoveUp) ||
74         (newcursor.position()/2==pos2 && newcursor.direction()==MoveDown) ||
75         (newcursor.position()==2*pos1 && newcursor.direction()==MoveLeft) ||
76         (newcursor.position()==2*pos2+1 && newcursor.direction()==MoveRight) ) {
77         return false;
78     }
79     switch (newcursor.direction()) {
80     case MoveLeft:
81         if (newcursor.position()==2*pos2+1) {
82             newcursor.moveTo(newcursor.currentElement()->childElements()[pos2]);
83         } else {
84             newcursor.moveTo(newcursor.currentElement()->childElements()[pos1]);
85         }
86         break;
87     case MoveRight:
88         if (newcursor.position()==2*pos1) {
89             newcursor.moveTo(newcursor.currentElement()->childElements()[pos1]);
90         } else {
91             newcursor.moveTo(newcursor.currentElement()->childElements()[pos2]);
92         }
93         break;
94     case MoveUp:
95     case MoveDown:
96         return newcursor.moveCloseTo(childElements()[newcursor.direction()==MoveUp ? pos1 : pos2],oldcursor);
97     case NoDirection:
98         break;
99     }
100     return true;
101 }
102 
moveVertSituation(FormulaCursor & newcursor,FormulaCursor & oldcursor,int pos1,int pos2)103 bool FixedElement::moveVertSituation(FormulaCursor& newcursor, FormulaCursor& oldcursor, int pos1, int pos2) {
104     if ((newcursor.position()/2==pos1 && newcursor.direction()==MoveUp) ||
105         (newcursor.position()/2==pos2 && newcursor.direction()==MoveDown) ||
106         (newcursor.position()%2==0 && newcursor.direction()==MoveLeft) ||
107         (newcursor.position()%2==1 && newcursor.direction()==MoveRight) ) {
108         return false;
109     }
110     switch (newcursor.direction()) {
111     case MoveLeft:
112     case MoveRight:
113         if (newcursor.position()/2==pos1) {
114             newcursor.moveTo(newcursor.currentElement()->childElements()[pos1]);
115         } else {
116             newcursor.moveTo(newcursor.currentElement()->childElements()[pos2]);
117         }
118         break;
119     case MoveUp:
120     case MoveDown:
121         return newcursor.moveCloseTo(childElements()[newcursor.direction()==MoveUp ? pos1 : pos2],oldcursor);
122     case NoDirection:
123         break;
124     }
125     return true;
126 }
127 
moveSingleSituation(FormulaCursor & newcursor,FormulaCursor & oldcursor,int pos)128 bool FixedElement::moveSingleSituation ( FormulaCursor& newcursor, FormulaCursor& oldcursor, int pos )
129 {
130     Q_UNUSED( oldcursor )
131     switch (newcursor.direction()) {
132     case MoveLeft:
133         if (newcursor.position()%2==1) {
134             newcursor.moveTo(newcursor.currentElement()->childElements()[pos]);
135             break;
136         }
137         return false;
138     case MoveRight:
139         if (newcursor.position()%2==0) {
140             newcursor.moveTo(newcursor.currentElement()->childElements()[pos]);
141             break;
142         }
143     case MoveUp:
144     case MoveDown:
145         return false;
146     case NoDirection:
147         break;
148     }
149     return true;
150 }
151 
152 
acceptCursor(const FormulaCursor & cursor)153 bool FixedElement::acceptCursor ( const FormulaCursor& cursor )
154 {
155     Q_UNUSED (cursor)
156     return false;
157 }
158 
cursorLine(int position) const159 QLineF FixedElement::cursorLine ( int position ) const
160 {
161     QRectF tmp;
162     if (position%2==1) {
163         tmp=elementBefore(position)->absoluteBoundingRect();
164         return QLineF(tmp.topRight(),tmp.bottomRight());
165     } else {
166         tmp=elementAfter(position)->absoluteBoundingRect();
167         return QLineF(tmp.topLeft(),tmp.bottomLeft());
168     }
169 }
170 
positionOfChild(BasicElement * child) const171 int FixedElement::positionOfChild ( BasicElement* child ) const
172 {
173     int tmp=childElements().indexOf(child);
174     if (tmp==-1) {
175         return -1;
176     } else {
177         return 2*tmp;
178     }
179 }
180 
loadElement(KoXmlElement & tmp,RowElement ** child)181 bool FixedElement::loadElement ( KoXmlElement& tmp, RowElement** child )
182 {
183     BasicElement *element;
184     element = ElementFactory::createElement( tmp.tagName(), this );
185     if( !element->readMathML( tmp ) ) {
186         return false;
187     }
188     if (element->elementType()==Row) {
189         delete (*child);
190         (*child)=static_cast<RowElement*>(element);
191     } else {
192         (*child)->insertChild(0,element);
193     }
194     return true;
195 }
196 
197 
endPosition() const198 int FixedElement::endPosition() const
199 {
200     return childElements().length()*2-1;
201 }
202