lib

KoVariable.cpp
1/* This file is part of the KDE project
2 Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
3 Copyright (C) 2005 David Faure <faure@kde.org>
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 "KoVariable.h"
22#include "KoVariable.moc"
23#include "KoTextZoomHandler.h"
24#include "TimeFormatWidget.h"
25#include "DateFormatWidget.h"
26#include "KoTextCommand.h"
27#include "KoTextObject.h"
28#include "KoTextParag.h"
29#include "KoOasisContext.h"
30#include <KoOasisSettings.h>
31
32#include <KoDocumentInfo.h>
33#include <KoOasisStyles.h>
34#include <KoXmlWriter.h>
35#include <KoDocument.h>
36#include <KoXmlNS.h>
37#include <KoDom.h>
38
39#include <tdelocale.h>
40#include <kdebug.h>
41#include <tdeglobal.h>
42#include <kdialogbase.h>
43#include <tdeconfig.h>
44#include <tdeversion.h>
45#include <tdeinstance.h>
46#include <kcalendarsystem.h>
47#include <tdeaboutdata.h>
48
49#include <tqstringlist.h>
50#include <tqcombobox.h>
51#include <tqvaluelist.h>
52#include <tqdom.h>
53#include <tqradiobutton.h>
54
55#include "IsoDuration.h"
56
57class KoVariableSettings::KoVariableSettingPrivate
58{
59public:
60 KoVariableSettingPrivate()
61 {
62 m_lastPrintingDate.setTime_t(0); // Default is 1970-01-01 midnight locale time
63 }
64 TQDateTime m_lastPrintingDate;
65 TQDateTime m_creationDate;
66 TQDateTime m_modificationDate;
67};
68
69
70KoVariableSettings::KoVariableSettings()
71{
72 d = new KoVariableSettingPrivate;
73 m_startingPageNumber = 1;
74 m_displayLink = true;
75 m_displayComment = true;
76 m_underlineLink = true;
77 m_displayFieldCode = false;
78}
79
80KoVariableSettings::~KoVariableSettings()
81{
82 delete d;
83 d = 0;
84}
85
86TQDateTime KoVariableSettings::lastPrintingDate() const
87{
88 return d->m_lastPrintingDate;
89}
90
91void KoVariableSettings::setLastPrintingDate( const TQDateTime & _date)
92{
93 d->m_lastPrintingDate = _date;
94}
95
96TQDateTime KoVariableSettings::creationDate() const
97{
98 return d->m_creationDate;
99}
100
101void KoVariableSettings::setCreationDate( const TQDateTime & _date )
102{
103 d->m_creationDate = _date;
104}
105
106TQDateTime KoVariableSettings::modificationDate() const
107{
108 return d->m_modificationDate;
109}
110
111void KoVariableSettings::setModificationDate( const TQDateTime & _date)
112{
113 d->m_modificationDate = _date;
114}
115
116void KoVariableSettings::saveOasis( KoXmlWriter &settingsWriter ) const
117{
118 settingsWriter.startElement("config:config-item-set");
119 settingsWriter.addAttribute("config:name", "configuration-variable-settings");
120 settingsWriter.addConfigItem("displaylink", m_displayLink );
121 settingsWriter.addConfigItem( "underlinelink", m_underlineLink);
122 settingsWriter.addConfigItem( "displaycomment", m_displayComment);
123 settingsWriter.addConfigItem( "displayfieldcode", m_displayFieldCode);
124 // m_startingPageNumber isn't saved to OASIS. Applications must use either
125 // style:page-number in the first parag of a page (see KoTextParag), or
126 // style:first-page-number in style:page-layout, for spreadsheets etc.
127 if ( d->m_lastPrintingDate.isValid())
128 settingsWriter.addConfigItem("lastPrintingDate", d->m_lastPrintingDate.toString(TQt::ISODate));
129
130 if ( d->m_creationDate.isValid())
131 settingsWriter.addConfigItem("creationDate", d->m_creationDate.toString(TQt::ISODate));
132
133 if ( d->m_modificationDate.isValid())
134 settingsWriter.addConfigItem("modificationDate", d->m_modificationDate.toString(TQt::ISODate));
135
136 settingsWriter.endElement(); // config:config-item-set
137}
138
139void KoVariableSettings::loadOasis(const KoOasisSettings&settingsDoc)
140{
141 KoOasisSettings::Items configurationSettings = settingsDoc.itemSet( "configuration-variable-settings" );
142 if ( !configurationSettings.isNull() )
143 {
144 m_displayLink = configurationSettings.parseConfigItemBool( "displaylink", true );
145 m_underlineLink = configurationSettings.parseConfigItemBool( "underlinelink", true );
146 m_displayComment = configurationSettings.parseConfigItemBool( "displaycomment", true );
147 m_displayFieldCode = configurationSettings.parseConfigItemBool( "displayfieldcode", false );
148
149 TQString str = configurationSettings.parseConfigItemString( "lastPrintingDate" );
150 if ( !str.isEmpty() )
151 d->m_lastPrintingDate = TQDateTime::fromString( str, TQt::ISODate );
152 else
153 d->m_lastPrintingDate.setTime_t(0); // 1970-01-01 00:00:00.000 locale time
154
155 str = configurationSettings.parseConfigItemString( "creationDate" );
156 if ( !str.isEmpty() ) {
157 d->m_creationDate = TQDateTime::fromString( str, TQt::ISODate );
158 }
159
160 str = configurationSettings.parseConfigItemString( "modificationDate" );
161 if ( !str.isEmpty() )
162 d->m_modificationDate = TQDateTime::fromString( str, TQt::ISODate );
163
164 // m_startingPageNumber isn't loaded from OASIS here. KWTextParag::loadOasis does it.
165 }
166}
167
168void KoVariableSettings::save( TQDomElement &parentElem )
169{
170 TQDomElement elem = parentElem.ownerDocument().createElement( "VARIABLESETTINGS" );
171 parentElem.appendChild( elem );
172 if(m_startingPageNumber!=1)
173 {
174 elem.setAttribute( "startingPageNumber", m_startingPageNumber );
175 }
176 elem.setAttribute("displaylink",(int)m_displayLink);
177 elem.setAttribute("underlinelink",(int)m_underlineLink);
178 elem.setAttribute("displaycomment",(int)m_displayComment);
179 elem.setAttribute("displayfieldcode", (int)m_displayFieldCode);
180
181 if ( d->m_lastPrintingDate.isValid())
182 elem.setAttribute("lastPrintingDate", d->m_lastPrintingDate.toString(TQt::ISODate));
183
184 if ( d->m_creationDate.isValid())
185 elem.setAttribute("creationDate", d->m_creationDate.toString(TQt::ISODate));
186
187 if ( d->m_modificationDate.isValid())
188 elem.setAttribute("modificationDate", d->m_modificationDate.toString(TQt::ISODate));
189}
190
191void KoVariableSettings::load( TQDomElement &elem )
192{
193 TQDomElement e = elem.namedItem( "VARIABLESETTINGS" ).toElement();
194 if (!e.isNull())
195 {
196 if(e.hasAttribute("startingPageNumber"))
197 m_startingPageNumber = e.attribute("startingPageNumber").toInt();
198 if(e.hasAttribute("displaylink"))
199 m_displayLink=(bool)e.attribute("displaylink").toInt();
200 if(e.hasAttribute("underlinelink"))
201 m_underlineLink=(bool)e.attribute("underlinelink").toInt();
202 if(e.hasAttribute("displaycomment"))
203 m_displayComment=(bool)e.attribute("displaycomment").toInt();
204 if (e.hasAttribute("displayfieldcode"))
205 m_displayFieldCode=(bool)e.attribute("displayfieldcode").toInt();
206
207 if (e.hasAttribute("lastPrintingDate"))
208 d->m_lastPrintingDate = TQDateTime::fromString( e.attribute( "lastPrintingDate" ), TQt::ISODate );
209 else
210 d->m_lastPrintingDate.setTime_t(0); // 1970-01-01 00:00:00.000 locale time
211
212 if (e.hasAttribute("creationDate")) {
213 d->m_creationDate = TQDateTime::fromString( e.attribute( "creationDate" ), TQt::ISODate );
214 }
215
216 if (e.hasAttribute("modificationDate"))
217 d->m_modificationDate = TQDateTime::fromString( e.attribute( "modificationDate" ), TQt::ISODate );
218 }
219}
220
221KoVariableDateFormat::KoVariableDateFormat() : KoVariableFormat()
222{
223}
224
225TQString KoVariableDateFormat::convert( const TQVariant& data ) const
226{
227 if ( data.type() != TQVariant::Date && data.type() != TQVariant::DateTime )
228 {
229 kdWarning(32500)<<" Error in KoVariableDateFormat::convert. Value is a "
230 << data.typeName() << "(" << data.type() << ")" << endl;
231 // dateTime will be invalid, then set to 1970-01-01
232 }
233 TQDateTime dateTime ( data.toDateTime() );
234 if ( !dateTime.isValid() )
235 return i18n("No date set"); // e.g. old KWord documents
236
237 if (m_strFormat.lower() == "locale" || m_strFormat.isEmpty())
238 return TDEGlobal::locale()->formatDate( dateTime.date(), false );
239 else if ( m_strFormat.lower() == "localeshort" )
240 return TDEGlobal::locale()->formatDate( dateTime.date(), true );
241 else if ( m_strFormat.lower() == "localedatetime" )
242 return TDEGlobal::locale()->formatDateTime( dateTime, false );
243 else if ( m_strFormat.lower() == "localedatetimeshort" )
244 return TDEGlobal::locale()->formatDateTime( dateTime, true );
245
246 TQString tmp ( dateTime.toString(m_strFormat) );
247 const int month = dateTime.date().month();
248 tmp.replace("PPPP", TDEGlobal::locale()->calendar()->monthNamePossessive(month, false)); //long possessive month name
249 tmp.replace("PPP", TDEGlobal::locale()->calendar()->monthNamePossessive(month, true)); //short possessive month name
250 return tmp;
251}
252
254{
255 return getKey( m_strFormat );
256}
257
258TQCString KoVariableDateFormat::getKey( const TQString& props ) const
259{
260 return TQCString("DATE") + props.utf8();
261}
262
263void KoVariableDateFormat::load( const TQCString &key )
264{
265 TQCString params( key.mid( 4 ) ); // skip "DATE"
266 if ( !params.isEmpty() )
267 {
268 if (params[0] == '1' || params[0] == '0') // old m_bShort crap
269 params = params.mid(1); // skip it
270 m_strFormat = TQString::fromUtf8( params );
271 }
272}
273
274// Used by KoVariableFormatCollection::popupActionList(), to apply all formats
275// to the current data, in the popup menu.
276TQStringList KoVariableDateFormat::staticFormatPropsList()
277{
278 TQStringList listDateFormat;
279 listDateFormat<<"locale";
280 listDateFormat<<"localeshort";
281 listDateFormat<<"localedatetime";
282 listDateFormat<<"localedatetimeshort";
283 listDateFormat<<"dd/MM/yy";
284 listDateFormat<<"dd/MM/yyyy";
285 listDateFormat<<"MMM dd,yy";
286 listDateFormat<<"MMM dd,yyyy";
287 listDateFormat<<"dd.MMM.yyyy";
288 listDateFormat<<"MMMM dd, yyyy";
289 listDateFormat<<"ddd, MMM dd,yy";
290 listDateFormat<<"dddd, MMM dd,yy";
291 listDateFormat<<"MM-dd";
292 listDateFormat<<"yyyy-MM-dd";
293 listDateFormat<<"dd/yy";
294 listDateFormat<<"MMMM";
295 listDateFormat<<"yyyy-MM-dd hh:mm";
296 listDateFormat<<"dd.MMM.yyyy hh:mm";
297 listDateFormat<<"MMM dd,yyyy h:mm AP";
298 listDateFormat<<"yyyy-MM-ddThh:mm:ss"; // ISO 8601
299 return listDateFormat;
300}
301
302// Used by dateformatwidget_impl
303// TODO: shouldn't it apply the formats to the value, like the popupmenu does?
304TQStringList KoVariableDateFormat::staticTranslatedFormatPropsList()
305{
306 TQStringList listDateFormat;
307 listDateFormat<<i18n("Locale date format");
308 listDateFormat<<i18n("Short locale date format");
309 listDateFormat<<i18n("Locale date & time format");
310 listDateFormat<<i18n("Short locale date & time format");
311 listDateFormat<<"dd/MM/yy";
312 listDateFormat<<"dd/MM/yyyy";
313 listDateFormat<<"MMM dd,yy";
314 listDateFormat<<"MMM dd,yyyy";
315 listDateFormat<<"dd.MMM.yyyy";
316 listDateFormat<<"MMMM dd, yyyy";
317 listDateFormat<<"ddd, MMM dd,yy";
318 listDateFormat<<"dddd, MMM dd,yy";
319 listDateFormat<<"MM-dd";
320 listDateFormat<<"yyyy-MM-dd";
321 listDateFormat<<"dd/yy";
322 listDateFormat<<"MMMM";
323 listDateFormat<<"yyyy-MM-dd hh:mm";
324 listDateFormat<<"dd.MMM.yyyy hh:mm";
325 listDateFormat<<"MMM dd,yyyy h:mm AP";
326 listDateFormat<<"yyyy-MM-ddThh:mm:ss"; // ISO 8601
327 return listDateFormat;
328}
329
331
332KoVariableTimeFormat::KoVariableTimeFormat() : KoVariableFormat()
333{
334}
335
336void KoVariableTimeFormat::load( const TQCString &key )
337{
338 TQCString params( key.mid( 4 ) );
339 if ( !params.isEmpty() )
340 m_strFormat = TQString::fromUtf8(params);
341}
342
343TQString KoVariableTimeFormat::convert( const TQVariant & time ) const
344{
345 if ( time.type() != TQVariant::Time )
346 {
347 kdDebug(32500)<<" Error in KoVariableTimeFormat::convert. Value is a "
348 << time.typeName() << "(" << time.type() << ")" << endl;
349 return TQString();
350 }
351
352 if( m_strFormat.lower() == "locale" || m_strFormat.isEmpty() )
353 return TDEGlobal::locale()->formatTime( time.toTime() );
354 return time.toTime().toString(m_strFormat);
355}
356
358{
359 return getKey( m_strFormat );
360}
361
362TQCString KoVariableTimeFormat::getKey( const TQString& props ) const
363{
364 return TQCString("TIME") + props.utf8();
365}
366
367// Used by KoVariableFormatCollection::popupActionList(), to apply all formats
368// to the current data, in the popup menu.
369TQStringList KoVariableTimeFormat::staticFormatPropsList()
370{
371 TQStringList listTimeFormat;
372 listTimeFormat<<"locale";
373 listTimeFormat<<"hh:mm";
374 listTimeFormat<<"hh:mm:ss";
375 listTimeFormat<<"hh:mm AP";
376 listTimeFormat<<"hh:mm:ss AP";
377 listTimeFormat<<"mm:ss.zzz";
378 return listTimeFormat;
379}
380
381// Used by timeformatwidget_impl
382TQStringList KoVariableTimeFormat::staticTranslatedFormatPropsList()
383{
384 TQStringList listTimeFormat;
385 listTimeFormat<<i18n("Locale format");
386 listTimeFormat<<"hh:mm";
387 listTimeFormat<<"hh:mm:ss";
388 listTimeFormat<<"hh:mm AP";
389 listTimeFormat<<"hh:mm:ss AP";
390 listTimeFormat<<"mm:ss.zzz";
391 return listTimeFormat;
392}
393
395
396TQString KoVariableStringFormat::convert( const TQVariant & string ) const
397{
398 if ( string.type() != TQVariant::String )
399 {
400 kdDebug(32500)<<" Error in KoVariableStringFormat::convert. Value is a " << string.typeName() << endl;
401 return TQString();
402 }
403
404 return string.toString();
405}
406
408{
409 return getKey( TQString() );
410 // TODO prefix & suffix
411}
412
413TQCString KoVariableStringFormat::getKey( const TQString& props ) const
414{
415 return TQCString("STRING") + props.utf8();
416}
417
419
420TQString KoVariableNumberFormat::convert( const TQVariant &value ) const
421{
422 if ( value.type() != TQVariant::Int )
423 {
424 kdDebug(32500)<<" Error in KoVariableNumberFormat::convert. Value is a " << value.typeName() << endl;
425 return TQString();
426 }
427
428 return TQString::number( value.toInt() );
429}
430
431TQCString KoVariableNumberFormat::key() const
432{
433 return getKey(TQString());
434}
435
436TQCString KoVariableNumberFormat::getKey( const TQString& props ) const
437{
438 return TQCString("NUMB") + props.utf8();
439}
440
442
443KoVariableFormatCollection::KoVariableFormatCollection()
444{
445 m_dict.setAutoDelete( true );
446}
447
449{
450 KoVariableFormat *f = m_dict[ key.data() ];
451 if (f)
452 return f;
453 else
454 return createFormat( key );
455}
456
457KoVariableFormat * KoVariableFormatCollection::createFormat( const TQCString &key )
458{
459 kdDebug(32500) << "KoVariableFormatCollection: creating format for key=" << key << endl;
461 // The first 4 chars identify the class
462 TQCString type = key.left(4);
463 if ( type == "DATE" )
465 else if ( type == "TIME" )
467 else if ( type == "NUMB" ) // this type of programming makes me numb ;)
468 format = new KoVariableNumberFormat();
469 else if ( type == "STRI" )
471
472 if ( format )
473 {
474 format->load( key );
475 m_dict.insert( format->key() /* not 'key', it could be incomplete */, format );
476 }
477 return format;
478}
479
480/******************************************************************/
481/* Class: KoVariableCollection */
482/******************************************************************/
483KoVariableCollection::KoVariableCollection(KoVariableSettings *_settings, KoVariableFormatCollection *formatCollection)
484{
485 m_variableSettings = _settings;
486 m_varSelected = 0L;
487 m_formatCollection = formatCollection;
488}
489
490KoVariableCollection::~KoVariableCollection()
491{
492 delete m_variableSettings;
493}
494
495void KoVariableCollection::clear()
496{
497 variables.clear();
498 varValues.clear();
499 m_varSelected = 0;
500}
501
502void KoVariableCollection::registerVariable( KoVariable *var )
503{
504 if ( !var )
505 return;
506 variables.append( var );
507}
508
509void KoVariableCollection::unregisterVariable( KoVariable *var )
510{
511 variables.take( variables.findRef( var ) );
512}
513
514TQValueList<KoVariable *> KoVariableCollection::recalcVariables(int type)
515{
516 TQValueList<KoVariable *> modifiedVariables;
517 TQPtrListIterator<KoVariable> it( variables );
518 for ( ; it.current() ; ++it )
519 {
520 KoVariable* variable = it.current();
521 if ( variable->isDeleted() )
522 continue;
523 if ( variable->type() == type || type == VT_ALL )
524 {
525 TQVariant oldValue = variable->varValue();
526 variable->recalc();
527 if(variable->height == 0)
528 variable->resize();
529 if ( variable->varValue() != oldValue )
530 modifiedVariables.append( variable );
531 KoTextParag * parag = variable->paragraph();
532 if ( parag )
533 {
534 //kdDebug(32500) << "KoDoc::recalcVariables -> invalidating parag " << parag->paragId() << endl;
535 parag->invalidate( 0 );
536 parag->setChanged( true );
537 }
538 }
539 }
540#if 0
541 // TODO pass list of textdocuments as argument
542 // Or even better, call emitRepaintChanged on all modified textobjects
543 if( !modifiedVariables.isEmpty() )
544 emit repaintVariable();
545#endif
546 return modifiedVariables;
547}
548
549
550void KoVariableCollection::setVariableValue( const TQString &name, const TQString &value )
551{
552 varValues[ name ] = value;
553}
554
555TQString KoVariableCollection::getVariableValue( const TQString &name ) const
556{
557 if ( !varValues.contains( name ) )
558 return i18n( "No value" );
559 return varValues[ name ];
560}
561
562bool KoVariableCollection::customVariableExist(const TQString &varname) const
563{
564 return varValues.contains( varname );
565}
566
567void KoVariableCollection::setVariableSelected(KoVariable * var)
568{
569 m_varSelected=var;
570}
571
572// TODO change to TQValueList<TDEAction *>, but only once plugActionList takes that
573TQPtrList<TDEAction> KoVariableCollection::popupActionList() const
574{
575 TQPtrList<TDEAction> listAction;
576 // Insert list of actions that change the subtype
577 const TQStringList subTypeList = m_varSelected->subTypeList();
578 kdDebug() << k_funcinfo << "current subtype=" << m_varSelected->subType() << endl;
579 TQStringList::ConstIterator it = subTypeList.begin();
580 for ( int i = 0; it != subTypeList.end() ; ++it, ++i )
581 {
582 if ( !(*it).isEmpty() ) // in case of removed subtypes or placeholders
583 {
584 // We store the subtype number as the action name
585 TQCString name; name.setNum(i);
586 TDEToggleAction * act = new TDEToggleAction( *it, TDEShortcut(), 0, name );
587 connect( act, TQ_SIGNAL(activated()), this, TQ_SLOT(slotChangeSubType()) );
588 if ( i == m_varSelected->subType() )
589 act->setChecked( true );
590 //m_subTextMap.insert( act, i );
591 listAction.append( act );
592 }
593 }
594 // Insert list of actions that change the format properties
595 KoVariableFormat* format = m_varSelected->variableFormat();
596 TQString currentFormat = format->formatProperties();
597
598 const TQStringList list = format->formatPropsList();
599 it = list.begin();
600 for ( int i = 0; it != list.end() ; ++it, ++i )
601 {
602 if( i == 0 ) // first item, and list not empty
603 listAction.append( new TDEActionSeparator() );
604
605 if ( !(*it).isEmpty() ) // in case of removed subtypes or placeholders
606 {
607 format->setFormatProperties( *it ); // temporary change
608 TQString text = format->convert( m_varSelected->varValue() );
609 // We store the raw format as the action name
610 TDEToggleAction * act = new TDEToggleAction(text, TDEShortcut(), 0, (*it).utf8());
611 connect( act, TQ_SIGNAL(activated()), this, TQ_SLOT(slotChangeFormat()) );
612 if ( (*it) == currentFormat )
613 act->setChecked( true );
614 listAction.append( act );
615 }
616 }
617
618 // Restore current format
619 format->setFormatProperties( currentFormat );
620 return listAction;
621}
622
623void KoVariableCollection::slotChangeSubType()
624{
625 TDEAction * act = (TDEAction *)(sender());
626 int menuNumber = TQCString(act->name()).toInt();
627 int newSubType = m_varSelected->variableSubType(menuNumber);
628 kdDebug(32500) << "slotChangeSubType: menuNumber=" << menuNumber << " newSubType=" << newSubType << endl;
629 if ( m_varSelected->subType() != newSubType )
630 {
632 m_varSelected->subType(), newSubType, m_varSelected );
633 cmd->execute();
634 m_varSelected->textDocument()->emitNewCommand(cmd);
635 }
636}
637
638void KoVariableCollection::slotChangeFormat()
639{
640 TDEAction * act = (TDEAction *)(sender());
641 TQString newFormat = TQString::fromUtf8(act->name());
642 TQString oldFormat = m_varSelected->variableFormat()->formatProperties();
643 if (oldFormat != newFormat )
644 {
646 oldFormat, newFormat, m_varSelected );
647 cmd->execute();
648 m_varSelected->textDocument()->emitNewCommand(cmd);
649 }
650}
651
652KoVariable * KoVariableCollection::createVariable( int type, short int subtype, KoVariableFormatCollection * coll, KoVariableFormat *varFormat,KoTextDocument *textdoc, KoDocument * doc, int _correct, bool _forceDefaultFormat, bool /*loadFootNote*/ )
653{
654 Q_ASSERT( coll == m_formatCollection ); // why do we need a parameter ?!?
655 TQCString string;
656 TQStringList stringList;
657 if ( varFormat == 0L )
658 {
659 // Get the default format for this variable (this method is only called in the interactive case, not when loading)
660 switch ( type ) {
661 case VT_DATE:
662 case VT_DATE_VAR_KWORD10: // compatibility with kword 1.0
663 {
664 if ( _forceDefaultFormat )
665 varFormat = coll->format( KoDateVariable::defaultFormat() );
666 else
667 {
668 TQCString result = KoDateVariable::formatStr(_correct);
669 if ( result.isNull() )//we cancel insert variable
670 return 0L;
671 varFormat = coll->format( result );
672 }
673 break;
674 }
675 case VT_TIME:
676 case VT_TIME_VAR_KWORD10: // compatibility with kword 1.0
677 {
678 if ( _forceDefaultFormat )
679 varFormat = coll->format( KoTimeVariable::defaultFormat() );
680 else
681 {
682 TQCString result = KoTimeVariable::formatStr(_correct);
683 if ( result.isNull() )//we cancel insert variable
684 return 0L;
685 varFormat = coll->format( result );
686 }
687 break;
688 }
689 case VT_PGNUM:
690 varFormat = coll->format( "NUMBER" );
691 break;
692 case VT_FIELD:
693 case VT_CUSTOM:
694 case VT_MAILMERGE:
695 case VT_LINK:
696 case VT_NOTE:
697 varFormat = coll->format( "STRING" );
698 break;
699 case VT_FOOTNOTE: // this is a KWord-specific variable
700 kdError() << "Footnote type not handled in KoVariableCollection: VT_FOOTNOTE" << endl;
701 return 0L;
702 case VT_STATISTIC:
703 kdError() << " Statistic type not handled in KoVariableCollection: VT_STATISTIC" << endl;
704 return 0L;
705 }
706 }
707 Q_ASSERT( varFormat );
708 if ( varFormat == 0L ) // still 0 ? Impossible!
709 return 0L ;
710
711 kdDebug(32500) << "Creating variable. Format=" << varFormat->key() << " type=" << type << endl;
712 KoVariable * var = 0L;
713 switch ( type ) {
714 case VT_DATE:
715 case VT_DATE_VAR_KWORD10: // compatibility with kword 1.0
716 var = new KoDateVariable( textdoc, subtype, varFormat, this, _correct );
717 break;
718 case VT_TIME:
719 case VT_TIME_VAR_KWORD10: // compatibility with kword 1.0
720 var = new KoTimeVariable( textdoc, subtype, varFormat, this, _correct );
721 break;
722 case VT_PGNUM:
723 kdError() << "VT_PGNUM must be handled by the application's reimplementation of KoVariableCollection::createVariable" << endl;
724 //var = new KoPageVariable( textdoc, subtype, varFormat, this );
725 break;
726 case VT_FIELD:
727 var = new KoFieldVariable( textdoc, subtype, varFormat,this,doc );
728 break;
729 case VT_CUSTOM:
730 var = new KoCustomVariable( textdoc, TQString(), varFormat, this);
731 break;
732 case VT_MAILMERGE:
733 var = new KoMailMergeVariable( textdoc, TQString(), varFormat ,this);
734 break;
735 case VT_LINK:
736 var = new KoLinkVariable( textdoc,TQString(), TQString(), varFormat ,this);
737 break;
738 case VT_NOTE:
739 var = new KoNoteVariable( textdoc, TQString(), varFormat ,this);
740 break;
741 }
742 Q_ASSERT( var );
743 return var;
744}
745
746
747KoVariable* KoVariableCollection::loadOasisField( KoTextDocument* textdoc, const TQDomElement& tag, KoOasisContext& context )
748{
749 const TQString localName( tag.localName() );
750 const bool isTextNS = tag.namespaceURI() == KoXmlNS::text;
751 TQString key;
752 int type = -1;
753 if ( isTextNS )
754 {
755 if ( localName.endsWith( "date" ) || localName.endsWith( "time" ) )
756 {
757 TQString dataStyleName = tag.attributeNS( KoXmlNS::style, "data-style-name", TQString() );
758 TQString dateFormat = "locale";
759 const KoOasisStyles::DataFormatsMap& map = context.oasisStyles().dataFormats();
760 KoOasisStyles::DataFormatsMap::const_iterator it = map.find( dataStyleName );
761 if ( it != map.end() )
762 dateFormat = (*it).formatStr;
763
764 // Only text:time is a pure time (the data behind is only h/m/s)
765 // ### FIXME: not true, a time can have a date too (reason: for MS Word (already from long ago) time and date are the same thing. But for OO the correction is not in the same unit for time and date.)
766 // Whereas print-time/creation-time etc. are actually related to a date/time value.
767 if ( localName == "time" )
768 {
769 type = VT_TIME;
770 key = "TIME" + dateFormat;
771 }
772 else
773 {
774 type = VT_DATE;
775 key = "DATE" + dateFormat;
776 }
777 }
778 else if (localName == "page-number" || localName == "page-count" )
779 {
780 type = VT_PGNUM;
781 key = "NUMBER";
782 }
783 else if (localName == "chapter")
784 {
785 type = VT_PGNUM;
786 key = "STRING";
787 }
788 else if (localName == "file-name")
789 {
790 type = VT_FIELD;
791 key = "STRING";
792 }
793 else if (localName == "author-name"
794 || localName == "author-initials"
795 || localName == "subject"
796 || localName == "title"
797 || localName == "description"
798 || localName == "keywords")
799 {
800 type = VT_FIELD;
801 key = "STRING";
802 }
803 else if ( localName.startsWith( "sender-" )
804 && localName != "sender-firstname" // not supported
805 && localName != "sender-lastname" // not supported
806 && localName != "sender-initials" // not supported
807 )
808 {
809 type = VT_FIELD;
810 key = "STRING";
811 }
812 else if ( localName == "variable-set"
813 || localName == "user-defined"
814 || localName == "user-field-get" )
815 {
816 key = "STRING";
817 type = VT_CUSTOM;
818 }
819 else
820 return 0L;
821 }
822 else if ( tag.namespaceURI() == KoXmlNS::office && localName == "annotation" )
823 {
824 type = VT_NOTE;
825 key = "NUMBER";
826 }
827 else
828 {
829 // Not an error. It's simply not a variable tag (the caller doesn't check for that)
830 return 0;
831 }
832// TODO localName == "page-variable-get", "initial-creator" and many more
833// TODO VT_MAILMERGE
834
835 return loadOasisFieldCreateVariable( textdoc, tag, context, key, type );
836}
837
838KoVariable* KoVariableCollection::loadOasisFieldCreateVariable( KoTextDocument* textdoc, const TQDomElement& tag, KoOasisContext& context, const TQString &key, int type )
839{
840 KoVariableFormat * varFormat = key.isEmpty() ? 0 : m_formatCollection->format( key.latin1() );
841 // If varFormat is 0 (no key specified), the default format will be used.
842
843 KoVariable* var = createVariable( type, -1, m_formatCollection, varFormat, textdoc, context.koDocument(), 0 /*correct*/, true );
844 var->loadOasis( tag, context );
845 return var;
846}
847
848/******************************************************************/
849/* Class: KoVariable */
850/******************************************************************/
851KoVariable::KoVariable( KoTextDocument *textdoc, KoVariableFormat *varFormat, KoVariableCollection *_varColl)
852 : KoTextCustomItem( textdoc )
853{
854 //d = new Private;
855 m_varColl=_varColl;
856 m_varFormat = varFormat;
857 m_varColl->registerVariable( this );
858 m_ascent = 0;
859}
860
861KoVariable::~KoVariable()
862{
863 //kdDebug(32500) << "KoVariable::~KoVariable " << this << endl;
864 m_varColl->unregisterVariable( this );
865 //delete d;
866}
867
869{
870 return TQStringList();
871}
872
874{
875 if ( m_deleted )
876 return;
877 KoTextFormat *fmt = format();
878 TQFontMetrics fm = fmt->refFontMetrics();
879 TQString txt = text();
880
881 width = 0;
882 // size at 100%
883 for ( int i = 0 ; i < (int)txt.length() ; ++i )
884 width += fm.width( txt[i] ); // was fm.charWidth(txt,i), but see drawCustomItemHelper...
885 // zoom to LU
886 width = tqRound( KoTextZoomHandler::ptToLayoutUnitPt( width ) );
887 height = fmt->height();
888 m_ascent = fmt->ascent();
889 //kdDebug(32500) << "KoVariable::resize text=" << txt << " width=" << width << " height=" << height << " ascent=" << m_ascent << endl;
890}
891
893{
894 recalc();
895 KoTextParag * parag = paragraph();
896 if ( parag )
897 {
898 //kdDebug(32500) << "KoVariable::recalcAndRepaint -> invalidating parag " << parag->paragId() << endl;
899 parag->invalidate( 0 );
900 parag->setChanged( true );
901 }
902 textDocument()->emitRepaintChanged();
903}
904
905TQString KoVariable::fieldCode()
906{
907 return i18n("Variable");
908}
909
910TQString KoVariable::text(bool realValue)
911{
912 KoTextFormat *fmt = format();
913 TQString str;
914 if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
915 str = fieldCode();
916 else
917 str = m_varFormat->convert( m_varValue );
918
919 return fmt->displayedString( str);
920}
921
922void KoVariable::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 )
923{
924 KoTextFormat * fmt = format();
925 KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
926 TQFont font( fmt->screenFont( zh ) );
927 drawCustomItemHelper( p, x, y, wpix, hpix, ascentpix, cg, selected, offset, fmt, font, fmt->color(), drawingShadow );
928}
929
930void KoVariable::drawCustomItemHelper( TQPainter* p, int x, int y, int wpix, int hpix, int ascentpix, const TQColorGroup& cg, bool selected, int offset, KoTextFormat* fmt, const TQFont& font, TQColor textColor, bool drawingShadow )
931{
932 // Important: the y value already includes the difference between the parag baseline
933 // and the char's own baseline (ascent) (see paintDefault in korichtext.cpp)
934 // So we just draw the text there. But we need the baseline for drawFontEffects...
935 KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
936
937 p->save();
938
939 if ( fmt->textBackgroundColor().isValid() )
940 p->fillRect( x, y, wpix, hpix, fmt->textBackgroundColor() );
941
942 if ( drawingShadow ) // Use shadow color if drawing a shadow
943 {
944 textColor = fmt->shadowColor();
945 p->setPen( textColor );
946 }
947 else if ( selected )
948 {
949 textColor = cg.color( TQColorGroup::HighlightedText );
950 p->setPen( TQPen( textColor ) );
951 p->fillRect( x, y, wpix, hpix, cg.color( TQColorGroup::Highlight ) );
952 }
953 else if ( textDocument() && textDocument()->drawFormattingChars()
954 && p->device()->devType() != TQInternal::Printer )
955 {
956 textColor = cg.color( TQColorGroup::Highlight );
957 p->setPen( TQPen ( textColor, 0, TQt::DotLine ) );
958 p->drawRect( x, y, wpix, hpix );
959 }
960 else {
961 if ( !textColor.isValid() ) // Resolve the color at this point
962 textColor = KoTextFormat::defaultTextColor( p );
963 p->setPen( TQPen( textColor ) );
964 }
965
966 p->setFont( font ); // already done by KoTextCustomItem::draw but someone might
967 // change the font passed to drawCustomItemHelper (e.g. KoLinkVariable)
968 TQString str = text();
969 KoTextParag::drawFontEffects( p, fmt, zh, font, textColor, x, ascentpix, wpix, y, hpix, str[0] );
970 int posY = y + ascentpix + offset;
971 if ( fmt->vAlign() == KoTextFormat::AlignSubScript )
972 posY +=p->fontMetrics().height() / 6;
973 if ( fmt->vAlign() != KoTextFormat::AlignSuperScript )
974 posY -= fmt->offsetFromBaseLine();
975 else if ( fmt->offsetFromBaseLine() < 0 )
976 posY -= 2*fmt->offsetFromBaseLine();
977
978 //p->drawText( x, posY, str );
979 // We can't just drawText, it wouldn't use the same kerning as the one
980 // that resize() planned for [which is zoom-independent].
981 // We need to do the layout using layout units instead, so for simplicity
982 // I just draw every char individually (whereas KoTextFormatter/KoTextParag
983 // detect runs of text that can be drawn together)
984 const int len = str.length();
985 int xLU = zh->pixelToLayoutUnitX( x );
986 TQFontMetrics fm = fmt->refFontMetrics();
987 for ( int i = 0; i < len; ++i )
988 {
989 const TQChar ch = str[i];
990 p->drawText( x, posY, TQString(ch) );
991 // Do like KoTextFormatter: do the layout in layout units.
992 xLU += KoTextZoomHandler::ptToLayoutUnitPt( fm.width( ch ) );
993 // And then compute the X position in pixels from the layout unit X.
994 x = zh->layoutUnitToPixelX( xLU );
995 }
996
997 p->restore();
998}
999
1000void KoVariable::save( TQDomElement &parentElem )
1001{
1002 //kdDebug(32500) << "KoVariable::save" << endl;
1003 TQDomElement variableElem = parentElem.ownerDocument().createElement( "VARIABLE" );
1004 parentElem.appendChild( variableElem );
1005 TQDomElement typeElem = parentElem.ownerDocument().createElement( "TYPE" );
1006 variableElem.appendChild( typeElem );
1007 typeElem.setAttribute( "type", static_cast<int>( type() ) );
1008
1011 typeElem.setAttribute( "key", m_varFormat->key().data() );
1012 typeElem.setAttribute( "text", text(true) );
1013 if ( correctValue() != 0)
1014 typeElem.setAttribute( "correct", correctValue() );
1015 saveVariable( variableElem );
1016}
1017
1018void KoVariable::load( TQDomElement & )
1019{
1020}
1021
1022
1023void KoVariable::loadOasis( const TQDomElement &/*elem*/, KoOasisContext& /*context*/ )
1024{
1025 // nothing to do here, reimplemented in subclasses (make it pure virtual?)
1026}
1027
1028void KoVariable::saveOasis( KoXmlWriter& /*writer*/, KoSavingContext& /*context*/ ) const
1029{
1030}
1031
1032void KoVariable::setVariableFormat( KoVariableFormat *_varFormat )
1033{
1034 // TODO if ( _varFormat ) _varFormat->deref();
1035 m_varFormat = _varFormat;
1036 // TODO m_varFormat->ref();
1037}
1038
1039#define addText( text, newFormat ) { \
1040 if ( !text.isEmpty() ) \
1041 { \
1042 newFormat +=text; \
1043 text=""; \
1044 } \
1045}
1046
1047TQString KoVariable::convertKlocaleToTQDateTimeFormat( const TQString & _format )
1048{
1049 TQString newFormat;
1050 TQString format( _format );
1051 TQString text;
1052 do
1053 {
1054 if ( format.startsWith( "%Y" ) )
1055 {
1056 addText( text, newFormat );
1057 newFormat+="yyyy";
1058 format = format.remove( 0, 2 );
1059 }
1060 else if ( format.startsWith( "%y" ) )
1061 {
1062 addText( text, newFormat );
1063 newFormat+="yyyy";
1064
1065 format = format.remove( 0, 2 );
1066 }
1067 else if ( format.startsWith( "%n" ) )
1068 {
1069 addText( text, newFormat );
1070 newFormat+="M";
1071 format = format.remove( 0, 2 );
1072 }
1073 else if ( format.startsWith( "%m" ) )
1074 {
1075 addText( text, newFormat );
1076 newFormat+="MM";
1077 format = format.remove( 0, 2 );
1078 }
1079 else if ( format.startsWith( "%e" ) )
1080 {
1081 addText( text, newFormat );
1082 newFormat+="d";
1083 format = format.remove( 0, 2 );
1084 }
1085 else if ( format.startsWith( "%d" ) )
1086 {
1087 addText( text, newFormat );
1088 newFormat+="dd";
1089 format = format.remove( 0, 2 );
1090 }
1091 else if ( format.startsWith( "%b" ) )
1092 {
1093 addText( text, newFormat );
1094 newFormat+="MMM";
1095 format = format.remove( 0, 2 );
1096 }
1097 else if ( format.startsWith( "%B" ) )
1098 {
1099 addText( text, newFormat );
1100 newFormat+="MMMM";
1101 format = format.remove( 0, 2 );
1102 }
1103 else if ( format.startsWith( "%a" ) )
1104 {
1105 addText( text, newFormat );
1106 newFormat+="ddd";
1107
1108 format = format.remove( 0, 2 );
1109 }
1110 else if ( format.startsWith( "%A" ) )
1111 {
1112 addText( text, newFormat );
1113 newFormat+="dddd";
1114 format = format.remove( 0, 2 );
1115 }
1116 if ( format.startsWith( "%H" ) ) //hh
1117 {
1118 //hour in 24h
1119 addText( text, newFormat );
1120 newFormat+="hh";
1121 format = format.remove( 0, 2 );
1122 }
1123 else if ( format.startsWith( "%k" ) )//h
1124 {
1125 addText( text, newFormat );
1126 newFormat+="h";
1127 format = format.remove( 0, 2 );
1128 }
1129 else if ( format.startsWith( "%I" ) )// ?????
1130 {
1131 addText( text, newFormat );
1132 //TODO hour in 12h
1133 }
1134 else if ( format.startsWith( "%l" ) )
1135 {
1136 addText( text, newFormat );
1137 //TODO hour in 12h with 1 digit
1138 }
1139 else if ( format.startsWith( "%M" ) )// mm
1140 {
1141 addText( text, newFormat );
1142 newFormat+="mm";
1143 format = format.remove( 0, 2 );
1144 }
1145 else if ( format.startsWith( "%S" ) ) //ss
1146 {
1147 addText( text, newFormat );
1148 newFormat+="ss";
1149 format = format.remove( 0, 2 );
1150 }
1151 else if ( format.startsWith( "%p" ) )
1152 {
1153 //TODO am or pm
1154 addText( text, newFormat );
1155 newFormat+="ap";
1156 format = format.remove( 0, 2 );
1157 }
1158
1159 else
1160 {
1161 text += format[0];
1162 format = format.remove( 0, 1 );
1163 }
1164 }
1165 while ( format.length() > 0 );
1166 addText( text, format );
1167 return format;
1168}
1169
1170
1171/******************************************************************/
1172/* Class: KoDateVariable */
1173/******************************************************************/
1174KoDateVariable::KoDateVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *_varFormat, KoVariableCollection *_varColl, int _correctDate)
1175 : KoVariable( textdoc, _varFormat,_varColl ), m_subtype( subtype ), m_correctDate( _correctDate)
1176{
1177}
1178
1179TQString KoDateVariable::fieldCode()
1180{
1181 if ( m_subtype == VST_DATE_FIX )
1182 return i18n("Date (Fixed)");
1183 else if ( m_subtype == VST_DATE_CURRENT)
1184 return i18n("Date");
1185 else if ( m_subtype == VST_DATE_LAST_PRINTING)
1186 return i18n("Last Printing");
1187 else if ( m_subtype == VST_DATE_CREATE_FILE )
1188 return i18n( "File Creation");
1189 else if ( m_subtype == VST_DATE_MODIFY_FILE )
1190 return i18n( "File Modification");
1191 else
1192 return i18n("Date");
1193}
1194
1196{
1197 KoTextFormat * fmt = format();
1198 TQString oldLanguage;
1199 if ( !fmt->language().isEmpty())
1200 {
1201 oldLanguage=TDEGlobal::locale()->language();
1202 bool changeLanguage = TDEGlobal::locale()->setLanguage( fmt->language() );
1204 if ( changeLanguage )
1205 TDEGlobal::locale()->setLanguage( oldLanguage );
1206 }
1207 else
1209}
1210
1212{
1213 if ( m_subtype == VST_DATE_CURRENT )
1214 m_varValue = TQDateTime(TQDateTime::currentDateTime().addDays(m_correctDate));
1215 else if ( m_subtype == VST_DATE_LAST_PRINTING )
1216 m_varValue = m_varColl->variableSetting()->lastPrintingDate();
1217 else if ( m_subtype == VST_DATE_CREATE_FILE )
1218 m_varValue = m_varColl->variableSetting()->creationDate();
1219 else if ( m_subtype == VST_DATE_MODIFY_FILE )
1220 m_varValue = m_varColl->variableSetting()->modificationDate();
1221 else
1222 {
1223 // Only if never set before (i.e. upon insertion)
1224 if ( m_varValue.isNull() )
1225 m_varValue = TQDateTime(TQDateTime::currentDateTime().addDays(m_correctDate));
1226 }
1227 resize();
1228}
1229
1230void KoDateVariable::saveVariable( TQDomElement& varElem )
1231{
1232 TQDomElement elem = varElem.ownerDocument().createElement( "DATE" );
1233 varElem.appendChild( elem );
1234
1235 TQDate date = m_varValue.toDate(); // works with Date and DateTime
1236 date = date.addDays( -m_correctDate );//remove correctDate value otherwise value stored is bad
1237 elem.setAttribute( "year", date.year() );
1238 elem.setAttribute( "month", date.month() );
1239 elem.setAttribute( "day", date.day() );
1240 elem.setAttribute( "fix", m_subtype == VST_DATE_FIX ); // for compat
1241 elem.setAttribute( "correct", m_correctDate);
1242 elem.setAttribute( "subtype", m_subtype);
1243 if ( m_varValue.type() == TQVariant::DateTime )
1244 {
1245 TQTime time = m_varValue.toTime();
1246 elem.setAttribute( "hour", time.hour() );
1247 elem.setAttribute( "minute", time.minute() );
1248 elem.setAttribute( "second", time.second() );
1249 }
1250}
1251
1252void KoDateVariable::load( TQDomElement& elem )
1253{
1254 KoVariable::load( elem );
1255
1256 TQDomElement e = elem.namedItem( "DATE" ).toElement();
1257 if (!e.isNull())
1258 {
1259 const bool fix = e.attribute("fix").toInt() == 1;
1260 if ( e.hasAttribute("correct"))
1261 m_correctDate = e.attribute("correct").toInt();
1262 if ( fix )
1263 {
1264 const int y = e.attribute("year").toInt();
1265 const int month = e.attribute("month").toInt();
1266 const int d = e.attribute("day").toInt();
1267 const int h = e.attribute("hour").toInt();
1268 const int min = e.attribute("minute").toInt();
1269 const int s = e.attribute("second").toInt();
1270 const int ms = e.attribute("msecond").toInt();
1271 TQDate date( y, month, d );
1272 date = date.addDays( m_correctDate );
1273 const TQTime time( h, min, s, ms );
1274 if (time.isValid())
1275 m_varValue = TQVariant ( TQDateTime( date, time ) );
1276 else
1277 m_varValue = TQVariant( date );
1278 }
1279 //old date variable format
1280 m_subtype = fix ? VST_DATE_FIX : VST_DATE_CURRENT;
1281 if ( e.hasAttribute( "subtype" ))
1282 m_subtype = e.attribute( "subtype").toInt();
1283 }
1284}
1285
1287{
1288 switch( m_subtype )
1289 {
1290 case VST_DATE_FIX:
1291 case VST_DATE_CURRENT:
1292 writer.startElement( "text:date" );
1293 if ( m_subtype == VST_DATE_FIX )
1294 {
1295 writer.addAttribute( "text:date-value", m_varValue.toDate().toString( TQt::ISODate) );
1296 writer.addAttribute( "text:fixed", "true" );
1297 }
1298 break;
1299 case VST_DATE_LAST_PRINTING:
1300 writer.startElement( "text:print-date" );
1301 break;
1302 case VST_DATE_CREATE_FILE:
1303 writer.startElement( "text:creation-date" );
1304 break;
1305 case VST_DATE_MODIFY_FILE:
1306 writer.startElement( "text:modification-date" );
1307 break;
1308 }
1309 TQString value( m_varFormat->formatProperties() );
1310 bool klocaleFormat = false;
1311 if ( value.lower() == "locale" ||
1312 value.isEmpty() ||
1313 value.lower() == "localeshort" ||
1314 value.lower() == "localedatetime" ||
1315 value.lower() == "localedatetimeshort" )
1316 {
1317 if ( value.lower() == "locale" || value.isEmpty())
1318 value = TDEGlobal::locale()->dateFormat();
1319 else if ( value.lower() == "localeshort" )
1320 value = TDEGlobal::locale()->dateFormatShort();
1321 else if ( value.lower() == "localedatetime" )
1322 value = TQString( "%1 %2" ).arg( TDEGlobal::locale()->dateFormat() ).arg( TDEGlobal::locale()->timeFormat() );
1323 else if ( value.lower() == "localedatetimeshort" )
1324 value = TQString( "%1 %2" ).arg( TDEGlobal::locale()->dateFormatShort() ).arg( TDEGlobal::locale()->timeFormat() );
1325 klocaleFormat = true;
1326 }
1327 writer.addAttribute( "style:data-style-name", KoOasisStyles::saveOasisDateStyle(context.mainStyles(), value, klocaleFormat ) );
1328
1329 if ( m_correctDate != 0 )
1330 writer.addAttribute( "text:date-adjust", daysToISODuration( m_correctDate ) );
1331 writer.endElement();
1332}
1333
1334void KoDateVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
1335{
1336 const TQString localName( elem.localName() );
1337 if ( localName == "date" ) // current (or fixed) date
1338 {
1339 // Standard form of the date is in text:date-value. Example: 2004-01-21T10:57:05
1340 const TQString dateValue = elem.attributeNS( KoXmlNS::text, "date-value", TQString());
1341 TQDateTime dt;
1342 if ( !dateValue.isEmpty() ) // avoid TQDate warning
1343 dt = TQDate::fromString(dateValue, TQt::ISODate);
1344
1345 bool fixed = (elem.hasAttributeNS( KoXmlNS::text, "fixed") && elem.attributeNS( KoXmlNS::text, "fixed", TQString())=="true");
1346 if (!dt.isValid())
1347 fixed = false; // OOo docs say so: not valid = current datetime
1348 if ( fixed )
1349 m_varValue = TQVariant( dt );
1350 m_subtype = fixed ? VST_DATE_FIX : VST_DATE_CURRENT;
1351 }
1352 // For all those the value of the date will be retrieved from meta.xml
1353 else if ( localName.startsWith( "print" ) )
1354 m_subtype = VST_DATE_LAST_PRINTING;
1355 else if ( localName.startsWith( "creation" ) )
1356 m_subtype = VST_DATE_CREATE_FILE;
1357 else if ( localName.startsWith( "modification" ) )
1358 m_subtype = VST_DATE_MODIFY_FILE;
1359 const TQString adjustStr = elem.attributeNS( KoXmlNS::text, "date-adjust", TQString() );
1360 if ( !adjustStr.isEmpty() )
1361 m_correctDate = ISODurationToDays( adjustStr );
1362}
1363
1364TQStringList KoDateVariable::actionTexts()
1365{
1366 TQStringList lst;
1367 lst << i18n( "Current Date (fixed)" );
1368 lst << i18n( "Current Date (variable)" );
1369 lst << i18n( "Date of Last Printing" );
1370 lst << i18n( "Date of File Creation" );
1371 lst << i18n( "Date of File Modification" );
1372 return lst;
1373}
1374
1376{
1377 return KoDateVariable::actionTexts();
1378}
1379
1381{
1382 return TQCString("DATE") + "locale";
1383}
1384
1385TQCString KoDateVariable::formatStr(int & correct)
1386{
1387 TQCString string;
1388 TQStringList stringList;
1389 KDialogBase* dialog=new KDialogBase(0, 0, true, i18n("Date Format"), KDialogBase::Ok|KDialogBase::Cancel);
1390 DateFormatWidget* widget=new DateFormatWidget(dialog);
1391 int count=0;
1392 dialog->setMainWidget(widget);
1393 TDEConfig* config = KoGlobal::kofficeConfig();
1394 if( config->hasGroup("Date format history") )
1395 {
1396 TDEConfigGroupSaver cgs( config, "Date format history");
1397 const int noe=config->readNumEntry("Number Of Entries", 5);
1398 for(int i=0;i<noe;i++)
1399 {
1400 TQString num;
1401 num.setNum(i);
1402 const TQString tmpString(config->readEntry("Last Used"+num));
1403 if(tmpString.startsWith("locale"))
1404 continue;
1405 else if(stringList.contains(tmpString))
1406 continue;
1407 else if(!tmpString.isEmpty())
1408 {
1409 stringList.append(tmpString);
1410 count++;
1411 }
1412 }
1413
1414 }
1415 if(!stringList.isEmpty())
1416 {
1417 widget->combo1->insertItem("---");
1418 widget->combo1->insertStringList(stringList);
1419 }
1420 if(false) { // ### TODO: select the last used item
1421 TQComboBox *combo= widget->combo1;
1422 combo->setCurrentItem(combo->count() -1);
1423 widget->updateLabel();
1424 }
1425
1426 if(dialog->exec()==TQDialog::Accepted)
1427 {
1428 string = widget->resultString().utf8();
1429 correct = widget->correctValue();
1430 }
1431 else
1432 {
1433 delete dialog;
1434 return 0;
1435 }
1436 config->setGroup("Date format history");
1437 stringList.remove(string);
1438 stringList.prepend(string);
1439 for(int i=0;i<=count;i++)
1440 {
1441 TQString num;
1442 num.setNum(i);
1443 config->writeEntry("Last Used"+num, stringList[i]);
1444 }
1445 config->sync();
1446 delete dialog;
1447 return TQCString("DATE") + string;
1448}
1449
1450/******************************************************************/
1451/* Class: KoTimeVariable */
1452/******************************************************************/
1453KoTimeVariable::KoTimeVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat, KoVariableCollection *_varColl, int _correct)
1454 : KoVariable( textdoc, varFormat,_varColl ), m_subtype( subtype ), m_correctTime( _correct)
1455{
1456}
1457
1458TQString KoTimeVariable::fieldCode()
1459{
1460 return (m_subtype == VST_TIME_FIX)?i18n("Time (Fixed)"):i18n("Time");
1461}
1462
1463
1465{
1466 KoTextFormat * fmt = format();
1467 if ( !fmt->language().isEmpty() )
1468 {
1469 TQString oldLanguage = TDEGlobal::locale()->language();
1470 bool changeLanguage = TDEGlobal::locale()->setLanguage( fmt->language() );
1472 if ( changeLanguage )
1473 TDEGlobal::locale()->setLanguage( oldLanguage );
1474 }
1475 else
1477}
1478
1480{
1481 if ( m_subtype == VST_TIME_CURRENT )
1482 m_varValue = TQVariant( TQTime(TQTime::currentTime().addSecs(60*m_correctTime)));
1483 else
1484 {
1485 // Only if never set before (i.e. upon insertion)
1486 if ( m_varValue.toTime().isNull() )
1487 m_varValue = TQVariant( TQTime(TQTime::currentTime().addSecs(60*m_correctTime)));
1488 }
1489 resize();
1490}
1491
1492
1493void KoTimeVariable::saveVariable( TQDomElement& parentElem )
1494{
1495 TQDomElement elem = parentElem.ownerDocument().createElement( "TIME" );
1496 parentElem.appendChild( elem );
1497
1498 TQTime time = m_varValue.toTime();
1499 time = time.addSecs(-60*m_correctTime);
1500 elem.setAttribute( "hour", time.hour() );
1501 elem.setAttribute( "minute", time.minute() );
1502 elem.setAttribute( "second", time.second() );
1503 elem.setAttribute( "msecond", time.msec() );
1504 elem.setAttribute( "fix", m_subtype == VST_TIME_FIX );
1505 elem.setAttribute( "correct", m_correctTime );
1506}
1507
1508void KoTimeVariable::load( TQDomElement& elem )
1509{
1510 KoVariable::load( elem );
1511
1512 TQDomElement e = elem.namedItem( "TIME" ).toElement();
1513 if (!e.isNull())
1514 {
1515 int h = e.attribute("hour").toInt();
1516 int m = e.attribute("minute").toInt();
1517 int s = e.attribute("second").toInt();
1518 int ms = e.attribute("msecond").toInt();
1519 int correct = 0;
1520 if ( e.hasAttribute("correct"))
1521 correct=e.attribute("correct").toInt();
1522 bool fix = static_cast<bool>( e.attribute("fix").toInt() );
1523 if ( fix )
1524 {
1525 TQTime time;
1526 time.setHMS( h, m, s, ms );
1527 time = time.addSecs( 60*m_correctTime );
1528 m_varValue = TQVariant( time);
1529
1530 }
1531 m_subtype = fix ? VST_TIME_FIX : VST_TIME_CURRENT;
1532 m_correctTime = correct;
1533 }
1534}
1535
1536void KoTimeVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
1537{
1538 const TQString localName( elem.localName() );
1539 Q_ASSERT( localName == "time" ); // caller checked for it
1540 if ( localName == "time" ) // current (or fixed) time
1541 {
1542 // Use TQDateTime to work around a possible problem of TQTime::fromString in Qt 3.2.2
1543 TQDateTime dt(TQDateTime::fromString(elem.attributeNS( KoXmlNS::text, "time-value", TQString()), TQt::ISODate));
1544
1545 bool fixed = (elem.hasAttributeNS( KoXmlNS::text, "fixed") && elem.attributeNS( KoXmlNS::text, "fixed", TQString())=="true");
1546 if (!dt.isValid())
1547 fixed = false; // OOo docs say so: not valid = current datetime
1548 if ( fixed )
1549 m_varValue = TQVariant( dt.time() );
1550 m_subtype = fixed ? VST_TIME_FIX : VST_TIME_CURRENT;
1551 TQString adjustStr = elem.attributeNS( KoXmlNS::text, "time-adjust", TQString() );
1552 if ( !adjustStr.isEmpty() )
1553 m_correctTime = ISODurationToMinutes( adjustStr );
1554 }
1555}
1556
1558{
1559 writer.startElement( "text:time" );
1560 if ( m_correctTime != 0 ) {
1561 writer.addAttribute( "text:time-adjust", minutesToISODuration( m_correctTime ) );
1562 }
1563 if (m_subtype == VST_TIME_FIX )
1564 {
1565 writer.addAttribute( "text:fixed", "true" );
1566 writer.addAttribute( "text:time-value", m_varValue.toTime().toString( TQt::ISODate ) );
1567 }
1568
1569 TQString value( m_varFormat->formatProperties() );
1570 bool klocaleFormat = false;
1571 if ( value.lower() == "locale" )
1572 {
1573 value = TDEGlobal::locale()->timeFormat();
1574 klocaleFormat = true;
1575 }
1576 writer.addAttribute( "style:data-style-name", KoOasisStyles::saveOasisTimeStyle(context.mainStyles(), m_varFormat->formatProperties(), klocaleFormat ) );
1577 //writer.addTextNode( /*value*/ value displayed as texte );
1578 //TODO save text value
1579 //<text:time style:data-style-name="N43" text:time-value="2004-11-11T14:42:19" text:fixed="true">02:42:19 PM</text:time>
1580 writer.endElement();
1581}
1582
1583
1584TQStringList KoTimeVariable::actionTexts()
1585{
1586 TQStringList lst;
1587 lst << i18n( "Current Time (fixed)" );
1588 lst << i18n( "Current Time (variable)" );
1589 return lst;
1590}
1591
1593{
1594 return KoTimeVariable::actionTexts();
1595}
1596
1597TQCString KoTimeVariable::formatStr(int & _correct)
1598{
1599 TQCString string;
1600 TQStringList stringList;
1601 KDialogBase* dialog=new KDialogBase(0, 0, true, i18n("Time Format"), KDialogBase::Ok|KDialogBase::Cancel);
1602 TimeFormatWidget* widget=new TimeFormatWidget(dialog);
1603 dialog->setMainWidget(widget);
1604 TDEConfig* config = KoGlobal::kofficeConfig();
1605 int count=0;
1606 if( config->hasGroup("Time format history") )
1607 {
1608 TDEConfigGroupSaver cgs( config, "Time format history" );
1609 const int noe=config->readNumEntry("Number Of Entries", 5);
1610 for(int i=0;i<noe;i++)
1611 {
1612 TQString num;
1613 num.setNum(i);
1614 TQString tmpString(config->readEntry("Last Used"+num));
1615 if(tmpString.startsWith("locale"))
1616 continue;
1617 else if(stringList.contains(tmpString))
1618 continue;
1619 else if(!tmpString.isEmpty())
1620 {
1621 stringList.append(tmpString);
1622 count++;
1623 }
1624 }
1625 }
1626 if(!stringList.isEmpty())
1627 {
1628 widget->combo1->insertItem("---");
1629 widget->combo1->insertStringList(stringList);
1630 }
1631 if(false) // ### TODO: select the last used item
1632 {
1633 TQComboBox *combo= widget->combo1;
1634 combo->setCurrentItem(combo->count() -1);
1635 }
1636 if(dialog->exec()==TQDialog::Accepted)
1637 {
1638 string = widget->resultString().utf8();
1639 _correct = widget->correctValue();
1640 }
1641 else
1642 {
1643 delete dialog;
1644 return 0;
1645 }
1646 config->setGroup("Time format history");
1647 stringList.remove(string);
1648 stringList.prepend(string);
1649 for(int i=0;i<=count;i++)
1650 {
1651 TQString num;
1652 num.setNum(i);
1653 config->writeEntry("Last Used"+num, stringList[i]);
1654 }
1655 config->sync();
1656 delete dialog;
1657 return TQCString("TIME"+string );
1658}
1659
1661{
1662 return TQCString(TQCString("TIME")+TQCString("locale") );
1663}
1664
1665
1666/******************************************************************/
1667/* Class: KoCustomVariable */
1668/******************************************************************/
1669KoCustomVariable::KoCustomVariable( KoTextDocument *textdoc, const TQString &name, KoVariableFormat *varFormat, KoVariableCollection *_varColl )
1670 : KoVariable( textdoc, varFormat,_varColl )
1671{
1672 m_varValue = TQVariant( name );
1673}
1674
1675TQString KoCustomVariable::fieldCode()
1676{
1677 return i18n("Custom Variable");
1678}
1679
1680TQString KoCustomVariable::text(bool realValue)
1681{
1682 if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
1683 return fieldCode();
1684 else
1685 return value();
1686} // use a format when they are customizable
1687
1688
1689
1690void KoCustomVariable::saveVariable( TQDomElement& parentElem )
1691{
1692 TQDomElement elem = parentElem.ownerDocument().createElement( "CUSTOM" );
1693 parentElem.appendChild( elem );
1694 elem.setAttribute( "name", m_varValue.toString() );
1695 elem.setAttribute( "value", value() );
1696}
1697
1698void KoCustomVariable::load( TQDomElement& elem )
1699{
1700 KoVariable::load( elem );
1701 TQDomElement e = elem.namedItem( "CUSTOM" ).toElement();
1702 if (!e.isNull())
1703 {
1704 m_varValue = TQVariant (e.attribute( "name" ));
1705 setValue( e.attribute( "value" ) );
1706 }
1707}
1708
1709void KoCustomVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
1710{
1711 const TQString localName( elem.localName() );
1712 // We treat all those the same. For OO/OpenDocument the difference is that
1713 // - user-field-get is related to text:user-field-decls in <body>
1714 // - variable-set is related to variable-decls (defined in <body>);
1715 // its value can change in the middle of the document.
1716 // - user-defined is related to meta:user-defined in meta.xml
1717 if ( localName == "variable-set"
1718 || localName == "user-defined"
1719 || localName == "user-field-get" ) {
1720 m_varValue = elem.attributeNS( KoXmlNS::text, "name", TQString() );
1721 setValue( elem.text() );
1722 }
1723}
1724
1726{
1727 //TODO save value into meta:user-defined
1728 writer.startElement( "text:user-field-get" ); //see 6.3.6
1729 writer.addAttribute( "text:name", m_varValue.toString() );
1730 writer.addTextNode( value() );
1731 writer.endElement();
1732}
1733
1734TQString KoCustomVariable::value() const
1735{
1736 return m_varColl->getVariableValue( m_varValue.toString() );
1737}
1738
1739void KoCustomVariable::setValue( const TQString &v )
1740{
1741 m_varColl->setVariableValue( m_varValue.toString(), v );
1742}
1743
1744TQStringList KoCustomVariable::actionTexts()
1745{
1746 return TQStringList( i18n( "Custom..." ) );
1747}
1748
1750{
1751 resize();
1752}
1753
1754/******************************************************************/
1755/* Class: KoMailMergeVariable */
1756/******************************************************************/
1757KoMailMergeVariable::KoMailMergeVariable( KoTextDocument *textdoc, const TQString &name, KoVariableFormat *varFormat,KoVariableCollection *_varColl )
1758 : KoVariable( textdoc, varFormat, _varColl )
1759{
1760 m_varValue = TQVariant ( name );
1761}
1762
1763TQString KoMailMergeVariable::fieldCode()
1764{
1765 return i18n("Mail Merge");
1766}
1767
1768void KoMailMergeVariable::loadOasis( const TQDomElement &/*elem*/, KoOasisContext& /*context*/ )
1769{
1770 // TODO
1771}
1772
1773void KoMailMergeVariable::saveOasis( KoXmlWriter& /*writer*/, KoSavingContext& /*context*/ ) const
1774{
1775 kdWarning(32500) << "Not implemented: OASIS saving of mail merge variables" << endl;
1776}
1777
1778
1779
1780void KoMailMergeVariable::saveVariable( TQDomElement& parentElem )
1781{
1782 TQDomElement elem = parentElem.ownerDocument().createElement( "MAILMERGE" );
1783 parentElem.appendChild( elem );
1784 elem.setAttribute( "name", m_varValue.toString() );
1785}
1786
1787void KoMailMergeVariable::load( TQDomElement& elem )
1788{
1789 KoVariable::load( elem );
1790 TQDomElement e = elem.namedItem( "MAILMERGE" ).toElement();
1791 if (!e.isNull())
1792 m_varValue = TQVariant( e.attribute( "name" ) );
1793}
1794
1795TQString KoMailMergeVariable::value() const
1796{
1797 return TQString();//m_doc->getMailMergeDataBase()->getValue( m_name );
1798}
1799
1800TQString KoMailMergeVariable::text(bool /*realValue*/)
1801{
1802 // ## should use a format maybe
1803 TQString v = value();
1804 if ( v == name() )
1805 return "<" + v + ">";
1806 return v;
1807}
1808
1809TQStringList KoMailMergeVariable::actionTexts()
1810{
1811 return TQStringList( i18n( "&Mail Merge..." ) );
1812}
1813
1814/******************************************************************/
1815/* Class: KoPageVariable */
1816/******************************************************************/
1817KoPageVariable::KoPageVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat,KoVariableCollection *_varColl )
1818 : KoVariable( textdoc, varFormat, _varColl ), m_subtype( subtype )
1819{
1820}
1821
1822TQString KoPageVariable::fieldCode()
1823{
1824 if ( m_subtype == VST_PGNUM_CURRENT )
1825 return i18n("Page Current Num");
1826 else if ( m_subtype == VST_PGNUM_TOTAL )
1827 return i18n("Total Page Num");
1828 else if ( m_subtype == VST_CURRENT_SECTION )
1829 return i18n("Current Section");
1830 else if ( m_subtype == VST_PGNUM_PREVIOUS )
1831 return i18n("Previous Page Number");
1832 else if ( m_subtype == VST_PGNUM_NEXT )
1833 return i18n("Next Page Number");
1834
1835 else
1836 return i18n("Current Section");
1837}
1838
1839
1840void KoPageVariable::saveVariable( TQDomElement& parentElem )
1841{
1842 TQDomElement pgNumElem = parentElem.ownerDocument().createElement( "PGNUM" );
1843 parentElem.appendChild( pgNumElem );
1844 pgNumElem.setAttribute( "subtype", m_subtype );
1845 if ( m_subtype != VST_CURRENT_SECTION )
1846 pgNumElem.setAttribute( "value", m_varValue.toInt() );
1847 else
1848 pgNumElem.setAttribute( "value", m_varValue.toString() );
1849}
1850
1851void KoPageVariable::load( TQDomElement& elem )
1852{
1853 KoVariable::load( elem );
1854 TQDomElement pgNumElem = elem.namedItem( "PGNUM" ).toElement();
1855 if (!pgNumElem.isNull())
1856 {
1857 m_subtype = pgNumElem.attribute("subtype").toInt();
1858 // ### This could use the format...
1859 if ( m_subtype != VST_CURRENT_SECTION )
1860 m_varValue = TQVariant(pgNumElem.attribute("value").toInt());
1861 else
1862 m_varValue = TQVariant(pgNumElem.attribute("value"));
1863 }
1864}
1865
1866void KoPageVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
1867{
1868 switch( m_subtype )
1869 {
1870 case VST_PGNUM_PREVIOUS:
1871 case VST_PGNUM_NEXT:
1872 case VST_PGNUM_CURRENT:
1873 {
1874 writer.startElement( "text:page-number" );
1875 if ( m_subtype == VST_PGNUM_PREVIOUS )
1876 {
1877 writer.addAttribute( "text:select-page", "previous" );
1878 }
1879 else if ( m_subtype == VST_PGNUM_NEXT )
1880 {
1881 writer.addAttribute( "text:select-page", "next" );
1882 }
1883 else if ( m_subtype == VST_PGNUM_CURRENT )
1884 {
1885 writer.addAttribute( "text:select-page", "current" );
1886 }
1887 writer.addTextNode( m_varValue.toString() );
1888 writer.endElement();
1889 }
1890 break;
1891 case VST_CURRENT_SECTION:
1892 {
1893 writer.startElement( "text:chapter" );
1894 writer.addTextNode( m_varValue.toString() );
1895 writer.endElement();
1896 }
1897 break;
1898 case VST_PGNUM_TOTAL:
1899 {
1900 writer.startElement( "text:page-count" );
1901 writer.addTextNode( m_varValue.toString() );
1902 writer.endElement();
1903 }
1904 break;
1905 }
1906}
1907
1908void KoPageVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
1909{
1910 const TQString localName( elem.localName() );
1911 if ( localName == "page-number" )
1912 {
1913 m_subtype = VST_PGNUM_CURRENT;
1914
1915 if ( elem.hasAttributeNS( KoXmlNS::text, "select-page") )
1916 {
1917 const TQString select = elem.attributeNS( KoXmlNS::text, "select-page", TQString());
1918 if (select == "previous")
1919 m_subtype = VST_PGNUM_PREVIOUS;
1920 else if (select == "next")
1921 m_subtype = VST_PGNUM_NEXT;
1922 }
1923 // Missing: fixed, page adjustment, formatting style
1924 m_varValue = TQVariant( elem.text().toInt() );
1925 }
1926 else if ( localName == "chapter" )
1927 {
1928 m_subtype = VST_CURRENT_SECTION;
1929 m_varValue = TQVariant( elem.text() );
1930 // text:display attribute can be name, number (i.e. with prefix/suffix),
1931 // number-and-name, plain-number-and-name, plain-number
1932 // TODO: a special format class for this, so that it can be easily switched using the RMB
1933 }
1934 else if ( localName == "page-count" )
1935 {
1936 m_subtype = VST_PGNUM_TOTAL;
1937 m_varValue = TQVariant( elem.text() );
1938 }
1939}
1940
1941TQStringList KoPageVariable::actionTexts()
1942{
1943 TQStringList lst;
1944 lst << i18n( "Page Number" );
1945 lst << i18n( "Number of Pages" );
1946 lst << i18n( "Section Title" );
1947 lst << i18n( "Previous Page" );
1948 lst << i18n( "Next Page" );
1949 return lst;
1950}
1951
1953{
1954 return KoPageVariable::actionTexts();
1955}
1956
1958{
1959 m_subtype = type;
1960 Q_ASSERT( m_varColl );
1961 KoVariableFormatCollection* fc = m_varColl->formatCollection();
1962 setVariableFormat((m_subtype == VST_CURRENT_SECTION) ? fc->format("STRING") : fc->format("NUMBER"));
1963}
1964
1965/******************************************************************/
1966/* Class: KoFieldVariable */
1967/******************************************************************/
1968KoFieldVariable::KoFieldVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat, KoVariableCollection *_varColl ,KoDocument *_doc )
1969 : KoVariable( textdoc, varFormat,_varColl ), m_subtype( subtype ), m_doc(_doc)
1970{
1971}
1972
1973TQString KoFieldVariable::fieldCode()
1974{
1975 switch( m_subtype ) {
1976 case VST_FILENAME:
1977 return i18n("Filename");
1978 break;
1979 case VST_DIRECTORYNAME:
1980 return i18n("Directory Name");
1981 break;
1982 case VST_PATHFILENAME:
1983 return i18n("Path Filename");
1984 break;
1985 case VST_FILENAMEWITHOUTEXTENSION:
1986 return i18n("Filename Without Extension");
1987 break;
1988 case VST_AUTHORNAME:
1989 return i18n("Author Name");
1990 break;
1991 case VST_EMAIL:
1992 return i18n("Email");
1993 break;
1994 case VST_COMPANYNAME:
1995 return i18n("Company Name");
1996 break;
1997 case VST_TELEPHONE_WORK:
1998 return i18n("Telephone (work)");
1999 break;
2000 case VST_TELEPHONE_HOME:
2001 return i18n("Telephone (home)");
2002 break;
2003 case VST_FAX:
2004 return i18n("Fax");
2005 break;
2006 case VST_COUNTRY:
2007 return i18n("Country");
2008 break;
2009 case VST_POSTAL_CODE:
2010 return i18n("Postal Code");
2011 break;
2012 case VST_CITY:
2013 return i18n("City");
2014 break;
2015 case VST_STREET:
2016 return i18n("Street");
2017 break;
2018 case VST_AUTHORTITLE:
2019 return i18n("Author Title");
2020 break;
2021 case VST_TITLE:
2022 return i18n("Title");
2023 break;
2024 case VST_SUBJECT:
2025 return i18n("Subject");
2026 break;
2027 case VST_ABSTRACT:
2028 return i18n("Abstract");
2029 break;
2030 case VST_KEYWORDS:
2031 return i18n("Keywords");
2032 break;
2033 case VST_INITIAL:
2034 return i18n("Initials");
2035 break;
2036 }
2037 return i18n("Field");
2038}
2039
2040TQString KoFieldVariable::text(bool realValue)
2041{
2042 if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
2043 return fieldCode();
2044 else
2045 return value();
2046} // use a format when they are customizable
2047
2048
2049void KoFieldVariable::saveVariable( TQDomElement& parentElem )
2050{
2051 //kdDebug(32500) << "KoFieldVariable::saveVariable" << endl;
2052 TQDomElement elem = parentElem.ownerDocument().createElement( "FIELD" );
2053 parentElem.appendChild( elem );
2054 elem.setAttribute( "subtype", m_subtype );
2055 elem.setAttribute( "value", m_varValue.toString() );
2056}
2057
2058void KoFieldVariable::load( TQDomElement& elem )
2059{
2060 KoVariable::load( elem );
2061 TQDomElement e = elem.namedItem( "FIELD" ).toElement();
2062 if (!e.isNull())
2063 {
2064 m_subtype = e.attribute( "subtype" ).toInt();
2065 if ( m_subtype == VST_NONE )
2066 kdWarning() << "Field subtype of -1 found in the file !" << endl;
2067 m_varValue = TQVariant( e.attribute( "value" ) );
2068 } else
2069 kdWarning() << "FIELD element not found !" << endl;
2070}
2071
2072void KoFieldVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
2073{
2074 const TQString localName( elem.localName() );
2075 if ( localName == "file-name" ) {
2076 const TQString display = elem.attributeNS( KoXmlNS::text, "display", TQString() );
2077 if (display == "path")
2078 m_subtype = VST_DIRECTORYNAME;
2079 else if (display == "name")
2080 m_subtype = VST_FILENAMEWITHOUTEXTENSION;
2081 else if (display == "name-and-extension")
2082 m_subtype = VST_FILENAME;
2083 else
2084 m_subtype = VST_PATHFILENAME;
2085 }
2086 else if ( localName == "author-name" )
2087 m_subtype = VST_AUTHORNAME;
2088 else if ( localName == "author-initials" )
2089 m_subtype = VST_INITIAL;
2090 else if ( localName == "subject" )
2091 m_subtype = VST_SUBJECT;
2092 else if ( localName == "title" )
2093 m_subtype = VST_TITLE;
2094 else if ( localName == "description" )
2095 m_subtype = VST_ABSTRACT;
2096 else if ( localName == "keywords" )
2097 m_subtype = VST_KEYWORDS;
2098
2099 else if ( localName == "sender-company" )
2100 m_subtype = VST_COMPANYNAME;
2101 else if ( localName == "sender-firstname" )
2102 ; // ## This is different from author-name, but the notion of 'sender' is unclear...
2103 else if ( localName == "sender-lastname" )
2104 ; // ## This is different from author-name, but the notion of 'sender' is unclear...
2105 else if ( localName == "sender-initials" )
2106 ; // ## This is different from author-initials, but the notion of 'sender' is unclear...
2107 else if ( localName == "sender-street" )
2108 m_subtype = VST_STREET;
2109 else if ( localName == "sender-country" )
2110 m_subtype = VST_COUNTRY;
2111 else if ( localName == "sender-postal-code" )
2112 m_subtype = VST_POSTAL_CODE;
2113 else if ( localName == "sender-city" )
2114 m_subtype = VST_CITY;
2115 else if ( localName == "sender-title" )
2116 m_subtype = VST_AUTHORTITLE; // Small hack (it's supposed to be about the sender, not about the author)
2117 else if ( localName == "sender-position" )
2118 m_subtype = VST_AUTHORPOSITION;
2119 else if ( localName == "sender-phone-private" )
2120 m_subtype = VST_TELEPHONE_HOME;
2121 else if ( localName == "sender-phone-work" )
2122 m_subtype = VST_TELEPHONE_WORK;
2123 else if ( localName == "sender-fax" )
2124 m_subtype = VST_FAX;
2125 else if ( localName == "sender-email" )
2126 m_subtype = VST_EMAIL;
2127
2128 m_varValue = TQVariant( elem.text() );
2129}
2130
2131void KoFieldVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
2132{
2133 switch( m_subtype )
2134 {
2135 case VST_NONE:
2136 break;
2137 case VST_FILENAME:
2138 writer.startElement( "text:file-name" );
2139 writer.addAttribute( "text:display", "name-and-extension" );
2140 break;
2141 case VST_DIRECTORYNAME:
2142 writer.startElement( "text:file-name" );
2143 writer.addAttribute( "text:display", "path" );
2144 break;
2145 case VST_AUTHORNAME:
2146 writer.startElement( "text:author-name" );
2147 break;
2148 case VST_EMAIL:
2149 writer.startElement("text:sender-email" );
2150 break;
2151 case VST_COMPANYNAME:
2152 writer.startElement("text:sender-company" );
2153 break;
2154 case VST_PATHFILENAME:
2155 writer.startElement("text:display" );
2156 writer.addAttribute( "text:display", "pathfilename" ); // ???????? not define !
2157 break;
2158 case VST_FILENAMEWITHOUTEXTENSION:
2159 writer.startElement("text:display" );
2160 writer.addAttribute( "text:display", "name-and-extension" ); // ???????? not define !
2161 break;
2162 case VST_TELEPHONE_WORK:
2163 writer.startElement("text:sender-phone-work" );
2164 break;
2165 case VST_TELEPHONE_HOME:
2166 writer.startElement("text:sender-phone-private" );
2167 break;
2168 case VST_FAX:
2169 writer.startElement("text:sender-fax" );
2170 break;
2171 case VST_COUNTRY:
2172 writer.startElement("text:sender-country" );
2173 break;
2174 case VST_TITLE:
2175 writer.startElement("text:title" );
2176 break;
2177 case VST_KEYWORDS:
2178 writer.startElement("text:keywords" );
2179 break;
2180 case VST_SUBJECT:
2181 writer.startElement("text:subject" );
2182 break;
2183 case VST_ABSTRACT:
2184 writer.startElement("text:description" );
2185 break;
2186 case VST_POSTAL_CODE:
2187 writer.startElement("text:sender-postal-code" );
2188 break;
2189 case VST_CITY:
2190 writer.startElement("text:sender-city" );
2191 break;
2192 case VST_STREET:
2193 writer.startElement("text:sender-street" );
2194 break;
2195 case VST_AUTHORTITLE:
2196 writer.startElement("text:sender-title" );
2197 break;
2198 case VST_AUTHORPOSITION:
2199 writer.startElement("text:sender-position" );
2200 break;
2201 case VST_INITIAL:
2202 writer.startElement("text:author-initials" );
2203 break;
2204 }
2205 writer.addTextNode( m_varValue.toString() );
2206 writer.endElement();
2207}
2208
2210{
2211 TQString value;
2212 switch( m_subtype ) {
2213 case VST_NONE:
2214 kdWarning() << "KoFieldVariable::recalc() called with m_subtype = VST_NONE !" << endl;
2215 break;
2216 case VST_FILENAME:
2217 value = m_doc->url().fileName();
2218 break;
2219 case VST_DIRECTORYNAME:
2220 value = m_doc->url().directory();
2221 break;
2222 case VST_PATHFILENAME:
2223 value=m_doc->url().path();
2224 break;
2225 case VST_FILENAMEWITHOUTEXTENSION:
2226 {
2227 TQString file=m_doc->url().fileName();
2228 int pos=file.findRev(".");
2229 if(pos !=-1)
2230 value=file.mid(0,pos);
2231 else
2232 value=file;
2233 }
2234 break;
2235 case VST_AUTHORNAME:
2236 case VST_EMAIL:
2237 case VST_COMPANYNAME:
2238 case VST_TELEPHONE_WORK:
2239 case VST_TELEPHONE_HOME:
2240 case VST_FAX:
2241 case VST_COUNTRY:
2242 case VST_POSTAL_CODE:
2243 case VST_CITY:
2244 case VST_STREET:
2245 case VST_AUTHORTITLE:
2246 case VST_AUTHORPOSITION:
2247 case VST_INITIAL:
2248 {
2249 KoDocumentInfo * info = m_doc->documentInfo();
2250 KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor *>(info->page( "author" ));
2251 if ( !authorPage )
2252 kdWarning() << "Author information not found in documentInfo !" << endl;
2253 else
2254 {
2255 if ( m_subtype == VST_AUTHORNAME )
2256 value = authorPage->fullName();
2257 else if ( m_subtype == VST_EMAIL )
2258 value = authorPage->email();
2259 else if ( m_subtype == VST_COMPANYNAME )
2260 value = authorPage->company();
2261 else if ( m_subtype == VST_TELEPHONE_WORK )
2262 value = authorPage->telephoneWork();
2263 else if ( m_subtype == VST_TELEPHONE_HOME )
2264 value = authorPage->telephoneHome();
2265 else if ( m_subtype == VST_FAX )
2266 value = authorPage->fax();
2267 else if ( m_subtype == VST_COUNTRY )
2268 value = authorPage->country();
2269 else if ( m_subtype == VST_POSTAL_CODE )
2270 value = authorPage->postalCode();
2271 else if ( m_subtype == VST_CITY )
2272 value = authorPage->city();
2273 else if ( m_subtype == VST_STREET )
2274 value = authorPage->street();
2275 else if ( m_subtype == VST_AUTHORTITLE )
2276 value = authorPage->title();
2277 else if ( m_subtype == VST_INITIAL )
2278 value = authorPage->initial();
2279 else if ( m_subtype == VST_AUTHORPOSITION )
2280 value = authorPage->position();
2281 }
2282 }
2283 break;
2284 case VST_TITLE:
2285 case VST_ABSTRACT:
2286 case VST_SUBJECT:
2287 case VST_KEYWORDS:
2288 {
2289 KoDocumentInfo * info = m_doc->documentInfo();
2290 KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>(info->page( "about" ));
2291 if ( !aboutPage )
2292 kdWarning() << "'About' page not found in documentInfo !" << endl;
2293 else
2294 {
2295 if ( m_subtype == VST_TITLE )
2296 value = aboutPage->title();
2297 else if ( m_subtype == VST_SUBJECT )
2298 value = aboutPage->subject();
2299 else if ( m_subtype == VST_KEYWORDS )
2300 value = aboutPage->keywords();
2301 else
2302 value = aboutPage->abstract();
2303 }
2304 }
2305 break;
2306 }
2307
2308 if (value.isEmpty()) // try the initial value
2309 value = m_varValue.toString();
2310
2311 if (value.isEmpty()) // still empty? give up
2312 value = i18n("<None>");
2313
2314 m_varValue = TQVariant( value );
2315
2316 resize();
2317}
2318
2319TQStringList KoFieldVariable::actionTexts()
2320{
2321 // NOTE: if you change here, also change fieldSubType()
2322 TQStringList lst;
2323 lst << i18n( "Author Name" );
2324 lst << i18n( "Title" );
2325 lst << i18n( "Initials" );
2326 lst << i18n( "Position" );
2327 lst << i18n( "Company" );
2328 lst << i18n( "Email" );
2329 lst << i18n( "Telephone (work)");
2330 lst << i18n( "Telephone (private)");
2331
2332 lst << i18n( "Fax");
2333 lst << i18n( "Street" );
2334 lst << i18n( "Postal Code" );
2335 lst << i18n( "City" );
2336 lst << i18n( "Country");
2337
2338 lst << i18n( "Document Title" );
2339 lst << i18n( "Document Abstract" );
2340 lst << i18n( "Document Subject" );
2341 lst << i18n( "Document Keywords" );
2342
2343 lst << i18n( "File Name" );
2344 lst << i18n( "File Name without Extension" );
2345 lst << i18n( "Directory Name" ); // is "Name" necessary ?
2346 lst << i18n( "Directory && File Name" );
2347 return lst;
2348}
2349
2350short int KoFieldVariable::variableSubType( short int menuNumber )
2351{
2352 return fieldSubType(menuNumber);
2353}
2354
2355KoFieldVariable::FieldSubType KoFieldVariable::fieldSubType(short int menuNumber)
2356{
2357 // NOTE: if you change here, also change actionTexts()
2358 FieldSubType v;
2359 switch (menuNumber)
2360 {
2361 case 0: v = VST_AUTHORNAME;
2362 break;
2363 case 1: v = VST_AUTHORTITLE;
2364 break;
2365 case 2: v = VST_INITIAL;
2366 break;
2367 case 3: v = VST_AUTHORPOSITION;
2368 break;
2369 case 4: v = VST_COMPANYNAME;
2370 break;
2371 case 5: v = VST_EMAIL;
2372 break;
2373 case 6: v = VST_TELEPHONE_WORK;
2374 break;
2375 case 7: v = VST_TELEPHONE_HOME;
2376 break;
2377 case 8: v = VST_FAX;
2378 break;
2379 case 9: v = VST_STREET;
2380 break;
2381 case 10: v = VST_POSTAL_CODE;
2382 break;
2383 case 11: v = VST_CITY;
2384 break;
2385 case 12: v = VST_COUNTRY;
2386 break;
2387 case 13: v = VST_TITLE;
2388 break;
2389 case 14: v = VST_ABSTRACT;
2390 break;
2391 case 15: v = VST_SUBJECT;
2392 break;
2393 case 16: v = VST_KEYWORDS;
2394 break;
2395 case 17: v = VST_FILENAME;
2396 break;
2397 case 18: v = VST_FILENAMEWITHOUTEXTENSION;
2398 break;
2399 case 19: v = VST_DIRECTORYNAME;
2400 break;
2401 case 20: v = VST_PATHFILENAME;
2402 break;
2403 default:
2404 v = VST_NONE;
2405 break;
2406 }
2407 return v;
2408}
2409
2411{
2412 return KoFieldVariable::actionTexts();
2413}
2414
2415/******************************************************************/
2416/* Class: KoLinkVariable */
2417/******************************************************************/
2418KoLinkVariable::KoLinkVariable( KoTextDocument *textdoc, const TQString & _linkName, const TQString & _ulr,KoVariableFormat *varFormat,KoVariableCollection *_varColl )
2419 : KoVariable( textdoc, varFormat,_varColl )
2420 ,m_url(_ulr)
2421{
2422 m_varValue = TQVariant( _linkName );
2423}
2424
2425TQString KoLinkVariable::fieldCode()
2426{
2427 return i18n("Link");
2428}
2429
2430void KoLinkVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
2431{
2432 if ( elem.localName() == "a" && elem.namespaceURI() == KoXmlNS::text ) {
2433 m_url = elem.attributeNS( KoXmlNS::xlink, "href", TQString());
2434 m_varValue = TQVariant(elem.text());
2435 }
2436}
2437
2438void KoLinkVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
2439{
2440 //<text:a xlink:type="simple" xlink:href="http://www.kde.org/" office:name="sdgfsdfgs">kde org wxc &lt;wxc </text:a>
2441 writer.startElement( "text:a" );
2442 writer.addAttribute( "xlink:type", "simple" );
2443 writer.addAttribute( "xlink:href", m_url );
2444 writer.addAttribute( "office:name", m_varValue.toString() );
2445 writer.addTextNode( m_varValue.toString() );
2446 writer.endElement();
2447
2448}
2449
2450TQString KoLinkVariable::text(bool realValue)
2451{
2452 if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
2453 return fieldCode();
2454 else
2455 return value();
2456}
2457
2458void KoLinkVariable::saveVariable( TQDomElement& parentElem )
2459{
2460 TQDomElement linkElem = parentElem.ownerDocument().createElement( "LINK" );
2461 parentElem.appendChild( linkElem );
2462 linkElem.setAttribute( "linkName", m_varValue.toString() );
2463 linkElem.setAttribute( "hrefName", m_url );
2464}
2465
2466void KoLinkVariable::load( TQDomElement& elem )
2467{
2468 KoVariable::load( elem );
2469 TQDomElement linkElem = elem.namedItem( "LINK" ).toElement();
2470 if (!linkElem.isNull())
2471 {
2472 m_varValue = TQVariant(linkElem.attribute("linkName"));
2473 m_url = linkElem.attribute("hrefName");
2474 }
2475}
2476
2477void KoLinkVariable::recalc()
2478{
2479 resize();
2480}
2481
2482TQStringList KoLinkVariable::actionTexts()
2483{
2484 return TQStringList( i18n( "Link..." ) );
2485}
2486
2487
2488void KoLinkVariable::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 )
2489{
2490 KoTextFormat * fmt = format();
2491 KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
2492
2493 bool displayLink = m_varColl->variableSetting()->displayLink();
2494 TQFont font( fmt->screenFont( zh ) );
2495 if ( m_varColl->variableSetting()->underlineLink() )
2496 font.setUnderline( true );
2497 TQColor textColor = displayLink ? cg.color( TQColorGroup::Link ) : fmt->color();
2498
2499 drawCustomItemHelper( p, x, y, wpix, hpix, ascentpix, cg, selected, offset, fmt, font, textColor, drawingShadow );
2500}
2501
2502
2503/******************************************************************/
2504/* Class: KoNoteVariable */
2505/******************************************************************/
2506KoNoteVariable::KoNoteVariable( KoTextDocument *textdoc, const TQString & _note,KoVariableFormat *varFormat,KoVariableCollection *_varColl )
2507 : KoVariable( textdoc, varFormat,_varColl )
2508 , m_createdNoteDate( TQDate::currentDate() )
2509{
2510 m_varValue = TQVariant( _note );
2511}
2512
2513TQString KoNoteVariable::fieldCode()
2514{
2515 return i18n("Note");
2516}
2517
2518TQString KoNoteVariable::createdNote() const
2519{
2520 return TDEGlobal::locale()->formatDate( m_createdNoteDate, false );
2521}
2522
2523void KoNoteVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
2524{
2525 const TQString localName = elem.localName();
2526 TQString note;
2527 if ( localName == "annotation" && elem.namespaceURI() == KoXmlNS::office )
2528 {
2529 TQDomElement date = KoDom::namedItemNS( elem, KoXmlNS::dc, "date" );
2530 m_createdNoteDate = TQDate::fromString( date.text(), TQt::ISODate );
2531 TQDomNode text = KoDom::namedItemNS( elem, KoXmlNS::text, "p" );
2532 for ( ; !text.isNull(); text = text.nextSibling() )
2533 {
2534 if ( text.isElement() )
2535 {
2536 TQDomElement t = text.toElement();
2537 note += t.text() + "\n";
2538 }
2539 }
2540 }
2541 m_varValue = TQVariant( note );
2542}
2543
2544void KoNoteVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
2545{
2546// <office:annotation><dc:date>2004-11-10</dc:date><text:p/><text:p>---- 10/11/2004, 16:18 ----</text:p><text:p>dfgsdfsdfg</text:p><text:p>---- 10/11/2004, 16:18 ----</text:p><text:p/><text:p>---- 10/11/2004, 16:18 ----</text:p><text:p>gs</text:p><text:p>---- 10/11/2004, 16:18 ----</text:p><text:p>fg</text:p></office:annotation>
2547 writer.startElement( "office:annotation" );
2548 writer.startElement( "dc:date" );
2549 writer.addTextNode( m_createdNoteDate.toString(TQt::ISODate) );
2550 writer.endElement();
2551 TQStringList text = TQStringList::split( "\n", m_varValue.toString() );
2552 for ( TQStringList::Iterator it = text.begin(); it != text.end(); ++it ) {
2553 writer.startElement( "text:p" );
2554 writer.addTextNode( *it );
2555 writer.endElement();
2556 }
2557 writer.endElement();
2558}
2559
2560void KoNoteVariable::saveVariable( TQDomElement& parentElem )
2561{
2562 TQDomElement linkElem = parentElem.ownerDocument().createElement( "NOTE" );
2563 parentElem.appendChild( linkElem );
2564 linkElem.setAttribute( "note", m_varValue.toString() );
2565}
2566
2567void KoNoteVariable::load( TQDomElement& elem )
2568{
2569 KoVariable::load( elem );
2570 TQDomElement linkElem = elem.namedItem( "NOTE" ).toElement();
2571 if (!linkElem.isNull())
2572 {
2573 m_varValue = TQVariant(linkElem.attribute("note"));
2574 }
2575}
2576
2577void KoNoteVariable::recalc()
2578{
2579 resize();
2580}
2581
2582TQStringList KoNoteVariable::actionTexts()
2583{
2584 return TQStringList( i18n( "Note..." ) );
2585}
2586
2587TQString KoNoteVariable::text(bool realValue)
2588{
2589 if (m_varColl->variableSetting()->displayComment() &&
2590 m_varColl->variableSetting()->displayFieldCode()&&!realValue)
2591 return fieldCode();
2592 else
2593 //for a note return just a "space" we can look at
2594 //note when we "right button"
2595 return TQString(" ");
2596
2597}
2598
2599void KoNoteVariable::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 )
2600{
2601 if ( !m_varColl->variableSetting()->displayComment())
2602 return;
2603
2604 KoTextFormat * fmt = format();
2605 //kdDebug(32500) << "KoNoteVariable::drawCustomItem index=" << index() << " x=" << x << " y=" << y << endl;
2606
2607 p->save();
2608 p->setPen( TQPen( fmt->color() ) );
2609 if ( fmt->textBackgroundColor().isValid() )
2610 p->fillRect( x, y, wpix, hpix, fmt->textBackgroundColor() );
2611 if ( selected )
2612 {
2613 p->setPen( TQPen( cg.color( TQColorGroup::HighlightedText ) ) );
2614 p->fillRect( x, y, wpix, hpix, cg.color( TQColorGroup::Highlight ) );
2615 }
2616 else if ( textDocument() && p->device()->devType() != TQInternal::Printer
2617 && !textDocument()->dontDrawingNoteVariable())
2618 {
2619 p->fillRect( x, y, wpix, hpix, TQt::yellow);
2620 p->setPen( TQPen( cg.color( TQColorGroup::Highlight ), 0, TQt::DotLine ) );
2621 p->drawRect( x, y, wpix, hpix );
2622 }
2623 //call it for use drawCustomItemHelper just for draw font effect
2624 KoVariable::drawCustomItem( p, x, y, wpix, hpix, ascentpix, cx, cy, cw, ch, cg, selected, offset, drawingShadow );
2625
2626 p->restore();
2627}
2628
2629void KoPageVariable::setSectionTitle( const TQString& _title )
2630{
2631 TQString title( _title );
2632 if ( title.isEmpty() )
2633 {
2634 title = i18n("<No title>");
2635 }
2636 m_varValue = TQVariant( title );
2637}
2638
2639
2640// ----------------------------------------------------------------
2641// class KoStatisticVariable
2642
2643
2644bool KoStatisticVariable::m_extendedType = false;
2645
2646
2647KoStatisticVariable::KoStatisticVariable( KoTextDocument *textdoc,
2648 short int subtype,
2649 KoVariableFormat *varFormat,
2650 KoVariableCollection *_varColl )
2651 : KoVariable( textdoc, varFormat, _varColl ),
2652 m_subtype( subtype )
2653{
2654}
2655
2656
2657TQStringList KoStatisticVariable::actionTexts()
2658{
2659 TQStringList lst;
2660 lst << i18n( "Number of Words" );
2661 lst << i18n( "Number of Sentences" );
2662 lst << i18n( "Number of Lines" );
2663 lst << i18n( "Number of Characters" );
2664 lst << i18n( "Number of Non-Whitespace Characters" );
2665 lst << i18n( "Number of Syllables" );
2666 lst << i18n( "Number of Frames" );
2667 lst << i18n( "Number of Embedded Objects" );
2668 lst << i18n( "Number of Pictures" );
2669 if ( m_extendedType )
2670 lst << i18n( "Number of Tables" );
2671 return lst;
2672}
2673
2674
2675void KoStatisticVariable::setVariableSubType( short int subtype )
2676{
2677 m_subtype = subtype;
2678 Q_ASSERT( m_varColl );
2679 KoVariableFormatCollection* fc = m_varColl->formatCollection();
2680 setVariableFormat(fc->format("NUMBER") );
2681}
2682
2683
2684TQStringList KoStatisticVariable::subTypeList()
2685{
2686 return KoStatisticVariable::actionTexts();
2687}
2688
2689
2690void KoStatisticVariable::saveVariable( TQDomElement& varElem )
2691{
2692 TQDomElement elem = varElem.ownerDocument().createElement( "STATISTIC" );
2693 varElem.appendChild( elem );
2694
2695 elem.setAttribute( "type", TQString::number(m_subtype) );
2696 elem.setAttribute( "value", TQString::number(m_varValue.toInt()) );
2697}
2698
2699
2700void KoStatisticVariable::load( TQDomElement &elem )
2701{
2702 KoVariable::load( elem );
2703
2704 TQDomElement e = elem.namedItem( "STATISTIC" ).toElement();
2705 if ( !e.isNull() ) {
2706 // FIXME: Error handling.
2707 m_subtype = e.attribute( "type" ).toInt();
2708 m_varValue = e.attribute( "value" ).toInt();
2709 }
2710}
2711
2712
2713void KoStatisticVariable::loadOasis( const TQDomElement &elem, KoOasisContext& /*context*/ )
2714{
2715 const TQString localName( elem.localName() );
2716 if ( localName == "object-count" )
2717 {
2718 m_subtype = VST_STATISTIC_NB_EMBEDDED;
2719 m_varValue = TQVariant( elem.text().toInt() );
2720 }
2721 else if ( localName == "table-count" )
2722 {
2723 m_subtype = VST_STATISTIC_NB_TABLE;
2724 m_varValue = TQVariant( elem.text().toInt() );
2725 }
2726 else if ( localName == "picture-count" )
2727 {
2728 m_subtype = VST_STATISTIC_NB_PICTURE;
2729 m_varValue = TQVariant( elem.text().toInt() );
2730 }
2731 else if ( localName == "word-count" )
2732 {
2733 m_subtype = VST_STATISTIC_NB_WORD;
2734 m_varValue = TQVariant( elem.text().toInt() );
2735 }
2736 else if ( localName == "character-count" )
2737 {
2738 m_subtype = VST_STATISTIC_NB_CHARACTERE;
2739 m_varValue = TQVariant( elem.text().toInt() );
2740 }
2741 else if ( localName == "frame-count" )
2742 {
2743 m_subtype = VST_STATISTIC_NB_FRAME;
2744 m_varValue = TQVariant( elem.text().toInt() );
2745 }
2746 else if ( localName == "line-count" )
2747 {
2748 m_subtype = VST_STATISTIC_NB_LINES;
2749 m_varValue = TQVariant( elem.text().toInt() );
2750 }
2751 else if ( localName == "sentence-count" )
2752 {
2753 m_subtype = VST_STATISTIC_NB_SENTENCE;
2754 m_varValue = TQVariant( elem.text().toInt() );
2755 }
2756 else if ( localName == "non-whitespace-character-count" )
2757 {
2758 m_subtype = VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE;
2759 m_varValue = TQVariant( elem.text().toInt() );
2760 }
2761 else if ( localName == "syllable-count" )
2762 {
2763 m_subtype = VST_STATISTIC_NB_SYLLABLE;
2764 m_varValue = TQVariant( elem.text().toInt() );
2765 }
2766 //TODO other copy
2767}
2768
2769void KoStatisticVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
2770{
2771 switch( m_subtype )
2772 {
2773 case VST_STATISTIC_NB_EMBEDDED:
2774 writer.startElement( "text:object-count" );
2775 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2776 writer.endElement();
2777 break;
2778 case VST_STATISTIC_NB_TABLE:
2779 writer.startElement( "text:table-count" );
2780 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2781 writer.endElement();
2782 break;
2783 case VST_STATISTIC_NB_PICTURE:
2784 writer.startElement( "text:picture-count" );
2785 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2786 writer.endElement();
2787 break;
2788 case VST_STATISTIC_NB_FRAME:
2789 //TODO verify that it's implemented into oasis file format
2790 writer.startElement( "text:frame-count" );
2791 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2792 writer.endElement();
2793 break;
2794 case VST_STATISTIC_NB_WORD:
2795 writer.startElement( "text:word-count" );
2796 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2797 writer.endElement();
2798 break;
2799 case VST_STATISTIC_NB_SENTENCE:
2800 //TODO verify that it's implemented into oasis file format
2801 writer.startElement( "text:sentence-count" );
2802 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2803 writer.endElement();
2804 break;
2805 case VST_STATISTIC_NB_CHARACTERE:
2806 writer.startElement( "text:character-count" );
2807 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2808 writer.endElement();
2809 break;
2810 case VST_STATISTIC_NB_LINES:
2811 //TODO verify that it's implemented into oasis file format
2812 writer.startElement( "text:line-count" );
2813 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2814 writer.endElement();
2815 break;
2816 case VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE:
2817 //TODO verify that it's implemented into oasis file format
2818 writer.startElement( "text:non-whitespace-character-count" );
2819 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2820 writer.endElement();
2821 break;
2822 case VST_STATISTIC_NB_SYLLABLE:
2823 //TODO verify that it's implemented into oasis file format
2824 writer.startElement( "text:syllable-count" );
2825 writer.addTextNode( TQString::number( m_varValue.toInt() ) );
2826 writer.endElement();
2827 break;
2828 }
2829}
2830
2831TQString KoStatisticVariable::fieldCode()
2832{
2833 if ( m_subtype == VST_STATISTIC_NB_FRAME )
2834 {
2835 return i18n( "Number of Frames" );
2836 }
2837 else if( m_subtype == VST_STATISTIC_NB_PICTURE )
2838 {
2839 return i18n( "Number of Pictures" );
2840 }
2841 else if( m_subtype == VST_STATISTIC_NB_TABLE )
2842 {
2843 return i18n( "Number of Tables" );
2844 }
2845 else if( m_subtype == VST_STATISTIC_NB_EMBEDDED )
2846 {
2847 return i18n( "Number of Embedded Objects" );
2848 }
2849 else if( m_subtype == VST_STATISTIC_NB_WORD )
2850 {
2851 return i18n( "Number of Words" );
2852 }
2853 else if( m_subtype == VST_STATISTIC_NB_SENTENCE )
2854 {
2855 return i18n( "Number of Sentences" );
2856 }
2857 else if( m_subtype == VST_STATISTIC_NB_LINES )
2858 {
2859 return i18n( "Number of Lines" );
2860 }
2861 else if ( m_subtype == VST_STATISTIC_NB_CHARACTERE )
2862 {
2863 return i18n( "Number of Characters" );
2864 }
2865 else if ( m_subtype == VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE )
2866 {
2867 return i18n( "Number of Non-Whitespace Characters" );
2868 }
2869 else if ( m_subtype == VST_STATISTIC_NB_SYLLABLE )
2870 {
2871 return i18n( "Number of Syllables" );
2872 }
2873 else
2874 return i18n( "Number of Frames" );
2875}
2876
2877
virtual void execute()=0
void setMainWidget(TQWidget *widget)
Command created when changing the properties of a variable's format (e.g.
Command created when changing the subtype of a variable (turning "fixed date" into "variable date").
A custom variable is a variable whose value is entered by the user.
Definition KoVariable.h:552
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
virtual void saveVariable(TQDomElement &parentElem)
Variable should reimplement this to implement saving.
virtual TQString text(bool realValue=false)
Returns the text to be displayed for this variable It doesn't need to be cached, convert() is fast,...
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
Date-related variables.
Definition KoVariable.h:460
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
virtual TQStringList subTypeList()
List of available subtypes (translated). Use variableSubType() to map index to ID.
virtual void saveVariable(TQDomElement &parentElem)
Variable should reimplement this to implement saving.
static TQCString defaultFormat()
Return the default date format for old file.
virtual void resize()
Reimplement this to calculate the item width It is important to start with "if ( m_deleted ) return;"...
static TQCString formatStr(int &correct)
Ask the user and return the date format string with prefix "DATE".
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
The KOffice document class.
Definition KoDocument.h:61
KoDocumentInfo * documentInfo() const
Any variable that is a string, and whose value is automatically determined - as opposed to custom var...
Definition KoVariable.h:584
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
virtual short int variableSubType(short int menuNumber)
Converts menuNumber to field variable subtype number.
virtual void saveVariable(TQDomElement &parentElem)
Variable should reimplement this to implement saving.
virtual TQStringList subTypeList()
List of available subtypes (translated). Use variableSubType() to map index to ID.
virtual TQString text(bool realValue=false)
Returns the text to be displayed for this variable It doesn't need to be cached, convert() is fast,...
static FieldSubType fieldSubType(short int menuNumber)
Converts menuNumber to field variable subtype number.
Used during loading of Oasis format (and discarded at the end of the loading).
Represents a collection of items (config-item or maps).
Parse settings.xml file.
Items itemSet(const TQString &itemSetName) const
Returns the toplevel item-set named itemSetName.
const DataFormatsMap & dataFormats() const
Value (date/time/number...) formats found while parsing styles.
virtual void saveVariable(TQDomElement &parentElem)
Variable should reimplement this to implement saving.
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
virtual void setVariableSubType(short int subtype)
Set this variable's subtype.
virtual TQStringList subTypeList()
List of available subtypes (translated). Use variableSubType() to map index to ID.
Used during saving to Oasis format (and discarded at the end of the saving).
KoTextCustomItem is the base class for custom items (i.e.
KoTextFormat * format() const
The formatting given to this 'special' character Slightly slow (does a linear search in the paragraph...
KoTextDocument * textDocument() const
The text document in which this customitem is.
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
Each character (KoTextStringChar) points to a KoTextFormat that defines the formatting of that charac...
const TQFontMetrics & refFontMetrics() const
TQFont screenFont(const KoTextZoomHandler *zh) const
Returns the font to be used at the zoom & resolution given by 'zh'.
static TQColor defaultTextColor(TQPainter *painter)
Call this when a text color is set to 'invalid', meaning 'whatever the default for the color scheme i...
This class extends KoZoomHandler to add support for WYSIWYG text layouting.
static double ptToLayoutUnitPt(double pt)
Not zoom dependent.
int layoutUnitToPixelX(int lupix) const
The "layout unit pixel" -> "[zoomed] view pixel" conversions.
int pixelToLayoutUnitX(int x) const
The "[zoomed] view pixel" -> "layout unit pixel" conversions.
Time-related variables.
Definition KoVariable.h:505
static TQCString defaultFormat()
Return the default date format for old file.
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
virtual void saveVariable(TQDomElement &parentElem)
Variable should reimplement this to implement saving.
virtual void recalc()
Reimplemented by KoVariable to recalculate the value.
static TQCString formatStr(int &_correct)
Returns the time format string with prefix "TIME".
virtual TQStringList subTypeList()
List of available subtypes (translated). Use variableSubType() to map index to ID.
virtual void resize()
Reimplement this to calculate the item width It is important to start with "if ( m_deleted ) return;"...
Implementation of the "date" formats TODO: merge with KoVariableTimeFormat, for a single TQDateTime-b...
Definition KoVariable.h:170
virtual void load(const TQCString &key)
Create a format from this key.
virtual TQString convert(const TQVariant &data) const
Use this format to convert a piece of data into a string.
virtual TQCString key() const
Return a key describing this format.
virtual TQCString getKey(const TQString &props) const
The collection of formats for variables.
Definition KoVariable.h:263
KoVariableFormat * format(const TQCString &key)
Find or create the format for the given key.
void clear()
Forget (and erase) all the formats this collection knows about.
Definition KoVariable.h:270
Class: KoVariableFormat Base class for a variable format - held by KWDocument.
Definition KoVariable.h:122
virtual TQCString key() const =0
Return a key describing this format.
virtual TQString formatProperties() const
Definition KoVariable.h:154
virtual TQString convert(const TQVariant &data) const =0
Use this format to convert a piece of data into a string.
virtual TQStringList formatPropsList() const
Definition KoVariable.h:158
virtual void setFormatProperties(const TQString &)
Set the properties of this format, e.g.
Definition KoVariable.h:150
virtual void load(const TQCString &key)=0
Create a format from this key.
Implementation of the string format.
Definition KoVariable.h:235
virtual TQCString key() const
Return a key describing this format.
virtual TQString convert(const TQVariant &data) const
Use this format to convert a piece of data into a string.
virtual TQCString getKey(const TQString &props) const
Implementation of the "time" formats.
Definition KoVariable.h:202
virtual TQCString key() const
Return a key describing this format.
virtual TQString convert(const TQVariant &data) const
Use this format to convert a piece of data into a string.
virtual void load(const TQCString &)
Create a format from this key.
virtual TQCString getKey(const TQString &props) const
A KoVariable is a custom item, i.e.
Definition KoVariable.h:364
virtual void 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)
All coordinates are in pixels.
virtual TQStringList subTypeList()
List of available subtypes (translated). Use variableSubType() to map index to ID.
TQVariant varValue() const
Return the variable value, as a TQVariant, before format conversion.
Definition KoVariable.h:405
void drawCustomItemHelper(TQPainter *p, int x, int y, int wpix, int hpix, int ascentpix, const TQColorGroup &cg, bool selected, int offset, KoTextFormat *fmt, const TQFont &font, TQColor textColor, bool drawingShadow)
Called by drawCustomItem.
virtual TQString text(bool realValue=false)
Returns the text to be displayed for this variable It doesn't need to be cached, convert() is fast,...
virtual void resize()
Reimplement this to calculate the item width It is important to start with "if ( m_deleted ) return;"...
virtual void saveVariable(TQDomElement &parentElem)=0
Variable should reimplement this to implement saving.
virtual void saveOasis(KoXmlWriter &writer, KoSavingContext &context) const
Save to Oasis XML.
virtual void save(TQDomElement &parentElem)
Save the variable.
void recalcAndRepaint()
Ask this variable to recalculate and to repaint itself Only use this if you're working on a single va...
A class for writing out XML (to any TQIODevice), with a special attention on performance.
Definition KoXmlWriter.h:37
void addConfigItem(const TQString &configName, const TQString &value)
Special helper for writing config item into settings.xml.
void startElement(const char *tagName, bool indentInside=true)
Start a new element, as a child of the current element.
void addTextNode(const TQString &str)
Overloaded version of addTextNode( const char* ), which is a bit slower because it needs to convert s...
void endElement()
Terminate the current element.
void addAttribute(const char *attrName, const TQString &value)
Overloaded version of addAttribute( const char*, const char* ), which is a bit slower because it need...
Definition KoXmlWriter.h:76
virtual void setChecked(bool)
const char * name(StdAction id)
KOFFICECORE_EXPORT TQDomElement namedItemNS(const TQDomNode &node, const char *nsURI, const char *localName)
A namespace-aware version of TQDomNode::namedItem(), which also takes care of casting to a TQDomEleme...
Definition KoDom.cpp:22