kformula/flake
FormulaCursor.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 "FormulaCursor.h"
00024 #include "BasicElement.h"
00025 #include "RowElement.h"
00026 #include "FixedElement.h"
00027 #include "NumberElement.h"
00028 #include "ElementFactory.h"
00029 #include "OperatorElement.h"
00030 #include "IdentifierElement.h"
00031 #include "ElementFactory.h"
00032 #include "FormulaCommand.h"
00033 #include <QPainter>
00034 #include <QPen>
00035 #include <algorithm>
00036
00037 #include <kdebug.h>
00038 #include <QUndoCommand>
00039 #include <KoOdfLoadingContext.h>
00040 #include <KoOdfStylesReader.h>
00041
00042 FormulaCursor::FormulaCursor(BasicElement* element, bool selecting, int position, int mark) {
00043 m_currentElement=element;
00044 m_selecting=selecting;
00045 m_position=position;
00046 m_mark=mark;
00047 }
00048
00049 FormulaCursor::FormulaCursor ( BasicElement* element, int position )
00050 {
00051 m_currentElement=element;
00052 m_position=position;
00053 m_mark=0;
00054 m_selecting=false;
00055 }
00056
00057
00058 FormulaCursor::FormulaCursor()
00059 {
00060 FormulaCursor(0,0);
00061 }
00062
00063 FormulaCursor::FormulaCursor (const FormulaCursor& other )
00064 {
00065 m_currentElement=other.currentElement();
00066 m_position=other.position();
00067 m_mark=other.mark();
00068 m_selecting=other.isSelecting();
00069 }
00070
00071
00072 void FormulaCursor::paint( QPainter& painter ) const
00073 {
00074 kDebug() << "Drawing cursor with selecting: "<< isSelecting() << " from "
00075 << mark()<<" to " << position() << " in "<<ElementFactory::elementName(m_currentElement->elementType());
00076 if( !m_currentElement )
00077 return;
00078 painter.save();
00079 QPointF origin=m_currentElement->absoluteBoundingRect().topLeft();
00080 double baseline=m_currentElement->baseLine();
00081 QPen pen;
00082 pen.setWidthF( 0.5 );
00083 pen.setColor(Qt::black);
00084 painter.setPen( pen );
00085 painter.drawLine(m_currentElement->cursorLine( m_position ));
00086 pen.setWidth( 0.1);
00087 pen.setColor(Qt::blue);
00088 pen.setStyle(Qt::DashLine);
00089 painter.setPen( pen );
00090 painter.drawLine( origin+QPointF(0.0,baseline),origin+QPointF(m_currentElement->width(), baseline) );
00091 pen.setStyle(Qt::DotLine);
00092
00093 switch(m_currentElement->elementType()) {
00094 case Number:
00095 pen.setColor(Qt::red);
00096 break;
00097 case Identifier:
00098 pen.setColor(Qt::darkRed);
00099 break;
00100 case Row:
00101 pen.setColor(Qt::yellow);
00102 break;
00103 case Fraction:
00104 pen.setColor(Qt::blue);
00105 break;
00106 case Table:
00107 pen.setColor(Qt::darkGreen);
00108 break;
00109 case TableRow:
00110 pen.setColor(Qt::green);
00111 break;
00112 default:
00113 pen.setColor(Qt::darkGray);
00114 break;
00115 }
00116 painter.setPen(pen);
00117 painter.drawRect( m_currentElement->absoluteBoundingRect() );
00118
00119 if ( m_selecting ) {
00120 QBrush brush;
00121 QColor color(Qt::blue);
00122 color.setAlpha(128);
00123 brush.setColor(color);
00124 brush.setStyle(Qt::SolidPattern);
00125 painter.setBrush(brush);
00126 painter.setPen(Qt::NoPen);
00127 int p1=position()<mark()? position() : mark();
00128 int p2=position()<mark()? mark() : position() ;
00129 painter.drawPath(m_currentElement->selectionRegion(p1,p2));
00130 }
00131 painter.restore();
00132 }
00133
00134 void FormulaCursor::selectElement(BasicElement* element)
00135 {
00136 m_selecting=true;
00137 m_currentElement=element;
00138 m_mark=0;
00139 m_position=m_currentElement->endPosition();
00140 }
00141
00142 void FormulaCursor::move( CursorDirection direction )
00143 {
00144 FormulaCursor oldcursor(*this);
00145 m_direction = direction;
00146 if (performMovement(oldcursor)==false) {
00147 (*this)=oldcursor;
00148 }
00149 m_direction=NoDirection;
00150 }
00151
00152 bool FormulaCursor::moveCloseTo(BasicElement* element, FormulaCursor& cursor)
00153 {
00154 if (element->setCursorTo(*this,cursor.getCursorPosition()-element->absoluteBoundingRect().topLeft())) {
00155 return true;
00156 } else {
00157 return false;
00158 }
00159 }
00160
00161 QPointF FormulaCursor::getCursorPosition()
00162 {
00163 return ( m_currentElement->cursorLine(m_position).p1()
00164 + m_currentElement->cursorLine(m_position).p2())/2.;
00165 }
00166
00167 void FormulaCursor::moveTo ( const FormulaCursor& pos )
00168 {
00169 m_currentElement=pos.currentElement();
00170 m_position=pos.position();
00171 m_selecting=pos.isSelecting();
00172 m_mark=pos.mark();
00173 }
00174
00175
00176 void FormulaCursor::moveTo ( BasicElement* element )
00177 {
00178 moveTo(element,0);
00179 if (direction()==MoveLeft) {
00180 moveEnd();
00181 }
00182 }
00183
00184
00185 void FormulaCursor::moveTo ( BasicElement* element, int position )
00186 {
00187 moveTo(FormulaCursor(element,position));
00188 }
00189
00190
00191 void FormulaCursor::setCursorTo( const QPointF& point )
00192 {
00193 if (m_selecting) {
00194 while (!m_currentElement->absoluteBoundingRect().contains(point)) {
00195 if ( m_currentElement->parentElement() ) {
00196 m_position=0;
00197 if (point.x()<m_currentElement->cursorLine(m_mark).p1().x()) {
00198
00199
00200 m_mark=m_currentElement->parentElement()->positionOfChild(m_currentElement)+1;
00201 } else {
00202 m_mark=m_currentElement->parentElement()->positionOfChild(m_currentElement);
00203 }
00204 m_currentElement=m_currentElement->parentElement();
00205 } else {
00206 return;
00207 }
00208 }
00209 while (!m_currentElement->setCursorTo(*this,point-m_currentElement->absoluteBoundingRect().topLeft())) {
00210 if ( m_currentElement->parentElement() ) {
00211 m_mark=m_currentElement->parentElement()->positionOfChild(m_currentElement);
00212 m_position=0;
00213 if (point.x()<m_currentElement->cursorLine(m_mark).p1().x()) {
00214
00215
00216 m_mark++;
00217 }
00218 m_currentElement=m_currentElement->parentElement();
00219 } else {
00220 return;
00221 }
00222 }
00223 } else {
00224 BasicElement* formulaElement = m_currentElement;
00225 while( formulaElement->parentElement() != 0 ) {
00226 formulaElement = formulaElement->parentElement();
00227 }
00228 formulaElement->setCursorTo(*this,point);
00229 }
00230 }
00231
00232 int FormulaCursor::mark() const
00233 {
00234 return m_mark;
00235 }
00236
00237 void FormulaCursor::moveHome()
00238 {
00239 m_position = 0;
00240 }
00241
00242 void FormulaCursor::moveEnd()
00243 {
00244 m_position=m_currentElement->endPosition();
00245 }
00246
00247 bool FormulaCursor::isHome() const
00248 {
00249 return m_position == 0;
00250 }
00251
00252 bool FormulaCursor::isEnd() const
00253 {
00254 return m_position == m_currentElement->endPosition();
00255 }
00256
00257 bool FormulaCursor::insideToken() const
00258 {
00259 if( m_currentElement->elementType() == Number ||
00260 m_currentElement->elementType() == Operator ||
00261 m_currentElement->elementType() == Identifier ) {
00262 return true;
00263 }
00264 return false;
00265 }
00266
00267 bool FormulaCursor::insideInferredRow() const
00268 {
00269 return m_currentElement->isInferredRow();
00270 }
00271
00272 bool FormulaCursor::insideFixedElement() const
00273 {
00274 if (m_currentElement->elementType() == Fraction ||
00275 m_currentElement->elementType() == Root ||
00276 m_currentElement->elementType() == SubScript ||
00277 m_currentElement->elementType() == SupScript ||
00278 m_currentElement->elementType() == SubScript ||
00279 m_currentElement->elementType() == SubSupScript ) {
00280 return true;
00281 }
00282 return false;
00283 }
00284
00285
00286
00287 BasicElement* FormulaCursor::currentElement() const
00288 {
00289 return m_currentElement;
00290 }
00291
00292 int FormulaCursor::position() const
00293 {
00294 return m_position;
00295 }
00296
00297 void FormulaCursor::setCurrentElement(BasicElement* element) {
00298 m_currentElement=element;
00299 }
00300
00301 void FormulaCursor::setPosition(int position) {
00302 m_position=position;
00303 }
00304
00305 CursorDirection FormulaCursor::direction() const
00306 {
00307 return m_direction;
00308 }
00309
00310 bool FormulaCursor::isSelecting() const
00311 {
00312 return m_selecting;
00313 }
00314
00315 void FormulaCursor::setSelecting( bool selecting )
00316 {
00317 if (selecting) {
00318 if (!m_selecting) {
00319
00320 m_selecting = selecting;
00321 m_mark=m_position;
00322 }
00323 } else {
00324 m_selecting = selecting;
00325 m_mark=0;
00326 }
00327 }
00328
00329 void FormulaCursor::setMark(int position) {
00330 m_mark=position;
00331 }
00332
00333 QPair< int,int > FormulaCursor::selection() const
00334 {
00335 if (m_mark<m_position) {
00336 return QPair<int,int>(m_mark,m_position);
00337 } else {
00338 return QPair<int,int>(m_position,m_mark);
00339 }
00340 }
00341
00342
00343 bool FormulaCursor::hasSelection() const
00344 {
00345 return (m_selecting && m_mark!=m_position);
00346 }
00347
00348
00349 bool FormulaCursor::isAccepted() const
00350 {
00351 if (mark()<0 || mark()>m_currentElement->endPosition() ||
00352 position()<0 || position()>m_currentElement->endPosition()) {
00353 return false;
00354 }
00355 return m_currentElement->acceptCursor(*this);
00356 }
00357
00358 bool FormulaCursor::performMovement ( FormulaCursor& oldcursor )
00359 {
00360
00361 if (isSelecting()) {
00362 while ( m_currentElement ) {
00363 if ( m_currentElement->moveCursor( *this, oldcursor ) ) {
00364 if (isAccepted()) {
00365 return true;
00366 }
00367 } else {
00368 if ( m_currentElement->parentElement() ) {
00369 bool ltr=m_mark<=m_position;
00370
00371 m_mark=m_currentElement->parentElement()->positionOfChild(m_currentElement);
00372
00373 m_position=m_currentElement->parentElement()->positionOfChild(m_currentElement);
00374 m_currentElement=m_currentElement->parentElement();
00375 if (ltr) {
00376 m_position++;
00377 } else {
00378 m_mark++;
00379 }
00380 if (isAccepted()) {
00381 return true;
00382 }
00383 } else {
00384
00385 return false;
00386 }
00387 }
00388 }
00389 } else {
00390 while ( m_currentElement ) {
00391 if ( m_currentElement->moveCursor( *this, oldcursor ) ) {
00392 if (isAccepted()) {
00393 return true;
00394 }
00395 } else {
00396 if ( m_currentElement->parentElement() ) {
00397
00398 m_position=m_currentElement->parentElement()->positionOfChild(m_currentElement);
00399 m_currentElement=m_currentElement->parentElement();
00400 if (m_direction==MoveRight || m_direction==MoveDown) {
00401 m_position++;
00402 }
00403 if (m_direction==MoveRight || m_direction==MoveLeft) {
00404 if (isAccepted()) {
00405 return true;
00406 }
00407 }
00408 } else {
00409
00410 return false;
00411 }
00412 }
00413 }
00414 }
00415 return false;
00416 }
00417
00418 FormulaCursor& FormulaCursor::operator+= ( int step )
00419 {
00420 m_position+=step;
00421 return *this;
00422 }
00423
00424 int FormulaCursor::offset ( )
00425 {
00426 if (m_direction==MoveDown || m_direction==MoveRight) {
00427 return -1;
00428 } else if (m_direction==MoveUp || m_direction==MoveLeft) {
00429 return 1;
00430 }
00431 return 0;
00432 }
00433
|