F:/KPlato/koffice/libs/kotext/KoVariable.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C) 1998, 1999 Reginald Stadlbauer <reggie@kde.org>
00003    Copyright (C) 2005 David Faure <faure@kde.org>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "KoVariable.h"
00022 #include "KoVariable.moc"
00023 #include "KoTextZoomHandler.h"
00024 #include "TimeFormatWidget.h"
00025 #include "DateFormatWidget.h"
00026 #include "KoTextCommand.h"
00027 #include "KoTextObject.h"
00028 #include "KoTextParag.h"
00029 #include "KoOasisContext.h"
00030 #include <KoOasisSettings.h>
00031 
00032 #include <KoDocumentInfo.h>
00033 #include <KoOasisStyles.h>
00034 #include <KoXmlWriter.h>
00035 #include <KoDocument.h>
00036 #include <KoXmlNS.h>
00037 #include <KoDom.h>
00038 
00039 #include <klocale.h>
00040 #include <kdebug.h>
00041 #include <kglobal.h>
00042 #include <kdialog.h>
00043 #include <kconfig.h>
00044 #include <kdeversion.h>
00045 #include <kinstance.h>
00046 #include <kcalendarsystem.h>
00047 #include <kseparatoraction.h>
00048 #include <ktoggleaction.h>
00049 #include <kaboutdata.h>
00050 
00051 #include <QStringList>
00052 #include <QComboBox>
00053 #include <q3valuelist.h>
00054 
00055 #include <QRadioButton>
00056 //Added by qt3to4:
00057 #include <QString>
00058 #include <Q3PtrList>
00059 
00060 #include "IsoDuration.h"
00061 
00062 class KoVariableSettings::KoVariableSettingPrivate
00063 {
00064 public:
00065     KoVariableSettingPrivate()
00066     {
00067         m_lastPrintingDate.setTime_t(0); // Default is 1970-01-01 midnight locale time
00068     }
00069     QDateTime m_lastPrintingDate;
00070     QDateTime m_creationDate;
00071     QDateTime m_modificationDate;
00072 };
00073 
00074 
00075 KoVariableSettings::KoVariableSettings()
00076 {
00077     d = new KoVariableSettingPrivate;
00078     m_startingPageNumber = 1;
00079     m_displayLink = true;
00080     m_displayComment = true;
00081     m_underlineLink = true;
00082     m_displayFieldCode = false;
00083 }
00084 
00085 KoVariableSettings::~KoVariableSettings()
00086 {
00087     delete d;
00088     d = 0;
00089 }
00090 
00091 QDateTime KoVariableSettings::lastPrintingDate() const
00092 {
00093     return d->m_lastPrintingDate;
00094 }
00095 
00096 void KoVariableSettings::setLastPrintingDate( const QDateTime & _date)
00097 {
00098     d->m_lastPrintingDate = _date;
00099 }
00100 
00101 QDateTime KoVariableSettings::creationDate() const
00102 {
00103     return d->m_creationDate;
00104 }
00105 
00106 void KoVariableSettings::setCreationDate( const QDateTime & _date )
00107 {
00108     d->m_creationDate = _date;
00109 }
00110 
00111 QDateTime KoVariableSettings::modificationDate() const
00112 {
00113     return d->m_modificationDate;
00114 }
00115 
00116 void KoVariableSettings::setModificationDate( const QDateTime & _date)
00117 {
00118     d->m_modificationDate = _date;
00119 }
00120 
00121 void KoVariableSettings::saveOasis( KoXmlWriter &settingsWriter ) const
00122 {
00123     settingsWriter.startElement("config:config-item-set");
00124     settingsWriter.addAttribute("config:name", "configuration-variable-settings");
00125     settingsWriter.addConfigItem("displaylink", m_displayLink );
00126     settingsWriter.addConfigItem( "underlinelink", m_underlineLink);
00127     settingsWriter.addConfigItem( "displaycomment", m_displayComment);
00128     settingsWriter.addConfigItem( "displayfieldcode", m_displayFieldCode);
00129     // m_startingPageNumber isn't saved to OASIS. Applications must use either
00130     // style:page-number in the first parag of a page (see KoTextParag), or
00131     // style:first-page-number in style:page-layout, for spreadsheets etc.
00132     if ( d->m_lastPrintingDate.isValid())
00133         settingsWriter.addConfigItem("lastPrintingDate", d->m_lastPrintingDate.toString(Qt::ISODate));
00134 
00135     if ( d->m_creationDate.isValid())
00136         settingsWriter.addConfigItem("creationDate", d->m_creationDate.toString(Qt::ISODate));
00137 
00138     if ( d->m_modificationDate.isValid())
00139         settingsWriter.addConfigItem("modificationDate", d->m_modificationDate.toString(Qt::ISODate));
00140 
00141     settingsWriter.endElement(); // config:config-item-set
00142 }
00143 
00144 void KoVariableSettings::loadOasis(const KoOasisSettings&settingsDoc)
00145 {
00146     KoOasisSettings::Items configurationSettings = settingsDoc.itemSet( "configuration-variable-settings" );
00147     if ( !configurationSettings.isNull() )
00148     {
00149         m_displayLink = configurationSettings.parseConfigItemBool( "displaylink", true );
00150         m_underlineLink = configurationSettings.parseConfigItemBool( "underlinelink", true );
00151         m_displayComment = configurationSettings.parseConfigItemBool( "displaycomment", true );
00152         m_displayFieldCode = configurationSettings.parseConfigItemBool( "displayfieldcode", false );
00153 
00154         QString str = configurationSettings.parseConfigItemString( "lastPrintingDate" );
00155         if ( !str.isEmpty() )
00156             d->m_lastPrintingDate = QDateTime::fromString( str, Qt::ISODate );
00157         else
00158             d->m_lastPrintingDate.setTime_t(0); // 1970-01-01 00:00:00.000 locale time
00159 
00160         str = configurationSettings.parseConfigItemString( "creationDate" );
00161         if ( !str.isEmpty() ) {
00162             d->m_creationDate = QDateTime::fromString( str, Qt::ISODate );
00163         }
00164 
00165         str = configurationSettings.parseConfigItemString( "modificationDate" );
00166         if ( !str.isEmpty() )
00167             d->m_modificationDate = QDateTime::fromString( str, Qt::ISODate );
00168 
00169         // m_startingPageNumber isn't loaded from OASIS here. KWTextParag::loadOasis does it.
00170     }
00171 }
00172 
00173 void KoVariableSettings::save( QDomElement &parentElem )
00174 {
00175      QDomElement elem = parentElem.ownerDocument().createElement( "VARIABLESETTINGS" );
00176      parentElem.appendChild( elem );
00177     if(m_startingPageNumber!=1)
00178     {
00179         elem.setAttribute( "startingPageNumber", m_startingPageNumber );
00180     }
00181     elem.setAttribute("displaylink",(int)m_displayLink);
00182     elem.setAttribute("underlinelink",(int)m_underlineLink);
00183     elem.setAttribute("displaycomment",(int)m_displayComment);
00184     elem.setAttribute("displayfieldcode", (int)m_displayFieldCode);
00185 
00186     if ( d->m_lastPrintingDate.isValid())
00187         elem.setAttribute("lastPrintingDate", d->m_lastPrintingDate.toString(Qt::ISODate));
00188 
00189     if ( d->m_creationDate.isValid())
00190         elem.setAttribute("creationDate", d->m_creationDate.toString(Qt::ISODate));
00191 
00192     if ( d->m_modificationDate.isValid())
00193         elem.setAttribute("modificationDate", d->m_modificationDate.toString(Qt::ISODate));
00194 }
00195 
00196 void KoVariableSettings::load( QDomElement &elem )
00197 {
00198     QDomElement e = elem.namedItem( "VARIABLESETTINGS" ).toElement();
00199     if (!e.isNull())
00200     {
00201         if(e.hasAttribute("startingPageNumber"))
00202             m_startingPageNumber = e.attribute("startingPageNumber").toInt();
00203         if(e.hasAttribute("displaylink"))
00204             m_displayLink=(bool)e.attribute("displaylink").toInt();
00205         if(e.hasAttribute("underlinelink"))
00206             m_underlineLink=(bool)e.attribute("underlinelink").toInt();
00207         if(e.hasAttribute("displaycomment"))
00208             m_displayComment=(bool)e.attribute("displaycomment").toInt();
00209         if (e.hasAttribute("displayfieldcode"))
00210             m_displayFieldCode=(bool)e.attribute("displayfieldcode").toInt();
00211 
00212         if (e.hasAttribute("lastPrintingDate"))
00213             d->m_lastPrintingDate = QDateTime::fromString( e.attribute( "lastPrintingDate" ), Qt::ISODate );
00214         else
00215             d->m_lastPrintingDate.setTime_t(0); // 1970-01-01 00:00:00.000 locale time
00216 
00217         if (e.hasAttribute("creationDate")) {
00218             d->m_creationDate = QDateTime::fromString( e.attribute( "creationDate" ), Qt::ISODate );
00219         }
00220 
00221         if (e.hasAttribute("modificationDate"))
00222             d->m_modificationDate = QDateTime::fromString( e.attribute( "modificationDate" ), Qt::ISODate );
00223     }
00224 }
00225 
00226 KoVariableDateFormat::KoVariableDateFormat() : KoVariableFormat()
00227 {
00228 }
00229 
00230 QString KoVariableDateFormat::convert( const QVariant& data ) const
00231 {
00232     if ( data.type() != QVariant::Date && data.type() != QVariant::DateTime )
00233     {
00234         kWarning(32500)<<" Error in KoVariableDateFormat::convert. Value is a "
00235                       << data.typeName() << "(" << data.type() << ")" << endl;
00236         // dateTime will be invalid, then set to 1970-01-01
00237     }
00238     QDateTime dateTime ( data.toDateTime() );
00239     if ( !dateTime.isValid() )
00240         return i18n("No date set"); // e.g. old KWord documents
00241 
00242     if (m_strFormat.toLower() == "locale" || m_strFormat.isEmpty())
00243         return KGlobal::locale()->formatDate( dateTime.date(), false );
00244     else if ( m_strFormat.toLower() == "localeshort" )
00245         return KGlobal::locale()->formatDate( dateTime.date(), true );
00246     else if ( m_strFormat.toLower() == "localedatetime" )
00247         return KGlobal::locale()->formatDateTime( dateTime, false );
00248     else if ( m_strFormat.toLower() == "localedatetimeshort" )
00249         return KGlobal::locale()->formatDateTime( dateTime, true );
00250 
00251     QString tmp ( dateTime.toString(m_strFormat) );
00252     const int month = dateTime.date().month();
00253     tmp.replace("PPPP", KGlobal::locale()->calendar()->monthNamePossessive(month, false)); //long possessive month name
00254     tmp.replace("PPP",  KGlobal::locale()->calendar()->monthNamePossessive(month, true));  //short possessive month name
00255     return tmp;
00256 }
00257 
00258 QString KoVariableDateFormat::key() const
00259 {
00260     return getKey( m_strFormat );
00261 }
00262 
00263 QString KoVariableDateFormat::getKey( const QString& props ) const
00264 {
00265     return QString("DATE") + props.toUtf8();
00266 }
00267 
00268 void KoVariableDateFormat::load( const QString &key )
00269 {
00270     QString params( key.mid( 4 ) ); // skip "DATE"
00271     if ( !params.isEmpty() )
00272     {
00273         if (params[0] == '1' || params[0] == '0') // old m_bShort crap
00274             params = params.mid(1); // skip it
00275         m_strFormat = params;
00276     }
00277 }
00278 
00279 // Used by KoVariableFormatCollection::popupActionList(), to apply all formats
00280 // to the current data, in the popup menu.
00281 QStringList KoVariableDateFormat::staticFormatPropsList()
00282 {
00283     QStringList listDateFormat;
00284     listDateFormat<<"locale";
00285     listDateFormat<<"localeshort";
00286     listDateFormat<<"localedatetime";
00287     listDateFormat<<"localedatetimeshort";
00288     listDateFormat<<"dd/MM/yy";
00289     listDateFormat<<"dd/MM/yyyy";
00290     listDateFormat<<"MMM dd,yy";
00291     listDateFormat<<"MMM dd,yyyy";
00292     listDateFormat<<"dd.MMM.yyyy";
00293     listDateFormat<<"MMMM dd, yyyy";
00294     listDateFormat<<"ddd, MMM dd,yy";
00295     listDateFormat<<"dddd, MMM dd,yy";
00296     listDateFormat<<"MM-dd";
00297     listDateFormat<<"yyyy-MM-dd";
00298     listDateFormat<<"dd/yy";
00299     listDateFormat<<"MMMM";
00300     listDateFormat<<"yyyy-MM-dd hh:mm";
00301     listDateFormat<<"dd.MMM.yyyy hh:mm";
00302     listDateFormat<<"MMM dd,yyyy h:mm AP";
00303     listDateFormat<<"yyyy-MM-ddThh:mm:ss"; // ISO 8601
00304     return listDateFormat;
00305 }
00306 
00307 // Used by dateformatwidget_impl
00308 // TODO: shouldn't it apply the formats to the value, like the popupmenu does?
00309 QStringList KoVariableDateFormat::staticTranslatedFormatPropsList()
00310 {
00311     QStringList listDateFormat;
00312     listDateFormat<<i18n("Locale date format");
00313     listDateFormat<<i18n("Short locale date format");
00314     listDateFormat<<i18n("Locale date & time format");
00315     listDateFormat<<i18n("Short locale date & time format");
00316     listDateFormat<<"dd/MM/yy";
00317     listDateFormat<<"dd/MM/yyyy";
00318     listDateFormat<<"MMM dd,yy";
00319     listDateFormat<<"MMM dd,yyyy";
00320     listDateFormat<<"dd.MMM.yyyy";
00321     listDateFormat<<"MMMM dd, yyyy";
00322     listDateFormat<<"ddd, MMM dd,yy";
00323     listDateFormat<<"dddd, MMM dd,yy";
00324     listDateFormat<<"MM-dd";
00325     listDateFormat<<"yyyy-MM-dd";
00326     listDateFormat<<"dd/yy";
00327     listDateFormat<<"MMMM";
00328     listDateFormat<<"yyyy-MM-dd hh:mm";
00329     listDateFormat<<"dd.MMM.yyyy hh:mm";
00330     listDateFormat<<"MMM dd,yyyy h:mm AP";
00331     listDateFormat<<"yyyy-MM-ddThh:mm:ss"; // ISO 8601
00332     return listDateFormat;
00333 }
00334 
00336 
00337 KoVariableTimeFormat::KoVariableTimeFormat() : KoVariableFormat()
00338 {
00339 }
00340 
00341 void KoVariableTimeFormat::load( const QString &key )
00342 {
00343     QString params( key.mid( 4 ) );
00344     if ( !params.isEmpty() )
00345         m_strFormat = params;
00346 }
00347 
00348 QString KoVariableTimeFormat::convert( const QVariant & time ) const
00349 {
00350     if ( time.type() != QVariant::Time )
00351     {
00352         kDebug(32500)<<" Error in KoVariableTimeFormat::convert. Value is a "
00353                       << time.typeName() << "(" << time.type() << ")" << endl;
00354         return QString::null;
00355     }
00356 
00357     if( m_strFormat.toLower() == "locale" || m_strFormat.isEmpty() )
00358         return KGlobal::locale()->formatTime( time.toTime() );
00359     return time.toTime().toString(m_strFormat);
00360 }
00361 
00362 QString KoVariableTimeFormat::key() const
00363 {
00364     return getKey( m_strFormat );
00365 }
00366 
00367 QString KoVariableTimeFormat::getKey( const QString& props ) const
00368 {
00369     return QString("TIME") + props.toUtf8();
00370 }
00371 
00372 // Used by KoVariableFormatCollection::popupActionList(), to apply all formats
00373 // to the current data, in the popup menu.
00374 QStringList KoVariableTimeFormat::staticFormatPropsList()
00375 {
00376     QStringList listTimeFormat;
00377     listTimeFormat<<"locale";
00378     listTimeFormat<<"hh:mm";
00379     listTimeFormat<<"hh:mm:ss";
00380     listTimeFormat<<"hh:mm AP";
00381     listTimeFormat<<"hh:mm:ss AP";
00382     listTimeFormat<<"mm:ss.zzz";
00383     return listTimeFormat;
00384 }
00385 
00386 // Used by timeformatwidget_impl
00387 QStringList KoVariableTimeFormat::staticTranslatedFormatPropsList()
00388 {
00389     QStringList listTimeFormat;
00390     listTimeFormat<<i18n("Locale format");
00391     listTimeFormat<<"hh:mm";
00392     listTimeFormat<<"hh:mm:ss";
00393     listTimeFormat<<"hh:mm AP";
00394     listTimeFormat<<"hh:mm:ss AP";
00395     listTimeFormat<<"mm:ss.zzz";
00396     return listTimeFormat;
00397 }
00398 
00400 
00401 QString KoVariableStringFormat::convert( const QVariant & string ) const
00402 {
00403     if ( string.type() != QVariant::String )
00404     {
00405         kDebug(32500)<<" Error in KoVariableStringFormat::convert. Value is a " << string.typeName() << endl;
00406         return QString::null;
00407     }
00408 
00409     return string.toString();
00410 }
00411 
00412 QString KoVariableStringFormat::key() const
00413 {
00414     return getKey( QString::null );
00415     // TODO prefix & suffix
00416 }
00417 
00418 QString KoVariableStringFormat::getKey( const QString& props ) const
00419 {
00420     return QString("STRING") + props.toUtf8();
00421 }
00422 
00424 
00425 QString KoVariableNumberFormat::convert( const QVariant &value ) const
00426 {
00427     if ( value.type() != QVariant::Int )
00428     {
00429         kDebug(32500)<<" Error in KoVariableNumberFormat::convert. Value is a " << value.typeName() << endl;
00430         return QString::null;
00431     }
00432 
00433     return QString::number( value.toInt() );
00434 }
00435 
00436 QString KoVariableNumberFormat::key() const
00437 {
00438     return getKey(QString::null);
00439 }
00440 
00441 QString KoVariableNumberFormat::getKey( const QString& props ) const
00442 {
00443     return QString("NUMB") + props.toUtf8();
00444 }
00445 
00447 
00448 KoVariableFormatCollection::KoVariableFormatCollection()
00449 {
00450     m_dict.setAutoDelete( true );
00451 }
00452 
00453 KoVariableFormat * KoVariableFormatCollection::format( const QString &key )
00454 {
00455     KoVariableFormat *f = m_dict[ key.toLatin1() ];
00456     if (f)
00457         return f;
00458     else
00459         return createFormat( key );
00460 }
00461 
00462 KoVariableFormat * KoVariableFormatCollection::createFormat( const QString &key )
00463 {
00464     kDebug(32500) << "KoVariableFormatCollection: creating format for key=" << key << endl;
00465     KoVariableFormat * format = 0L;
00466     // The first 4 chars identify the class
00467     QString type = key.left(4);
00468     if ( type == "DATE" )
00469         format = new KoVariableDateFormat();
00470     else if ( type == "TIME" )
00471         format = new KoVariableTimeFormat();
00472     else if ( type == "NUMB" ) // this type of programming makes me numb ;)
00473         format = new KoVariableNumberFormat();
00474     else if ( type == "STRI" )
00475         format = new KoVariableStringFormat();
00476 
00477     if ( format )
00478     {
00479         format->load( key );
00480         m_dict.insert( format->key().toLatin1()/* not 'key', it could be incomplete */, format );
00481     }
00482     return format;
00483 }
00484 
00485 /******************************************************************/
00486 /* Class:       KoVariableCollection                              */
00487 /******************************************************************/
00488 KoVariableCollection::KoVariableCollection(KoVariableSettings *_settings, KoVariableFormatCollection *formatCollection)
00489 {
00490     m_variableSettings = _settings;
00491     m_varSelected = 0L;
00492     m_formatCollection = formatCollection;
00493 }
00494 
00495 KoVariableCollection::~KoVariableCollection()
00496 {
00497     delete m_variableSettings;
00498 }
00499 
00500 void KoVariableCollection::clear()
00501 {
00502     variables.clear();
00503     varValues.clear();
00504     m_varSelected = 0;
00505 }
00506 
00507 void KoVariableCollection::registerVariable( KoVariable *var )
00508 {
00509     if ( !var )
00510         return;
00511     variables.append( var );
00512 }
00513 
00514 void KoVariableCollection::unregisterVariable( KoVariable *var )
00515 {
00516     variables.take( variables.findRef( var ) );
00517 }
00518 
00519 Q3ValueList<KoVariable *> KoVariableCollection::recalcVariables(int type)
00520 {
00521     Q3ValueList<KoVariable *> modifiedVariables;
00522     Q3PtrListIterator<KoVariable> it( variables );
00523     for ( ; it.current() ; ++it )
00524     {
00525         KoVariable* variable = it.current();
00526         if ( variable->isDeleted() )
00527             continue;
00528         if ( variable->type() == type || type == VT_ALL )
00529         {
00530             QVariant oldValue = variable->varValue();
00531             variable->recalc();
00532             if(variable->height == 0)
00533                 variable->resize();
00534             if ( variable->varValue() != oldValue )
00535                 modifiedVariables.append( variable );
00536             KoTextParag * parag = variable->paragraph();
00537             if ( parag )
00538             {
00539                 //kDebug(32500) << "KoDoc::recalcVariables -> invalidating parag " << parag->paragId() << endl;
00540                 parag->invalidate( 0 );
00541                 parag->setChanged( true );
00542             }
00543         }
00544     }
00545 #if 0
00546     // TODO pass list of textdocuments as argument
00547     // Or even better, call emitRepaintChanged on all modified textobjects
00548     if( !modifiedVariables.isEmpty() )
00549         emit repaintVariable();
00550 #endif
00551     return modifiedVariables;
00552 }
00553 
00554 
00555 void KoVariableCollection::setVariableValue( const QString &name, const QString &value )
00556 {
00557     varValues[ name ] = value;
00558 }
00559 
00560 QString KoVariableCollection::getVariableValue( const QString &name ) const
00561 {
00562     if ( !varValues.contains( name ) )
00563         return i18n( "No value" );
00564     return varValues[ name ];
00565 }
00566 
00567 bool KoVariableCollection::customVariableExist(const QString &varname) const
00568 {
00569     return varValues.contains( varname );
00570 }
00571 
00572 void KoVariableCollection::setVariableSelected(KoVariable * var)
00573 {
00574     m_varSelected=var;
00575 }
00576 
00577 // TODO change to QValueList<KAction *>, but only once plugActionList takes that
00578 QList<KAction*> KoVariableCollection::popupActionList() const
00579 {
00580     QList<KAction*> listAction;
00581     // Insert list of actions that change the subtype
00582     const QStringList subTypeList = m_varSelected->subTypeList();
00583     kDebug() << k_funcinfo << "current subtype=" << m_varSelected->subType() << endl;
00584     QStringList::ConstIterator it = subTypeList.begin();
00585     for ( int i = 0; it != subTypeList.end() ; ++it, ++i )
00586     {
00587         if ( !(*it).isEmpty() ) // in case of removed subtypes or placeholders
00588         {
00589             // We store the subtype number as the action name
00590             QString name; name.setNum(i);
00591             KToggleAction * act = new KToggleAction( *it, KShortcut(), 0, name );
00592             connect( act, SIGNAL(activated()), this, SLOT(slotChangeSubType()) );
00593             if ( i == m_varSelected->subType() )
00594                 act->setChecked( true );
00595             //m_subTextMap.insert( act, i );
00596             listAction.append( act );
00597         }
00598     }
00599     // Insert list of actions that change the format properties
00600     KoVariableFormat* format = m_varSelected->variableFormat();
00601     QString currentFormat = format->formatProperties();
00602 
00603     const QStringList list = format->formatPropsList();
00604     it = list.begin();
00605     for ( int i = 0; it != list.end() ; ++it, ++i )
00606     {
00607         if( i == 0 ) // first item, and list not empty
00608             listAction.append( new KSeparatorAction() );
00609 
00610         if ( !(*it).isEmpty() ) // in case of removed subtypes or placeholders
00611         {
00612             format->setFormatProperties( *it ); // temporary change
00613             QString text = format->convert( m_varSelected->varValue() );
00614             // We store the raw format as the action name
00615             KToggleAction * act = new KToggleAction(text, KShortcut(), 0, (*it).toUtf8());
00616             connect( act, SIGNAL(activated()), this, SLOT(slotChangeFormat()) );
00617             if ( (*it) == currentFormat )
00618                 act->setChecked( true );
00619             listAction.append( act );
00620         }
00621     }
00622 
00623     // Restore current format
00624     format->setFormatProperties( currentFormat );
00625     return listAction;
00626 }
00627 
00628 void KoVariableCollection::slotChangeSubType()
00629 {
00630     KAction * act = (KAction *)(sender());
00631     int menuNumber = act->objectName().toInt();
00632     int newSubType = m_varSelected->variableSubType(menuNumber);
00633     kDebug(32500) << "slotChangeSubType: menuNumber=" << menuNumber << " newSubType=" << newSubType << endl;
00634     if ( m_varSelected->subType() != newSubType )
00635     {
00636         KoChangeVariableSubType *cmd=new KoChangeVariableSubType(
00637             m_varSelected->subType(), newSubType, m_varSelected );
00638         cmd->execute();
00639         m_varSelected->textDocument()->emitNewCommand(cmd);
00640     }
00641 }
00642 
00643 void KoVariableCollection::slotChangeFormat()
00644 {
00645     KAction * act = (KAction *)(sender());
00646     QString newFormat = act->objectName();
00647     QString oldFormat = m_varSelected->variableFormat()->formatProperties();
00648     if (oldFormat != newFormat )
00649     {
00650         KCommand *cmd=new KoChangeVariableFormatProperties(
00651             oldFormat, newFormat, m_varSelected );
00652         cmd->execute();
00653         m_varSelected->textDocument()->emitNewCommand(cmd);
00654     }
00655 }
00656 
00657 KoVariable * KoVariableCollection::createVariable( int type, short int subtype, KoVariableFormatCollection * coll, KoVariableFormat *varFormat,KoTextDocument *textdoc, KoDocument * doc, int _correct, bool _forceDefaultFormat, bool /*loadFootNote*/ )
00658 {
00659     Q_ASSERT( coll == m_formatCollection ); // why do we need a parameter ?!?
00660     QString string;
00661     QStringList stringList;
00662     if ( varFormat == 0L )
00663     {
00664         // Get the default format for this variable (this method is only called in the interactive case, not when loading)
00665         switch ( type ) {
00666         case VT_DATE:
00667         case VT_DATE_VAR_KWORD10:  // compatibility with kword 1.0
00668         {
00669             if ( _forceDefaultFormat )
00670                 varFormat = coll->format( KoDateVariable::defaultFormat() );
00671             else
00672             {
00673                 QString result = KoDateVariable::formatStr(_correct);
00674                 if ( result.isNull() )//we cancel insert variable
00675                     return 0L;
00676                 varFormat = coll->format( result );
00677             }
00678             break;
00679         }
00680         case VT_TIME:
00681         case VT_TIME_VAR_KWORD10:  // compatibility with kword 1.0
00682         {
00683             if ( _forceDefaultFormat )
00684                 varFormat = coll->format( KoTimeVariable::defaultFormat() );
00685             else
00686             {
00687                 QString result = KoTimeVariable::formatStr(_correct);
00688                 if ( result.isNull() )//we cancel insert variable
00689                     return 0L;
00690                 varFormat = coll->format( result );
00691             }
00692             break;
00693         }
00694         case VT_PGNUM:
00695             varFormat = coll->format( "NUMBER" );
00696             break;
00697         case VT_FIELD:
00698         case VT_CUSTOM:
00699         case VT_MAILMERGE:
00700         case VT_LINK:
00701         case VT_NOTE:
00702             varFormat = coll->format( "STRING" );
00703             break;
00704         case VT_FOOTNOTE: // this is a KWord-specific variable
00705             kError() << "Footnote type not handled in KoVariableCollection: VT_FOOTNOTE" << endl;
00706             return 0L;
00707         case VT_STATISTIC:
00708             kError() << " Statistic type not handled in KoVariableCollection: VT_STATISTIC" << endl;
00709             return 0L;
00710         }
00711     }
00712     Q_ASSERT( varFormat );
00713     if ( varFormat == 0L ) // still 0 ? Impossible!
00714         return 0L ;
00715 
00716     kDebug(32500) << "Creating variable. Format=" << varFormat->key() << " type=" << type << endl;
00717     KoVariable * var = 0L;
00718     switch ( type ) {
00719         case VT_DATE:
00720         case VT_DATE_VAR_KWORD10:  // compatibility with kword 1.0
00721             var = new KoDateVariable( textdoc, subtype, varFormat, this, _correct );
00722             break;
00723         case VT_TIME:
00724         case VT_TIME_VAR_KWORD10:  // compatibility with kword 1.0
00725             var = new KoTimeVariable( textdoc, subtype, varFormat, this, _correct );
00726             break;
00727         case VT_PGNUM:
00728             kError() << "VT_PGNUM must be handled by the application's reimplementation of KoVariableCollection::createVariable" << endl;
00729             //var = new KoPageVariable( textdoc, subtype, varFormat, this );
00730             break;
00731         case VT_FIELD:
00732             var = new KoFieldVariable( textdoc, subtype, varFormat,this,doc );
00733             break;
00734         case VT_CUSTOM:
00735             var = new KoCustomVariable( textdoc, QString::null, varFormat, this);
00736             break;
00737         case VT_MAILMERGE:
00738             var = new KoMailMergeVariable( textdoc, QString::null, varFormat ,this);
00739             break;
00740         case VT_LINK:
00741             var = new KoLinkVariable( textdoc,QString::null, QString::null, varFormat ,this);
00742             break;
00743         case VT_NOTE:
00744             var = new KoNoteVariable( textdoc, QString::null, varFormat ,this);
00745             break;
00746     }
00747     Q_ASSERT( var );
00748     return var;
00749 }
00750 
00751 
00752 KoVariable* KoVariableCollection::loadOasisField( KoTextDocument* textdoc, const QDomElement& tag, KoOasisContext& context )
00753 {
00754     const QString localName( tag.localName() );
00755     const bool isTextNS = tag.namespaceURI() == KoXmlNS::text;
00756     QString key;
00757     int type = -1;
00758     if ( isTextNS )
00759     {
00760         if ( localName.endsWith( "date" ) || localName.endsWith( "time" ) )
00761         {
00762             QString dataStyleName = tag.attributeNS( KoXmlNS::style, "data-style-name", QString::null );
00763             QString dateFormat = "locale";
00764             const KoOasisStyles::DataFormatsMap& map = context.oasisStyles().dataFormats();
00765             KoOasisStyles::DataFormatsMap::const_iterator it = map.find( dataStyleName );
00766             if ( it != map.end() )
00767                 dateFormat = (*it).formatStr;
00768 
00769             // Only text:time is a pure time (the data behind is only h/m/s)
00770             // ### 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.)
00771             // Whereas print-time/creation-time etc. are actually related to a date/time value.
00772             if ( localName == "time" )
00773             {
00774                 type = VT_TIME;
00775                 key = "TIME" + dateFormat;
00776             }
00777             else
00778             {
00779                 type = VT_DATE;
00780                 key = "DATE" + dateFormat;
00781             }
00782         }
00783         else if (localName == "page-number" || localName == "page-count" )
00784         {
00785             type = VT_PGNUM;
00786             key = "NUMBER";
00787         }
00788         else if (localName == "chapter")
00789         {
00790             type = VT_PGNUM;
00791             key = "STRING";
00792         }
00793         else if (localName == "file-name")
00794         {
00795             type = VT_FIELD;
00796             key = "STRING";
00797         }
00798         else if (localName == "author-name"
00799                  || localName == "author-initials"
00800                  || localName == "subject"
00801                  || localName == "title"
00802                  || localName == "description"
00803                  || localName == "keywords")
00804         {
00805             type = VT_FIELD;
00806             key = "STRING";
00807         }
00808         else if ( localName.startsWith( "sender-" )
00809                   && localName != "sender-firstname" // not supported
00810                   && localName != "sender-lastname" // not supported
00811                   && localName != "sender-initials" // not supported
00812             )
00813         {
00814             type = VT_FIELD;
00815             key = "STRING";
00816         }
00817         else if ( localName == "variable-set"
00818                   || localName == "user-defined"
00819                   || localName == "user-field-get" )
00820         {
00821             key = "STRING";
00822             type = VT_CUSTOM;
00823         }
00824         else
00825             return 0L;
00826     }
00827     else if ( tag.namespaceURI() == KoXmlNS::office && localName == "annotation" )
00828     {
00829         type = VT_NOTE;
00830         key = "NUMBER";
00831     }
00832     else
00833     {
00834         // Not an error. It's simply not a variable tag (the caller doesn't check for that)
00835         return 0;
00836     }
00837 // TODO localName == "page-variable-get", "initial-creator" and many more
00838 // TODO VT_MAILMERGE
00839 
00840     return loadOasisFieldCreateVariable( textdoc, tag, context, key, type );
00841 }
00842 
00843 KoVariable* KoVariableCollection::loadOasisFieldCreateVariable( KoTextDocument* textdoc, const QDomElement& tag, KoOasisContext& context, const QString &key, int type )
00844 {
00845     KoVariableFormat * varFormat = key.isEmpty() ? 0 : m_formatCollection->format( key.toLatin1() );
00846     // If varFormat is 0 (no key specified), the default format will be used.
00847 
00848     KoVariable* var = createVariable( type, -1, m_formatCollection, varFormat, textdoc, context.koDocument(), 0 /*correct*/, true );
00849     var->loadOasis( tag, context );
00850     return var;
00851 }
00852 
00853 /******************************************************************/
00854 /* Class: KoVariable                                              */
00855 /******************************************************************/
00856 KoVariable::KoVariable( KoTextDocument *textdoc, KoVariableFormat *varFormat, KoVariableCollection *_varColl)
00857     : KoTextCustomItem( textdoc )
00858 {
00859     //d = new Private;
00860     m_varColl=_varColl;
00861     m_varFormat = varFormat;
00862     m_varColl->registerVariable( this );
00863     m_ascent = 0;
00864 }
00865 
00866 KoVariable::~KoVariable()
00867 {
00868     //kDebug(32500) << "KoVariable::~KoVariable " << this << endl;
00869     m_varColl->unregisterVariable( this );
00870     //delete d;
00871 }
00872 
00873 QStringList KoVariable::subTypeList()
00874 {
00875     return QStringList();
00876 }
00877 
00878 void KoVariable::resize()
00879 {
00880     if ( m_deleted )
00881         return;
00882     KoTextFormat *fmt = format();
00883     QFontMetrics fm = fmt->refFontMetrics();
00884     QString txt = text();
00885 
00886     width = 0;
00887      // size at 100%
00888     for ( int i = 0 ; i < (int)txt.length() ; ++i )
00889         width += fm.width( txt[i] ); // was fm.charWidth(txt,i), but see drawCustomItemHelper...
00890     // zoom to LU
00891     width = qRound( KoTextZoomHandler::ptToLayoutUnitPt( width ) );
00892     height = fmt->height();
00893     m_ascent = fmt->ascent();
00894     //kDebug(32500) << "KoVariable::resize text=" << txt << " width=" << width << " height=" << height << " ascent=" << m_ascent << endl;
00895 }
00896 
00897 void KoVariable::recalcAndRepaint()
00898 {
00899     recalc();
00900     KoTextParag * parag = paragraph();
00901     if ( parag )
00902     {
00903         //kDebug(32500) << "KoVariable::recalcAndRepaint -> invalidating parag " << parag->paragId() << endl;
00904         parag->invalidate( 0 );
00905         parag->setChanged( true );
00906     }
00907     textDocument()->emitRepaintChanged();
00908 }
00909 
00910 QString KoVariable::fieldCode()
00911 {
00912     return i18n("Variable");
00913 }
00914 
00915 QString KoVariable::text(bool realValue)
00916 {
00917     KoTextFormat *fmt = format();
00918     QString str;
00919     if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
00920         str = fieldCode();
00921     else
00922         str = m_varFormat->convert( m_varValue );
00923 
00924     return fmt->displayedString( str);
00925 }
00926 
00927 void KoVariable::drawCustomItem( QPainter* p, int x, int y, int wpix, int hpix, int ascentpix, int /*cx*/, int /*cy*/, int /*cw*/, int /*ch*/, const QColorGroup& cg, bool selected, int offset, bool drawingShadow )
00928 {
00929     KoTextFormat * fmt = format();
00930     KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
00931     QFont font( fmt->screenFont( zh ) );
00932     drawCustomItemHelper( p, x, y, wpix, hpix, ascentpix, cg, selected, offset, fmt, font, fmt->color(), drawingShadow );
00933 }
00934 
00935 void KoVariable::drawCustomItemHelper( QPainter* p, int x, int y, int wpix, int hpix, int ascentpix, const QColorGroup& cg, bool selected, int offset, KoTextFormat* fmt, const QFont& font, QColor textColor, bool drawingShadow )
00936 {
00937     // Important: the y value already includes the difference between the parag baseline
00938     // and the char's own baseline (ascent) (see paintDefault in korichtext.cpp)
00939     // So we just draw the text there. But we need the baseline for drawFontEffects...
00940     KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
00941 
00942     p->save();
00943 
00944     if ( fmt->textBackgroundColor().isValid() )
00945         p->fillRect( x, y, wpix, hpix, fmt->textBackgroundColor() );
00946 
00947     if ( drawingShadow ) // Use shadow color if drawing a shadow
00948     {
00949         textColor = fmt->shadowColor();
00950         p->setPen( textColor );
00951     }
00952     else if ( selected )
00953     {
00954         textColor = cg.color( QColorGroup::HighlightedText );
00955         p->setPen( QPen( textColor ) );
00956         p->fillRect( x, y, wpix, hpix, cg.color( QColorGroup::Highlight ) );
00957     }
00958     else if ( textDocument() && textDocument()->drawFormattingChars()
00959               && p->device()->devType() != QInternal::Printer )
00960     {
00961         textColor = cg.color( QColorGroup::Highlight );
00962         p->setPen( QPen ( textColor, 0, Qt::DotLine ) );
00963         p->drawRect( x, y, wpix, hpix );
00964     }
00965     else {
00966         if ( !textColor.isValid() ) // Resolve the color at this point
00967             textColor = KoTextFormat::defaultTextColor( p );
00968         p->setPen( QPen( textColor ) );
00969     }
00970 
00971     p->setFont( font ); // already done by KoTextCustomItem::draw but someone might
00972                         // change the font passed to drawCustomItemHelper (e.g. KoLinkVariable)
00973     QString str = text();
00974     KoTextParag::drawFontEffects( p, fmt, zh, font, textColor, x, ascentpix, wpix, y, hpix, str[0] );
00975     int posY = y + ascentpix + offset;
00976     if ( fmt->vAlign() == KoTextFormat::AlignSubScript )
00977         posY +=p->fontMetrics().height() / 6;
00978     if ( fmt->vAlign() != KoTextFormat::AlignSuperScript )
00979         posY -= fmt->offsetFromBaseLine();
00980     else if ( fmt->offsetFromBaseLine() < 0 )
00981         posY -= 2*fmt->offsetFromBaseLine();
00982 
00983     //p->drawText( x, posY, str );
00984     // We can't just drawText, it wouldn't use the same kerning as the one
00985     // that resize() planned for [which is zoom-independent].
00986     // We need to do the layout using layout units instead, so for simplicity
00987     // I just draw every char individually (whereas KoTextFormatter/KoTextParag
00988     // detect runs of text that can be drawn together)
00989     const int len = str.length();
00990     int xLU = zh->pixelToLayoutUnitX( x );
00991     QFontMetrics fm = fmt->refFontMetrics();
00992     for ( int i = 0; i < len; ++i )
00993     {
00994         const QChar ch = str[i];
00995         p->drawText( x, posY, ch );
00996         // Do like KoTextFormatter: do the layout in layout units.
00997         xLU += KoTextZoomHandler::ptToLayoutUnitPt( fm.width( ch ) );
00998         // And then compute the X position in pixels from the layout unit X.
00999         x = zh->layoutUnitToPixelX( xLU );
01000     }
01001 
01002     p->restore();
01003 }
01004 
01005 void KoVariable::save( QDomElement &parentElem )
01006 {
01007     //kDebug(32500) << "KoVariable::save" << endl;
01008     QDomElement variableElem = parentElem.ownerDocument().createElement( "VARIABLE" );
01009     parentElem.appendChild( variableElem );
01010     QDomElement typeElem = parentElem.ownerDocument().createElement( "TYPE" );
01011     variableElem.appendChild( typeElem );
01012     typeElem.setAttribute( "type", static_cast<int>( type() ) );
01013 
01016     typeElem.setAttribute( "key", m_varFormat->key() );
01017     typeElem.setAttribute( "text", text(true) );
01018     if ( correctValue() != 0)
01019         typeElem.setAttribute( "correct", correctValue() );
01020     saveVariable( variableElem );
01021 }
01022 
01023 void KoVariable::load( QDomElement & )
01024 {
01025 }
01026 
01027 
01028 void KoVariable::loadOasis( const QDomElement &/*elem*/, KoOasisContext& /*context*/ )
01029 {
01030     // nothing to do here, reimplemented in subclasses (make it pure virtual?)
01031 }
01032 
01033 void KoVariable::saveOasis( KoXmlWriter& /*writer*/, KoSavingContext& /*context*/ ) const
01034 {
01035 }
01036 
01037 void KoVariable::setVariableFormat( KoVariableFormat *_varFormat )
01038 {
01039     // TODO if ( _varFormat ) _varFormat->deref();
01040     m_varFormat = _varFormat;
01041     // TODO m_varFormat->ref();
01042 }
01043 
01044 #define addText( text, newFormat ) { \
01045         if ( !text.isEmpty() ) \
01046         { \
01047             newFormat +=text; \
01048             text=""; \
01049         } \
01050 }
01051 
01052 QString KoVariable::convertKlocaleToQDateTimeFormat( const QString & _format )
01053 {
01054     QString newFormat;
01055     QString format( _format );
01056     QString text;
01057     do
01058     {
01059         if ( format.startsWith( "%Y" ) )
01060         {
01061             addText( text, newFormat );
01062             newFormat+="yyyy";
01063             format = format.remove( 0, 2 );
01064         }
01065         else if ( format.startsWith( "%y" ) )
01066         {
01067             addText( text, newFormat );
01068             newFormat+="yyyy";
01069 
01070             format = format.remove( 0, 2 );
01071         }
01072         else if ( format.startsWith( "%n" ) )
01073         {
01074             addText( text, newFormat );
01075             newFormat+='M';
01076             format = format.remove( 0, 2 );
01077         }
01078         else if ( format.startsWith( "%m" ) )
01079         {
01080             addText( text, newFormat );
01081             newFormat+="MM";
01082             format = format.remove( 0, 2 );
01083         }
01084         else if ( format.startsWith( "%e" ) )
01085         {
01086             addText( text, newFormat );
01087             newFormat+='d';
01088             format = format.remove( 0, 2 );
01089         }
01090         else if ( format.startsWith( "%d" ) )
01091         {
01092             addText( text, newFormat );
01093             newFormat+="dd";
01094             format = format.remove( 0, 2 );
01095         }
01096         else if ( format.startsWith( "%b" ) )
01097         {
01098             addText( text, newFormat );
01099             newFormat+="MMM";
01100             format = format.remove( 0, 2 );
01101         }
01102         else if ( format.startsWith( "%B" ) )
01103         {
01104             addText( text, newFormat );
01105             newFormat+="MMMM";
01106             format = format.remove( 0, 2 );
01107         }
01108         else if ( format.startsWith( "%a" ) )
01109         {
01110             addText( text, newFormat );
01111             newFormat+="ddd";
01112 
01113             format = format.remove( 0, 2 );
01114         }
01115         else if ( format.startsWith( "%A" ) )
01116         {
01117             addText( text, newFormat );
01118             newFormat+="dddd";
01119             format = format.remove( 0, 2 );
01120         }
01121         if ( format.startsWith( "%H" ) ) //hh
01122         {
01123             //hour in 24h
01124             addText( text, newFormat );
01125             newFormat+="hh";
01126             format = format.remove( 0, 2 );
01127         }
01128         else if ( format.startsWith( "%k" ) )//h
01129         {
01130             addText( text, newFormat );
01131             newFormat+='h';
01132             format = format.remove( 0, 2 );
01133         }
01134         else if ( format.startsWith( "%I" ) )// ?????
01135         {
01136             addText( text, newFormat );
01137             //TODO hour in 12h
01138         }
01139         else if ( format.startsWith( "%l" ) )
01140         {
01141             addText( text, newFormat );
01142             //TODO hour in 12h with 1 digit
01143         }
01144         else if ( format.startsWith( "%M" ) )// mm
01145         {
01146             addText( text, newFormat );
01147             newFormat+="mm";
01148             format = format.remove( 0, 2 );
01149         }
01150         else if ( format.startsWith( "%S" ) ) //ss
01151         {
01152             addText( text, newFormat );
01153             newFormat+="ss";
01154             format = format.remove( 0, 2 );
01155         }
01156         else if ( format.startsWith( "%p" ) )
01157         {
01158             //TODO am or pm
01159             addText( text, newFormat );
01160             newFormat+="ap";
01161             format = format.remove( 0, 2 );
01162         }
01163 
01164         else
01165         {
01166             text += format[0];
01167             format = format.remove( 0, 1 );
01168         }
01169     }
01170     while ( format.length() > 0 );
01171     addText( text, format );
01172     return format;
01173 }
01174 
01175 
01176 /******************************************************************/
01177 /* Class: KoDateVariable                                          */
01178 /******************************************************************/
01179 KoDateVariable::KoDateVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *_varFormat, KoVariableCollection *_varColl, int _correctDate)
01180     : KoVariable( textdoc, _varFormat,_varColl ), m_subtype( subtype ), m_correctDate( _correctDate)
01181 {
01182 }
01183 
01184 QString KoDateVariable::fieldCode()
01185 {
01186     if ( m_subtype == VST_DATE_FIX )
01187         return i18n("Date (Fixed)");
01188     else if ( m_subtype == VST_DATE_CURRENT)
01189         return i18n("Date");
01190     else if ( m_subtype == VST_DATE_LAST_PRINTING)
01191         return i18n("Last Printing");
01192     else if ( m_subtype == VST_DATE_CREATE_FILE )
01193         return i18n( "File Creation");
01194     else if ( m_subtype == VST_DATE_MODIFY_FILE )
01195         return i18n( "File Modification");
01196     else
01197         return i18n("Date");
01198 }
01199 
01200 void KoDateVariable::resize()
01201 {
01202     KoTextFormat * fmt = format();
01203     QString oldLanguage;
01204     if ( !fmt->language().isEmpty())
01205     {
01206          oldLanguage=KGlobal::locale()->language();
01207          bool changeLanguage = KGlobal::locale()->setLanguage( fmt->language() );
01208          KoVariable::resize();
01209          if ( changeLanguage )
01210              KGlobal::locale()->setLanguage( oldLanguage );
01211     }
01212     else
01213         KoVariable::resize();
01214 }
01215 
01216 void KoDateVariable::recalc()
01217 {
01218     if ( m_subtype == VST_DATE_CURRENT )
01219         m_varValue = QDateTime::currentDateTime().addDays(m_correctDate);
01220     else if ( m_subtype == VST_DATE_LAST_PRINTING )
01221         m_varValue = m_varColl->variableSetting()->lastPrintingDate();
01222     else if ( m_subtype == VST_DATE_CREATE_FILE )
01223         m_varValue = m_varColl->variableSetting()->creationDate();
01224     else if ( m_subtype == VST_DATE_MODIFY_FILE )
01225         m_varValue = m_varColl->variableSetting()->modificationDate();
01226     else
01227     {
01228         // Only if never set before (i.e. upon insertion)
01229         if ( m_varValue.isNull() )
01230             m_varValue = QDateTime::currentDateTime().addDays(m_correctDate);
01231     }
01232     resize();
01233 }
01234 
01235 void KoDateVariable::saveVariable( QDomElement& varElem )
01236 {
01237     QDomElement elem = varElem.ownerDocument().createElement( "DATE" );
01238     varElem.appendChild( elem );
01239 
01240     QDate date = m_varValue.toDate(); // works with Date and DateTime
01241     date = date.addDays( -m_correctDate );//remove correctDate value otherwise value stored is bad
01242     elem.setAttribute( "year", date.year() );
01243     elem.setAttribute( "month", date.month() );
01244     elem.setAttribute( "day", date.day() );
01245     elem.setAttribute( "fix", m_subtype == VST_DATE_FIX ); // for compat
01246     elem.setAttribute( "correct", m_correctDate);
01247     elem.setAttribute( "subtype", m_subtype);
01248     if ( m_varValue.type() == QVariant::DateTime )
01249     {
01250         QTime time = m_varValue.toTime();
01251         elem.setAttribute( "hour", time.hour() );
01252         elem.setAttribute( "minute", time.minute() );
01253         elem.setAttribute( "second", time.second() );
01254     }
01255 }
01256 
01257 void KoDateVariable::load( QDomElement& elem )
01258 {
01259     KoVariable::load( elem );
01260 
01261     QDomElement e = elem.namedItem( "DATE" ).toElement();
01262     if (!e.isNull())
01263     {
01264         const bool fix = e.attribute("fix").toInt() == 1;
01265         if ( e.hasAttribute("correct"))
01266             m_correctDate = e.attribute("correct").toInt();
01267         if ( fix )
01268         {
01269             const int y = e.attribute("year").toInt();
01270             const int month = e.attribute("month").toInt();
01271             const int d = e.attribute("day").toInt();
01272             const int h = e.attribute("hour").toInt();
01273             const int min = e.attribute("minute").toInt();
01274             const int s = e.attribute("second").toInt();
01275             const int ms = e.attribute("msecond").toInt();
01276             QDate date( y, month, d );
01277             date = date.addDays( m_correctDate );
01278             const QTime time( h, min, s, ms );
01279             if (time.isValid())
01280                 m_varValue = QVariant ( QDateTime( date, time ) );
01281             else
01282                 m_varValue = QVariant( date );
01283         }
01284         //old date variable format
01285         m_subtype = fix ? VST_DATE_FIX : VST_DATE_CURRENT;
01286         if ( e.hasAttribute( "subtype" ))
01287             m_subtype = e.attribute( "subtype").toInt();
01288     }
01289 }
01290 
01291 void KoDateVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& context ) const
01292 {
01293     switch( m_subtype )
01294     {
01295     case VST_DATE_FIX:
01296     case VST_DATE_CURRENT:
01297         writer.startElement( "text:date" );
01298         if ( m_subtype == VST_DATE_FIX )
01299         {
01300             writer.addAttribute( "text:date-value", m_varValue.toDate().toString( Qt::ISODate) );
01301             writer.addAttribute( "text:fixed", "true" );
01302         }
01303         break;
01304     case VST_DATE_LAST_PRINTING:
01305         writer.startElement( "text:print-date" );
01306         break;
01307     case VST_DATE_CREATE_FILE:
01308         writer.startElement( "text:creation-date" );
01309         break;
01310     case VST_DATE_MODIFY_FILE:
01311         writer.startElement( "text:modification-date" );
01312         break;
01313     }
01314     QString value(  m_varFormat->formatProperties() );
01315     bool klocaleFormat = false;
01316     if ( value.toLower() == "locale" ||
01317          value.isEmpty() ||
01318          value.toLower() == "localeshort" ||
01319          value.toLower() == "localedatetime" ||
01320          value.toLower() == "localedatetimeshort" )
01321     {
01322         if ( value.toLower() == "locale" || value.isEmpty())
01323             value =  KGlobal::locale()->dateFormat();
01324         else if ( value.toLower() == "localeshort" )
01325             value = KGlobal::locale()->dateFormatShort();
01326         else if ( value.toLower() == "localedatetime" )
01327             value =  QString( "%1 %2" ).arg( KGlobal::locale()->dateFormat() ).arg( KGlobal::locale()->timeFormat() );
01328         else if ( value.toLower() == "localedatetimeshort" )
01329             value =  QString( "%1 %2" ).arg( KGlobal::locale()->dateFormatShort() ).arg( KGlobal::locale()->timeFormat() );
01330         klocaleFormat = true;
01331     }
01332     writer.addAttribute( "style:data-style-name", KoOasisStyles::saveOasisDateStyle(context.mainStyles(), value, klocaleFormat ) );
01333 
01334     if ( m_correctDate != 0 )
01335         writer.addAttribute( "text:date-adjust", daysToISODuration( m_correctDate ) );
01336     writer.endElement();
01337 }
01338 
01339 void KoDateVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
01340 {
01341     const QString localName( elem.localName() );
01342     if ( localName == "date" ) // current (or fixed) date
01343     {
01344         // Standard form of the date is in text:date-value. Example: 2004-01-21T10:57:05
01345         const QString dateValue = elem.attributeNS( KoXmlNS::text, "date-value", QString::null);
01346         QDateTime dt;
01347 #warning "kde4 port it"
01348         //if ( !dateValue.isEmpty() ) // avoid QDate warning
01349             //dt = QDate::fromString(dateValue, Qt::ISODate);
01350 
01351         bool fixed = (elem.hasAttributeNS( KoXmlNS::text, "fixed") && elem.attributeNS( KoXmlNS::text, "fixed", QString::null)=="true");
01352         if (!dt.isValid())
01353             fixed = false; // OOo docs say so: not valid = current datetime
01354         if ( fixed )
01355             m_varValue = QVariant( dt );
01356         m_subtype = fixed ? VST_DATE_FIX : VST_DATE_CURRENT;
01357     }
01358     // For all those the value of the date will be retrieved from meta.xml
01359     else if ( localName.startsWith( "print" ) )
01360         m_subtype = VST_DATE_LAST_PRINTING;
01361     else if ( localName.startsWith( "creation" ) )
01362         m_subtype = VST_DATE_CREATE_FILE;
01363     else if ( localName.startsWith( "modification" ) )
01364         m_subtype = VST_DATE_MODIFY_FILE;
01365     const QString adjustStr = elem.attributeNS( KoXmlNS::text, "date-adjust", QString::null );
01366     if ( !adjustStr.isEmpty() )
01367         m_correctDate = ISODurationToDays( adjustStr );
01368 }
01369 
01370 QStringList KoDateVariable::actionTexts()
01371 {
01372     QStringList lst;
01373     lst << i18n( "Current Date (fixed)" );
01374     lst << i18n( "Current Date (variable)" );
01375     lst << i18n( "Date of Last Printing" );
01376     lst << i18n( "Date of File Creation" );
01377     lst << i18n( "Date of File Modification" );
01378     return lst;
01379 }
01380 
01381 QStringList KoDateVariable::subTypeList()
01382 {
01383     return KoDateVariable::actionTexts();
01384 }
01385 
01386 QString KoDateVariable::defaultFormat()
01387 {
01388     return QString("DATE") + "locale";
01389 }
01390 
01391 QString KoDateVariable::formatStr(int & correct)
01392 {
01393     QString string;
01394     QStringList stringList;
01395     KDialog* dialog=new KDialog();
01396     dialog->setCaption( i18n("Date Format") );
01397     dialog->setModal( true );
01398     dialog->setButtons( KDialog::Ok|KDialog::Cancel );
01399 
01400     dialog->setWindowTitle( i18nc( "DateFormat", "Format of Date Variable" ) );
01401     DateFormatWidget* widget=new DateFormatWidget(dialog);
01402     int count=0;
01403     dialog->setMainWidget(widget);
01404     KConfig* config = KoGlobal::kofficeConfig();
01405     if( config->hasGroup("Date format history") )
01406     {
01407         KConfigGroup configGroup( config, "Date format history");
01408         const int noe=configGroup.readEntry("Number Of Entries", 5);
01409         for(int i=0;i<noe;i++)
01410         {
01411             QString num;
01412             num.setNum(i);
01413             const QString tmpString(configGroup.readEntry("Last Used"+num,QString()));
01414             if(tmpString.startsWith("locale"))
01415                 continue;
01416             else if(stringList.contains(tmpString))
01417                 continue;
01418             else if(!tmpString.isEmpty())
01419             {
01420                 stringList.append(tmpString);
01421                 count++;
01422             }
01423         }
01424 
01425     }
01426     if(!stringList.isEmpty())
01427     {
01428         widget->combo1()->addItem("---");
01429         widget->combo1()->addItems(stringList);
01430     }
01431     if(false) { // ### TODO: select the last used item
01432         QComboBox *combo= widget->combo1();
01433         combo->setCurrentIndex(combo->count() -1);
01434         widget->updateLabel();
01435     }
01436 
01437     if(dialog->exec()==QDialog::Accepted)
01438     {
01439         string = widget->resultString().toUtf8();
01440         correct = widget->correctValue();
01441     }
01442     else
01443     {
01444         delete dialog;
01445         return 0;
01446     }
01447     config->setGroup("Date format history");
01448     stringList.removeAll(string);
01449     stringList.prepend(string);
01450     for(int i=0;i<=count;i++)
01451     {
01452         QString num;
01453         num.setNum(i);
01454 #warning "kde4: port it"
01455         //configGroup.writeEntry("Last Used"+num, stringList[i]);
01456     }
01457     config->sync();
01458     delete dialog;
01459     return QString("DATE") + string;
01460 }
01461 
01462 /******************************************************************/
01463 /* Class: KoTimeVariable                                          */
01464 /******************************************************************/
01465 KoTimeVariable::KoTimeVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat, KoVariableCollection *_varColl, int _correct)
01466     : KoVariable( textdoc, varFormat,_varColl ), m_subtype( subtype ), m_correctTime( _correct)
01467 {
01468 }
01469 
01470 QString KoTimeVariable::fieldCode()
01471 {
01472     return (m_subtype == VST_TIME_FIX)?i18n("Time (Fixed)"):i18n("Time");
01473 }
01474 
01475 
01476 void KoTimeVariable::resize()
01477 {
01478     KoTextFormat * fmt = format();
01479     if ( !fmt->language().isEmpty() )
01480     {
01481         QString oldLanguage = KGlobal::locale()->language();
01482         bool changeLanguage = KGlobal::locale()->setLanguage( fmt->language() );
01483         KoVariable::resize();
01484         if ( changeLanguage )
01485             KGlobal::locale()->setLanguage( oldLanguage );
01486     }
01487     else
01488         KoVariable::resize();
01489 }
01490 
01491 void KoTimeVariable::recalc()
01492 {
01493     if ( m_subtype == VST_TIME_CURRENT )
01494         m_varValue = QVariant( QTime::currentTime().addSecs(60*m_correctTime));
01495     else
01496     {
01497         // Only if never set before (i.e. upon insertion)
01498         if ( m_varValue.toTime().isNull() )
01499             m_varValue = QVariant( QTime::currentTime().addSecs(60*m_correctTime));
01500     }
01501     resize();
01502 }
01503 
01504 
01505 void KoTimeVariable::saveVariable( QDomElement& parentElem )
01506 {
01507     QDomElement elem = parentElem.ownerDocument().createElement( "TIME" );
01508     parentElem.appendChild( elem );
01509 
01510     QTime time = m_varValue.toTime();
01511     time = time.addSecs(-60*m_correctTime);
01512     elem.setAttribute( "hour", time.hour() );
01513     elem.setAttribute( "minute", time.minute() );
01514     elem.setAttribute( "second", time.second() );
01515     elem.setAttribute( "msecond", time.msec() );
01516     elem.setAttribute( "fix", m_subtype == VST_TIME_FIX );
01517     elem.setAttribute( "correct", m_correctTime );
01518 }
01519 
01520 void KoTimeVariable::load( QDomElement& elem )
01521 {
01522     KoVariable::load( elem );
01523 
01524     QDomElement e = elem.namedItem( "TIME" ).toElement();
01525     if (!e.isNull())
01526     {
01527         int h = e.attribute("hour").toInt();
01528         int m = e.attribute("minute").toInt();
01529         int s = e.attribute("second").toInt();
01530         int ms = e.attribute("msecond").toInt();
01531         int correct = 0;
01532         if ( e.hasAttribute("correct"))
01533             correct=e.attribute("correct").toInt();
01534         bool fix = static_cast<bool>( e.attribute("fix").toInt() );
01535         if ( fix )
01536         {
01537             QTime time;
01538             time.setHMS( h, m, s, ms );
01539             time = time.addSecs( 60*m_correctTime );
01540             m_varValue = QVariant( time);
01541 
01542         }
01543         m_subtype = fix ? VST_TIME_FIX : VST_TIME_CURRENT;
01544         m_correctTime = correct;
01545     }
01546 }
01547 
01548 void KoTimeVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
01549 {
01550     const QString localName( elem.localName() );
01551     Q_ASSERT( localName == "time" ); // caller checked for it
01552     if ( localName == "time" ) // current (or fixed) time
01553     {
01554         // Use QDateTime to work around a possible problem of QTime::fromString in Qt 3.2.2
01555         QDateTime dt(QDateTime::fromString(elem.attributeNS( KoXmlNS::text, "time-value", QString::null), Qt::ISODate));
01556 
01557         bool fixed = (elem.hasAttributeNS( KoXmlNS::text, "fixed") && elem.attributeNS( KoXmlNS::text, "fixed", QString::null)=="true");
01558         if (!dt.isValid())
01559             fixed = false; // OOo docs say so: not valid = current datetime
01560         if ( fixed )
01561             m_varValue = QVariant( dt.time() );
01562         m_subtype = fixed ? VST_TIME_FIX : VST_TIME_CURRENT;
01563         QString adjustStr = elem.attributeNS( KoXmlNS::text, "time-adjust", QString::null );
01564         if ( !adjustStr.isEmpty() )
01565             m_correctTime = ISODurationToMinutes( adjustStr );
01566     }
01567 }
01568 
01569 void KoTimeVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& context ) const
01570 {
01571     writer.startElement( "text:time" );
01572     if ( m_correctTime != 0 ) {
01573         writer.addAttribute( "text:time-adjust", minutesToISODuration( m_correctTime ) );
01574     }
01575     if (m_subtype == VST_TIME_FIX )
01576     {
01577         writer.addAttribute( "text:fixed", "true" );
01578         writer.addAttribute( "text:time-value", m_varValue.toTime().toString( Qt::ISODate ) );
01579     }
01580 
01581     QString value(  m_varFormat->formatProperties() );
01582     bool klocaleFormat = false;
01583     if ( value.toLower() == "locale" )
01584     {
01585         value = KGlobal::locale()->timeFormat();
01586         klocaleFormat = true;
01587     }
01588     writer.addAttribute( "style:data-style-name", KoOasisStyles::saveOasisTimeStyle(context.mainStyles(), m_varFormat->formatProperties(), klocaleFormat ) );
01589     //writer.addTextNode( /*value*/ value displayed as texte );
01590     //TODO save text value
01591     //<text:time style:data-style-name="N43" text:time-value="2004-11-11T14:42:19" text:fixed="true">02:42:19 PM</text:time>
01592     writer.endElement();
01593 }
01594 
01595 
01596 QStringList KoTimeVariable::actionTexts()
01597 {
01598     QStringList lst;
01599     lst << i18n( "Current Time (fixed)" );
01600     lst << i18n( "Current Time (variable)" );
01601     return lst;
01602 }
01603 
01604 QStringList KoTimeVariable::subTypeList()
01605 {
01606     return KoTimeVariable::actionTexts();
01607 }
01608 
01609 QString KoTimeVariable::formatStr(int & _correct)
01610 {
01611     QString string;
01612     QStringList stringList;
01613     KDialog* dialog=new KDialog();
01614     dialog->setCaption( i18n("Time Format") );
01615     dialog->setModal( true );
01616     dialog->setButtons( KDialog::Ok|KDialog::Cancel );
01617 
01618 
01619     dialog->setWindowTitle( i18nc( "TimeFormat", "This Dialog Allows You to Set the Format of the Time Variable" ) );
01620     TimeFormatWidget* widget=new TimeFormatWidget(dialog);
01621     dialog->setMainWidget(widget);
01622     KConfig* config = KoGlobal::kofficeConfig();
01623     int count=0;
01624     if( config->hasGroup("Time format history") )
01625     {
01626         KConfigGroup configGroup( config, "Time format history" );
01627         const int noe=configGroup.readEntry("Number Of Entries", 5);
01628         for(int i=0;i<noe;i++)
01629         {
01630             QString num;
01631             num.setNum(i);
01632             QString tmpString(configGroup.readEntry("Last Used"+num,QString()));
01633             if(tmpString.startsWith("locale"))
01634                 continue;
01635             else if(stringList.contains(tmpString))
01636                 continue;
01637             else if(!tmpString.isEmpty())
01638             {
01639                 stringList.append(tmpString);
01640                 count++;
01641             }
01642         }
01643     }
01644     if(!stringList.isEmpty())
01645     {
01646         widget->combo1()->addItem("---");
01647         widget->combo1()->addItems(stringList);
01648     }
01649     if(false) // ### TODO: select the last used item
01650     {
01651         QComboBox *combo= widget->combo1();
01652         combo->setCurrentIndex( combo->count() -1 );
01653     }
01654     if(dialog->exec()==QDialog::Accepted)
01655     {
01656         string = widget->resultString().toUtf8();
01657         _correct = widget->correctValue();
01658     }
01659     else
01660     {
01661         delete dialog;
01662         return 0;
01663     }
01664     config->setGroup("Time format history");
01665     stringList.removeAll( string );
01666     stringList.prepend(string);
01667     for(int i=0;i<=count;i++)
01668     {
01669         QString num;
01670         num.setNum(i);
01671 #warning "kde4 port it"
01672         //configGroup.writeEntry("Last Used"+num, stringList[i]);
01673     }
01674     config->sync();
01675     delete dialog;
01676     return QString("TIME"+string );
01677 }
01678 
01679 QString KoTimeVariable::defaultFormat()
01680 {
01681     return QString(QString("TIME")+QString("locale") );
01682 }
01683 
01684 
01685 /******************************************************************/
01686 /* Class: KoCustomVariable                                        */
01687 /******************************************************************/
01688 KoCustomVariable::KoCustomVariable( KoTextDocument *textdoc, const QString &name, KoVariableFormat *varFormat, KoVariableCollection *_varColl )
01689     : KoVariable( textdoc, varFormat,_varColl )
01690 {
01691     m_varValue = QVariant( name );
01692 }
01693 
01694 QString KoCustomVariable::fieldCode()
01695 {
01696     return i18n("Custom Variable");
01697 }
01698 
01699 QString KoCustomVariable::text(bool realValue)
01700 {
01701     if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
01702         return fieldCode();
01703     else
01704         return value();
01705 } // use a format when they are customizable
01706 
01707 
01708 
01709 void KoCustomVariable::saveVariable( QDomElement& parentElem )
01710 {
01711     QDomElement elem = parentElem.ownerDocument().createElement( "CUSTOM" );
01712     parentElem.appendChild( elem );
01713     elem.setAttribute( "name", m_varValue.toString() );
01714     elem.setAttribute( "value", value() );
01715 }
01716 
01717 void KoCustomVariable::load( QDomElement& elem )
01718 {
01719     KoVariable::load( elem );
01720     QDomElement e = elem.namedItem( "CUSTOM" ).toElement();
01721     if (!e.isNull())
01722     {
01723         m_varValue = QVariant (e.attribute( "name" ));
01724         setValue( e.attribute( "value" ) );
01725     }
01726 }
01727 
01728 void KoCustomVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
01729 {
01730     const QString localName( elem.localName() );
01731     // We treat all those the same. For OO/OpenDocument the difference is that
01732     // - user-field-get is related to text:user-field-decls in <body>
01733     // - variable-set is related to variable-decls (defined in <body>);
01734     //                 its value can change in the middle of the document.
01735     // - user-defined is related to meta:user-defined in meta.xml
01736     if ( localName == "variable-set"
01737          || localName == "user-defined"
01738         || localName == "user-field-get" ) {
01739         m_varValue = elem.attributeNS( KoXmlNS::text, "name", QString::null );
01740         setValue( elem.text() );
01741     }
01742 }
01743 
01744 void KoCustomVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
01745 {
01746     //TODO save value into meta:user-defined
01747     writer.startElement( "text:user-field-get" ); //see 6.3.6
01748     writer.addAttribute( "text:name", m_varValue.toString() );
01749     writer.addTextNode( value() );
01750     writer.endElement();
01751 }
01752 
01753 QString KoCustomVariable::value() const
01754 {
01755     return m_varColl->getVariableValue( m_varValue.toString() );
01756 }
01757 
01758 void KoCustomVariable::setValue( const QString &v )
01759 {
01760     m_varColl->setVariableValue( m_varValue.toString(), v );
01761 }
01762 
01763 QStringList KoCustomVariable::actionTexts()
01764 {
01765     return QStringList( i18n( "Custom..." ) );
01766 }
01767 
01768 void KoCustomVariable::recalc()
01769 {
01770     resize();
01771 }
01772 
01773 /******************************************************************/
01774 /* Class: KoMailMergeVariable                                  */
01775 /******************************************************************/
01776 KoMailMergeVariable::KoMailMergeVariable( KoTextDocument *textdoc, const QString &name, KoVariableFormat *varFormat,KoVariableCollection *_varColl )
01777     : KoVariable( textdoc, varFormat, _varColl )
01778 {
01779     m_varValue = QVariant ( name );
01780 }
01781 
01782 QString KoMailMergeVariable::fieldCode()
01783 {
01784     return i18n("Mail Merge");
01785 }
01786 
01787 void KoMailMergeVariable::loadOasis( const QDomElement &/*elem*/, KoOasisContext& /*context*/ )
01788 {
01789     // TODO
01790 }
01791 
01792 void KoMailMergeVariable::saveOasis( KoXmlWriter& /*writer*/, KoSavingContext& /*context*/ ) const
01793 {
01794         kWarning(32500) << "Not implemented: OASIS saving of mail merge variables" << endl;
01795 }
01796 
01797 
01798 
01799 void KoMailMergeVariable::saveVariable( QDomElement& parentElem )
01800 {
01801     QDomElement elem = parentElem.ownerDocument().createElement( "MAILMERGE" );
01802     parentElem.appendChild( elem );
01803     elem.setAttribute( "name", m_varValue.toString() );
01804 }
01805 
01806 void KoMailMergeVariable::load( QDomElement& elem )
01807 {
01808     KoVariable::load( elem );
01809     QDomElement e = elem.namedItem( "MAILMERGE" ).toElement();
01810     if (!e.isNull())
01811         m_varValue = QVariant( e.attribute( "name" ) );
01812 }
01813 
01814 QString KoMailMergeVariable::value() const
01815 {
01816     return QString();//m_doc->getMailMergeDataBase()->getValue( m_name );
01817 }
01818 
01819 QString KoMailMergeVariable::text(bool /*realValue*/)
01820 {
01821     // ## should use a format maybe
01822     QString v = value();
01823     if ( v == name() )
01824         return '<' + v + '>';
01825     return v;
01826 }
01827 
01828 QStringList KoMailMergeVariable::actionTexts()
01829 {
01830     return QStringList( i18n( "&Mail Merge..." ) );
01831 }
01832 
01833 /******************************************************************/
01834 /* Class: KoPageVariable                                         */
01835 /******************************************************************/
01836 KoPageVariable::KoPageVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat,KoVariableCollection *_varColl )
01837         : KoVariable( textdoc, varFormat, _varColl ), m_subtype( subtype )
01838 {
01839 }
01840 
01841 QString KoPageVariable::fieldCode()
01842 {
01843     if ( m_subtype == VST_PGNUM_CURRENT )
01844         return i18n("Page Current Num");
01845     else if ( m_subtype == VST_PGNUM_TOTAL )
01846         return i18n("Total Page Num");
01847     else if ( m_subtype == VST_CURRENT_SECTION )
01848         return i18n("Current Section");
01849     else if ( m_subtype == VST_PGNUM_PREVIOUS )
01850         return i18n("Previous Page Number");
01851     else if ( m_subtype == VST_PGNUM_NEXT )
01852         return i18n("Next Page Number");
01853 
01854     else
01855         return i18n("Current Section");
01856 }
01857 
01858 
01859 void KoPageVariable::saveVariable( QDomElement& parentElem )
01860 {
01861     QDomElement pgNumElem = parentElem.ownerDocument().createElement( "PGNUM" );
01862     parentElem.appendChild( pgNumElem );
01863     pgNumElem.setAttribute( "subtype", m_subtype );
01864     if ( m_subtype != VST_CURRENT_SECTION )
01865         pgNumElem.setAttribute( "value", m_varValue.toInt() );
01866     else
01867         pgNumElem.setAttribute( "value", m_varValue.toString() );
01868 }
01869 
01870 void KoPageVariable::load( QDomElement& elem )
01871 {
01872     KoVariable::load( elem );
01873     QDomElement pgNumElem = elem.namedItem( "PGNUM" ).toElement();
01874     if (!pgNumElem.isNull())
01875     {
01876         m_subtype = pgNumElem.attribute("subtype").toInt();
01877         // ### This could use the format...
01878         if ( m_subtype != VST_CURRENT_SECTION )
01879             m_varValue = QVariant(pgNumElem.attribute("value").toInt());
01880         else
01881             m_varValue = QVariant(pgNumElem.attribute("value"));
01882     }
01883 }
01884 
01885 void KoPageVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
01886 {
01887     switch( m_subtype )
01888     {
01889     case VST_PGNUM_PREVIOUS:
01890     case VST_PGNUM_NEXT:
01891     case VST_PGNUM_CURRENT:
01892     {
01893         writer.startElement( "text:page-number" );
01894         if ( m_subtype == VST_PGNUM_PREVIOUS )
01895         {
01896             writer.addAttribute( "text:select-page", "previous" );
01897         }
01898         else if ( m_subtype == VST_PGNUM_NEXT )
01899         {
01900             writer.addAttribute( "text:select-page", "next" );
01901         }
01902         else if ( m_subtype == VST_PGNUM_CURRENT )
01903         {
01904             writer.addAttribute( "text:select-page", "current" );
01905         }
01906         writer.addTextNode( m_varValue.toString() );
01907         writer.endElement();
01908     }
01909     break;
01910     case VST_CURRENT_SECTION:
01911     {
01912         writer.startElement( "text:chapter" );
01913         writer.addTextNode( m_varValue.toString() );
01914         writer.endElement();
01915     }
01916     break;
01917     case VST_PGNUM_TOTAL:
01918     {
01919         writer.startElement( "text:page-count" );
01920         writer.addTextNode( m_varValue.toString() );
01921         writer.endElement();
01922     }
01923     break;
01924     }
01925 }
01926 
01927 void KoPageVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
01928 {
01929     const QString localName( elem.localName() );
01930     if ( localName == "page-number" )
01931     {
01932         m_subtype = VST_PGNUM_CURRENT;
01933 
01934         if ( elem.hasAttributeNS( KoXmlNS::text, "select-page") )
01935         {
01936             const QString select = elem.attributeNS( KoXmlNS::text, "select-page", QString::null);
01937             if (select == "previous")
01938                 m_subtype = VST_PGNUM_PREVIOUS;
01939             else if (select == "next")
01940                 m_subtype = VST_PGNUM_NEXT;
01941         }
01942         // Missing: fixed, page adjustment, formatting style
01943         m_varValue = QVariant( elem.text().toInt() );
01944     }
01945     else if ( localName == "chapter" )
01946     {
01947         m_subtype = VST_CURRENT_SECTION;
01948         m_varValue = QVariant( elem.text() );
01949         // text:display attribute can be name, number (i.e. with prefix/suffix),
01950         // number-and-name, plain-number-and-name, plain-number
01951         // TODO: a special format class for this, so that it can be easily switched using the RMB
01952     }
01953     else if ( localName == "page-count" )
01954     {
01955         m_subtype = VST_PGNUM_TOTAL;
01956         m_varValue = QVariant( elem.text() );
01957     }
01958 }
01959 
01960 QStringList KoPageVariable::actionTexts()
01961 {
01962     QStringList lst;
01963     lst << i18n( "Page Number" );
01964     lst << i18n( "Number of Pages" );
01965     lst << i18n( "Section Title" );
01966     lst << i18n( "Previous Page" );
01967     lst << i18n( "Next Page" );
01968     return lst;
01969 }
01970 
01971 QStringList KoPageVariable::subTypeList()
01972 {
01973     return KoPageVariable::actionTexts();
01974 }
01975 
01976 void KoPageVariable::setVariableSubType( short int type )
01977 {
01978     m_subtype = type;
01979     Q_ASSERT( m_varColl );
01980     KoVariableFormatCollection* fc = m_varColl->formatCollection();
01981     setVariableFormat((m_subtype == VST_CURRENT_SECTION) ? fc->format("STRING") : fc->format("NUMBER"));
01982 }
01983 
01984 /******************************************************************/
01985 /* Class: KoFieldVariable                                         */
01986 /******************************************************************/
01987 KoFieldVariable::KoFieldVariable( KoTextDocument *textdoc, short int subtype, KoVariableFormat *varFormat, KoVariableCollection *_varColl ,KoDocument *_doc )
01988     : KoVariable( textdoc, varFormat,_varColl ), m_subtype( subtype ), m_doc(_doc)
01989 {
01990 }
01991 
01992 QString KoFieldVariable::fieldCode()
01993 {
01994     switch( m_subtype ) {
01995     case VST_FILENAME:
01996         return i18n("Filename");
01997         break;
01998     case VST_DIRECTORYNAME:
01999         return i18n("Directory Name");
02000         break;
02001     case VST_PATHFILENAME:
02002         return i18n("Path Filename");
02003         break;
02004     case VST_FILENAMEWITHOUTEXTENSION:
02005         return i18n("Filename Without Extension");
02006         break;
02007     case VST_AUTHORNAME:
02008         return i18n("Author Name");
02009         break;
02010     case VST_EMAIL:
02011         return i18n("Email");
02012         break;
02013     case VST_COMPANYNAME:
02014         return i18n("Company Name");
02015         break;
02016     case VST_TELEPHONE_WORK:
02017         return i18n("Telephone (work)");
02018         break;
02019     case VST_TELEPHONE_HOME:
02020         return i18n("Telephone (home)");
02021         break;
02022     case VST_FAX:
02023         return i18n("Fax");
02024         break;
02025     case VST_COUNTRY:
02026         return i18n("Country");
02027         break;
02028     case VST_POSTAL_CODE:
02029         return i18n("Postal Code");
02030         break;
02031     case VST_CITY:
02032         return i18n("City");
02033         break;
02034     case VST_STREET:
02035         return i18n("Street");
02036         break;
02037     case VST_AUTHORTITLE:
02038         return i18n("Author Title");
02039         break;
02040     case VST_TITLE:
02041         return i18n("Title");
02042         break;
02043     case VST_SUBJECT:
02044         return i18n("Subject");
02045         break;
02046     case VST_ABSTRACT:
02047         return i18n("Abstract");
02048         break;
02049     case VST_KEYWORDS:
02050         return i18n("Keywords");
02051         break;
02052     case VST_INITIAL:
02053         return i18n("Initials");
02054         break;
02055     }
02056     return i18n("Field");
02057 }
02058 
02059 QString KoFieldVariable::text(bool realValue)
02060 {
02061     if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
02062         return fieldCode();
02063     else
02064         return value();
02065 } // use a format when they are customizable
02066 
02067 
02068 void KoFieldVariable::saveVariable( QDomElement& parentElem )
02069 {
02070     //kDebug(32500) << "KoFieldVariable::saveVariable" << endl;
02071     QDomElement elem = parentElem.ownerDocument().createElement( "FIELD" );
02072     parentElem.appendChild( elem );
02073     elem.setAttribute( "subtype", m_subtype );
02074     elem.setAttribute( "value", m_varValue.toString() );
02075 }
02076 
02077 void KoFieldVariable::load( QDomElement& elem )
02078 {
02079     KoVariable::load( elem );
02080     QDomElement e = elem.namedItem( "FIELD" ).toElement();
02081     if (!e.isNull())
02082     {
02083         m_subtype = e.attribute( "subtype" ).toInt();
02084         if ( m_subtype == VST_NONE )
02085             kWarning() << "Field subtype of -1 found in the file !" << endl;
02086         m_varValue = QVariant( e.attribute( "value" ) );
02087     } else
02088         kWarning() << "FIELD element not found !" << endl;
02089 }
02090 
02091 void KoFieldVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
02092 {
02093     const QString localName( elem.localName() );
02094     if ( localName == "file-name" ) {
02095         const QString display = elem.attributeNS( KoXmlNS::text, "display", QString::null );
02096         if (display == "path")
02097             m_subtype = VST_DIRECTORYNAME;
02098         else if (display == "name")
02099             m_subtype = VST_FILENAMEWITHOUTEXTENSION;
02100         else if (display == "name-and-extension")
02101             m_subtype = VST_FILENAME;
02102         else
02103             m_subtype = VST_PATHFILENAME;
02104     }
02105     else if ( localName == "author-name" )
02106         m_subtype = VST_AUTHORNAME;
02107     else if ( localName == "author-initials" )
02108         m_subtype = VST_INITIAL;
02109     else if ( localName == "subject" )
02110         m_subtype = VST_SUBJECT;
02111     else if ( localName == "title" )
02112         m_subtype = VST_TITLE;
02113     else if ( localName == "description" )
02114         m_subtype = VST_ABSTRACT;
02115     else if ( localName == "keywords" )
02116         m_subtype = VST_KEYWORDS;
02117 
02118     else if ( localName == "sender-company" )
02119         m_subtype = VST_COMPANYNAME;
02120     else if ( localName == "sender-firstname" )
02121         ; // ## This is different from author-name, but the notion of 'sender' is unclear...
02122     else if ( localName == "sender-lastname" )
02123         ; // ## This is different from author-name, but the notion of 'sender' is unclear...
02124     else if ( localName == "sender-initials" )
02125         ; // ## This is different from author-initials, but the notion of 'sender' is unclear...
02126     else if ( localName == "sender-street" )
02127         m_subtype = VST_STREET;
02128     else if ( localName == "sender-country" )
02129         m_subtype = VST_COUNTRY;
02130     else if ( localName == "sender-postal-code" )
02131         m_subtype = VST_POSTAL_CODE;
02132     else if ( localName == "sender-city" )
02133         m_subtype = VST_CITY;
02134     else if ( localName == "sender-title" )
02135         m_subtype = VST_AUTHORTITLE; // Small hack (it's supposed to be about the sender, not about the author)
02136     else if ( localName == "sender-position" )
02137         m_subtype = VST_AUTHORPOSITION;
02138     else if ( localName == "sender-phone-private" )
02139         m_subtype = VST_TELEPHONE_HOME;
02140     else if ( localName == "sender-phone-work" )
02141         m_subtype = VST_TELEPHONE_WORK;
02142     else if ( localName == "sender-fax" )
02143         m_subtype = VST_FAX;
02144     else if ( localName == "sender-email" )
02145         m_subtype = VST_EMAIL;
02146 
02147     m_varValue = QVariant( elem.text() );
02148 }
02149 
02150 void KoFieldVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
02151 {
02152     switch( m_subtype )
02153     {
02154     case VST_NONE:
02155         break;
02156     case VST_FILENAME:
02157         writer.startElement( "text:file-name" );
02158         writer.addAttribute( "text:display", "name-and-extension" );
02159         break;
02160     case VST_DIRECTORYNAME:
02161         writer.startElement( "text:file-name" );
02162         writer.addAttribute( "text:display", "path" );
02163         break;
02164     case VST_AUTHORNAME:
02165         writer.startElement( "text:author-name" );
02166         break;
02167     case VST_EMAIL:
02168         writer.startElement("text:sender-email" );
02169         break;
02170     case VST_COMPANYNAME:
02171         writer.startElement("text:sender-company" );
02172         break;
02173     case VST_PATHFILENAME:
02174         writer.startElement("text:display" );
02175         writer.addAttribute( "text:display", "pathfilename" ); // ???????? not define !
02176         break;
02177     case VST_FILENAMEWITHOUTEXTENSION:
02178         writer.startElement("text:display" );
02179         writer.addAttribute( "text:display", "name-and-extension" ); // ???????? not define !
02180         break;
02181     case VST_TELEPHONE_WORK:
02182         writer.startElement("text:sender-phone-work" );
02183         break;
02184     case VST_TELEPHONE_HOME:
02185         writer.startElement("text:sender-phone-private" );
02186         break;
02187     case VST_FAX:
02188         writer.startElement("text:sender-fax" );
02189         break;
02190     case VST_COUNTRY:
02191         writer.startElement("text:sender-country" );
02192         break;
02193     case VST_TITLE:
02194         writer.startElement("text:title" );
02195         break;
02196     case VST_KEYWORDS:
02197         writer.startElement("text:keywords" );
02198         break;
02199     case VST_SUBJECT:
02200         writer.startElement("text:subject" );
02201         break;
02202     case VST_ABSTRACT:
02203         writer.startElement("text:description" );
02204         break;
02205     case VST_POSTAL_CODE:
02206         writer.startElement("text:sender-postal-code" );
02207         break;
02208     case VST_CITY:
02209         writer.startElement("text:sender-city" );
02210         break;
02211     case VST_STREET:
02212         writer.startElement("text:sender-street" );
02213         break;
02214     case VST_AUTHORTITLE:
02215         writer.startElement("text:sender-title" );
02216         break;
02217     case VST_AUTHORPOSITION:
02218         writer.startElement("text:sender-position" );
02219         break;
02220     case VST_INITIAL:
02221         writer.startElement("text:author-initials" );
02222         break;
02223     }
02224     writer.addTextNode( m_varValue.toString() );
02225     writer.endElement();
02226 }
02227 
02228 void KoFieldVariable::recalc()
02229 {
02230     QString value;
02231     switch( m_subtype ) {
02232         case VST_NONE:
02233             kWarning() << "KoFieldVariable::recalc() called with m_subtype = VST_NONE !" << endl;
02234             break;
02235         case VST_FILENAME:
02236             value = m_doc->url().fileName();
02237             break;
02238         case VST_DIRECTORYNAME:
02239             value = m_doc->url().directory();
02240             break;
02241         case VST_PATHFILENAME:
02242             value=m_doc->url().path();
02243             break;
02244         case VST_FILENAMEWITHOUTEXTENSION:
02245         {
02246             QString file=m_doc->url().fileName();
02247             int pos = file.lastIndexOf(".");
02248             if(pos !=-1)
02249                 value=file.mid(0,pos);
02250             else
02251                 value=file;
02252         }
02253         break;
02254         case VST_AUTHORNAME:
02255         case VST_EMAIL:
02256         case VST_COMPANYNAME:
02257         case VST_TELEPHONE_WORK:
02258         case VST_TELEPHONE_HOME:
02259         case VST_FAX:
02260         case VST_COUNTRY:
02261         case VST_POSTAL_CODE:
02262         case VST_CITY:
02263         case VST_STREET:
02264         case VST_AUTHORTITLE:
02265     case VST_AUTHORPOSITION:
02266         case VST_INITIAL:
02267         {
02268             KoDocumentInfo * info = m_doc->documentInfo();
02269             if ( !info )
02270                 kWarning() << "Author information not found in documentInfo !" << endl;
02271             else
02272             {
02273                 if ( m_subtype == VST_AUTHORNAME )
02274                     value = info->authorInfo( "creator" );
02275                 else if ( m_subtype == VST_EMAIL )
02276                     value = info->authorInfo( "email" );
02277                 else if ( m_subtype == VST_COMPANYNAME )
02278                     value = info->authorInfo( "company" );
02279                 else if ( m_subtype == VST_TELEPHONE_WORK )
02280                     value = info->authorInfo( "telephone-work" );
02281                 else if ( m_subtype == VST_TELEPHONE_HOME )
02282                     value = info->authorInfo( "telephone" );
02283                 else if ( m_subtype == VST_FAX )
02284                     value = info->authorInfo( "fax" );
02285                 else if ( m_subtype == VST_COUNTRY )
02286                     value = info->authorInfo( "country" );
02287                 else if ( m_subtype == VST_POSTAL_CODE )
02288                     value = info->authorInfo( "postal-code" );
02289                 else if ( m_subtype == VST_CITY )
02290                     value = info->authorInfo( "city" );
02291                 else if ( m_subtype == VST_STREET )
02292                     value = info->authorInfo( "street" );
02293                 else if ( m_subtype == VST_AUTHORTITLE )
02294                     value = info->authorInfo( "title" );
02295                 else if ( m_subtype == VST_INITIAL )
02296                     value = info->authorInfo( "initial" );
02297                 else if ( m_subtype == VST_AUTHORPOSITION )
02298                     value = info->authorInfo( "position" );
02299             }
02300         }
02301         break;
02302         case VST_TITLE:
02303         case VST_ABSTRACT:
02304     case VST_SUBJECT:
02305     case VST_KEYWORDS:
02306         {
02307             KoDocumentInfo * info = m_doc->documentInfo();
02308 
02309             if ( !info )
02310                 kWarning() << "'About' page not found in documentInfo !" << endl;
02311             else
02312             {
02313                 if ( m_subtype == VST_TITLE )
02314                     value = info->aboutInfo( "title" );
02315                 else if ( m_subtype == VST_SUBJECT )
02316                     value = info->aboutInfo( "subject" );
02317                 else if ( m_subtype == VST_KEYWORDS )
02318                     value = info->aboutInfo( "keyword" );
02319                 else
02320                     value = info->aboutInfo( "comments" );
02321             }
02322         }
02323         break;
02324     }
02325 
02326     if (value.isEmpty())        // try the initial value
02327         value = m_varValue.toString();
02328 
02329     if (value.isEmpty())        // still empty? give up
02330         value = i18n("<None>");
02331 
02332     m_varValue = QVariant( value );
02333 
02334     resize();
02335 }
02336 
02337 QStringList KoFieldVariable::actionTexts()
02338 {
02339     // NOTE: if you change here, also change fieldSubType()
02340     QStringList lst;
02341     lst << i18n( "Author Name" );
02342     lst << i18n( "Title" );
02343     lst << i18n( "Initials" );
02344     lst << i18n( "Position" );
02345     lst << i18n( "Company" );
02346     lst << i18n( "Email" );
02347     lst << i18n( "Telephone (work)");
02348     lst << i18n( "Telephone (private)");
02349 
02350     lst << i18n( "Fax");
02351     lst << i18n( "Street" );
02352     lst << i18n( "Postal Code" );
02353     lst << i18n( "City" );
02354     lst << i18n( "Country");
02355 
02356     lst << i18n( "Document Title" );
02357     lst << i18n( "Document Abstract" );
02358     lst << i18n( "Document Subject" );
02359     lst << i18n( "Document Keywords" );
02360 
02361     lst << i18n( "File Name" );
02362     lst << i18n( "File Name without Extension" );
02363     lst << i18n( "Directory Name" ); // is "Name" necessary ?
02364     lst << i18n( "Directory && File Name" );
02365     return lst;
02366 }
02367 
02368 short int KoFieldVariable::variableSubType( short int menuNumber )
02369 {
02370     return fieldSubType(menuNumber);
02371 }
02372 
02373 KoFieldVariable::FieldSubType KoFieldVariable::fieldSubType(short int menuNumber)
02374 {
02375     // NOTE: if you change here, also change actionTexts()
02376     FieldSubType v;
02377     switch (menuNumber)
02378     {
02379         case 0: v = VST_AUTHORNAME;
02380                 break;
02381         case 1: v = VST_AUTHORTITLE;
02382                 break;
02383         case 2: v = VST_INITIAL;
02384                 break;
02385         case 3: v = VST_AUTHORPOSITION;
02386                 break;
02387         case 4: v = VST_COMPANYNAME;
02388                 break;
02389         case 5: v = VST_EMAIL;
02390                 break;
02391         case 6: v = VST_TELEPHONE_WORK;
02392                 break;
02393         case 7: v = VST_TELEPHONE_HOME;
02394                 break;
02395         case 8: v = VST_FAX;
02396                 break;
02397         case 9: v = VST_STREET;
02398                 break;
02399         case 10: v = VST_POSTAL_CODE;
02400                 break;
02401         case 11: v = VST_CITY;
02402                 break;
02403         case 12: v = VST_COUNTRY;
02404                 break;
02405         case 13: v = VST_TITLE;
02406                 break;
02407         case 14: v = VST_ABSTRACT;
02408                 break;
02409         case 15: v = VST_SUBJECT;
02410                 break;
02411         case 16: v = VST_KEYWORDS;
02412                 break;
02413         case 17: v = VST_FILENAME;
02414                 break;
02415         case 18: v = VST_FILENAMEWITHOUTEXTENSION;
02416                 break;
02417         case 19: v = VST_DIRECTORYNAME;
02418                 break;
02419         case 20: v = VST_PATHFILENAME;
02420                 break;
02421         default:
02422             v = VST_NONE;
02423             break;
02424     }
02425     return v;
02426 }
02427 
02428 QStringList KoFieldVariable::subTypeList()
02429 {
02430     return KoFieldVariable::actionTexts();
02431 }
02432 
02433 /******************************************************************/
02434 /* Class: KoLinkVariable                                          */
02435 /******************************************************************/
02436 KoLinkVariable::KoLinkVariable( KoTextDocument *textdoc, const QString & _linkName, const QString & _ulr,KoVariableFormat *varFormat,KoVariableCollection *_varColl )
02437     : KoVariable( textdoc, varFormat,_varColl )
02438     ,m_url(_ulr)
02439 {
02440     m_varValue = QVariant( _linkName );
02441 }
02442 
02443 QString KoLinkVariable::fieldCode()
02444 {
02445     return i18n("Link");
02446 }
02447 
02448 void KoLinkVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
02449 {
02450     if ( elem.localName() == "a" && elem.namespaceURI() == KoXmlNS::text ) {
02451         m_url = elem.attributeNS( KoXmlNS::xlink, "href", QString::null);
02452         m_varValue = QVariant(elem.text());
02453     }
02454 }
02455 
02456 void KoLinkVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
02457 {
02458     //<text:a xlink:type="simple" xlink:href="http://www.kde.org/" office:name="sdgfsdfgs">kde org wxc &lt;wxc </text:a>
02459     writer.startElement( "text:a" );
02460     writer.addAttribute( "xlink:type", "simple" );
02461     writer.addAttribute( "xlink:href", m_url );
02462     writer.addAttribute( "office:name", m_varValue.toString() );
02463     writer.addTextNode( m_varValue.toString() );
02464     writer.endElement();
02465 
02466 }
02467 
02468 QString KoLinkVariable::text(bool realValue)
02469 {
02470     if (m_varColl->variableSetting()->displayFieldCode()&&!realValue)
02471         return fieldCode();
02472     else
02473         return value();
02474 }
02475 
02476 void KoLinkVariable::saveVariable( QDomElement& parentElem )
02477 {
02478     QDomElement linkElem = parentElem.ownerDocument().createElement( "LINK" );
02479     parentElem.appendChild( linkElem );
02480     linkElem.setAttribute( "linkName", m_varValue.toString() );
02481     linkElem.setAttribute( "hrefName", m_url );
02482 }
02483 
02484 void KoLinkVariable::load( QDomElement& elem )
02485 {
02486     KoVariable::load( elem );
02487     QDomElement linkElem = elem.namedItem( "LINK" ).toElement();
02488     if (!linkElem.isNull())
02489     {
02490         m_varValue = QVariant(linkElem.attribute("linkName"));
02491         m_url = linkElem.attribute("hrefName");
02492     }
02493 }
02494 
02495 void KoLinkVariable::recalc()
02496 {
02497     resize();
02498 }
02499 
02500 QStringList KoLinkVariable::actionTexts()
02501 {
02502     return QStringList( i18n( "Link..." ) );
02503 }
02504 
02505 
02506 void KoLinkVariable::drawCustomItem( QPainter* p, int x, int y, int wpix, int hpix, int ascentpix, int /*cx*/, int /*cy*/, int /*cw*/, int /*ch*/, const QColorGroup& cg, bool selected, int offset, bool drawingShadow )
02507 {
02508     KoTextFormat * fmt = format();
02509     KoTextZoomHandler * zh = textDocument()->paintingZoomHandler();
02510 
02511     bool displayLink = m_varColl->variableSetting()->displayLink();
02512     QFont font( fmt->screenFont( zh ) );
02513     if ( m_varColl->variableSetting()->underlineLink() )
02514         font.setUnderline( true );
02515     QColor textColor = displayLink ? cg.color( QColorGroup::Link ) : fmt->color();
02516 
02517     drawCustomItemHelper( p, x, y, wpix, hpix, ascentpix, cg, selected, offset, fmt, font, textColor, drawingShadow );
02518 }
02519 
02520 
02521 /******************************************************************/
02522 /* Class: KoNoteVariable                                          */
02523 /******************************************************************/
02524 KoNoteVariable::KoNoteVariable( KoTextDocument *textdoc, const QString & _note,KoVariableFormat *varFormat,KoVariableCollection *_varColl )
02525     : KoVariable( textdoc, varFormat,_varColl )
02526     , m_createdNoteDate( QDate::currentDate() )
02527 {
02528     m_varValue = QVariant( _note );
02529 }
02530 
02531 QString KoNoteVariable::fieldCode()
02532 {
02533     return i18n("Note");
02534 }
02535 
02536 QString KoNoteVariable::createdNote() const
02537 {
02538     return KGlobal::locale()->formatDate( m_createdNoteDate, false );
02539 }
02540 
02541 void KoNoteVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
02542 {
02543     const QString localName = elem.localName();
02544     QString note;
02545     if ( localName == "annotation" && elem.namespaceURI() == KoXmlNS::office )
02546     {
02547         QDomElement date = KoDom::namedItemNS( elem, KoXmlNS::dc, "date" );
02548         m_createdNoteDate = QDate::fromString( date.text(), Qt::ISODate );
02549         QDomNode text = KoDom::namedItemNS( elem, KoXmlNS::text, "p" );
02550         for ( ; !text.isNull(); text = text.nextSibling() )
02551         {
02552             if ( text.isElement() )
02553             {
02554                 QDomElement t = text.toElement();
02555                 note += t.text() + '\n';
02556             }
02557         }
02558     }
02559     m_varValue = QVariant( note  );
02560 }
02561 
02562 void KoNoteVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
02563 {
02564 //    <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>
02565     writer.startElement( "office:annotation" );
02566     writer.startElement( "dc:date" );
02567     writer.addTextNode( m_createdNoteDate.toString(Qt::ISODate) );
02568     writer.endElement();
02569     QStringList text = m_varValue.toString().split( "\n" );
02570     for ( QStringList::Iterator it = text.begin(); it != text.end(); ++it ) {
02571         writer.startElement( "text:p" );
02572         writer.addTextNode( *it );
02573         writer.endElement();
02574     }
02575     writer.endElement();
02576 }
02577 
02578 void KoNoteVariable::saveVariable( QDomElement& parentElem )
02579 {
02580     QDomElement linkElem = parentElem.ownerDocument().createElement( "NOTE" );
02581     parentElem.appendChild( linkElem );
02582     linkElem.setAttribute( "note", m_varValue.toString() );
02583 }
02584 
02585 void KoNoteVariable::load( QDomElement& elem )
02586 {
02587     KoVariable::load( elem );
02588     QDomElement linkElem = elem.namedItem( "NOTE" ).toElement();
02589     if (!linkElem.isNull())
02590     {
02591         m_varValue = QVariant(linkElem.attribute("note"));
02592     }
02593 }
02594 
02595 void KoNoteVariable::recalc()
02596 {
02597     resize();
02598 }
02599 
02600 QStringList KoNoteVariable::actionTexts()
02601 {
02602     return QStringList( i18n( "Note..." ) );
02603 }
02604 
02605 QString KoNoteVariable::text(bool realValue)
02606 {
02607     if (m_varColl->variableSetting()->displayComment() &&
02608         m_varColl->variableSetting()->displayFieldCode()&&!realValue)
02609         return fieldCode();
02610     else
02611         //for a note return just a "space" we can look at
02612         //note when we "right button"
02613         return QString(" ");
02614 
02615 }
02616 
02617 void KoNoteVariable::drawCustomItem( QPainter* p, int x, int y, int wpix, int hpix, int ascentpix, int cx, int cy, int cw, int ch, const QColorGroup& cg, bool selected, int offset, bool drawingShadow )
02618 {
02619     if ( !m_varColl->variableSetting()->displayComment())
02620         return;
02621 
02622     KoTextFormat * fmt = format();
02623     //kDebug(32500) << "KoNoteVariable::drawCustomItem index=" << index() << " x=" << x << " y=" << y << endl;
02624 
02625     p->save();
02626     p->setPen( QPen( fmt->color() ) );
02627     if ( fmt->textBackgroundColor().isValid() )
02628         p->fillRect( x, y, wpix, hpix, fmt->textBackgroundColor() );
02629     if ( selected )
02630     {
02631         p->setPen( QPen( cg.color( QColorGroup::HighlightedText ) ) );
02632         p->fillRect( x, y, wpix, hpix, cg.color( QColorGroup::Highlight ) );
02633     }
02634     else if ( textDocument() && p->device()->devType() != QInternal::Printer
02635         && !textDocument()->dontDrawingNoteVariable())
02636     {
02637         p->fillRect( x, y, wpix, hpix, Qt::yellow);
02638         p->setPen( QPen( cg.color( QColorGroup::Highlight ), 0, Qt::DotLine ) );
02639         p->drawRect( x, y, wpix, hpix );
02640     }
02641     //call it for use drawCustomItemHelper just for draw font effect
02642     KoVariable::drawCustomItem( p, x, y, wpix, hpix, ascentpix, cx, cy, cw, ch, cg, selected, offset, drawingShadow );
02643 
02644     p->restore();
02645 }
02646 
02647 void KoPageVariable::setSectionTitle( const QString& _title )
02648 {
02649     QString title( _title );
02650     if ( title.isEmpty() )
02651     {
02652         title = i18n("<No title>");
02653     }
02654     m_varValue = QVariant( title );
02655 }
02656 
02657 
02658 // ----------------------------------------------------------------
02659 //                   class KoStatisticVariable
02660 
02661 
02662 bool KoStatisticVariable::m_extendedType = false;
02663 
02664 
02665 KoStatisticVariable::KoStatisticVariable( KoTextDocument *textdoc,
02666                                           short int subtype,
02667                                           KoVariableFormat *varFormat,
02668                                           KoVariableCollection *_varColl )
02669     : KoVariable( textdoc, varFormat, _varColl ),
02670       m_subtype( subtype )
02671 {
02672 }
02673 
02674 
02675 QStringList KoStatisticVariable::actionTexts()
02676 {
02677     QStringList lst;
02678     lst << i18n( "Number of Words" );
02679     lst << i18n( "Number of Sentences" );
02680     lst << i18n( "Number of Lines" );
02681     lst << i18n( "Number of Characters" );
02682     lst << i18n( "Number of Non-Whitespace Characters" );
02683     lst << i18n( "Number of Syllables" );
02684     lst << i18n( "Number of Frames" );
02685     lst << i18n( "Number of Embedded Objects" );
02686     lst << i18n( "Number of Pictures" );
02687     if (  m_extendedType )
02688         lst << i18n( "Number of Tables" );
02689     return lst;
02690 }
02691 
02692 
02693 void KoStatisticVariable::setVariableSubType( short int subtype )
02694 {
02695     m_subtype = subtype;
02696     Q_ASSERT( m_varColl );
02697     KoVariableFormatCollection* fc = m_varColl->formatCollection();
02698     setVariableFormat(fc->format("NUMBER") );
02699 }
02700 
02701 
02702 QStringList KoStatisticVariable::subTypeList()
02703 {
02704     return KoStatisticVariable::actionTexts();
02705 }
02706 
02707 
02708 void KoStatisticVariable::saveVariable( QDomElement& varElem )
02709 {
02710     QDomElement  elem = varElem.ownerDocument().createElement( "STATISTIC" );
02711     varElem.appendChild( elem );
02712 
02713     elem.setAttribute( "type",  QString::number(m_subtype) );
02714     elem.setAttribute( "value", QString::number(m_varValue.toInt()) );
02715 }
02716 
02717 
02718 void KoStatisticVariable::load( QDomElement &elem )
02719 {
02720     KoVariable::load( elem );
02721 
02722     QDomElement e = elem.namedItem( "STATISTIC" ).toElement();
02723     if ( !e.isNull() ) {
02724         // FIXME: Error handling.
02725         m_subtype  = e.attribute( "type" ).toInt();
02726         m_varValue = e.attribute( "value" ).toInt();
02727     }
02728 }
02729 
02730 
02731 void KoStatisticVariable::loadOasis( const QDomElement &elem, KoOasisContext& /*context*/ )
02732 {
02733     const QString localName( elem.localName() );
02734     if ( localName == "object-count" )
02735     {
02736         m_subtype = VST_STATISTIC_NB_EMBEDDED;
02737         m_varValue = QVariant( elem.text().toInt() );
02738     }
02739     else if ( localName == "table-count" )
02740     {
02741         m_subtype = VST_STATISTIC_NB_TABLE;
02742         m_varValue = QVariant( elem.text().toInt() );
02743     }
02744     else if ( localName == "picture-count" )
02745     {
02746         m_subtype = VST_STATISTIC_NB_PICTURE;
02747         m_varValue = QVariant( elem.text().toInt() );
02748     }
02749     else if ( localName == "word-count" )
02750     {
02751         m_subtype = VST_STATISTIC_NB_WORD;
02752         m_varValue = QVariant( elem.text().toInt() );
02753     }
02754     else if ( localName == "character-count" )
02755     {
02756         m_subtype = VST_STATISTIC_NB_CHARACTERE;
02757         m_varValue = QVariant( elem.text().toInt() );
02758     }
02759     else if ( localName == "frame-count" )
02760     {
02761         m_subtype = VST_STATISTIC_NB_FRAME;
02762         m_varValue = QVariant( elem.text().toInt() );
02763     }
02764     else if ( localName == "line-count" )
02765     {
02766         m_subtype = VST_STATISTIC_NB_LINES;
02767         m_varValue = QVariant( elem.text().toInt() );
02768     }
02769     else if ( localName == "sentence-count" )
02770     {
02771         m_subtype = VST_STATISTIC_NB_SENTENCE;
02772         m_varValue = QVariant( elem.text().toInt() );
02773     }
02774     else if ( localName == "non-whitespace-character-count" )
02775     {
02776         m_subtype = VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE;
02777         m_varValue = QVariant( elem.text().toInt() );
02778     }
02779     else if ( localName == "syllable-count" )
02780     {
02781         m_subtype = VST_STATISTIC_NB_SYLLABLE;
02782         m_varValue = QVariant( elem.text().toInt() );
02783     }
02784     //TODO other copy
02785 }
02786 
02787 void KoStatisticVariable::saveOasis( KoXmlWriter& writer, KoSavingContext& /*context*/ ) const
02788 {
02789     switch( m_subtype )
02790     {
02791     case VST_STATISTIC_NB_EMBEDDED:
02792         writer.startElement( "text:object-count" );
02793         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02794         writer.endElement();
02795         break;
02796     case VST_STATISTIC_NB_TABLE:
02797         writer.startElement( "text:table-count" );
02798         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02799         writer.endElement();
02800         break;
02801     case VST_STATISTIC_NB_PICTURE:
02802         writer.startElement( "text:picture-count" );
02803         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02804         writer.endElement();
02805         break;
02806     case VST_STATISTIC_NB_FRAME:
02807         //TODO verify that it's implemented into oasis file format
02808         writer.startElement( "text:frame-count" );
02809         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02810         writer.endElement();
02811         break;
02812     case VST_STATISTIC_NB_WORD:
02813         writer.startElement( "text:word-count" );
02814         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02815         writer.endElement();
02816         break;
02817     case VST_STATISTIC_NB_SENTENCE:
02818         //TODO verify that it's implemented into oasis file format
02819         writer.startElement( "text:sentence-count" );
02820         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02821         writer.endElement();
02822         break;
02823     case VST_STATISTIC_NB_CHARACTERE:
02824         writer.startElement( "text:character-count" );
02825         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02826         writer.endElement();
02827         break;
02828     case VST_STATISTIC_NB_LINES:
02829         //TODO verify that it's implemented into oasis file format
02830         writer.startElement( "text:line-count" );
02831         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02832         writer.endElement();
02833         break;
02834     case VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE:
02835         //TODO verify that it's implemented into oasis file format
02836         writer.startElement( "text:non-whitespace-character-count" );
02837         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02838         writer.endElement();
02839         break;
02840     case VST_STATISTIC_NB_SYLLABLE:
02841         //TODO verify that it's implemented into oasis file format
02842         writer.startElement( "text:syllable-count" );
02843         writer.addTextNode( QString::number( m_varValue.toInt() ) );
02844         writer.endElement();
02845         break;
02846     }
02847 }
02848 
02849 QString KoStatisticVariable::fieldCode()
02850 {
02851     if ( m_subtype == VST_STATISTIC_NB_FRAME )
02852     {
02853         return i18n( "Number of Frames" );
02854     }
02855     else if( m_subtype == VST_STATISTIC_NB_PICTURE )
02856     {
02857         return i18n( "Number of Pictures" );
02858     }
02859     else if( m_subtype == VST_STATISTIC_NB_TABLE )
02860     {
02861         return i18n( "Number of Tables" );
02862     }
02863     else if( m_subtype == VST_STATISTIC_NB_EMBEDDED )
02864     {
02865         return i18n( "Number of Embedded Objects" );
02866     }
02867     else if( m_subtype == VST_STATISTIC_NB_WORD )
02868     {
02869         return i18n( "Number of Words" );
02870     }
02871     else if( m_subtype == VST_STATISTIC_NB_SENTENCE )
02872     {
02873         return i18n( "Number of Sentences" );
02874     }
02875     else if( m_subtype == VST_STATISTIC_NB_LINES )
02876     {
02877         return i18n( "Number of Lines" );
02878     }
02879     else if ( m_subtype == VST_STATISTIC_NB_CHARACTERE )
02880     {
02881         return i18n( "Number of Characters" );
02882     }
02883     else if ( m_subtype == VST_STATISTIC_NB_NON_WHITESPACE_CHARACTERE )
02884     {
02885         return i18n( "Number of Non-Whitespace Characters" );
02886     }
02887     else if ( m_subtype == VST_STATISTIC_NB_SYLLABLE )
02888     {
02889         return i18n( "Number of Syllables" );
02890     }
02891     else
02892         return i18n( "Number of Frames" );
02893 }
02894 
02895 

Généré le Wed Nov 22 23:41:11 2006 pour KPlato par  doxygen 1.5.1-p1