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