identifierelement.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 "kformuladefs.h"
23#include "textelement.h"
24#include "identifierelement.h"
25#include "operatorelement.h"
26#include "numberelement.h"
27#include "kformulacommand.h"
28#include "kformulacontainer.h"
29#include "kformuladocument.h"
30#include "formulaelement.h"
31#include "creationstrategy.h"
32
33KFORMULA_NAMESPACE_BEGIN
34
35IdentifierElement::IdentifierElement( BasicElement* parent ) : TokenElement( parent ) {}
36
37/*
38 * Token elements' content has to be of homogeneous type. Every token element
39 * must (TODO: check this) appear inside a non-token sequence, and thus, if
40 * the command asks for a different content, a new element has to be created in
41 * parent sequence.
42 */
43KCommand* IdentifierElement::buildCommand( Container* container, Request* request )
44{
45 FormulaCursor* cursor = container->activeCursor();
46 if ( cursor->isReadOnly() ) {
47 formula()->tell( i18n( "write protection" ) );
48 return 0;
49 }
50
51 if ( *request == req_addText ) {
52 KFCReplace* command = new KFCReplace( i18n("Add Text"), container );
53 TextRequest* tr = static_cast<TextRequest*>( request );
54 for ( uint i = 0; i < tr->text().length(); i++ ) {
55 TextElement* element = creationStrategy->createTextElement( tr->text()[i] );
56 command->addElement( element );
57 }
58 return command;
59 }
60
61 else if ( *request == req_addTextChar ) {
62 KFCReplace* command = new KFCReplace( i18n("Add Text"), container );
63 TextCharRequest* tr = static_cast<TextCharRequest*>( request );
64 TextElement* element = creationStrategy->createTextElement( tr->ch(), tr->isSymbol() );
65 command->addElement( element );
66 return command;
67 }
68
69 if ( countChildren() == 0 || cursor->getPos() == countChildren() ) {
70 // We are in the last position, so it's easy, call the parent to
71 // create a new child
72 SequenceElement* parent = static_cast<SequenceElement*>( getParent() );
73 if ( parent ) {
74 uint pos = parent->childPos( this );
75 cursor->setTo( parent, pos + 1);
76 return parent->buildCommand( container, request );
77 }
78 }
79 if ( cursor->getPos() == 0 ) {
80 SequenceElement* parent = static_cast<SequenceElement*>( getParent() );
81 if ( parent ) {
82 uint pos = parent->childPos( this );
83 cursor->setTo( parent, pos );
84 return parent->buildCommand( container, request );
85 }
86 }
87
88 // We are in the middle of a token, so:
89 // a) Cut from mark to the end
90 // b) Create a new token and add an element from key pressed
91 // c) Create a new token and add elements cut previously
92 // d) Move cursor to parent so that it command execution works fine
93
94 switch( *request ) {
95 case req_addOperator: {
96 KFCSplitToken* command = new KFCSplitToken( i18n("Add Operator"), container );
97 OperatorRequest* opr = static_cast<OperatorRequest*>( request );
98 OperatorElement* op = creationStrategy->createOperatorElement();
99 TextElement* text = creationStrategy->createTextElement( opr->ch() );
100 command->addCursor( cursor );
101 command->addToken( op );
102 command->addContent( op, text );
103 SequenceElement* parent = static_cast< SequenceElement* >( getParent() );
104 if ( parent ) {
105 cursor->setTo( parent, parent->childPos( this ) + 1 );
106 }
107 return command;
108 }
109 case req_addNumber: {
110 KFCSplitToken* command = new KFCSplitToken( i18n("Add Number"), container );
111 NumberRequest* nr = static_cast<NumberRequest*>( request );
112 NumberElement* num = creationStrategy->createNumberElement();
113 TextElement* text = creationStrategy->createTextElement( nr->ch() );
114 command->addCursor( cursor );
115 command->addToken( num );
116 command->addContent( num, text );
117 SequenceElement* parent = static_cast< SequenceElement* >( getParent() );
118 if ( parent ) {
119 cursor->setTo( parent, parent->childPos( this ) + 1 );
120 }
121 return command;
122 }
123 case req_addEmptyBox:
124 case req_addNameSequence:
125 case req_addBracket:
126 case req_addSpace:
127 case req_addFraction:
128 case req_addRoot:
129 case req_addSymbol:
130 case req_addOneByTwoMatrix:
131 case req_addMatrix: {
132 uint pos = static_cast<SequenceElement*>(getParent())->childPos( this );
133 cursor->setTo( getParent(), pos + 1);
134 return getParent()->buildCommand( container, request );
135 }
136 default:
137 return SequenceElement::buildCommand( container, request );
138 }
139 return 0;
140}
141
142void IdentifierElement::setStyleVariant( StyleAttributes& style )
143{
144 if ( customMathVariant() ) {
145 style.setCustomMathVariant ( true );
146 style.setCustomFontWeight( false );
147 style.setCustomFontStyle( false );
148 style.setCustomFont( false );
149 if ( customMathVariant() ) {
150 style.setCharFamily ( charFamily() );
151 style.setCharStyle( charStyle() );
152 }
153 else {
154 style.setCharFamily( style.charFamily() );
155 style.setCharStyle( style.charStyle() );
156 }
157 }
158 else {
159 style.setCustomMathVariant( false );
160 if ( customFontFamily() ) {
161 style.setCustomFont( true );
162 style.setFont( TQFont(fontFamily()) );
163 }
164
165 bool fontweight = false;
166 if ( customFontWeight() || style.customFontWeight() ) {
167 style.setCustomFontWeight( true );
168 if ( customFontWeight() ) {
169 fontweight = fontWeight();
170 }
171 else {
172 fontweight = style.customFontWeight();
173 }
174 style.setFontWeight( fontweight );
175 }
176 else {
177 style.setCustomFontWeight( false );
178 }
179
180 bool fontstyle;
181 if ( customFontStyle() ) {
182 fontstyle = fontStyle();
183 }
184 else if ( countChildren() == 1 ) {
185 fontstyle = true;
186 }
187 else {
188 fontstyle = false;
189 }
190
191 if ( fontweight && fontstyle ) {
192 style.setCharStyle( boldItalicChar );
193 }
194 else if ( fontweight && ! fontstyle ) {
195 style.setCharStyle( boldChar );
196 }
197 else if ( ! fontweight && fontstyle ) {
198 style.setCharStyle( italicChar );
199 }
200 else {
201 style.setCharStyle( normalChar );
202 }
203 }
204}
205
206KFORMULA_NAMESPACE_END
Basis of every formula element.
The document.
FormulaCursor * activeCursor()
The selection.
void setTo(BasicElement *element, uint cursor, int mark=-1)
Sets the cursor to a new position.
bool isReadOnly() const
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.
Removes the current selection and adds any new elements afterwards.
Add and remove arbitrary token elements and their contents.
void addCursor(FormulaCursor *cursor)
Collect cursor data that will be needed to do the stuff properly.
The element that contains a number of children.
virtual KCommand * buildCommand(Container *, Request *)
This is called by the container to get a command depending on the current cursor position (this is ho...
An element that represents one char.
Definition textelement.h:37