|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2000 David Faure <faure@kde.org>
|
|
|
|
Copyright (C) 2000 Norbert Andres <nandres@web.de>
|
|
|
|
Copyright (C) 2005 Laurent Montel <montel@kde.org>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <float.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include <opencalcexport.h>
|
|
|
|
|
|
|
|
#include <tqdatetime.h>
|
|
|
|
#include <tqdom.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqregexp.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kmessagebox.h>
|
|
|
|
#include <kmdcodec.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
#include <KoDocumentInfo.h>
|
|
|
|
#include <KoFilterChain.h>
|
|
|
|
#include <KoGlobal.h>
|
|
|
|
|
|
|
|
#include <kspread_aboutdata.h>
|
|
|
|
#include <kspread_cell.h>
|
|
|
|
#include <kspread_doc.h>
|
|
|
|
#include <kspread_format.h>
|
|
|
|
#include <kspread_map.h>
|
|
|
|
#include <kspread_view.h>
|
|
|
|
#include <kspread_canvas.h>
|
|
|
|
#include <kspread_sheet.h>
|
|
|
|
#include <kspread_sheetprint.h>
|
|
|
|
#include <kspread_style.h>
|
|
|
|
#include <kspread_style_manager.h>
|
|
|
|
#include <kspread_util.h>
|
|
|
|
|
|
|
|
using namespace KSpread;
|
|
|
|
|
|
|
|
typedef TQValueList<Reference> AreaList;
|
|
|
|
|
|
|
|
class OpenCalcExportFactory : KGenericFactory<OpenCalcExport, KoFilter>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
OpenCalcExportFactory(void) : KGenericFactory<OpenCalcExport, KoFilter> ("kspreadopencalcexport")
|
|
|
|
{}
|
|
|
|
protected:
|
|
|
|
virtual void setupTranslations( void )
|
|
|
|
{
|
|
|
|
KGlobal::locale()->insertCatalogue( "kofficefilters" );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
K_EXPORT_COMPONENT_FACTORY( libopencalcexport, OpenCalcExportFactory() )
|
|
|
|
|
|
|
|
#define STOPEXPORT \
|
|
|
|
do \
|
|
|
|
{ \
|
|
|
|
delete store; \
|
|
|
|
return false; \
|
|
|
|
} while(0)
|
|
|
|
|
|
|
|
OpenCalcExport::OpenCalcExport( KoFilter *, const char *, const TQStringList & )
|
|
|
|
: KoFilter(), m_locale( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
KoFilter::ConversiontqStatus OpenCalcExport::convert( const TQCString & from,
|
|
|
|
const TQCString & to )
|
|
|
|
{
|
|
|
|
/* later...
|
|
|
|
KSpreadLeader * leader = new KSpreadLeader( m_chain );
|
|
|
|
OpenCalcWorker * worker = new OpenCalcWorker();
|
|
|
|
leader->setWorker( worker );
|
|
|
|
|
|
|
|
KoFilter::ConversiontqStatus status = leader->convert();
|
|
|
|
|
|
|
|
delete worker;
|
|
|
|
delete leader;
|
|
|
|
|
|
|
|
return status;
|
|
|
|
*/
|
|
|
|
|
|
|
|
KoDocument * document = m_chain->inputDocument();
|
|
|
|
|
|
|
|
if ( !document )
|
|
|
|
return KoFilter::StupidError;
|
|
|
|
|
|
|
|
if ( !::tqqt_cast<const KSpread::Doc *>( document ) )
|
|
|
|
{
|
|
|
|
kdWarning(30518) << "document isn't a KSpread::Doc but a "
|
|
|
|
<< document->className() << endl;
|
|
|
|
return KoFilter::NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( to != "application/vnd.sun.xml.calc") || (from != "application/x-kspread" ) )
|
|
|
|
{
|
|
|
|
kdWarning(30518) << "Invalid mimetypes " << to << " " << from << endl;
|
|
|
|
return KoFilter::NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Doc * ksdoc = static_cast<const Doc *>(document);
|
|
|
|
|
|
|
|
if ( ksdoc->mimeType() != "application/x-kspread" )
|
|
|
|
{
|
|
|
|
kdWarning(30518) << "Invalid document mimetype " << ksdoc->mimeType() << endl;
|
|
|
|
return KoFilter::NotImplemented;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_locale = static_cast<Doc*>(document)->locale();
|
|
|
|
if ( !writeFile( ksdoc ) )
|
|
|
|
return KoFilter::CreationError;
|
|
|
|
|
|
|
|
emit sigProgress( 100 );
|
|
|
|
|
|
|
|
return KoFilter::OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::writeFile( const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
KoStore * store = KoStore::createStore( m_chain->outputFile(), KoStore::Write, "", KoStore::Zip );
|
|
|
|
|
|
|
|
if ( !store )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
uint filesWritten = 0;
|
|
|
|
|
|
|
|
if ( !exportContent( store, ksdoc ) )
|
|
|
|
STOPEXPORT;
|
|
|
|
else
|
|
|
|
filesWritten |= contentXML;
|
|
|
|
|
|
|
|
// TODO: pass sheet number and cell number
|
|
|
|
if ( !exportDocInfo( store, ksdoc ) )
|
|
|
|
STOPEXPORT;
|
|
|
|
else
|
|
|
|
filesWritten |= metaXML;
|
|
|
|
|
|
|
|
if ( !exportStyles( store, ksdoc ) )
|
|
|
|
STOPEXPORT;
|
|
|
|
else
|
|
|
|
filesWritten |= stylesXML;
|
|
|
|
|
|
|
|
if ( !exportSettings( store, ksdoc ) )
|
|
|
|
STOPEXPORT;
|
|
|
|
else
|
|
|
|
filesWritten |= settingsXML;
|
|
|
|
|
|
|
|
if ( !writeMetaFile( store, filesWritten ) )
|
|
|
|
STOPEXPORT;
|
|
|
|
|
|
|
|
// writes zip file to disc
|
|
|
|
delete store;
|
|
|
|
store = 0;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::exportDocInfo( KoStore * store, const Doc* ksdoc )
|
|
|
|
{
|
|
|
|
if ( !store->open( "meta.xml" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
KoDocumentInfo * docInfo = ksdoc->documentInfo();
|
|
|
|
KoDocumentInfoAbout * aboutPage = static_cast<KoDocumentInfoAbout *>( docInfo->page( "about" ) );
|
|
|
|
KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
|
|
|
|
|
|
|
|
TQDomDocument meta;
|
|
|
|
meta.appendChild( meta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
|
|
|
|
|
|
TQDomElement content = meta.createElement( "office:document-meta" );
|
|
|
|
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office");
|
|
|
|
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
|
|
|
|
content.setAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/" );
|
|
|
|
content.setAttribute( "xmlns:meta", "http://openoffice.org/2000/meta" );
|
|
|
|
content.setAttribute( "office:version", "1.0" );
|
|
|
|
|
|
|
|
TQDomNode officeMeta = meta.createElement( "office:meta" );
|
|
|
|
|
|
|
|
TQDomElement data = meta.createElement( "meta:generator" );
|
|
|
|
TQString app( "KSpread " );
|
|
|
|
app += KSpread::version;
|
|
|
|
data.appendChild( meta.createTextNode( app ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "meta:initial-creator" );
|
|
|
|
data.appendChild( meta.createTextNode( authorPage->fullName() ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "meta:creator" );
|
|
|
|
data.appendChild( meta.createTextNode( authorPage->fullName() ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "dc:description" );
|
|
|
|
data.appendChild( meta.createTextNode( aboutPage->abstract() ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "meta:keywords" );
|
|
|
|
TQDomElement dataItem = meta.createElement( "meta:keyword" );
|
|
|
|
dataItem.appendChild( meta.createTextNode( aboutPage->keywords() ) );
|
|
|
|
data.appendChild( dataItem );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "dc:title" );
|
|
|
|
data.appendChild( meta.createTextNode( aboutPage->title() ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
data = meta.createElement( "dc:subject" );
|
|
|
|
data.appendChild( meta.createTextNode( aboutPage->subject() ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
const TQDateTime dt ( TQDateTime::tqcurrentDateTime() );
|
|
|
|
if ( dt.isValid() )
|
|
|
|
{
|
|
|
|
data = meta.createElement( "dc:date" );
|
|
|
|
data.appendChild( meta.createTextNode( dt.toString( Qt::ISODate ) ) );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO:
|
|
|
|
<meta:creation-date>2003-01-08T23:57:31</meta:creation-date>
|
|
|
|
<dc:language>en-US</dc:language>
|
|
|
|
<meta:editing-cycles>2</meta:editing-cycles>
|
|
|
|
<meta:editing-duration>PT38S</meta:editing-duration>
|
|
|
|
<meta:user-defined meta:name="Info 3"/>
|
|
|
|
<meta:user-defined meta:name="Info 4"/>
|
|
|
|
*/
|
|
|
|
|
|
|
|
data = meta.createElement( "meta:document-statistic" );
|
|
|
|
data.setAttribute( "meta:table-count", TQString::number( ksdoc->map()->count() ) );
|
|
|
|
// TODO: data.setAttribute( "meta:cell-count", );
|
|
|
|
officeMeta.appendChild( data );
|
|
|
|
|
|
|
|
content.appendChild( officeMeta );
|
|
|
|
meta.appendChild( content );
|
|
|
|
|
|
|
|
TQCString doc( meta.toCString() );
|
|
|
|
kdDebug(30518) << "Meta: " << doc << endl;
|
|
|
|
|
|
|
|
store->write( doc, doc.length() );
|
|
|
|
|
|
|
|
if ( !store->close() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::exportSettings( KoStore * store, const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
if ( !store->open( "settings.xml" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQDomDocument doc;
|
|
|
|
doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
|
|
|
|
|
|
TQDomElement settings = doc.createElement( "office:document-settings" );
|
|
|
|
settings.setAttribute( "xmlns:office", "http://openoffice.org/2000/office");
|
|
|
|
settings.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
|
|
|
|
settings.setAttribute( "xmlns:config", "http://openoffice.org/2001/config" );
|
|
|
|
settings.setAttribute( "office:version", "1.0" );
|
|
|
|
|
|
|
|
TQDomElement begin = doc.createElement( "office:settings" );
|
|
|
|
|
|
|
|
TQDomElement configItem = doc.createElement("config:config-item-set" );
|
|
|
|
configItem.setAttribute( "config:name", "view-settings" );
|
|
|
|
|
|
|
|
TQDomElement mapIndexed = doc.createElement( "config:config-item-map-indexed" );
|
|
|
|
mapIndexed.setAttribute("config:name", "Views" );
|
|
|
|
configItem.appendChild( mapIndexed );
|
|
|
|
|
|
|
|
TQDomElement mapItem = doc.createElement("config:config-item-map-entry" );
|
|
|
|
|
|
|
|
TQDomElement attribute = doc.createElement("config:config-item" );
|
|
|
|
attribute.setAttribute( "config:name", "ActiveTable" );
|
|
|
|
attribute.setAttribute( "config:type", "string" );
|
|
|
|
|
|
|
|
View * view = static_cast<View*>( ksdoc->views().getFirst());
|
|
|
|
TQString activeTable;
|
|
|
|
if ( view ) // no view if embedded document
|
|
|
|
{
|
|
|
|
Canvas * canvas = view->canvasWidget();
|
|
|
|
activeTable = canvas->activeSheet()->sheetName();
|
|
|
|
// save current sheet selection before to save marker, otherwise current pos is not saved
|
|
|
|
view->saveCurrentSheetSelection();
|
|
|
|
}
|
|
|
|
attribute.appendChild( doc.createTextNode( activeTable ) );
|
|
|
|
mapItem.appendChild( attribute );
|
|
|
|
|
|
|
|
TQDomElement configmaped = doc.createElement( "config:config-item-map-named" );
|
|
|
|
configmaped.setAttribute( "config:name","Tables" );
|
|
|
|
|
|
|
|
TQPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
|
|
|
|
for( ; it.current(); ++it )
|
|
|
|
{
|
|
|
|
TQPoint marker;
|
|
|
|
if ( view )
|
|
|
|
{
|
|
|
|
marker = view->markerFromSheet( *it );
|
|
|
|
}
|
|
|
|
TQDomElement tmpItemMapNamed = doc.createElement( "config:config-item-map-entry" );
|
|
|
|
tmpItemMapNamed.setAttribute( "config:name", ( *it )->tableName() );
|
|
|
|
|
|
|
|
TQDomElement sheetAttribute = doc.createElement( "config:config-item" );
|
|
|
|
sheetAttribute.setAttribute( "config:name", "CursorPositionX" );
|
|
|
|
sheetAttribute.setAttribute( "config:type", "int" );
|
|
|
|
sheetAttribute.appendChild( doc.createTextNode( TQString::number(marker.x() ) ) );
|
|
|
|
tmpItemMapNamed.appendChild( sheetAttribute );
|
|
|
|
|
|
|
|
sheetAttribute = doc.createElement( "config:config-item" );
|
|
|
|
sheetAttribute.setAttribute( "config:name", "CursorPositionY" );
|
|
|
|
sheetAttribute.setAttribute( "config:type", "int" );
|
|
|
|
sheetAttribute.appendChild( doc.createTextNode( TQString::number(marker.y() ) ) );
|
|
|
|
tmpItemMapNamed.appendChild( sheetAttribute );
|
|
|
|
|
|
|
|
configmaped.appendChild( tmpItemMapNamed );
|
|
|
|
}
|
|
|
|
mapItem.appendChild( configmaped );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mapIndexed.appendChild( mapItem );
|
|
|
|
|
|
|
|
begin.appendChild( configItem );
|
|
|
|
|
|
|
|
settings.appendChild( begin );
|
|
|
|
|
|
|
|
doc.appendChild( settings );
|
|
|
|
|
|
|
|
TQCString f( doc.toCString() );
|
|
|
|
kdDebug(30518) << "Settings: " << (char const * ) f << endl;
|
|
|
|
|
|
|
|
store->write( f, f.length() );
|
|
|
|
|
|
|
|
if ( !store->close() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::exportContent( KoStore * store, const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
if ( !store->open( "content.xml" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
createDefaultStyles();
|
|
|
|
|
|
|
|
TQDomDocument doc;
|
|
|
|
doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
|
|
|
|
|
|
TQDomElement content = doc.createElement( "office:document-content" );
|
|
|
|
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office");
|
|
|
|
content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" );
|
|
|
|
content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" );
|
|
|
|
content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" );
|
|
|
|
content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" );
|
|
|
|
content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" );
|
|
|
|
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
|
|
|
|
content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" );
|
|
|
|
content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" );
|
|
|
|
content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" );
|
|
|
|
content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" );
|
|
|
|
content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" );
|
|
|
|
content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" );
|
|
|
|
content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" );
|
|
|
|
content.setAttribute( "office:class", "spreadsheet" );
|
|
|
|
content.setAttribute( "office:version", "1.0" );
|
|
|
|
|
|
|
|
TQDomElement data = doc.createElement( "office:script" );
|
|
|
|
content.appendChild( data );
|
|
|
|
|
|
|
|
if ( !exportBody( doc, content, ksdoc ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
doc.appendChild( content );
|
|
|
|
|
|
|
|
TQCString f( doc.toCString() );
|
|
|
|
kdDebug(30518) << "Content: " << (char const * ) f << endl;
|
|
|
|
|
|
|
|
store->write( f, f.length() );
|
|
|
|
|
|
|
|
if ( !store->close() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void exportNamedExpr( TQDomDocument & doc, TQDomElement & parent,
|
|
|
|
AreaList const & namedAreas )
|
|
|
|
{
|
|
|
|
AreaList::const_iterator it = namedAreas.begin();
|
|
|
|
AreaList::const_iterator end = namedAreas.end();
|
|
|
|
|
|
|
|
while ( it != end )
|
|
|
|
{
|
|
|
|
TQDomElement namedRange = doc.createElement( "table:named-range" );
|
|
|
|
|
|
|
|
Reference ref = *it;
|
|
|
|
|
|
|
|
namedRange.setAttribute( "table:name", ref.ref_name );
|
|
|
|
namedRange.setAttribute( "table:base-cell-address", convertRefToBase( ref.sheet_name, ref.rect ) );
|
|
|
|
namedRange.setAttribute( "table:cell-range-address", convertRefToRange( ref.sheet_name, ref.rect ) );
|
|
|
|
|
|
|
|
parent.appendChild( namedRange );
|
|
|
|
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::exportBody( TQDomDocument & doc, TQDomElement & content, const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
TQDomElement fontDecls = doc.createElement( "office:font-decls" );
|
|
|
|
TQDomElement autoStyles = doc.createElement( "office:automatic-styles" );
|
|
|
|
TQDomElement body = doc.createElement( "office:body" );
|
|
|
|
|
|
|
|
if ( ksdoc->map()->isProtected() )
|
|
|
|
{
|
|
|
|
body.setAttribute( "table:structure-protected", "true" );
|
|
|
|
|
|
|
|
TQCString passwd;
|
|
|
|
ksdoc->map()->password( passwd );
|
|
|
|
if ( passwd.length() > 0 )
|
|
|
|
{
|
|
|
|
TQCString str( KCodecs::base64Encode( passwd ) );
|
|
|
|
body.setAttribute( "table:protection-key", TQString( str.data() ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TQPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
|
|
|
|
|
|
|
|
for( it.toFirst(); it.current(); ++it )
|
|
|
|
{
|
|
|
|
SheetStyle ts;
|
|
|
|
int maxCols = 1;
|
|
|
|
int maxRows = 1;
|
|
|
|
Sheet * sheet = it.current();
|
|
|
|
|
|
|
|
ts.visible = !sheet->isHidden();
|
|
|
|
|
|
|
|
TQDomElement tabElem = doc.createElement( "table:table" );
|
|
|
|
tabElem.setAttribute( "table:style-name", m_styles.sheetStyle( ts ) );
|
|
|
|
|
|
|
|
if ( sheet->isProtected() )
|
|
|
|
{
|
|
|
|
tabElem.setAttribute( "table:protected", "true" );
|
|
|
|
|
|
|
|
TQCString passwd;
|
|
|
|
sheet->password( passwd );
|
|
|
|
if ( passwd.length() > 0 )
|
|
|
|
{
|
|
|
|
TQCString str( KCodecs::base64Encode( passwd ) );
|
|
|
|
tabElem.setAttribute( "table:protection-key", TQString( str.data() ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString name( sheet->tableName() );
|
|
|
|
|
|
|
|
int n = name.find( ' ' );
|
|
|
|
if ( n != -1 )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "Sheet name converting: " << name << endl;
|
|
|
|
name[n] == '_';
|
|
|
|
kdDebug(30518) << "Sheet name converted: " << name << endl;
|
|
|
|
}
|
|
|
|
name = name.replace( ' ', "_" );
|
|
|
|
|
|
|
|
TQRect _printRange = sheet->print()->printRange();
|
|
|
|
if ( _printRange != ( TQRect( TQPoint( 1, 1 ), TQPoint( KS_colMax, KS_rowMax ) ) ) )
|
|
|
|
{
|
|
|
|
TQString range= convertRangeToRef( name, _printRange );
|
|
|
|
//kdDebug(30518)<<" range : "<<range<<endl;
|
|
|
|
tabElem.setAttribute( "table:print-ranges", range );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tabElem.setAttribute( "table:name", name );
|
|
|
|
|
|
|
|
maxRowCols( sheet, maxCols, maxRows );
|
|
|
|
|
|
|
|
exportSheet( doc, tabElem, sheet, maxCols, maxRows );
|
|
|
|
|
|
|
|
body.appendChild( tabElem );
|
|
|
|
}
|
|
|
|
|
|
|
|
KoDocument * document = m_chain->inputDocument();
|
|
|
|
Doc * kspreadDoc = static_cast<Doc *>( document );
|
|
|
|
|
|
|
|
AreaList namedAreas = kspreadDoc->listArea();
|
|
|
|
if ( namedAreas.count() > 0 )
|
|
|
|
{
|
|
|
|
TQDomElement namedExpr = doc.createElement( "table:named-expressions" );
|
|
|
|
exportNamedExpr( doc, namedExpr, namedAreas );
|
|
|
|
|
|
|
|
body.appendChild( namedExpr );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_styles.writeStyles( doc, autoStyles );
|
|
|
|
m_styles.writeFontDecl( doc, fontDecls );
|
|
|
|
|
|
|
|
content.appendChild( fontDecls );
|
|
|
|
content.appendChild( autoStyles );
|
|
|
|
content.appendChild( body );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::exportSheet( TQDomDocument & doc, TQDomElement & tabElem,
|
|
|
|
const Sheet * sheet, int maxCols, int maxRows )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "exportSheet: " << sheet->tableName() << endl;
|
|
|
|
int i = 1;
|
|
|
|
|
|
|
|
while ( i <= maxCols )
|
|
|
|
{
|
|
|
|
const ColumnFormat * column = sheet->columnFormat( i );
|
|
|
|
ColumnStyle cs;
|
|
|
|
cs.breakB = ::Style::automatic;
|
|
|
|
cs.size = column->mmWidth() / 10;
|
|
|
|
bool hide = column->isHide();
|
|
|
|
|
|
|
|
int j = i + 1;
|
|
|
|
int repeated = 1;
|
|
|
|
while ( j <= maxCols )
|
|
|
|
{
|
|
|
|
const ColumnFormat *c = sheet->columnFormat( j );
|
|
|
|
ColumnStyle cs1;
|
|
|
|
cs1.breakB = ::Style::automatic;
|
|
|
|
cs1.size = c->mmWidth() / 10;
|
|
|
|
|
|
|
|
if ( ColumnStyle::isEqual( &cs, cs1 ) && ( hide == c->isHide() ) )
|
|
|
|
++repeated;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
++j;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQDomElement colElem = doc.createElement( "table:table-column" );
|
|
|
|
colElem.setAttribute( "table:style-name", m_styles.columnStyle( cs ) );
|
|
|
|
colElem.setAttribute( "table:default-cell-style-name", "Default" );//todo fixme create style from cell
|
|
|
|
if ( hide )
|
|
|
|
colElem.setAttribute( "table:visibility", "collapse" );
|
|
|
|
|
|
|
|
if ( repeated > 1 )
|
|
|
|
colElem.setAttribute( "table:number-columns-repeated", TQString::number( repeated ) );
|
|
|
|
|
|
|
|
tabElem.appendChild( colElem );
|
|
|
|
i += repeated;
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 1; i <= maxRows; ++i )
|
|
|
|
{
|
|
|
|
const RowFormat * row = sheet->rowFormat( i );
|
|
|
|
RowStyle rs;
|
|
|
|
rs.breakB = ::Style::automatic;
|
|
|
|
rs.size = row->mmHeight() / 10;
|
|
|
|
|
|
|
|
TQDomElement rowElem = doc.createElement( "table:table-row" );
|
|
|
|
rowElem.setAttribute( "table:style-name", m_styles.rowStyle( rs ) );
|
|
|
|
if ( row->isHide() )
|
|
|
|
rowElem.setAttribute( "table:visibility", "collapse" );
|
|
|
|
|
|
|
|
exportCells( doc, rowElem, sheet, i, maxCols );
|
|
|
|
|
|
|
|
tabElem.appendChild( rowElem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::exportCells( TQDomDocument & doc, TQDomElement & rowElem,
|
|
|
|
const Sheet *sheet, int row, int maxCols )
|
|
|
|
{
|
|
|
|
int i = 1;
|
|
|
|
while ( i <= maxCols )
|
|
|
|
{
|
|
|
|
int repeated = 1;
|
|
|
|
bool hasComment = false;
|
|
|
|
const Cell* cell = sheet->cellAt( i, row );
|
|
|
|
TQDomElement cellElem;
|
|
|
|
|
|
|
|
if ( !cell->isPartOfMerged() )
|
|
|
|
cellElem = doc.createElement( "table:table-cell" );
|
|
|
|
else
|
|
|
|
cellElem = doc.createElement( "table:covered-table-cell" );
|
|
|
|
|
|
|
|
TQFont font;
|
|
|
|
Value const value( cell->value() );
|
|
|
|
if ( !cell->isDefault() )
|
|
|
|
{
|
|
|
|
font = cell->format()->textFont( i, row );
|
|
|
|
m_styles.addFont( font );
|
|
|
|
|
|
|
|
if ( cell->format()->hasProperty( Format::PComment ) )
|
|
|
|
hasComment = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
CellStyle c;
|
|
|
|
CellStyle::loadData( c, cell ); // TODO: number style
|
|
|
|
|
|
|
|
cellElem.setAttribute( "table:style-name", m_styles.cellStyle( c ) );
|
|
|
|
|
|
|
|
// group empty cells with the same style
|
|
|
|
if ( cell->isEmpty() && !hasComment && !cell->isPartOfMerged() && !cell->doesMergeCells() )
|
|
|
|
{
|
|
|
|
int j = i + 1;
|
|
|
|
while ( j <= maxCols )
|
|
|
|
{
|
|
|
|
const Cell *cell1 = sheet->cellAt( j, row );
|
|
|
|
|
|
|
|
CellStyle c1;
|
|
|
|
CellStyle::loadData( c1, cell1 ); // TODO: number style
|
|
|
|
|
|
|
|
if ( cell1->isEmpty() && !cell->format()->hasProperty( Format::PComment )
|
|
|
|
&& CellStyle::isEqual( &c, c1 ) && !cell->isPartOfMerged() && !cell->doesMergeCells() )
|
|
|
|
++repeated;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
++j;
|
|
|
|
}
|
|
|
|
if ( repeated > 1 )
|
|
|
|
cellElem.setAttribute( "table:number-columns-repeated", TQString::number( repeated ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( value.isBoolean() )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "Type: Boolean" << endl;
|
|
|
|
cellElem.setAttribute( "table:value-type", "boolean" );
|
|
|
|
cellElem.setAttribute( "table:boolean-value", ( value.asBoolean() ? "true" : "false" ) );
|
|
|
|
}
|
|
|
|
else if ( value.isNumber() )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "Type: Number" << endl;
|
|
|
|
FormatType type = cell->format()->getFormatType( i, row );
|
|
|
|
|
|
|
|
if ( type == Percentage_format )
|
|
|
|
cellElem.setAttribute( "table:value-type", "percentage" );
|
|
|
|
else
|
|
|
|
cellElem.setAttribute( "table:value-type", "float" );
|
|
|
|
|
|
|
|
cellElem.setAttribute( "table:value", TQString::number( value.asFloat() ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "Type: " << value.type() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cell->isFormula() )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "Formula found" << endl;
|
|
|
|
|
|
|
|
TQString formula( convertFormula( cell->text() ) );
|
|
|
|
cellElem.setAttribute( "table:formula", formula );
|
|
|
|
}
|
|
|
|
else if ( !cell->link().isEmpty() )
|
|
|
|
{
|
|
|
|
TQDomElement link = doc.createElement( "text:p" );
|
|
|
|
TQDomElement linkref = doc.createElement( "text:a" );
|
|
|
|
|
|
|
|
TQString tmp = cell->link();
|
|
|
|
if ( localReferenceAnchor( tmp ) )
|
|
|
|
linkref.setAttribute( "xlink:href", ( "#"+tmp ) );
|
|
|
|
else
|
|
|
|
linkref.setAttribute( "xlink:href", tmp );
|
|
|
|
|
|
|
|
linkref.appendChild( doc.createTextNode( cell->text() ) );
|
|
|
|
|
|
|
|
link.appendChild( linkref );
|
|
|
|
cellElem.appendChild( link );
|
|
|
|
}
|
|
|
|
else if ( !cell->isEmpty() )
|
|
|
|
{
|
|
|
|
TQDomElement textElem = doc.createElement( "text:p" );
|
|
|
|
textElem.appendChild( doc.createTextNode( cell->strOutText() ) );
|
|
|
|
|
|
|
|
cellElem.appendChild( textElem );
|
|
|
|
kdDebug(30518) << "Cell StrOut: " << cell->strOutText() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cell->doesMergeCells() )
|
|
|
|
{
|
|
|
|
int colSpan = cell->mergedXCells() + 1;
|
|
|
|
int rowSpan = cell->mergedYCells() + 1;
|
|
|
|
|
|
|
|
if ( colSpan > 1 )
|
|
|
|
cellElem.setAttribute( "table:number-columns-spanned", TQString::number( colSpan ) );
|
|
|
|
|
|
|
|
if ( rowSpan > 1 )
|
|
|
|
cellElem.setAttribute( "table:number-rows-spanned", TQString::number( rowSpan ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasComment )
|
|
|
|
{
|
|
|
|
TQString comment( cell->format()->comment( i, row ) );
|
|
|
|
TQDomElement annotation = doc.createElement( "office:annotation" );
|
|
|
|
TQDomElement text = doc.createElement( "text:p" );
|
|
|
|
text.appendChild( doc.createTextNode( comment ) );
|
|
|
|
|
|
|
|
annotation.appendChild( text );
|
|
|
|
cellElem.appendChild( annotation );
|
|
|
|
}
|
|
|
|
|
|
|
|
rowElem.appendChild( cellElem );
|
|
|
|
|
|
|
|
i += repeated;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::maxRowCols( const Sheet *sheet,
|
|
|
|
int & maxCols, int & maxRows )
|
|
|
|
{
|
|
|
|
Cell const * cell = sheet->firstCell();
|
|
|
|
|
|
|
|
while ( cell )
|
|
|
|
{
|
|
|
|
if ( cell->column() > maxCols )
|
|
|
|
maxCols = cell->column();
|
|
|
|
|
|
|
|
if ( cell->row() > maxRows )
|
|
|
|
maxRows = cell->row();
|
|
|
|
|
|
|
|
cell = cell->nextCell();
|
|
|
|
}
|
|
|
|
|
|
|
|
RowFormat const * row = sheet->firstRow();
|
|
|
|
|
|
|
|
while ( row )
|
|
|
|
{
|
|
|
|
if ( row->row() > maxRows )
|
|
|
|
maxRows = row->row();
|
|
|
|
|
|
|
|
row = row->next();
|
|
|
|
}
|
|
|
|
|
|
|
|
ColumnFormat const * col = sheet->firstCol();
|
|
|
|
while ( col )
|
|
|
|
{
|
|
|
|
if ( col->column() > maxCols )
|
|
|
|
maxCols = col->column();
|
|
|
|
|
|
|
|
col = col->next();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::exportStyles( KoStore * store, const Doc *ksdoc )
|
|
|
|
{
|
|
|
|
if ( !store->open( "styles.xml" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQDomDocument doc;
|
|
|
|
doc.appendChild( doc.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
|
|
|
|
|
|
TQDomElement content = doc.createElement( "office:document-styles" );
|
|
|
|
content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" );
|
|
|
|
content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" );
|
|
|
|
content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" );
|
|
|
|
content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" );
|
|
|
|
content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" );
|
|
|
|
content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" );
|
|
|
|
content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" );
|
|
|
|
content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" );
|
|
|
|
content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" );
|
|
|
|
content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" );
|
|
|
|
content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" );
|
|
|
|
content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" );
|
|
|
|
content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" );
|
|
|
|
content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" );
|
|
|
|
content.setAttribute( "office:version", "1.0" );
|
|
|
|
|
|
|
|
// order important here!
|
|
|
|
TQDomElement officeStyles = doc.createElement( "office:styles" );
|
|
|
|
exportDefaultCellStyle( doc, officeStyles );
|
|
|
|
|
|
|
|
TQDomElement fontDecls = doc.createElement( "office:font-decls" );
|
|
|
|
m_styles.writeFontDecl( doc, fontDecls );
|
|
|
|
|
|
|
|
// TODO: needs in new number/date/time parser...
|
|
|
|
// exportDefaultNumberStyles( doc, officeStyles );
|
|
|
|
|
|
|
|
TQDomElement defaultStyle = doc.createElement( "style:style" );
|
|
|
|
defaultStyle.setAttribute( "style:name", "Default" );
|
|
|
|
defaultStyle.setAttribute( "style:family", "table-cell" );
|
|
|
|
officeStyles.appendChild( defaultStyle );
|
|
|
|
|
|
|
|
TQDomElement autoStyles = doc.createElement( "office:automatic-styles" );
|
|
|
|
exportPageAutoStyles( doc, autoStyles, ksdoc );
|
|
|
|
|
|
|
|
TQDomElement masterStyles = doc.createElement( "office:master-styles" );
|
|
|
|
exportMasterStyles( doc, masterStyles, ksdoc );
|
|
|
|
|
|
|
|
content.appendChild( fontDecls );
|
|
|
|
content.appendChild( officeStyles );
|
|
|
|
content.appendChild( autoStyles );
|
|
|
|
content.appendChild( masterStyles );
|
|
|
|
|
|
|
|
doc.appendChild( content );
|
|
|
|
|
|
|
|
TQCString f( doc.toCString() );
|
|
|
|
kdDebug(30518) << "Content: " << (char const * ) f << endl;
|
|
|
|
|
|
|
|
store->write( f, f.length() );
|
|
|
|
|
|
|
|
if ( !store->close() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::exportDefaultCellStyle( TQDomDocument & doc, TQDomElement & officeStyles )
|
|
|
|
{
|
|
|
|
TQDomElement defStyle = doc.createElement( "style:default-style" );
|
|
|
|
defStyle.setAttribute( "style:family", "table-cell" );
|
|
|
|
|
|
|
|
KoDocument * document = m_chain->inputDocument();
|
|
|
|
Doc * ksdoc = static_cast<Doc *>(document);
|
|
|
|
|
|
|
|
Format * format = new Format( 0, ksdoc->styleManager()->defaultStyle() );
|
|
|
|
const KLocale *locale = ksdoc->locale();
|
|
|
|
TQString language;
|
|
|
|
TQString country;
|
|
|
|
TQString charSet;
|
|
|
|
|
|
|
|
TQString l( locale->language() );
|
|
|
|
KLocale::splitLocale( l, language, country, charSet );
|
|
|
|
TQFont font( format->font() );
|
|
|
|
m_styles.addFont( font, true );
|
|
|
|
|
|
|
|
TQDomElement style = doc.createElement( "style:properties" );
|
|
|
|
style.setAttribute( "style:font-name", font.family() );
|
|
|
|
style.setAttribute( "fo:font-size", TQString( "%1pt" ).tqarg( font.pointSize() ) );
|
|
|
|
style.setAttribute( "style:decimal-places", TQString::number( locale->fracDigits() ) );
|
|
|
|
style.setAttribute( "fo:language", language );
|
|
|
|
style.setAttribute( "fo:country", country );
|
|
|
|
style.setAttribute( "style:font-name-asian", "HG Mincho Light J" );
|
|
|
|
style.setAttribute( "style:language-asian", "none" );
|
|
|
|
style.setAttribute( "style:country-asian", "none" );
|
|
|
|
style.setAttribute( "style:font-name-complex", "Arial Unicode MS" );
|
|
|
|
style.setAttribute( "style:language-complex", "none" );
|
|
|
|
style.setAttribute( "style:country-complex", "none" );
|
|
|
|
style.setAttribute( "style:tab-stop-distance", "1.25cm" );
|
|
|
|
|
|
|
|
defStyle.appendChild( style );
|
|
|
|
officeStyles.appendChild( defStyle );
|
|
|
|
delete format;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::createDefaultStyles()
|
|
|
|
{
|
|
|
|
// TODO: default number styles, currency styles,...
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::exportPageAutoStyles( TQDomDocument & doc, TQDomElement & autoStyles,
|
|
|
|
const Doc *ksdoc )
|
|
|
|
{
|
|
|
|
TQPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
|
|
|
|
const Sheet * sheet = it.toFirst();
|
|
|
|
|
|
|
|
float width = 20.999;
|
|
|
|
float height = 29.699;
|
|
|
|
|
|
|
|
if ( sheet )
|
|
|
|
{
|
|
|
|
width = sheet->print()->paperWidth() / 10;
|
|
|
|
height = sheet->print()->paperHeight() / 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString sWidth = TQString( "%1cm" ).tqarg( width );
|
|
|
|
TQString sHeight = TQString( "%1cm" ).tqarg( height );
|
|
|
|
|
|
|
|
TQDomElement pageMaster = doc.createElement( "style:page-master" );
|
|
|
|
pageMaster.setAttribute( "style:name", "pm1" );
|
|
|
|
|
|
|
|
TQDomElement properties = doc.createElement( "style:properties" );
|
|
|
|
properties.setAttribute( "fo:page-width", sWidth );
|
|
|
|
properties.setAttribute( "fo:page-height", sHeight );
|
|
|
|
properties.setAttribute( "fo:border", "0.002cm solid #000000" );
|
|
|
|
properties.setAttribute( "fo:padding", "0cm" );
|
|
|
|
properties.setAttribute( "fo:background-color", "transparent" );
|
|
|
|
|
|
|
|
pageMaster.appendChild( properties );
|
|
|
|
|
|
|
|
TQDomElement header = doc.createElement( "style:header-style" );
|
|
|
|
properties = doc.createElement( "style:properties" );
|
|
|
|
properties.setAttribute( "fo:min-height", "0.75cm" );
|
|
|
|
properties.setAttribute( "fo:margin-left", "0cm" );
|
|
|
|
properties.setAttribute( "fo:margin-right", "0cm" );
|
|
|
|
properties.setAttribute( "fo:margin-bottom", "0.25cm" );
|
|
|
|
|
|
|
|
header.appendChild( properties );
|
|
|
|
|
|
|
|
TQDomElement footer = doc.createElement( "style:header-style" );
|
|
|
|
properties = doc.createElement( "style:properties" );
|
|
|
|
properties.setAttribute( "fo:min-height", "0.75cm" );
|
|
|
|
properties.setAttribute( "fo:margin-left", "0cm" );
|
|
|
|
properties.setAttribute( "fo:margin-right", "0cm" );
|
|
|
|
properties.setAttribute( "fo:margin-bottom", "0.25cm" );
|
|
|
|
|
|
|
|
footer.appendChild( properties );
|
|
|
|
|
|
|
|
pageMaster.appendChild( header );
|
|
|
|
pageMaster.appendChild( footer );
|
|
|
|
|
|
|
|
autoStyles.appendChild( pageMaster );
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::exportMasterStyles( TQDomDocument & doc, TQDomElement & masterStyles,
|
|
|
|
const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
TQDomElement masterPage = doc.createElement( "style:master-page" );
|
|
|
|
masterPage.setAttribute( "style:name", "Default" );
|
|
|
|
masterPage.setAttribute( "style:page-master-name", "pm1" );
|
|
|
|
|
|
|
|
TQPtrListIterator<Sheet> it( ksdoc->map()->sheetList() );
|
|
|
|
const Sheet * sheet = it.toFirst();
|
|
|
|
|
|
|
|
TQString headerLeft;
|
|
|
|
TQString headerCenter;
|
|
|
|
TQString headerRight;
|
|
|
|
TQString footerLeft;
|
|
|
|
TQString footerCenter;
|
|
|
|
TQString footerRight;
|
|
|
|
|
|
|
|
if ( sheet )
|
|
|
|
{
|
|
|
|
headerLeft = sheet->print()->headLeft();
|
|
|
|
headerCenter = sheet->print()->headMid();
|
|
|
|
headerRight = sheet->print()->headRight();
|
|
|
|
footerLeft = sheet->print()->footLeft();
|
|
|
|
footerCenter = sheet->print()->footMid();
|
|
|
|
footerRight = sheet->print()->footRight();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( headerLeft.length() > 0 ) || ( headerCenter.length() > 0 )
|
|
|
|
|| ( headerRight.length() > 0 ) )
|
|
|
|
{
|
|
|
|
TQDomElement header = doc.createElement( "style:header" );
|
|
|
|
TQDomElement left = doc.createElement( "style:region-left" );
|
|
|
|
TQDomElement text = doc.createElement( "text:p" );
|
|
|
|
convertPart( headerLeft, doc, text, ksdoc );
|
|
|
|
left.appendChild( text );
|
|
|
|
|
|
|
|
TQDomElement center = doc.createElement( "style:region-center" );
|
|
|
|
TQDomElement text1 = doc.createElement( "text:p" );
|
|
|
|
convertPart( headerCenter, doc, text1, ksdoc );
|
|
|
|
center.appendChild( text1 );
|
|
|
|
|
|
|
|
TQDomElement right = doc.createElement( "style:region-right" );
|
|
|
|
TQDomElement text2 = doc.createElement( "text:p" );
|
|
|
|
convertPart( headerRight, doc, text2, ksdoc );
|
|
|
|
right.appendChild( text2 );
|
|
|
|
|
|
|
|
header.appendChild( left );
|
|
|
|
header.appendChild( center );
|
|
|
|
header.appendChild( right );
|
|
|
|
|
|
|
|
masterPage.appendChild( header );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQDomElement header = doc.createElement( "style:header" );
|
|
|
|
TQDomElement text = doc.createElement( "text:p" );
|
|
|
|
TQDomElement name = doc.createElement( "text:sheet-name" );
|
|
|
|
name.appendChild( doc.createTextNode( "???" ) );
|
|
|
|
text.appendChild( name );
|
|
|
|
header.appendChild( text );
|
|
|
|
|
|
|
|
masterPage.appendChild( header );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( ( footerLeft.length() > 0 ) || ( footerCenter.length() > 0 )
|
|
|
|
|| ( footerRight.length() > 0 ) )
|
|
|
|
{
|
|
|
|
TQDomElement footer = doc.createElement( "style:footer" );
|
|
|
|
TQDomElement left = doc.createElement( "style:region-left" );
|
|
|
|
TQDomElement text = doc.createElement( "text:p" );
|
|
|
|
convertPart( footerLeft, doc, text, ksdoc );
|
|
|
|
left.appendChild( text );
|
|
|
|
|
|
|
|
TQDomElement center = doc.createElement( "style:region-center" );
|
|
|
|
TQDomElement text1 = doc.createElement( "text:p" );
|
|
|
|
convertPart( footerCenter, doc, text1, ksdoc );
|
|
|
|
center.appendChild( text1 );
|
|
|
|
|
|
|
|
TQDomElement right = doc.createElement( "style:region-right" );
|
|
|
|
TQDomElement text2 = doc.createElement( "text:p" );
|
|
|
|
convertPart( footerRight, doc, text2, ksdoc );
|
|
|
|
right.appendChild( text2 );
|
|
|
|
|
|
|
|
footer.appendChild( left );
|
|
|
|
footer.appendChild( center );
|
|
|
|
footer.appendChild( right );
|
|
|
|
|
|
|
|
masterPage.appendChild( footer );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQDomElement footer = doc.createElement( "style:footer" );
|
|
|
|
TQDomElement text = doc.createElement( "text:p" );
|
|
|
|
text.appendChild( doc.createTextNode( i18n( "Page " ) ) );
|
|
|
|
TQDomElement number = doc.createElement( "text:page-number" );
|
|
|
|
number.appendChild( doc.createTextNode( "1" ) );
|
|
|
|
text.appendChild( number );
|
|
|
|
footer.appendChild( text );
|
|
|
|
|
|
|
|
masterPage.appendChild( footer );
|
|
|
|
}
|
|
|
|
|
|
|
|
masterStyles.appendChild( masterPage );
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::addText( TQString const & text, TQDomDocument & doc,
|
|
|
|
TQDomElement & parent )
|
|
|
|
{
|
|
|
|
if (text.length() > 0 )
|
|
|
|
parent.appendChild( doc.createTextNode( text ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void OpenCalcExport::convertPart( TQString const & part, TQDomDocument & doc,
|
|
|
|
TQDomElement & parent, const Doc * ksdoc )
|
|
|
|
{
|
|
|
|
TQString text;
|
|
|
|
TQString var;
|
|
|
|
|
|
|
|
bool inVar = false;
|
|
|
|
uint i = 0;
|
|
|
|
uint l = part.length();
|
|
|
|
while ( i < l )
|
|
|
|
{
|
|
|
|
if ( inVar || part[i] == '<' )
|
|
|
|
{
|
|
|
|
inVar = true;
|
|
|
|
var += part[i];
|
|
|
|
if ( part[i] == '>' )
|
|
|
|
{
|
|
|
|
inVar = false;
|
|
|
|
if ( var == "<page>" )
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement page = doc.createElement( "text:page-number" );
|
|
|
|
page.appendChild( doc.createTextNode( "1" ) );
|
|
|
|
parent.appendChild( page );
|
|
|
|
}
|
|
|
|
else if ( var == "<pages>" )
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement page = doc.createElement( "text:page-count" );
|
|
|
|
page.appendChild( doc.createTextNode( "99" ) );
|
|
|
|
parent.appendChild( page );
|
|
|
|
}
|
|
|
|
else if ( var == "<date>" )
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement t = doc.createElement( "text:date" );
|
|
|
|
t.setAttribute( "text:date-value", "0-00-00" );
|
|
|
|
// todo: "style:data-style-name", "N2"
|
|
|
|
t.appendChild( doc.createTextNode( TQDate::tqcurrentDate().toString() ) );
|
|
|
|
parent.appendChild( t );
|
|
|
|
}
|
|
|
|
else if ( var == "<time>" )
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement t = doc.createElement( "text:time" );
|
|
|
|
t.appendChild( doc.createTextNode( TQTime::currentTime().toString() ) );
|
|
|
|
parent.appendChild( t );
|
|
|
|
}
|
|
|
|
else if ( var == "<file>" ) // filepath + name
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement t = doc.createElement( "text:file-name" );
|
|
|
|
t.setAttribute( "text:display", "full" );
|
|
|
|
t.appendChild( doc.createTextNode( "???" ) );
|
|
|
|
parent.appendChild( t );
|
|
|
|
}
|
|
|
|
else if ( var == "<name>" ) // filename
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement t = doc.createElement( "text:title" );
|
|
|
|
t.appendChild( doc.createTextNode( "???" ) );
|
|
|
|
parent.appendChild( t );
|
|
|
|
}
|
|
|
|
else if ( var == "<author>" )
|
|
|
|
{
|
|
|
|
KoDocumentInfo * docInfo = ksdoc->documentInfo();
|
|
|
|
KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
|
|
|
|
|
|
|
|
text += authorPage->fullName();
|
|
|
|
|
|
|
|
addText( text, doc, parent );
|
|
|
|
}
|
|
|
|
else if ( var == "<email>" )
|
|
|
|
{
|
|
|
|
KoDocumentInfo * docInfo = ksdoc->documentInfo();
|
|
|
|
KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
|
|
|
|
|
|
|
|
text += authorPage->email();
|
|
|
|
|
|
|
|
addText( text, doc, parent );
|
|
|
|
}
|
|
|
|
else if ( var == "<org>" )
|
|
|
|
{
|
|
|
|
KoDocumentInfo * docInfo = ksdoc->documentInfo();
|
|
|
|
KoDocumentInfoAuthor * authorPage = static_cast<KoDocumentInfoAuthor*>( docInfo->page( "author" ) );
|
|
|
|
|
|
|
|
text += authorPage->company();
|
|
|
|
|
|
|
|
addText( text, doc, parent );
|
|
|
|
}
|
|
|
|
else if ( var == "<sheet>" )
|
|
|
|
{
|
|
|
|
addText( text, doc, parent );
|
|
|
|
|
|
|
|
TQDomElement s = doc.createElement( "text:sheet-name" );
|
|
|
|
s.appendChild( doc.createTextNode( "???" ) );
|
|
|
|
parent.appendChild( s );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// no known variable:
|
|
|
|
text += var;
|
|
|
|
addText( text, doc, parent );
|
|
|
|
}
|
|
|
|
|
|
|
|
text = "";
|
|
|
|
var = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
text += part[i];
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
if ( !text.isEmpty() || !var.isEmpty() )
|
|
|
|
{
|
|
|
|
//we don't have var at the end =>store it
|
|
|
|
addText( text+var, doc, parent );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString OpenCalcExport::convertFormula( TQString const & formula ) const
|
|
|
|
{
|
|
|
|
TQChar decimalSymbol( '.' );
|
|
|
|
if ( m_locale )
|
|
|
|
{
|
|
|
|
const TQString decimal ( m_locale->decimalSymbol() );
|
|
|
|
if ( !decimal.isEmpty() )
|
|
|
|
{
|
|
|
|
decimalSymbol = decimal.at( 0 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString s;
|
|
|
|
TQRegExp exp("(\\$?)([a-zA-Z]+)(\\$?)([0-9]+)");
|
|
|
|
int n = exp.search( formula, 0 );
|
|
|
|
kdDebug(30518) << "Exp: " << formula << ", n: " << n << ", Length: " << formula.length()
|
|
|
|
<< ", Matched length: " << exp.matchedLength() << endl;
|
|
|
|
|
|
|
|
bool inQuote1 = false;
|
|
|
|
bool inQuote2 = false;
|
|
|
|
int i = 0;
|
|
|
|
int l = (int) formula.length();
|
|
|
|
if ( l <= 0 )
|
|
|
|
return formula;
|
|
|
|
while ( i < l )
|
|
|
|
{
|
|
|
|
if ( ( n != -1 ) && ( n < i ) )
|
|
|
|
{
|
|
|
|
n = exp.search( formula, i );
|
|
|
|
kdDebug(30518) << "Exp: " << formula.right( l - i ) << ", n: " << n << endl;
|
|
|
|
}
|
|
|
|
if ( formula[i] == '"' )
|
|
|
|
{
|
|
|
|
inQuote1 = !inQuote1;
|
|
|
|
s += formula[i];
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( formula[i] == '\'' )
|
|
|
|
{
|
|
|
|
// named area
|
|
|
|
inQuote2 = !inQuote2;
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( inQuote1 || inQuote2 )
|
|
|
|
{
|
|
|
|
s += formula[i];
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( ( formula[i] == '=' ) && ( formula[i + 1] == '=' ) )
|
|
|
|
{
|
|
|
|
s += '=';
|
|
|
|
++i;++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( formula[i] == '!' )
|
|
|
|
{
|
|
|
|
insertBracket( s );
|
|
|
|
s += '.';
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if ( formula[i] == decimalSymbol )
|
|
|
|
{
|
|
|
|
s += '.'; // decimal point
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( n == i )
|
|
|
|
{
|
|
|
|
int ml = exp.matchedLength();
|
|
|
|
if ( formula[ i + ml ] == '!' )
|
|
|
|
{
|
|
|
|
kdDebug(30518) << "No cell ref but sheet name" << endl;
|
|
|
|
s += formula[i];
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ( ( i > 0 ) && ( formula[i - 1] != '!' ) )
|
|
|
|
s += "[.";
|
|
|
|
for ( int j = 0; j < ml; ++j )
|
|
|
|
{
|
|
|
|
s += formula[i];
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
s += ']';
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
s += formula[i];
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OpenCalcExport::writeMetaFile( KoStore * store, uint filesWritten )
|
|
|
|
{
|
|
|
|
store->enterDirectory( "META-INF" );
|
|
|
|
if ( !store->open( "manifest.xml" ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
TQDomImplementation impl;
|
|
|
|
TQDomDocumentType type( impl.createDocumentType( "manifest:manifest", "-//OpenOffice.org//DTD Manifest 1.0//EN", "Manifest.dtd" ) );
|
|
|
|
|
|
|
|
TQDomDocument meta( type );
|
|
|
|
meta.appendChild( meta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) );
|
|
|
|
|
|
|
|
TQDomElement content = meta.createElement( "manifest:manifest" );
|
|
|
|
content.setAttribute( "xmlns:manifest", "http://openoffice.org/2001/manifest" );
|
|
|
|
|
|
|
|
TQDomElement entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
entry.setAttribute( "manifest:media-type", "application/vnd.sun.xml.calc" );
|
|
|
|
entry.setAttribute( "manifest:full-path", "/" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
|
|
|
|
entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
|
|
|
|
if ( filesWritten & contentXML )
|
|
|
|
{
|
|
|
|
entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
entry.setAttribute( "manifest:media-type", "text/xml" );
|
|
|
|
entry.setAttribute( "manifest:full-path", "content.xml" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( filesWritten & stylesXML )
|
|
|
|
{
|
|
|
|
entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
entry.setAttribute( "manifest:media-type", "text/xml" );
|
|
|
|
entry.setAttribute( "manifest:full-path", "styles.xml" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( filesWritten & metaXML )
|
|
|
|
{
|
|
|
|
entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
entry.setAttribute( "manifest:media-type", "text/xml" );
|
|
|
|
entry.setAttribute( "manifest:full-path", "meta.xml" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( filesWritten & settingsXML )
|
|
|
|
{
|
|
|
|
entry = meta.createElement( "manifest:file-entry" );
|
|
|
|
entry.setAttribute( "manifest:media-type", "text/xml" );
|
|
|
|
entry.setAttribute( "manifest:full-path", "settings.xml" );
|
|
|
|
content.appendChild( entry );
|
|
|
|
}
|
|
|
|
|
|
|
|
meta.appendChild( content );
|
|
|
|
|
|
|
|
TQCString doc( meta.toCString() );
|
|
|
|
kdDebug(30518) << "Manifest: " << doc << endl;
|
|
|
|
|
|
|
|
store->write( doc, doc.length() );
|
|
|
|
|
|
|
|
if ( !store->close() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include <opencalcexport.moc>
|