lib Library API Documentation

kovariable.cc

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