kword

KWVariable.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
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 "KWVariable.h"
21
22#include "KWTextFrameSet.h"
23#include "KWTextDocument.h"
24#include "KWMailMergeDataBase.h"
25#include "KWDocument.h"
26#include "KWCommand.h"
27#include "KWViewMode.h"
28#include "KWPageManager.h"
29
30#include <KoVariable.h>
31#include <KoXmlWriter.h>
32#include <KoXmlNS.h>
33#include <KoDom.h>
34
35#include <tdelocale.h>
36#include <kdebug.h>
37
38KWVariableSettings::KWVariableSettings() : KoVariableSettings()
39{
40 m_footNoteCounter.setSuffix( TQString() );
41 m_endNoteCounter.setSuffix( TQString() );
42 // By default endnotes are numbered in lowercase roman numbers, in other WPs.
43 m_endNoteCounter.setStyle( KoParagCounter::STYLE_ROM_NUM_L );
44}
45
46void KWVariableSettings::changeFootNoteCounter( KoParagCounter _c )
47{
48 m_footNoteCounter = _c;
49}
50
51void KWVariableSettings::changeEndNoteCounter( KoParagCounter _c )
52{
53 m_endNoteCounter = _c;
54}
55
56void KWVariableSettings::saveNoteConfiguration( KoXmlWriter& writer ) const
57{
58 writer.startElement( "text:notes-configuration" );
59 writer.addAttribute( "text:note-class", "footnote" );
60 // let the counter save: num-prefix num-suffix num-format start-value
61 m_footNoteCounter.saveOasisListLevel( writer, false );
62 writer.addAttribute( "text:footnotes-position", "page" ); // tell OO what we do
63 writer.addAttribute( "text:start-numbering-at", "document" ); // tell OO what we do
64 writer.endElement();
65 writer.startElement( "text:notes-configuration" );
66 writer.addAttribute( "text:note-class", "endnote" );
67 // let the counter save: num-prefix num-suffix num-format start-value
68 m_endNoteCounter.saveOasisListLevel( writer, false );
69 writer.addAttribute( "text:start-numbering-at", "document" ); // tell OO what we do
70 writer.endElement();
71}
72
73void KWVariableSettings::loadNoteConfiguration( const TQDomElement& parent )
74{
75 TQDomElement e;
76 forEachElement( e, parent )
77 {
78 if ( e.localName() == "notes-configuration" && e.namespaceURI() == KoXmlNS::text )
79 {
80 const TQString noteClass = e.attributeNS( KoXmlNS::text, "note-class", TQString() );
81 if ( noteClass == "footnote" ) {
82 m_footNoteCounter.loadOasisListStyle( e, TQDomElement(), TQDomElement(), -1, true, false, 1, false );
83 m_footNoteCounter.setNumbering( KoParagCounter::NUM_FOOTNOTE );
84 m_footNoteCounter.setRestartCounter( false );
85 }
86 else if ( noteClass == "endnote" ) {
87 m_endNoteCounter.loadOasisListStyle( e, TQDomElement(), TQDomElement(), -1, true, false, 1, false );
88 m_endNoteCounter.setNumbering( KoParagCounter::NUM_FOOTNOTE );
89 m_endNoteCounter.setRestartCounter( false );
90 }
91 }
92 }
93}
94
95void KWVariableSettings::save( TQDomElement &parentElem )
96{
97 KoVariableSettings::save( parentElem );
98 TQDomDocument doc = parentElem.ownerDocument();
99 TQDomElement footNoteSettingElem = doc.createElement( "FOOTNOTESETTING" );
100 parentElem.appendChild( footNoteSettingElem );
101 m_footNoteCounter.save( footNoteSettingElem );
102 TQDomElement endNoteSettingElem = doc.createElement( "ENDNOTESETTING" );
103 parentElem.appendChild( endNoteSettingElem );
104 m_endNoteCounter.save( endNoteSettingElem );
105}
106
107void KWVariableSettings::load( TQDomElement &elem )
108{
109 KoVariableSettings::load( elem );
110 TQDomElement footNoteSettings = elem.namedItem( "FOOTNOTESETTING" ).toElement();
111 if ( !footNoteSettings.isNull() )
112 m_footNoteCounter.load( footNoteSettings );
113 TQDomElement endNoteSettings = elem.namedItem( "ENDNOTESETTING" ).toElement();
114 if ( !endNoteSettings.isNull() )
115 m_endNoteCounter.load( endNoteSettings );
116}
117
118KWVariableCollection::KWVariableCollection(KWVariableSettings *_setting, KoVariableFormatCollection* coll)
119 : KoVariableCollection(_setting, coll)
120{
121}
122
123KoVariable* KWVariableCollection::loadOasisField( KoTextDocument* textdoc, const TQDomElement& tag, KoOasisContext& context )
124{
125 const TQString localName( tag.localName() );
126 const bool isTextNS = tag.namespaceURI() == KoXmlNS::text;
127 if ( isTextNS )
128 {
129 //kdDebug()<<" localName :"<<localName<<endl;
130 if ( localName == "note" )
131 {
132 TQString key = "STRING";
133 int type = VT_FOOTNOTE;
134 return loadOasisFieldCreateVariable( textdoc, tag, context, key, type );
135 }
136 else if ( localName == "table-count" ||
137 localName == "object-count" ||
138 localName == "picture-count" ||
139 localName == "paragraph-count" ||
140 localName == "word-count" ||
141 localName == "character-count" ||
142 localName == "sentence-count" ||
143 localName == "line-count" ||
144 localName == "frame-count" ||
145 localName == "non-whitespace-character-count" ||
146 localName == "syllable-count")
147 {
148 TQString key = "NUMBER";
149 int type = VT_STATISTIC;
150 return loadOasisFieldCreateVariable( textdoc, tag, context, key, type );
151 }
152 else
153 return KoVariableCollection::loadOasisField( textdoc, tag, context );
154 }
155 else
156 return KoVariableCollection::loadOasisField( textdoc, tag, context );
157}
158
159KoVariable *KWVariableCollection::createVariable( int type, short int subtype, KoVariableFormatCollection * coll, KoVariableFormat *varFormat,KoTextDocument *textdoc, KoDocument * doc, int _correct,bool _forceDefaultFormat, bool loadFootNote )
160{
161 KWDocument *m_doc = static_cast<KWDocument *>(doc);
162 KoVariable * var = 0L;
163 switch(type) {
164 case VT_PGNUM:
165 if ( !varFormat )
166 varFormat = (subtype == KoPageVariable::VST_CURRENT_SECTION) ? coll->format("STRING") : coll->format("NUMBER");
167 var = new KWPgNumVariable( textdoc, subtype, varFormat, this, m_doc );
168 break;
169 case VT_MAILMERGE:
170 var = new KWMailMergeVariable( textdoc, TQString(), coll->format("STRING"), this, m_doc );
171 break;
172 case VT_FOOTNOTE:
173 if ( !loadFootNote )
174 return 0L;
175 if ( !varFormat )
176 varFormat = coll->format("STRING");
177 var = new KWFootNoteVariable( textdoc, varFormat, this, m_doc );
178 break;
179 case VT_STATISTIC:
180 if ( !varFormat )
181 varFormat = coll->format("NUMBER");
182 var = new KWStatisticVariable( textdoc, subtype, varFormat, this, m_doc );
183 break;
184 default:
185 return KoVariableCollection::createVariable( type, subtype, coll, varFormat, textdoc, doc, _correct, _forceDefaultFormat );
186 }
187 return var;
188}
189
190/******************************************************************/
191/* Class: KWPgNumVariable */
192/******************************************************************/
193KWPgNumVariable::KWPgNumVariable( KoTextDocument *textdoc, int subtype, KoVariableFormat *varFormat ,KoVariableCollection *_varColl, KWDocument *doc )
194 : KoPageVariable( textdoc, subtype, varFormat ,_varColl ), m_doc(doc)
195{
196}
197
198void KWPgNumVariable::recalc()
199{
200 if ( !m_doc->layoutViewMode()->hasPages() ) // ModeText
201 {
202 //necessary to resize it in this mode because in this mode
203 //we don't call KWTextFrameSet::drawFrame()
204 resize();
205 return;
206 }
207
208 if ( m_subtype == VST_PGNUM_TOTAL )
209 {
210 m_varValue = TQVariant(m_doc->pageCount()+m_varColl->variableSetting()->startingPageNumber()-1);
211 resize();
212 }
213 // The other cases are handled by the more dynamic code in KWTextFrameSet::drawFrame()
214 // But we don't want to keep a width of -1 ...
215 if ( width == -1 )
216 width = 0;
217}
218
219TQString KWPgNumVariable::text(bool realValue)
220{
221 if (m_varColl->variableSetting()->displayFieldCode()&& !realValue)
222 return fieldCode();
223 // #### ??? What?
224 else if ( m_subtype != VST_CURRENT_SECTION && !m_doc->layoutViewMode()->hasPages() && !realValue)
225 return fieldCode();
226 else
227 return m_varFormat->convert( m_varValue );
228}
229
230/******************************************************************/
231/* Class: KWMailMergeVariable */
232/******************************************************************/
233KWMailMergeVariable::KWMailMergeVariable( KoTextDocument *textdoc, const TQString &name, KoVariableFormat *varFormat,KoVariableCollection *_varColl, KWDocument *doc )
234 : KoMailMergeVariable( textdoc, name, varFormat,_varColl ), m_doc(doc)
235{
236}
237
238TQString KWMailMergeVariable::value() const
239{
240 return m_doc->mailMergeDataBase()->getValue( m_varValue.toString() );
241}
242
243TQString KWMailMergeVariable::text(bool realValue)
244{
245 if (m_varColl->variableSetting()->displayFieldCode()&& !realValue)
246 return fieldCode();
247 // ## should use a format maybe
248 TQString v = value();
249 if ( m_doc->mailMergeDataBase()->isSampleRecord() )
250 return "<" + v + ">";
251 return v;
252}
253
254void KWMailMergeVariable::recalc()
255{
256 resize();
257}
258
260
261KWFootNoteVariable::KWFootNoteVariable( KoTextDocument *textdoc, KoVariableFormat *varFormat, KoVariableCollection *varColl, KWDocument *doc )
262 : KoVariable( textdoc, varFormat, varColl ),
263 m_doc(doc),
264 m_frameset( 0L ),
265 m_numberingType( Auto ),
266 m_num( -1 ),
267 m_numDisplay( -1 )
268{
269 m_varValue = TQVariant( TQString() );
270}
271
272void KWFootNoteVariable::setNumberingType( Numbering _type )
273{
274 m_numberingType = _type;
275 //delete m_varFormat;
276 setVariableFormat(m_doc->variableFormatCollection()->format("STRING"));
277}
278
279void KWFootNoteVariable::loadOasis( const TQDomElement& footNoteTag, KoOasisContext& context )
280{
281 /*<text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body>
282 <text:p text:style-name="Footnote"></text:p></text:note-body></text:note> */
283 const TQString id = footNoteTag.attributeNS( KoXmlNS::text, "id", TQString() );
284
285 if ( footNoteTag.hasAttributeNS( KoXmlNS::text, "note-class" ) )
286 {
287 const TQString str = footNoteTag.attributeNS( KoXmlNS::text, "note-class", TQString() );
288 if ( str == "footnote" )
289 m_noteType = FootNote;
290 else if ( str == "endnote" )
291 m_noteType = EndNote;
292 else {
293 kdWarning()<<" Unknown footnote type: '" << str << "'" << endl;
294 m_noteType = FootNote;
295 }
296 }
297
298 TQDomElement element;
299 TQDomElement bodyElement;
300 forEachElement( element, footNoteTag )
301 {
302 if ( element.namespaceURI() != KoXmlNS::text )
303 continue;
304
305 const TQString localName = element.localName();
306 if( localName == "note-citation" )
307 {
308 if ( element.hasAttributeNS( KoXmlNS::text, "label" ) )
309 m_numberingType = Manual;
310 else
311 m_numberingType = Auto;
312 if ( m_numberingType == Auto )
313 {
314 //kdDebug()<<" automatic \n";
315 m_numDisplay = element.text().toInt();
316 formatedNote();
317 }
318 else
319 {
320 // kdDebug()<<" manual \n";
321 m_varValue = TQVariant( element.text() );
322 }
323 } else if ( localName == "note-body" ) {
324 bodyElement = element;
325 }
326 }
327 Q_ASSERT( !bodyElement.isNull() );
328
329 Q_ASSERT( !m_frameset );
330 m_frameset = new KWFootNoteFrameSet( m_doc, id );
331 m_frameset->setFrameSetInfo( KWFrameSet::FI_FOOTNOTE );
332
333 m_frameset->setFootNoteVariable( this );
334 m_frameset->createInitialFrame( 0 );
335 m_doc->addFrameSet( m_frameset );
336
337 // Load the body of the footnote
338 m_frameset->loadOasisContent( bodyElement, context );
339}
340
341void KWFootNoteVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& context ) const
342{
343 if(! m_frameset) return; // see bug #126007
344
345 //<text:note text:id="ftn0" text:note-class="footnote"><text:note-citation>1</text:note-citation><text:note-body><text:p text:style-name="Footnote"/></text:note-body></text:note>
346 //<text:note text:id="ftn1" text:note-class="endnote"><text:note-citation>i</text:note-citation><text:note-body><text:p text:style-name="Endnote"/></text:note-body></text:note>
347 //<text:note text:id="ftn2" text:note-class="footnote"><text:note-citation text:label="vv">vv</text:note-citation><text:note-body><text:p text:style-name="Footnote"/></text:note-body></text:note>
348 writer.startElement( "text:note" );
349 writer.addAttribute( "text:id",m_frameset->name() );
350 writer.addAttribute( "text:note-class", m_noteType == FootNote ? "footnote" : "endnote" );
351
352 writer.startElement( "text:note-citation" );
353 if ( m_numberingType == Auto )
354 writer.addTextNode( TQString( "%1" ).arg( m_numDisplay ) );
355 else
356 {
357 writer.addAttribute( "text:label", m_varValue.toString() );
358 writer.addTextNode(m_varValue.toString() );
359 }
360 writer.endElement();
361
362 writer.startElement( "text:note-body" );
363 //save text from end/footnote
364 m_frameset->saveOasisContent( writer, context );
365 writer.endElement();
366
367 writer.endElement();
368}
369
370void KWFootNoteVariable::saveVariable( TQDomElement &parentElem )
371{
372 TQDomElement footnoteElem = parentElem.ownerDocument().createElement( "FOOTNOTE" );
373 parentElem.appendChild( footnoteElem );
374 //footnoteElem.setAttribute( "subtype", 0 );
375 if ( m_numberingType == Auto )
376 footnoteElem.setAttribute( "value", m_numDisplay );
377 else
378 footnoteElem.setAttribute( "value", m_varValue.toString() );
379 footnoteElem.setAttribute( "notetype", m_noteType == FootNote ? "footnote" : "endnote" );
380 footnoteElem.setAttribute( "numberingtype", m_numberingType == Auto ? "auto" : "manual" );
381 Q_ASSERT( m_frameset );
382 if( m_frameset )
383 footnoteElem.setAttribute( "frameset", m_frameset->name() );
384}
385
386void KWFootNoteVariable::load( TQDomElement &elem )
387{
388 KoVariable::load( elem );
389 TQDomElement footnoteElem = elem.namedItem( "FOOTNOTE" ).toElement();
390 if (!footnoteElem.isNull())
391 {
392 //m_subtype = footnoteElem.attribute("subtype").toInt();
393 TQString str = footnoteElem.attribute("notetype").lower();
394 if ( str == "footnote" )
395 m_noteType = FootNote;
396 else if ( str == "endnote" )
397 m_noteType = EndNote;
398 else
399 kdWarning() << "Unknown footnote type: '" << str << "'" << endl;
400
401 str = footnoteElem.attribute("numberingtype").lower();
402 if ( str == "auto" )
403 m_numberingType = Auto;
404 else if ( str == "manual")
405 m_numberingType = Manual;
406 else
407 kdWarning() << "Unknown footnote numbering: '" << str << "'" << endl;
408
409 if ( m_numberingType == Auto )
410 {
411 m_numDisplay = footnoteElem.attribute("value").toInt();
412 formatedNote();
413 }
414 else
415 m_varValue = TQVariant(footnoteElem.attribute("value"));
416
417 str = footnoteElem.attribute("frameset");
418 m_doc->addFootNoteRequest( str, this );
419 }
420}
421
422void KWFootNoteVariable::formatedNote()
423{
424 if ( m_numberingType == Auto )
425 {
426 m_varValue = TQVariant(applyStyle());
427 }
428}
429
430TQString KWFootNoteVariable::applyStyle()
431{
432 KWVariableSettings* settings = static_cast<KWVariableSettings*>(m_varColl->variableSetting());
433 KoParagCounter tmpCounter = (m_noteType == FootNote) ? settings->footNoteCounter() : settings->endNoteCounter();
434
435 TQString tmp;
436 int val = m_numDisplay + tmpCounter.startNumber()-1;
437 Q_ASSERT( val >= 0 );
438 if ( val < 0 ) // let's not go into makeRomanNumber with a negative number :}
439 return i18n("ERROR");
440 switch ( tmpCounter.style() )
441 {
442 case KoParagCounter::STYLE_NUM:
443 tmp.setNum( val );
444 break;
445 case KoParagCounter::STYLE_ALPHAB_L:
446 tmp=KoParagCounter::makeAlphaLowerNumber( val );
447 break;
448 case KoParagCounter::STYLE_ALPHAB_U:
449 tmp=KoParagCounter::makeAlphaUpperNumber( val );
450 break;
451 case KoParagCounter::STYLE_ROM_NUM_L:
452 tmp = KoParagCounter::makeRomanNumber( val ).lower();
453 break;
454 case KoParagCounter::STYLE_ROM_NUM_U:
455 tmp = KoParagCounter::makeRomanNumber( val ).upper();
456 break;
457 case KoParagCounter::STYLE_CUSTOMBULLET:
458 //todo change font
459 tmp = tmpCounter.customBulletCharacter();
460 break;
461 default:
462 tmp.setNum( val );
463 break;
464 }
465
466 tmp.prepend( tmpCounter.prefix() );
467 tmp.append( tmpCounter.suffix() );
468 return tmp;
469}
470
471TQString KWFootNoteVariable::text(bool realValue)
472{
473 if (m_varColl->variableSetting()->displayFieldCode()&& !realValue)
474 return fieldCode();
475 return m_varFormat->convert( m_varValue );
476}
477
478void KWFootNoteVariable::setNumDisplay( int val )
479{
480 m_numDisplay = val;
481 if ( val != -1 ) // -1 is used to 'invalidate so that renumberFootNotes recalcs'
482 formatedNote();
483}
484
485TQString KWFootNoteVariable::fieldCode()
486{
487 return (noteType()==FootNote) ?i18n("Footnote"):i18n("Endnote");
488}
489
490void KWFootNoteVariable::drawCustomItem( TQPainter* p, int x, int y, int wpix, int hpix, int ascentpix, int /*cx*/, int /*cy*/, int /*cw*/, int /*ch*/, const TQColorGroup& cg, bool selected, int _offset, bool drawingShadow )
491{
492 KoTextFormat * fmt = format();
493 KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
494
495 // Force drawing as "superscript" - hmm, the formatting will use too big font metrics though.
496 TQFont font( fmt->screenFont( zh ) );
497 int pointSize = ( ( font.pointSize() * 2 ) / 3 );
498 font.setPointSize( pointSize );
499
500 int offset = _offset;
501 if ( offset == 0 )
502 {
503 int h = zh->layoutUnitToPixelY( /*_y HACK,*/ height );
504 offset = -( h - TQFontMetrics(font).height() );
505 }
506
507 TQColor textColor( fmt->color() );
508 drawCustomItemHelper( p, x, y, wpix, hpix, ascentpix, cg, selected, offset, fmt, font, textColor, drawingShadow );
509}
510
511void KWFootNoteVariable::finalize()
512{
513 Q_ASSERT( m_frameset );
514 if (!m_frameset )
515 return;
516 Q_ASSERT( !m_frameset->isDeleted() );
517 if ( m_frameset->isDeleted() )
518 return;
519
520 //kdDebug(32001) << "KWFootNoteVariable::finalize" << endl;
521
522 int pageNum = this->pageNum();
523 if ( pageNum == -1 )
524 return;
525
526 KWFrame* footNoteFrame = m_frameset->frame( 0 );
527 int framePage = footNoteFrame->pageNumber();
528 if ( framePage != pageNum )
529 {
530 //kdDebug(32001) << "Footnote var '" << text() << "' at page " << pageNum << ", footnote frame at page " << framePage << " -> abortFormatting() and recalcFrames()" << endl;
531 KWTextFrameSet * fs = static_cast<KWTextDocument *>(textDocument())->textFrameSet();
532 fs->textObject()->abortFormatting();
533
534 // abortFormatting is a bool in kotextobject. So we need to return there before
535 // starting text layout again.
536 m_doc->delayedRecalcFrames( TQMIN( pageNum, framePage ) );
537 m_doc->delayedRepaintAllViews();
538 }
539}
540
541void KWFootNoteVariable::resize()
542{
543 if ( m_deleted )
544 return;
545 KoTextFormat *fmt = format();
546 TQFont font( fmt->refFont() ); // LU font
547 if ( fmt->vAlign() == KoTextFormat::AlignNormal ) // if it's still normal...
548 {
549 int pointSize = ( ( font.pointSize() * 2 ) / 3 ); // ...force superscript
550 font.setPointSize( pointSize );
551 }
552 TQFontMetrics fm( font );
553 TQString txt = text();
554 width = 0;
555 for ( int i = 0 ; i < (int)txt.length() ; ++i )
556 width += fm.charWidth( txt, i ); // size at 100%
557 // zoom to LU
558 width = tqRound( KoTextZoomHandler::ptToLayoutUnitPt( width ) );
559 height = fmt->height();
560 m_ascent = fmt->ascent();
561 //kdDebug() << "KWFootNoteVariable::resize text=" << txt << " width=" << width << " height=" << height << endl;
562}
563
564void KWFootNoteVariable::setDeleted( bool del )
565{
566 kdDebug() << "KWFootNoteVariable::setDeleted " << del << endl;
567 if ( del )
568 {
569 Q_ASSERT( m_frameset );
570 if ( m_frameset ) {
571 m_frameset->deleteAllFrames(); // Important, because we don't want to save it!
572 m_frameset->setVisible( false );
573 }
574 }
575 else
576 {
577 Q_ASSERT( m_frameset );
578 if ( m_frameset ) {
579 kdDebug() << "Making frameset " << m_frameset << " visible" << endl;
580 m_frameset->setVisible( true );
581 if ( m_frameset->isDeleted() )
582 m_frameset->createInitialFrame( 0 ); // Page number shouldn't matter (see recalcFrames below).
583 Q_ASSERT( m_frameset->isVisible() );
584 }
585 }
586
587 // hmm, maybe compress all the stuff below and do only once
588 // (e.g. when deleting multiple footnotes)?
589 // (but we can't really delay it with a sst, the formatMore after undo/redo
590 // needs this to be done already, I think). Bah.
591
592 // Re-number footnote variables
593 KWTextFrameSet * textfs = static_cast<KWTextDocument *>(textDocument())->textFrameSet();
594 textfs->renumberFootNotes();
595
596 m_doc->recalcFrames();
597
598 if (!del)
599 m_frameset->layout(); // format its text, so that it resizes the frame
600 KoVariable::setDeleted( del );
601 // Does this compress? Probably not.
602 m_doc->delayedRepaintAllViews();
603}
604
605int KWFootNoteVariable::pageNum() const
606{
607 int page = m_doc->pageManager()->pageNumber(varY());
608 Q_ASSERT( page <= m_doc->lastPage() );
609 return page;
610}
611
612double KWFootNoteVariable::varY() const
613{
614 // Find out the position of the footnote variable in document coordinates.
615 int paragy = paragraph()->rect().y();
616 KWTextFrameSet * fs = static_cast<KWTextDocument *>(textDocument())->textFrameSet();
617 if ( !fs->hasFramesInPageArray() ) // we need it for internalToDocument
618 {
619 kdDebug(32001) << "KWFootNoteVariable::varY too early, no updateFrames yet" << endl;
620 return 0; // this happens on loading - frame layout is done before text layout
621 }
622 // What we need is "has never been formatted". Not "has just been invalidated"...
623 //if ( !paragraph()->isValid() )
624 //{
625 // kdDebug(32001) << "KWFootNoteVariable::varY called but paragraph " << paragraph()->paragId() << " not valid" << endl;
626 // return 0;
627 //}
628 KoPoint dPoint;
629 //kdDebug(32001) << "KWFootNoteVariable::pageNum position of variable (LU): " << TQPoint( x(), paragy + y() + height ) << endl;
630 KWFrame* containingFrame = fs->internalToDocument( TQPoint( x(), paragy + y() + height ), dPoint );
631 if ( containingFrame )
632 {
633 // Ok, the (bottom of the) footnote variable is at dPoint.
634 double varY = dPoint.y();
635 //kdDebug(32001) << " found containingFrame " << containingFrame << " page:" << containingFrame->pageNumber() << " varY=" << varY << endl;
636 //int pageNum = containingFrame->pageNumber(); // and at page pageNum
637 return varY;
638 } else
639 {
640 // This can happen if the page hasn't been created yet
641 //kdDebug(32001) << "KWFootNoteVariable::pageNum internalToDocument returned 0L for " << x << ", " << y+paragy << endl;
642 return 0;
643 }
644}
645
646
647KWStatisticVariable::KWStatisticVariable( KoTextDocument *textdoc, int subtype, KoVariableFormat *varFormat,KoVariableCollection *_varColl, KWDocument *doc )
648 : KoStatisticVariable( textdoc, subtype, varFormat, _varColl ),
649 m_doc(doc)
650{
651}
652
653void KWStatisticVariable::recalc()
654{
655 int nb = 0;
656 ulong charsWithSpace = 0L;
657 ulong charsWithoutSpace = 0L;
658 ulong words = 0L;
659 ulong sentences = 0L;
660 ulong lines = 0L;
661 ulong syllables = 0L;
662 bool frameInfo = ( m_subtype == VST_STATISTIC_NB_WORD ||
663 m_subtype == VST_STATISTIC_NB_SENTENCE ||
664 m_subtype == VST_STATISTIC_NB_LINES ||
665 m_subtype == VST_STATISTIC_NB_CHARACTERE);
666 TQPtrListIterator<KWFrameSet> framesetIt( m_doc->framesetsIterator() );
667 //TODO change int to ulong
668 for ( framesetIt.toFirst(); framesetIt.current(); ++framesetIt )
669 {
670 KWFrameSet *frameSet = framesetIt.current();
671 if ( frameSet->isVisible() )
672 {
673 if ( m_subtype == VST_STATISTIC_NB_FRAME )
674 {
675 ++nb;
676 }
677 else if( m_subtype == VST_STATISTIC_NB_PICTURE && frameSet->type() == FT_PICTURE )
678 {
679 ++nb;
680 }
681 else if( m_subtype == VST_STATISTIC_NB_TABLE && frameSet->type() == FT_TABLE )
682 {
683 ++nb;
684 }
685 else if( m_subtype == VST_STATISTIC_NB_EMBEDDED && frameSet->type() == FT_PART )
686 {
687 ++nb;
688 }
689 if ( frameInfo
690 && (frameSet->frameSetInfo() == KWFrameSet::FI_FOOTNOTE || frameSet->frameSetInfo() == KWFrameSet::FI_BODY)
691 && frameSet->isVisible() )
692 {
693 frameSet->statistics( 0L, charsWithSpace, charsWithoutSpace,
694 words, sentences, syllables, lines, false );
695 }
696 }
697 if ( frameInfo )
698 {
699 if( m_subtype == VST_STATISTIC_NB_WORD )
700 {
701 nb = words;
702 }
703 else if( m_subtype == VST_STATISTIC_NB_SENTENCE )
704 {
705 nb = sentences;
706 }
707 else if( m_subtype == VST_STATISTIC_NB_LINES )
708 {
709 nb = lines;
710 }
711 else if ( m_subtype == VST_STATISTIC_NB_CHARACTERE )
712 {
713 nb = charsWithSpace;
714 }
715 else if ( m_subtype == VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE )
716 {
717 nb = charsWithoutSpace;
718 }
719 else if ( m_subtype == VST_STATISTIC_NB_SYLLABLE )
720 {
721 nb = syllables;
722 }
723 else
724 nb = 0;
725 }
726 }
727 m_varValue = TQVariant(nb);
728 resize();
729 if ( width == -1 )
730 width = 0;
731}
732
733TQString KWStatisticVariable::text(bool realValue)
734{
735 if ( m_varColl->variableSetting()->displayFieldCode() && !realValue )
736 return fieldCode();
737 else
738 return m_varFormat->convert( m_varValue );
739}
The variable showing the footnote number in superscript, in the text.
Definition KWVariable.h:106
Class: KWFrameSet Base type, a frameset holds content as well as frames to show that content.
Definition KWFrameSet.h:62
virtual FrameSetType type() const
The type of frameset.
Definition KWFrameSet.h:76
Info frameSetInfo() const
Returns the type of TextFrameSet this is.
Definition KWFrameSet.h:95
bool isVisible(KWViewMode *viewMode=0L) const
Returns true if the frameset is visible.
bool hasFramesInPageArray() const
Allows to detect that updateFrames() hasn't been called yet (e.g.
Definition KWFrameSet.h:311
This class represents a single frame.
Definition KWFrame.h:68
int pageNumber() const
The page on which this frame is.
Definition KWFrame.cpp:116
Mail Merge variable.
Definition KWVariable.h:91
"current page number" and "number of pages" variables
Definition KWVariable.h:75
This is our KoTextDocument reimplementation, to create KWTextParag instead of KoTextParags,...
Class: KWTextFrameSet Contains text (KoTextObject) and frames to display that text.
KoTextObject * textObject() const
Return the contained text object.
KWFrame * internalToDocument(const KoPoint &relPoint, KoPoint &dPoint) const
Convert the in the internal qtextdoc coordinates (in layout units) into a point in the document coord...
void renumberFootNotes(bool repaint=true)
(Assuming this==main frameset), recalc the foot note numbers