lib

numberelement.cpp
1/* This file is part of the KDE project
2 Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
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 <tdelocale.h>
21
22#include "numberelement.h"
23#include "kformuladefs.h"
24#include "textelement.h"
25#include "identifierelement.h"
26#include "operatorelement.h"
27#include "kformulacommand.h"
28#include "kformulacontainer.h"
29#include "formulaelement.h"
30#include "creationstrategy.h"
31
32KFORMULA_NAMESPACE_BEGIN
33
34NumberElement::NumberElement( BasicElement* parent ) : TokenElement( parent ) {}
35
36/*
37 * Token elements' content has to be of homogeneous type. Every token element
38 * must (TODO: check this) appear inside a non-token sequence, and thus, if
39 * the command asks for a different content, a new element has to be created in
40 * parent sequence.
41 */
42KCommand* NumberElement::buildCommand( Container* container, Request* request )
43{
44 FormulaCursor* cursor = container->activeCursor();
45 if ( cursor->isReadOnly() ) {
46 formula()->tell( i18n( "write protection" ) );
47 return 0;
48 }
49
50 if ( *request == req_addNumber ) {
51 KFCReplace* command = new KFCReplace( i18n("Add Number"), container );
52 NumberRequest* nr = static_cast<NumberRequest*>( request );
53 TextElement* element = creationStrategy->createTextElement( nr->ch(), false );
54 command->addElement( element );
55 return command;
56 }
57
58 if ( countChildren() == 0 || cursor->getPos() == countChildren() ) {
59 // We are in the last position, so it's easy, call the parent to
60 // create a new child
61 SequenceElement* parent = static_cast<SequenceElement*>( getParent() );
62 if ( parent ) {
63 uint pos = parent->childPos( this );
64 cursor->setTo( parent, pos + 1);
65 return parent->buildCommand( container, request );
66 }
67 }
68 if ( cursor->getPos() == 0 ) {
69 SequenceElement* parent = static_cast<SequenceElement*>( getParent() );
70 if ( parent ) {
71 uint pos = parent->childPos( this );
72 cursor->setTo( parent, pos );
73 return parent->buildCommand( container, request );
74 }
75 }
76
77 // We are in the middle of a token, so:
78 // a) Cut from mark to the end
79 // b) Create a new token and add an element from key pressed
80 // c) Create a new token and add elements cut previously
81 // d) Move cursor to parent so that it command execution works fine
82
83 switch( *request ) {
84 case req_addTextChar: {
85 KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container );
86 TextCharRequest* tr = static_cast<TextCharRequest*>( request );
87 IdentifierElement* id = creationStrategy->createIdentifierElement();
88 TextElement* text = creationStrategy->createTextElement( tr->ch() );
89 command->addCursor( cursor );
90 command->addToken( id );
91 command->addContent( id, text );
92 SequenceElement* parent = static_cast< SequenceElement* >( getParent() );
93 if ( parent ) {
94 cursor->setTo( parent, parent->childPos( this ) + 1 );
95 }
96 return command;
97 }
98
99 case req_addText: {
100 KFCSplitToken* command = new KFCSplitToken( i18n("Add Text"), container );
101 TextRequest* tr = static_cast<TextRequest*>( request );
102 IdentifierElement* id = creationStrategy->createIdentifierElement();
103 command->addCursor( cursor );
104 command->addToken( id );
105 for ( uint i = 0; i < tr->text().length(); i++ ) {
106 TextElement* text = creationStrategy->createTextElement( tr->text()[i] );
107 command->addContent( id, text );
108 }
109 SequenceElement* parent = static_cast< SequenceElement* >( getParent() );
110 if ( parent ) {
111 cursor->setTo( parent, parent->childPos( this ) + 1 );
112 }
113 return command;
114 }
115
116 case req_addOperator: {
117 KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container );
118 OperatorRequest* opr = static_cast<OperatorRequest*>( request );
119 OperatorElement* op = creationStrategy->createOperatorElement();
120 TextElement* text = creationStrategy->createTextElement( opr->ch() );
121 command->addCursor( cursor );
122 command->addToken( op );
123 command->addContent( op, text );
124 SequenceElement* parent = static_cast< SequenceElement* >( getParent() );
125 if ( parent ) {
126 cursor->setTo( parent, parent->childPos( this ) + 1 );
127 }
128 return command;
129 }
130 case req_addEmptyBox:
131 case req_addNameSequence:
132 case req_addBracket:
133 case req_addSpace:
134 case req_addFraction:
135 case req_addRoot:
136 case req_addSymbol:
137 case req_addOneByTwoMatrix:
138 case req_addMatrix: {
139 SequenceElement* parent = static_cast<SequenceElement*>( getParent() );
140 if ( parent ) {
141 uint pos = parent->childPos( this );
142 cursor->setTo( parent, pos + 1);
143 return parent->buildCommand( container, request );
144 }
145 }
146 default:
147 return SequenceElement::buildCommand( container, request );
148 }
149 return 0;
150}
151
152
153KFORMULA_NAMESPACE_END
Basis of every formula element.
virtual FormulaElement * formula()
Provide fast access to the rootElement for each child.
The document.
FormulaCursor * activeCursor()
void setTo(BasicElement *element, uint cursor, int mark=-1)
Sets the cursor to a new position.
bool isReadOnly() const
void tell(const TQString &msg)
Tell the user something has happened.
void addContent(BasicElement *element, BasicElement *content)
Collect content for each token.
void addToken(BasicElement *element)
Collect all tokens that are to be added.
void addElement(BasicElement *element)
Collects all elements that are to be added.
void addCursor(FormulaCursor *cursor)
Collect cursor data that will be needed to do the stuff properly.
uint countChildren() const
virtual KCommand * buildCommand(Container *, Request *)
This is called by the container to get a command depending on the current cursor position (this is ho...