~ubuntu-branches/ubuntu/precise/koffice/precise

« back to all changes in this revision

Viewing changes to kformula/flake/MultiscriptElement.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-10-27 17:52:57 UTC
  • mfrom: (0.12.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20101027175257-s04zqqk5bs8ckm9o
Tags: 1:2.2.83-0ubuntu1
* Merge with Debian git remaining changes:
 - Add build-deps on librcps-dev, opengtl-dev, libqtgtl-dev, freetds-dev,
   create-resources, libspnav-dev
 - Remove needless build-dep on libwv2-dev
 - koffice-libs recommends create-resources
 - krita recommends pstoedit
 - Keep our patches
* New upstream release 2.3 beta 3
  - Remove debian/patches fixed by upstream
  - Update install files

Show diffs side-by-side

added added

removed removed

Lines of Context:
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>
4
 
 
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.
9
 
 
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.
14
 
 
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.
19
 
*/
20
 
 
21
 
#include "MultiscriptElement.h"
22
 
#include "AttributeManager.h"
23
 
#include <KoXmlWriter.h>
24
 
#include <KoXmlReader.h>
25
 
#include <QPainter>
26
 
#include "FormulaCursor.h"
27
 
#include "kdebug.h"
28
 
 
29
 
MultiscriptElement::MultiscriptElement( BasicElement* parent ) : FixedElement( parent )
30
 
{
31
 
    m_baseElement = new RowElement( this );
32
 
}
33
 
 
34
 
MultiscriptElement::~MultiscriptElement()
35
 
{
36
 
    delete m_baseElement;
37
 
    //Delete all of the scripts
38
 
    while (!m_preScripts.isEmpty())
39
 
        delete m_preScripts.takeFirst();
40
 
    while (!m_postScripts.isEmpty())
41
 
        delete m_postScripts.takeFirst();
42
 
}
43
 
 
44
 
void MultiscriptElement::paint( QPainter& painter, AttributeManager* am )
45
 
46
 
    Q_UNUSED(painter)
47
 
    Q_UNUSED(am)
48
 
    /*do nothing as this element has no visual representation*/
49
 
}
50
 
 
51
 
void MultiscriptElement::ensureEvenNumberElements() {
52
 
    if(m_postScripts.size() % 2 == 1) {
53
 
        //Odd number - at a None element on the end
54
 
        m_postScripts.append(NULL);
55
 
    }
56
 
    if(m_preScripts.size() % 2 == 1) {
57
 
        //Odd number - at a None element on the end
58
 
        m_preScripts.append(NULL);
59
 
    }
60
 
}
61
 
 
62
 
void MultiscriptElement::layout( const AttributeManager* am )
63
 
{
64
 
    // Get the minimum amount of shifting
65
 
    double subscriptshift   = am->doubleOf( "subscriptshift", this ); 
66
 
    double superscriptshift = am->doubleOf( "superscriptshift", this );
67
 
    //Add half a thin space between both sup and superscript, so there is a minimum
68
 
    //of a whole thin space between them.
69
 
    double halfthinspace   = am->layoutSpacing( this )/2.0;
70
 
 
71
 
    //First make sure that there are an even number of elements in both subscript and superscript
72
 
    ensureEvenNumberElements();
73
 
    
74
 
    // Go through all the superscripts (pre and post) and find the maximum heights;
75
 
    // BaseLine is the distance from the top to the baseline.
76
 
    // Depth is the distance from the baseline to the bottom
77
 
    double maxSuperScriptDepth     = 0.0;
78
 
    double maxSuperScriptBaseLine  = 0.0;
79
 
    double maxSubScriptDepth       = 0.0;
80
 
    double maxSubScriptBaseLine    = 0.0;
81
 
    bool isSuperscript = true;  //Toggle after each element time
82
 
    foreach( BasicElement *script, m_postScripts ) {
83
 
        isSuperscript = !isSuperscript;  //Toggle each time
84
 
        if(!script)
85
 
            continue;  // Null means no element - just a blank
86
 
        if(isSuperscript) {
87
 
            maxSuperScriptDepth = qMax( script->height() - script->baseLine(), maxSuperScriptDepth );
88
 
            maxSuperScriptBaseLine = qMax( script->baseLine(), maxSuperScriptBaseLine );
89
 
        } else {
90
 
            //Find out how much the subscript sticks below the baseline
91
 
            maxSubScriptDepth = qMax( script->height() - script->baseLine(), maxSubScriptDepth );
92
 
            maxSubScriptBaseLine = qMax( script->baseLine(), maxSubScriptBaseLine );
93
 
        }
94
 
    }
95
 
    foreach( BasicElement *script, m_preScripts ) {
96
 
        isSuperscript = !isSuperscript;  //Toggle each time
97
 
        if(!script)
98
 
            continue;  // Null means no element - just a blank
99
 
        if(isSuperscript) {
100
 
            maxSuperScriptDepth = qMax( script->height() - script->baseLine(), maxSuperScriptDepth );
101
 
            maxSuperScriptBaseLine = qMax( script->baseLine(), maxSuperScriptBaseLine );
102
 
        } else {
103
 
            //Find out how much the subscript sticks below the baseline
104
 
            maxSubScriptDepth = qMax( script->height() - script->baseLine(), maxSubScriptDepth );
105
 
            maxSubScriptBaseLine = qMax( script->baseLine(), maxSubScriptBaseLine );
106
 
        }
107
 
    }
108
 
    // The yOffsetBase is the amount the base element is moved down to make
109
 
    // room for the superscript
110
 
    double yOffsetBase = 0;
111
 
    if(maxSuperScriptDepth + maxSuperScriptBaseLine > 0) {
112
 
        yOffsetBase = maxSuperScriptDepth + maxSuperScriptBaseLine - m_baseElement->height()/2.0 + halfthinspace;
113
 
        yOffsetBase = qMax( yOffsetBase, superscriptshift );
114
 
    }
115
 
    // The yOffsetSub is the amount the subscript elements /baseline/ are moved down.
116
 
    double yOffsetSub = yOffsetBase + maxSubScriptBaseLine +
117
 
                qMax( m_baseElement->height()/2 + halfthinspace, 
118
 
                      m_baseElement->height() - maxSubScriptBaseLine
119
 
                          + subscriptshift );
120
 
    
121
 
    double xOffset = 0.0;  //We increment this as we go along, to keep track of where to place elements
122
 
    double lastSuperScriptWidth= 0.0;
123
 
    // Now we have all the information needed to start putting elements in place.
124
 
    // We start from the far left, and work to the far right.
125
 
    for( int i = m_preScripts.size()-1; i >= 0; i--) {
126
 
        //We start from the end, and work in.
127
 
        //m_preScripts[0] is subscript etc.  So even i is subscript, odd i is superscript
128
 
        if( i%2 == 0) {
129
 
            // i is even, so subscript
130
 
            if(!m_preScripts[i]) {
131
 
                xOffset += lastSuperScriptWidth;
132
 
            } else {
133
 
                // For a given vertical line, this is processed after the superscript
134
 
                double offset = qMax(0.0, (lastSuperScriptWidth - m_preScripts[i]->width())/2.0);
135
 
                m_preScripts[i]->setOrigin( QPointF( 
136
 
                            offset + xOffset, 
137
 
                            yOffsetSub - m_preScripts[i]->baseLine() ) );
138
 
                xOffset += qMax(lastSuperScriptWidth, m_preScripts[i]->width());
139
 
            }
140
 
            if(i!=0)  //No halfthinspace between the first element and the base element
141
 
                xOffset += halfthinspace;
142
 
        } else {
143
 
            // i is odd, so superscript
144
 
            // For a given vertical line, we process the superscript first, then 
145
 
            // the subscript.  We need to look at the subscript (i-1) as well
146
 
            // to find out how to align them
147
 
            if( !m_preScripts[i] )
148
 
                lastSuperScriptWidth = 0.0;
149
 
            else {
150
 
                lastSuperScriptWidth = m_preScripts[i]->width();
151
 
                double offset = 0.0;
152
 
                if(m_preScripts[i-1]) //the subscript directly below us. 
153
 
                    offset = qMax(0.0, (m_preScripts[i-1]->width() - lastSuperScriptWidth)/2.0);
154
 
                m_preScripts[i]->setOrigin( QPointF(
155
 
                            offset + xOffset,
156
 
                            maxSuperScriptBaseLine - m_preScripts[i]->baseLine()));
157
 
            }
158
 
        }
159
 
    }
160
 
 
161
 
    //We have placed all the prescripts now.  So now place the base element
162
 
    m_baseElement->setOrigin( QPointF( xOffset, yOffsetBase ) );
163
 
    xOffset += m_baseElement->width();
164
 
    double lastSubScriptWidth = 0.0;
165
 
    //Now we can draw the post scripts.  This code is very similar, but this time we will parse
166
 
    //the subscript before the superscript
167
 
    for( int i = 0; i < m_postScripts.size(); i++) {
168
 
        //We start from the start, and work out.
169
 
        //m_preScripts[0] is subscript etc.  So even i is subscript, odd i is superscript
170
 
        if( i%2 == 0) {
171
 
            // i is even, so subscript
172
 
            // For a given vertical line, we process the subscript first, then 
173
 
            // the superscript.  We need to look at the superscript (i+1) as well
174
 
            // to find out how to align them
175
 
 
176
 
            if(!m_postScripts[i]) {
177
 
                lastSubScriptWidth = 0.0;
178
 
            } else {
179
 
                lastSubScriptWidth = m_postScripts[i]->width();
180
 
                // For a given vertical line, this is processed after the superscript
181
 
                double offset = 0.0;
182
 
                if(m_postScripts.size() > i+1 && m_postScripts[i+1] != NULL) //the subscript directly below us. 
183
 
                    offset = qMax(0.0, (m_postScripts[i+1]->width() - lastSubScriptWidth)/2.0);
184
 
                m_postScripts[i]->setOrigin( QPointF( 
185
 
                            offset + xOffset,
186
 
                            yOffsetSub - m_postScripts[i]->baseLine() ) );
187
 
            }
188
 
        } else {
189
 
            // i is odd, so superscript
190
 
           if( !m_postScripts[i] )
191
 
                xOffset += lastSubScriptWidth;
192
 
           else {
193
 
                double offset = qMax(0.0, (lastSubScriptWidth - m_postScripts[i]->width())/2.0);
194
 
                m_postScripts[i]->setOrigin( QPointF(
195
 
                            offset + xOffset,
196
 
                            maxSuperScriptBaseLine - m_postScripts[i]->baseLine()));
197
 
                xOffset += qMax(lastSubScriptWidth, m_postScripts[i]->width());
198
 
            }
199
 
           if(i != m_postScripts.size()-1)
200
 
               xOffset += halfthinspace; //Don't add an unneeded space at the very end
201
 
        }
202
 
    }
203
 
 
204
 
 
205
 
    //Finally, set our boundingbox
206
 
    setWidth( xOffset );
207
 
    setHeight( yOffsetSub + maxSubScriptDepth );
208
 
    setBaseLine( yOffsetBase + m_baseElement->baseLine() );
209
 
}
210
 
 
211
 
bool MultiscriptElement::acceptCursor( const FormulaCursor& cursor )
212
 
{
213
 
    Q_UNUSED( cursor )
214
 
    return false;
215
 
}
216
 
 
217
 
const QList<BasicElement*> MultiscriptElement::childElements() const
218
 
{
219
 
    QList<BasicElement*> list;
220
 
    for (int i=m_preScripts.count()-2;i>=0; i-=2 ) {
221
 
        if(m_preScripts[i]) list << m_preScripts[i];
222
 
        if(m_preScripts[i+1]) list << m_preScripts[i+1];
223
 
    }
224
 
    list << m_baseElement;
225
 
    foreach( BasicElement* tmp, m_postScripts ) {
226
 
        if(tmp)
227
 
            list << tmp;
228
 
    }
229
 
 
230
 
 
231
 
    return list;
232
 
}
233
 
 
234
 
QString MultiscriptElement::attributesDefaultValue( const QString& attribute ) const
235
 
{
236
 
    Q_UNUSED( attribute )
237
 
    return QString();
238
 
}
239
 
 
240
 
ElementType MultiscriptElement::elementType() const
241
 
{
242
 
    return MultiScript;
243
 
}
244
 
 
245
 
bool MultiscriptElement::readMathMLContent( const KoXmlElement& parent )
246
 
{
247
 
    QString name = parent.tagName().toLower();
248
 
    BasicElement* tmpElement = 0;
249
 
    KoXmlElement tmp;
250
 
    bool prescript = false; //When we see a mprescripts tag, we enable this
251
 
    bool baseElement = true;
252
 
    forEachElement( tmp, parent ) { 
253
 
        if(tmp.tagName() == "none") {
254
 
            //In mathml, we read subscript, then superscript, etc.  To skip one,
255
 
            //you use "none"
256
 
            //To represent "none" we use a NULL pointer
257
 
            if(prescript)
258
 
                m_preScripts.append(NULL);
259
 
            else
260
 
                m_postScripts.append(NULL);
261
 
            continue;
262
 
        } else if(tmp.tagName() == "mprescripts") {
263
 
            prescript = true;  
264
 
            //In mathml, when we see this tag, all the elements after it are
265
 
            // for prescripts
266
 
            continue;
267
 
        }
268
 
        
269
 
        tmpElement = ElementFactory::createElement( tmp.tagName(), this );
270
 
        if( !tmpElement->readMathML( tmp ) )
271
 
            return false;
272
 
        if( baseElement ) {  //Very first element is the base
273
 
            delete m_baseElement; 
274
 
            m_baseElement = tmpElement;
275
 
            baseElement = true;
276
 
        }
277
 
        else if( prescript)
278
 
            m_preScripts.append( tmpElement );
279
 
        else 
280
 
            m_postScripts.append( tmpElement );
281
 
    }
282
 
    ensureEvenNumberElements();
283
 
    Q_ASSERT(m_baseElement);  //We should have at least a BasicElement for the base
284
 
    return true;
285
 
}
286
 
 
287
 
void MultiscriptElement::writeMathMLContent( KoXmlWriter* writer ) const
288
 
{
289
 
    m_baseElement->writeMathML( writer );        // Just save the children in
290
 
                                                 // the right order
291
 
    foreach( BasicElement* tmp, m_postScripts ) {
292
 
        if(tmp)
293
 
            tmp->writeMathML( writer );
294
 
        else {
295
 
            //We need to use a none element for missing elements in the super/sub scripts
296
 
            writer->startElement("none");
297
 
            writer->endElement();
298
 
        }
299
 
    }
300
 
    if( m_preScripts.isEmpty() ) return;
301
 
    writer->startElement("mprescripts");
302
 
    writer->endElement();
303
 
    foreach( BasicElement* tmp, m_preScripts ) {
304
 
        if(tmp)
305
 
            tmp->writeMathML( writer );
306
 
        else {
307
 
            //We need to use a none element for missing elements in the super/sub scripts
308
 
            writer->startElement("none");
309
 
            writer->endElement();
310
 
        }
311
 
    }
312
 
}
313
 
 
314
 
// int MultiscriptElement::length() const
315
 
// {
316
 
//     if (!m_postScripts.isEmpty() && m_postScripts.last()==0) {
317
 
//         //the last element is empty, so there are no cursor positions around it
318
 
//         return 2*(m_preScripts.count()+m_postScripts.count())-1;
319
 
//     } else {
320
 
//         return 2*(m_preScripts.count()+m_postScripts.count()+1)-1;
321
 
//     }
322
 
// }
323
 
 
324
 
bool MultiscriptElement::moveCursor ( FormulaCursor& newcursor, FormulaCursor& oldcursor )
325
 
{
326
 
    // grouppositions:  1 3   1 3
327
 
    //                  0 2 2 0 2
328
 
    //                  |     | |
329
 
    // pairs:           0 1   0 1
330
 
    //TODO: Fill this out
331
 
 
332
 
    int childposition=newcursor.position()/2;
333
 
    //this should be cached
334
 
    int prescriptCount=0;
335
 
    foreach (BasicElement* tmp, m_preScripts) {
336
 
        if (tmp) {
337
 
            prescriptCount++;
338
 
        }
339
 
    }
340
 
    if (childposition==prescriptCount) {
341
 
        //we are in BasePosition
342
 
        if (newcursor.direction()==MoveUp || newcursor.direction()==MoveDown) {
343
 
            return false;
344
 
        }
345
 
        if (m_postScripts.isEmpty() && m_preScripts.isEmpty()) {
346
 
            //this should not happen
347
 
            return moveSingleSituation(newcursor,oldcursor,
348
 
                                        childElements().indexOf(m_baseElement));
349
 
        }
350
 
        if (newcursor.direction()==MoveLeft) {
351
 
            if (!m_preScripts.isEmpty()) {
352
 
                // we search for the first non NULL element to the left
353
 
                int i;
354
 
                for (i=0; i<m_preScripts.count(); i++) {
355
 
                    if (m_preScripts[i]) {
356
 
                        break;
357
 
                    }
358
 
                }
359
 
                if ((i<m_preScripts.count()) && m_preScripts[i]) {
360
 
                    return moveHorSituation(newcursor,oldcursor,
361
 
                                             childElements().indexOf(m_preScripts[i]),
362
 
                                             childElements().indexOf(m_baseElement));
363
 
                }
364
 
            }
365
 
            return moveSingleSituation(newcursor,oldcursor,0);
366
 
        } else if (newcursor.direction()==MoveRight) {
367
 
            if (!m_postScripts.isEmpty()) {
368
 
                // we search for the first non NULL element to the left
369
 
                int i;
370
 
                for (i=0; i<m_postScripts.count(); i++) {
371
 
                    if (m_postScripts[i]) {
372
 
                        break;
373
 
                    }
374
 
                }
375
 
                if (m_postScripts[i]) {
376
 
                    return moveHorSituation(newcursor,oldcursor,
377
 
                                             childElements().indexOf(m_baseElement),
378
 
                                             childElements().indexOf(m_postScripts[i]));
379
 
                }
380
 
            }
381
 
            return moveSingleSituation(newcursor,oldcursor,
382
 
                                        childElements().indexOf(m_baseElement));
383
 
        }
384
 
    } else {
385
 
        int groupposition;
386
 
        bool prescript=true;
387
 
        if (childposition<prescriptCount) {
388
 
                //determine the position in the pre-/postscripts we are in
389
 
                groupposition=m_preScripts.indexOf(childElements()[childposition]);
390
 
        } else {
391
 
                groupposition=m_postScripts.indexOf(childElements()[childposition]);
392
 
                prescript=false;
393
 
        }
394
 
        int pair=groupposition/2;
395
 
        if (newcursor.direction()==MoveUp || newcursor.direction()==MoveDown) {
396
 
//             kDebug()<<groupposition<<" - "<<prescriptCount<< "-" <<pair;
397
 
            if (prescript) {
398
 
                if (m_preScripts[pair*2] && m_preScripts[pair*2+1]) {
399
 
                    return moveVertSituation(newcursor,oldcursor,
400
 
                                              childElements().indexOf(m_preScripts[pair*2+1]),
401
 
                                              childElements().indexOf(m_preScripts[pair*2]));
402
 
                } else {
403
 
                    return false;
404
 
                }
405
 
            } else {
406
 
                if (m_postScripts[pair*2] && m_postScripts[pair*2+1]) {
407
 
                    return moveVertSituation(newcursor,oldcursor,
408
 
                                              childElements().indexOf(m_postScripts[pair*2+1]),
409
 
                                              childElements().indexOf(m_postScripts[pair*2]));
410
 
                } else {
411
 
                    return false;
412
 
                }
413
 
            }
414
 
        } else if (newcursor.direction()==MoveLeft) {
415
 
            if (prescript) {
416
 
                //we are in the prescripts
417
 
                int i=groupposition+2;
418
 
                if (!((i<m_preScripts.count()) && m_preScripts[i])) {
419
 
                    for (i=groupposition+1; i<m_preScripts.count(); i++) {
420
 
                        if (m_preScripts[i]) {
421
 
                            break;
422
 
                        }
423
 
                    }
424
 
                }
425
 
                if ((i<m_preScripts.count()) && m_preScripts[i]) {
426
 
                    return moveHorSituation(newcursor,oldcursor,
427
 
                                             childElements().indexOf(m_preScripts[i]),
428
 
                                             childElements().indexOf(m_preScripts[groupposition]));
429
 
                } else {
430
 
                    return moveSingleSituation(newcursor,oldcursor,
431
 
                                                childElements().indexOf(m_preScripts[groupposition]));
432
 
                }
433
 
            } else {
434
 
                //we are in the postscripts
435
 
                int i=groupposition-1;
436
 
                if (!(i>=0) && m_postScripts[i]) {
437
 
                    for (i=groupposition-2; i>=0; i--) {
438
 
                        if (m_postScripts[i]) {
439
 
                            break;
440
 
                        }
441
 
                    }
442
 
                }
443
 
                if ((i>=0) && m_postScripts[i]) {
444
 
                    return moveHorSituation(newcursor,oldcursor,
445
 
                                             childElements().indexOf(m_postScripts[i]),
446
 
                                             childElements().indexOf(m_postScripts[groupposition]));
447
 
                } else {
448
 
                    return moveHorSituation(newcursor,oldcursor,
449
 
                                             childElements().indexOf(m_baseElement),
450
 
                                             childElements().indexOf(elementNext(newcursor.position())));
451
 
                }
452
 
            }
453
 
        } else if (newcursor.direction()==MoveRight) {
454
 
            if (prescript) {
455
 
                //we are in the prescripts
456
 
                int i=groupposition-2;
457
 
                if (!((i>=0) && m_preScripts[i])) {
458
 
                    for (i=groupposition-1; i>=0; i--) {
459
 
                        if (m_preScripts[i]) {
460
 
                            break;
461
 
                        }
462
 
                    }
463
 
                }
464
 
                if ((i>=0) && m_preScripts[i]) {
465
 
//                    kDebug()<<"Going from "<< groupposition <<" to " <<i;
466
 
                    return moveHorSituation(newcursor,oldcursor,
467
 
                                             childElements().indexOf(m_preScripts[groupposition]),
468
 
                                             childElements().indexOf(m_preScripts[i]));
469
 
                } else {
470
 
                    return moveHorSituation(newcursor,oldcursor,
471
 
                                             childElements().indexOf(elementNext(newcursor.position())),
472
 
                                             childElements().indexOf(m_baseElement));
473
 
                }
474
 
            } else {
475
 
                //we are in the postscripts
476
 
                int i=groupposition+2;
477
 
                if (!((i<m_postScripts.count()) && m_postScripts[i])) {
478
 
                    for (i=groupposition+1; i<m_postScripts.count(); i++) {
479
 
                        if (m_postScripts[i]) {
480
 
                            break;
481
 
                        }
482
 
                    }
483
 
                }
484
 
                if ((i<m_postScripts.count()) && m_postScripts[i]) {
485
 
                    return moveHorSituation(newcursor,oldcursor,
486
 
                                             childElements().indexOf(m_postScripts[groupposition]),
487
 
                                             childElements().indexOf(m_postScripts[i]));
488
 
                } else {
489
 
                    return moveSingleSituation(newcursor,oldcursor,
490
 
                                                childElements().indexOf(m_preScripts[groupposition]));
491
 
                }
492
 
            }
493
 
        }
494
 
    }
495
 
    return false;
496
 
}
497
 
 
498
 
bool MultiscriptElement::setCursorTo ( FormulaCursor& cursor, QPointF point )
499
 
{
500
 
    if (cursor.isSelecting()) {
501
 
        return false;
502
 
    }
503
 
    foreach (BasicElement* tmp, childElements()) {
504
 
        if (tmp->boundingRect().contains(point)) {
505
 
            return tmp->setCursorTo(cursor,point-tmp->origin());
506
 
        }
507
 
    }
508
 
    return m_baseElement->setCursorTo(cursor,point-m_baseElement->origin());
509
 
}