Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / dbaccess / source / ui / misc / TokenWriter.cxx
blobcac82ba92d9ac824791cd6a512bde60476aa26d2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "TokenWriter.hxx"
21 #include <tools/debug.hxx>
22 #include <tools/diagnose_ex.h>
23 #include <tools/stream.hxx>
24 #include <osl/diagnose.h>
25 #include "RtfReader.hxx"
26 #include "HtmlReader.hxx"
27 #include "dbustrings.hrc"
28 #include <comphelper/processfactory.hxx>
29 #include <comphelper/string.hxx>
30 #include <comphelper/types.hxx>
31 #include <connectivity/dbtools.hxx>
32 #include <com/sun/star/sdb/DatabaseContext.hpp>
33 #include <com/sun/star/sdbc/XConnection.hpp>
34 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
35 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
36 #include <com/sun/star/sdbc/XRowSet.hpp>
37 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
38 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
39 #include <com/sun/star/sdbc/XDataSource.hpp>
40 #include <com/sun/star/awt/FontWeight.hpp>
41 #include <com/sun/star/awt/FontStrikeout.hpp>
42 #include <com/sun/star/awt/FontSlant.hpp>
43 #include <com/sun/star/awt/FontUnderline.hpp>
44 #include <com/sun/star/document/DocumentProperties.hpp>
45 #include <svtools/htmlkywd.hxx>
46 #include <svtools/rtfkeywd.hxx>
47 #include <tools/color.hxx>
48 #include <svtools/htmlout.hxx>
49 #include <sfx2/frmhtmlw.hxx>
50 #include <svl/numuno.hxx>
51 #include <vcl/svapp.hxx>
52 #include "UITools.hxx"
53 #include <toolkit/helper/vclunohelper.hxx>
54 #include <vcl/outdev.hxx>
55 #include <vcl/settings.hxx>
56 #include <svtools/rtfout.hxx>
57 #include <svtools/htmlcfg.hxx>
58 #include <connectivity/formattedcolumnvalue.hxx>
59 #include <unotools/syslocale.hxx>
60 #include <memory>
62 using namespace dbaui;
63 using namespace dbtools;
64 using namespace svx;
65 using namespace ::com::sun::star;
66 using namespace ::com::sun::star::uno;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::container;
69 using namespace ::com::sun::star::sdbc;
70 using namespace ::com::sun::star::sdb;
71 using namespace ::com::sun::star::frame;
72 using namespace ::com::sun::star::lang;
73 using namespace ::com::sun::star::sdbcx;
74 using namespace ::com::sun::star::awt;
75 using namespace ::com::sun::star::util;
77 const static char sMyBegComment[] = "<!-- ";
78 const static char sMyEndComment[] = " -->";
79 const static char sFontFamily[] = "font-family: ";
80 const static char sFontSize[] = "font-size: ";
82 #define SBA_FORMAT_SELECTION_COUNT 4
83 #define CELL_X 1437
85 ODatabaseImportExport::ODatabaseImportExport(const svx::ODataAccessDescriptor& _aDataDescriptor,
86 const Reference< XComponentContext >& _rM,
87 const Reference< css::util::XNumberFormatter >& _rxNumberF,
88 const OUString& rExchange)
89 :m_bBookmarkSelection( false )
90 ,m_xFormatter(_rxNumberF)
91 ,m_xContext(_rM)
92 ,m_nCommandType(CommandType::TABLE)
93 ,m_bNeedToReInitialize(false)
94 ,m_pReader(nullptr)
95 ,m_pRowMarker(nullptr)
96 ,m_bInInitialize(false)
97 ,m_bCheckOnly(false)
99 m_eDestEnc = osl_getThreadTextEncoding();
101 osl_atomic_increment( &m_refCount );
102 impl_initFromDescriptor( _aDataDescriptor, false );
104 sal_Int32 nCount = comphelper::string::getTokenCount(rExchange, char(11));
105 if( nCount > SBA_FORMAT_SELECTION_COUNT && !rExchange.getToken(4, ';').isEmpty())
107 m_pRowMarker = new sal_Int32[nCount-SBA_FORMAT_SELECTION_COUNT];
108 for(sal_Int32 i=SBA_FORMAT_SELECTION_COUNT; i<nCount; ++i)
109 m_pRowMarker[i-SBA_FORMAT_SELECTION_COUNT] = rExchange.getToken(i,char(11)).toInt32();
111 osl_atomic_decrement( &m_refCount );
114 // import data
115 ODatabaseImportExport::ODatabaseImportExport( const ::dbtools::SharedConnection& _rxConnection,
116 const Reference< XNumberFormatter >& _rxNumberF, const Reference< XComponentContext >& _rM )
117 :m_bBookmarkSelection( false )
118 ,m_pStream(nullptr)
119 ,m_xConnection(_rxConnection)
120 ,m_xFormatter(_rxNumberF)
121 ,m_xContext(_rM)
122 ,m_nCommandType(css::sdb::CommandType::TABLE)
123 ,m_bNeedToReInitialize(false)
124 ,m_pReader(nullptr)
125 ,m_pRowMarker(nullptr)
126 ,m_bInInitialize(false)
127 ,m_bCheckOnly(false)
129 m_eDestEnc = osl_getThreadTextEncoding();
132 SvtSysLocale aSysLocale;
133 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
135 catch(Exception&)
140 ODatabaseImportExport::~ODatabaseImportExport()
142 acquire();
144 dispose();
146 if(m_pReader)
147 m_pReader->release();
148 delete m_pRowMarker;
151 void ODatabaseImportExport::dispose()
153 // remove me as listener
154 Reference< XComponent > xComponent(m_xConnection, UNO_QUERY);
155 if (xComponent.is())
157 Reference< XEventListener> xEvt(static_cast<cppu::OWeakObject*>(this),UNO_QUERY);
158 xComponent->removeEventListener(xEvt);
160 m_xConnection.clear();
162 ::comphelper::disposeComponent(m_xRow);
164 m_xObject.clear();
165 m_xResultSetMetaData.clear();
166 m_xResultSet.clear();
167 m_xRow.clear();
168 m_xRowLocate.clear();
169 m_xFormatter.clear();
172 void SAL_CALL ODatabaseImportExport::disposing( const EventObject& Source ) throw(css::uno::RuntimeException, std::exception)
174 Reference<XConnection> xCon(Source.Source,UNO_QUERY);
175 if(m_xConnection.is() && m_xConnection == xCon)
177 m_xConnection.clear();
178 dispose();
179 m_bNeedToReInitialize = true;
183 void ODatabaseImportExport::initialize( const ODataAccessDescriptor& _aDataDescriptor )
185 impl_initFromDescriptor( _aDataDescriptor, true );
188 void ODatabaseImportExport::impl_initFromDescriptor( const ODataAccessDescriptor& _aDataDescriptor, bool _bPlusDefaultInit)
190 if ( !_bPlusDefaultInit )
192 m_sDataSourceName = _aDataDescriptor.getDataSource();
193 _aDataDescriptor[daCommandType] >>= m_nCommandType;
194 _aDataDescriptor[daCommand] >>= m_sName;
195 // some additional information
196 if(_aDataDescriptor.has(daConnection))
198 Reference< XConnection > xPureConn( _aDataDescriptor[daConnection], UNO_QUERY );
199 m_xConnection.reset( xPureConn, SharedConnection::NoTakeOwnership );
200 Reference< XEventListener> xEvt(static_cast<cppu::OWeakObject*>(this),UNO_QUERY);
201 Reference< XComponent > xComponent(m_xConnection, UNO_QUERY);
202 if (xComponent.is() && xEvt.is())
203 xComponent->addEventListener(xEvt);
206 if ( _aDataDescriptor.has( daSelection ) )
207 _aDataDescriptor[ daSelection ] >>= m_aSelection;
209 if ( _aDataDescriptor.has( daBookmarkSelection ) )
210 _aDataDescriptor[ daBookmarkSelection ] >>= m_bBookmarkSelection;
212 if ( _aDataDescriptor.has( daCursor ) )
214 _aDataDescriptor[ daCursor ] >>= m_xResultSet;
215 m_xRowLocate.set( m_xResultSet, UNO_QUERY );
218 if ( m_aSelection.getLength() != 0 )
220 if ( !m_xResultSet.is() )
222 SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: selection without result set is nonsense!" );
223 m_aSelection.realloc( 0 );
227 if ( m_aSelection.getLength() != 0 )
229 if ( m_bBookmarkSelection && !m_xRowLocate.is() )
231 SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: no XRowLocate -> no bookmars!" );
232 m_aSelection.realloc( 0 );
236 else
237 initialize();
241 SvtSysLocale aSysLocale;
242 m_aLocale = aSysLocale.GetLanguageTag().getLocale();
244 catch(Exception&)
249 void ODatabaseImportExport::initialize()
251 m_bInInitialize = true;
252 m_bNeedToReInitialize = false;
254 if ( !m_xConnection.is() )
255 { // we need a connection
256 OSL_ENSURE(!m_sDataSourceName.isEmpty(),"There must be a datsource name!");
257 Reference<XNameAccess> xDatabaseContext( DatabaseContext::create(m_xContext), UNO_QUERY_THROW);
258 Reference< XEventListener> xEvt(static_cast<cppu::OWeakObject*>(this),UNO_QUERY);
260 Reference< XConnection > xConnection;
261 SQLExceptionInfo aInfo = ::dbaui::createConnection( m_sDataSourceName, xDatabaseContext, m_xContext, xEvt, xConnection );
262 m_xConnection.reset( xConnection );
264 if(aInfo.isValid() && aInfo.getType() == SQLExceptionInfo::TYPE::SQLException)
265 throw *static_cast<const SQLException*>(aInfo);
268 Reference<XNameAccess> xNameAccess;
269 switch(m_nCommandType)
271 case CommandType::TABLE:
273 // only for tables
274 Reference<XTablesSupplier> xSup(m_xConnection,UNO_QUERY);
275 if(xSup.is())
276 xNameAccess = xSup->getTables();
278 break;
279 case CommandType::QUERY:
281 Reference<XQueriesSupplier> xSup(m_xConnection,UNO_QUERY);
282 if(xSup.is())
283 xNameAccess = xSup->getQueries();
285 break;
287 if(xNameAccess.is() && xNameAccess->hasByName(m_sName))
289 Reference<XPropertySet> xSourceObject;
290 xNameAccess->getByName(m_sName) >>= m_xObject;
293 if(m_xObject.is())
297 if(m_xObject->getPropertySetInfo()->hasPropertyByName(PROPERTY_FONT))
298 m_xObject->getPropertyValue(PROPERTY_FONT) >>= m_aFont;
300 // the result set may be already set with the datadescriptor
301 if ( !m_xResultSet.is() )
303 m_xResultSet.set( m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.sdb.RowSet", m_xContext), UNO_QUERY );
304 Reference< XPropertySet > xProp( m_xResultSet, UNO_QUERY_THROW );
305 xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( m_xConnection.getTyped() ) );
306 xProp->setPropertyValue( PROPERTY_COMMAND_TYPE, makeAny( m_nCommandType ) );
307 xProp->setPropertyValue( PROPERTY_COMMAND, makeAny( m_sName ) );
308 Reference< XRowSet > xRowSet( xProp, UNO_QUERY );
309 xRowSet->execute();
311 impl_initializeRowMember_throw();
313 catch(Exception& )
315 m_xRow = nullptr;
316 m_xResultSetMetaData = nullptr;
317 ::comphelper::disposeComponent(m_xResultSet);
318 throw;
321 if ( m_aFont.Name.isEmpty() )
323 vcl::Font aApplicationFont = OutputDevice::GetDefaultFont(
324 DefaultFontType::SANS_UNICODE,
325 Application::GetSettings().GetUILanguageTag().getLanguageType(),
326 GetDefaultFontFlags::OnlyOne
328 m_aFont = VCLUnoHelper::CreateFontDescriptor( aApplicationFont );
331 m_bInInitialize = false;
334 bool ODatabaseImportExport::Write()
336 if ( m_bNeedToReInitialize )
338 if ( !m_bInInitialize )
339 initialize();
341 return true;
344 bool ODatabaseImportExport::Read()
346 if ( m_bNeedToReInitialize )
348 if ( !m_bInInitialize )
349 initialize();
351 return true;
354 void ODatabaseImportExport::impl_initializeRowMember_throw()
356 if ( !m_xRow.is() && m_xResultSet.is() )
358 m_xRow.set( m_xResultSet, UNO_QUERY );
359 m_xRowLocate.set( m_xResultSet, UNO_QUERY );
360 m_xResultSetMetaData = Reference<XResultSetMetaDataSupplier>(m_xRow,UNO_QUERY)->getMetaData();
361 Reference<XColumnsSupplier> xSup(m_xResultSet,UNO_QUERY_THROW);
362 m_xRowSetColumns.set(xSup->getColumns(),UNO_QUERY_THROW);
366 bool ORTFImportExport::Write()
368 ODatabaseImportExport::Write();
369 m_pStream->WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RTF );
370 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ANSI ).WriteCharPtr( SAL_NEWLINE_STRING );
371 rtl_TextEncoding eDestEnc = RTL_TEXTENCODING_MS_1252;
373 bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight );
374 bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant );
375 bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline );
376 bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout );
378 sal_Int32 nColor = 0;
379 if(m_xObject.is())
380 m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= nColor;
381 ::Color aColor(nColor);
383 OString aFonts(OUStringToOString(m_aFont.Name, eDestEnc));
384 if (aFonts.isEmpty())
386 OUString aName = Application::GetSettings().GetStyleSettings().GetAppFont().GetFamilyName();
387 aFonts = OUStringToOString(aName, eDestEnc);
390 m_pStream->WriteCharPtr( "{\\fonttbl" );
391 sal_Int32 nTokenCount = comphelper::string::getTokenCount(aFonts, ';');
392 for(sal_Int32 j=0; j<nTokenCount; ++j)
394 m_pStream->WriteCharPtr( "\\f" );
395 m_pStream->WriteInt32AsString(j);
396 m_pStream->WriteCharPtr( "\\fcharset0\\fnil " );
397 m_pStream->WriteCharPtr( aFonts.getToken(j, ';').getStr() );
398 m_pStream->WriteChar( ';' );
400 m_pStream->WriteChar( '}' ) ;
401 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
402 // write the rtf color table
403 m_pStream->WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_COLORTBL ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RED );
404 m_pStream->WriteUInt32AsString(aColor.GetRed());
405 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_GREEN );
406 m_pStream->WriteUInt32AsString(aColor.GetGreen());
407 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_BLUE );
408 m_pStream->WriteUInt32AsString(aColor.GetBlue());
410 m_pStream->WriteCharPtr( ";\\red255\\green255\\blue255;\\red192\\green192\\blue192;}" )
411 .WriteCharPtr( SAL_NEWLINE_STRING );
413 static char const aTRRH[] = "\\trrh-270\\pard\\intbl";
414 static char const aFS[] = "\\fs20\\f0\\cf0\\cb2";
415 static char const aCell1[] = "\\clbrdrl\\brdrs\\brdrcf0\\clbrdrt\\brdrs\\brdrcf0\\clbrdrb\\brdrs\\brdrcf0\\clbrdrr\\brdrs\\brdrcf0\\clshdng10000\\clcfpat2\\cellx";
417 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TROWD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRGAPH );
418 m_pStream->WriteInt32AsString(40);
419 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
421 if(m_xObject.is())
423 Reference<XColumnsSupplier> xColSup(m_xObject,UNO_QUERY);
424 Reference<XNameAccess> xColumns = xColSup->getColumns();
425 Sequence< OUString> aNames(xColumns->getElementNames());
426 const OUString* pIter = aNames.getConstArray();
428 sal_Int32 nCount = aNames.getLength();
429 bool bUseResultMetaData = false;
430 if ( !nCount )
432 nCount = m_xResultSetMetaData->getColumnCount();
433 bUseResultMetaData = true;
436 for( sal_Int32 i=1; i<=nCount; ++i )
438 m_pStream->WriteCharPtr( aCell1 );
439 m_pStream->WriteInt32AsString(i*CELL_X);
440 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
443 // column description
444 m_pStream->WriteChar( '{' ).WriteCharPtr( SAL_NEWLINE_STRING );
445 m_pStream->WriteCharPtr( aTRRH );
447 std::unique_ptr<OString[]> pHorzChar(new OString[nCount]);
449 for ( sal_Int32 i=1; i <= nCount; ++i )
451 sal_Int32 nAlign = 0;
452 OUString sColumnName;
453 if ( bUseResultMetaData )
454 sColumnName = m_xResultSetMetaData->getColumnName(i);
455 else
457 sColumnName = *pIter;
458 Reference<XPropertySet> xColumn;
459 xColumns->getByName(sColumnName) >>= xColumn;
460 xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign;
461 ++pIter;
464 const char* pChar;
465 switch( nAlign )
467 case 1: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
468 case 2: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
469 case 0:
470 default:pChar = OOO_STRING_SVTOOLS_RTF_QL; break;
473 pHorzChar[i-1] = pChar; // to avoid to always rummage in the ITEMSET later on
475 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
476 m_pStream->WriteChar( '{' );
477 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_QC ); // column header always centered
479 if ( bBold ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_B );
480 if ( bItalic ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_I );
481 if ( bUnderline ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_UL );
482 if ( bStrikeout ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_STRIKE );
484 m_pStream->WriteCharPtr( aFS );
485 m_pStream->WriteChar( ' ' );
486 RTFOutFuncs::Out_String(*m_pStream,sColumnName,eDestEnc);
488 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL );
489 m_pStream->WriteChar( '}' );
490 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
491 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PARD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INTBL );
494 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ROW );
495 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '}' );
496 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
498 Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY);
499 sal_Int32 k=1;
500 sal_Int32 kk=0;
501 if ( m_aSelection.getLength() )
503 const Any* pSelIter = m_aSelection.getConstArray();
504 const Any* pEnd = pSelIter + m_aSelection.getLength();
506 bool bContinue = true;
507 for( ; pSelIter != pEnd && bContinue; ++pSelIter )
509 if ( m_bBookmarkSelection )
511 bContinue = m_xRowLocate->moveToBookmark( *pSelIter );
513 else
515 sal_Int32 nPos = -1;
516 OSL_VERIFY( *pSelIter >>= nPos );
517 bContinue = ( m_xResultSet->absolute( nPos ) );
520 if ( bContinue )
521 appendRow( pHorzChar.get(), nCount, k, kk );
524 else
526 m_xResultSet->beforeFirst(); // set back before the first row
527 while(m_xResultSet->next())
529 appendRow(pHorzChar.get(),nCount,k,kk);
534 m_pStream->WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
535 m_pStream->WriteUChar( 0 );
536 return ((*m_pStream).GetError() == SVSTREAM_OK);
539 void ORTFImportExport::appendRow(OString* pHorzChar,sal_Int32 _nColumnCount,sal_Int32& k,sal_Int32& kk)
541 if(!m_pRowMarker || m_pRowMarker[kk] == k)
543 ++kk;
544 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TROWD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRGAPH );
545 m_pStream->WriteInt32AsString(40);
546 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
548 static char const aCell2[] = "\\clbrdrl\\brdrs\\brdrcf2\\clbrdrt\\brdrs\\brdrcf2\\clbrdrb\\brdrs\\brdrcf2\\clbrdrr\\brdrs\\brdrcf2\\clshdng10000\\clcfpat1\\cellx";
549 static char const aTRRH[] = "\\trrh-270\\pard\\intbl";
551 for ( sal_Int32 i=1; i<=_nColumnCount; ++i )
553 m_pStream->WriteCharPtr( aCell2 );
554 m_pStream->WriteInt32AsString(i*CELL_X);
555 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
558 const bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight );
559 const bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant );
560 const bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline );
561 const bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout );
562 Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY);
564 m_pStream->WriteChar( '{' );
565 m_pStream->WriteCharPtr( aTRRH );
566 for ( sal_Int32 i=1; i <= _nColumnCount; ++i )
568 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
569 m_pStream->WriteChar( '{' );
570 m_pStream->WriteCharPtr( pHorzChar[i-1].getStr() );
572 if ( bBold ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_B );
573 if ( bItalic ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_I );
574 if ( bUnderline ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_UL );
575 if ( bStrikeout ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_STRIKE );
577 m_pStream->WriteCharPtr( "\\fs20\\f1\\cf0\\cb1 " );
581 Reference<XPropertySet> xColumn(m_xRowSetColumns->getByIndex(i-1),UNO_QUERY_THROW);
582 dbtools::FormattedColumnValue aFormatedValue(m_xContext,xRowSet,xColumn);
583 OUString sValue = aFormatedValue.getFormattedValue();
584 if ( !sValue.isEmpty() )
585 RTFOutFuncs::Out_String(*m_pStream,sValue,m_eDestEnc);
587 catch (Exception&)
589 SAL_WARN("dbaccess.ui","RTF WRITE!");
592 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL );
593 m_pStream->WriteChar( '}' );
594 m_pStream->WriteCharPtr( SAL_NEWLINE_STRING );
595 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PARD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INTBL );
597 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ROW ).WriteCharPtr( SAL_NEWLINE_STRING );
598 m_pStream->WriteChar( '}' );
600 ++k;
603 bool ORTFImportExport::Read()
605 ODatabaseImportExport::Read();
606 SvParserState eState = SVPAR_ERROR;
607 if ( m_pStream )
609 m_pReader = new ORTFReader((*m_pStream),m_xConnection,m_xFormatter,m_xContext);
610 static_cast<ORTFReader*>(m_pReader)->AddFirstRef();
611 if ( isCheckEnabled() )
612 m_pReader->enableCheckOnly();
613 eState = static_cast<ORTFReader*>(m_pReader)->CallParser();
614 m_pReader->release();
615 m_pReader = nullptr;
618 return eState != SVPAR_ERROR;
621 const sal_Int16 OHTMLImportExport::nDefaultFontSize[SBA_HTML_FONTSIZES] =
623 HTMLFONTSZ1_DFLT, HTMLFONTSZ2_DFLT, HTMLFONTSZ3_DFLT, HTMLFONTSZ4_DFLT,
624 HTMLFONTSZ5_DFLT, HTMLFONTSZ6_DFLT, HTMLFONTSZ7_DFLT
627 sal_Int16 OHTMLImportExport::nFontSize[SBA_HTML_FONTSIZES] = { 0 };
629 const sal_Int16 OHTMLImportExport::nCellSpacing = 0;
630 const char OHTMLImportExport::sIndentSource[nIndentMax+1] = "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
632 // Macros for HTML-Export
633 #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( (*m_pStream), tag )
634 #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( (*m_pStream), tag, false )
635 #define OUT_LF() m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() )
636 #define TAG_ON_LF( tag ) (TAG_ON( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
637 #define TAG_OFF_LF( tag ) (TAG_OFF( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ))
639 OHTMLImportExport::OHTMLImportExport(const svx::ODataAccessDescriptor& _aDataDescriptor,
640 const Reference< XComponentContext >& _rM,
641 const Reference< css::util::XNumberFormatter >& _rxNumberF,
642 const OUString& rExchange)
643 : ODatabaseImportExport(_aDataDescriptor,_rM,_rxNumberF,rExchange)
644 ,m_nIndent(0)
645 #if OSL_DEBUG_LEVEL > 0
646 ,m_bCheckFont(false)
647 #endif
649 // set HTML configuration
650 SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get();
651 m_eDestEnc = rHtmlOptions.GetTextEncoding();
652 strncpy( sIndent, sIndentSource ,std::min(sizeof(sIndent),sizeof(sIndentSource)));
653 sIndent[0] = 0;
656 bool OHTMLImportExport::Write()
658 ODatabaseImportExport::Write();
659 if(m_xObject.is())
661 m_pStream->WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype ).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype40 ).WriteChar( '>' ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( SAL_NEWLINE_STRING );
662 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html );
663 WriteHeader();
664 OUT_LF();
665 WriteBody();
666 OUT_LF();
667 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html );
669 return ((*m_pStream).GetError() == SVSTREAM_OK);
671 return false;
674 bool OHTMLImportExport::Read()
676 ODatabaseImportExport::Read();
677 SvParserState eState = SVPAR_ERROR;
678 if ( m_pStream )
680 m_pReader = new OHTMLReader((*m_pStream),m_xConnection,m_xFormatter,m_xContext);
681 static_cast<OHTMLReader*>(m_pReader)->AddFirstRef();
682 if ( isCheckEnabled() )
683 m_pReader->enableCheckOnly();
684 m_pReader->SetTableName(m_sDefaultTableName);
685 eState = static_cast<OHTMLReader*>(m_pReader)->CallParser();
686 m_pReader->release();
687 m_pReader = nullptr;
690 return eState != SVPAR_ERROR;
693 void OHTMLImportExport::WriteHeader()
695 uno::Reference<document::XDocumentProperties> xDocProps(
696 document::DocumentProperties::create( m_xContext ) );
697 if (xDocProps.is()) {
698 xDocProps->setTitle(m_sName);
701 IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head );
703 SfxFrameHTMLWriter::Out_DocInfo( (*m_pStream), OUString(),
704 xDocProps, sIndent );
705 OUT_LF();
706 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head );
709 void OHTMLImportExport::WriteBody()
711 IncIndent(1);
712 m_pStream->WriteCharPtr( "<" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_style ).WriteCharPtr( " " ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_type ).WriteCharPtr( "=\"text/css\">" );
714 m_pStream->WriteCharPtr( sMyBegComment ); OUT_LF();
715 m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body ).WriteCharPtr( " { " ).WriteCharPtr( sFontFamily ).WriteChar( '"' ).WriteCharPtr( OUStringToOString(m_aFont.Name, osl_getThreadTextEncoding()).getStr() ).WriteChar( '\"' );
716 // TODO : think about the encoding of the font name
717 m_pStream->WriteCharPtr( "; " ).WriteCharPtr( sFontSize );
718 m_pStream->WriteInt32AsString(m_aFont.Height);
719 m_pStream->WriteChar( '}' );
721 OUT_LF();
722 m_pStream->WriteCharPtr( sMyEndComment );
723 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style );
724 OUT_LF();
726 // default Textcolour black
727 m_pStream->WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body ).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_text ).WriteChar( '=' );
728 sal_Int32 nColor = 0;
729 if(m_xObject.is())
730 m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= nColor;
731 ::Color aColor(nColor);
732 HTMLOutFuncs::Out_Color( (*m_pStream), aColor );
734 m_pStream->WriteCharPtr( " " OOO_STRING_SVTOOLS_HTML_O_bgcolor "=" );
735 HTMLOutFuncs::Out_Color( (*m_pStream), aColor );
737 m_pStream->WriteChar( '>' ); OUT_LF();
739 WriteTables();
741 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body );
744 void OHTMLImportExport::WriteTables()
746 OString aStrOut = OOO_STRING_SVTOOLS_HTML_table;
747 aStrOut = aStrOut + " ";
748 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_frame;
749 aStrOut = aStrOut + "=";
750 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_TF_void;
752 Sequence< OUString> aNames;
753 Reference<XNameAccess> xColumns;
754 bool bUseResultMetaData = false;
755 if(m_xObject.is())
757 Reference<XColumnsSupplier> xColSup(m_xObject,UNO_QUERY);
758 xColumns = xColSup->getColumns();
759 aNames = xColumns->getElementNames();
760 if ( !aNames.getLength() )
762 sal_Int32 nCount = m_xResultSetMetaData->getColumnCount();
763 aNames.realloc(nCount);
764 for (sal_Int32 i= 0; i < nCount; ++i)
765 aNames[i] = m_xResultSetMetaData->getColumnName(i+1);
766 bUseResultMetaData = true;
770 aStrOut = aStrOut + " ";
771 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_align;
772 aStrOut = aStrOut + "=";
773 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_AL_left;
774 aStrOut = aStrOut + " ";
775 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_cellspacing;
776 aStrOut = aStrOut + "=";
777 aStrOut = aStrOut + OString::number(nCellSpacing);
778 aStrOut = aStrOut + " ";
779 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_cols;
780 aStrOut = aStrOut + "=";
781 aStrOut = aStrOut + OString::number(aNames.getLength());
782 aStrOut = aStrOut + " ";
783 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_border;
784 aStrOut = aStrOut + "=1";
786 IncIndent(1);
787 TAG_ON( aStrOut.getStr() );
789 FontOn();
791 TAG_ON( OOO_STRING_SVTOOLS_HTML_caption );
792 TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
794 m_pStream->WriteCharPtr( OUStringToOString(m_sName, osl_getThreadTextEncoding()).getStr() );
795 // TODO : think about the encoding of the name
796 TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
797 TAG_OFF( OOO_STRING_SVTOOLS_HTML_caption );
799 FontOff();
800 OUT_LF();
801 // </FONT>
803 IncIndent(1);
804 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_thead );
806 IncIndent(1);
807 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
809 if(m_xObject.is())
811 std::unique_ptr<sal_Int32[]> pFormat(new sal_Int32[aNames.getLength()]);
813 std::unique_ptr<const char *[]> pHorJustify(new const char*[aNames.getLength()]);
814 std::unique_ptr<sal_Int32[]> pColWidth(new sal_Int32[aNames.getLength()]);
816 sal_Int32 nHeight = 0;
817 m_xObject->getPropertyValue(PROPERTY_ROW_HEIGHT) >>= nHeight;
819 // 1. writing the column description
820 const OUString* pIter = aNames.getConstArray();
821 const OUString* pEnd = pIter + aNames.getLength();
823 for( sal_Int32 i=0;pIter != pEnd; ++pIter,++i )
825 sal_Int32 nAlign = 0;
826 pFormat[i] = 0;
827 pColWidth[i] = 100;
828 if ( !bUseResultMetaData )
830 Reference<XPropertySet> xColumn;
831 xColumns->getByName(*pIter) >>= xColumn;
832 xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign;
833 pFormat[i] = ::comphelper::getINT32(xColumn->getPropertyValue(PROPERTY_FORMATKEY));
834 pColWidth[i] = ::comphelper::getINT32(xColumn->getPropertyValue(PROPERTY_WIDTH));
837 switch( nAlign )
839 case 1: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_center; break;
840 case 2: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_right; break;
841 default: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_left; break;
844 if(i == aNames.getLength()-1)
845 IncIndent(-1);
847 WriteCell(pFormat[i],pColWidth[i],nHeight,pHorJustify[i],*pIter,OOO_STRING_SVTOOLS_HTML_tableheader);
850 IncIndent(-1);
851 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
852 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_thead );
854 IncIndent(1);
855 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
857 // 2. and now the data
858 Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY);
859 sal_Int32 j=1;
860 sal_Int32 kk=0;
861 m_xResultSet->beforeFirst(); // set back before the first row
862 while(m_xResultSet->next())
864 IncIndent(1);
865 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
867 if(!m_pRowMarker || m_pRowMarker[kk] == j)
869 ++kk;
870 for(sal_Int32 i=1;i<=aNames.getLength();++i)
872 if(i == aNames.getLength())
873 IncIndent(-1);
875 OUString aValue;
878 Reference<XPropertySet> xColumn(m_xRowSetColumns->getByIndex(i-1),UNO_QUERY_THROW);
879 dbtools::FormattedColumnValue aFormatedValue(m_xContext,xRowSet,xColumn);
880 OUString sValue = aFormatedValue.getFormattedValue();
881 if (!sValue.isEmpty())
883 aValue = sValue;
886 catch( const Exception& )
888 DBG_UNHANDLED_EXCEPTION();
890 WriteCell(pFormat[i-1],pColWidth[i-1],nHeight,pHorJustify[i-1],aValue,OOO_STRING_SVTOOLS_HTML_tabledata);
893 ++j;
894 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
897 else
899 IncIndent(-1);
900 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow );
901 TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_thead );
903 IncIndent(1);
904 TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody );
907 IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody );
908 IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table );
911 void OHTMLImportExport::WriteCell( sal_Int32 nFormat, sal_Int32 nWidthPixel, sal_Int32 nHeightPixel, const char* pChar,
912 const OUString& rValue, const char* pHtmlTag)
914 OString aStrTD = pHtmlTag;
916 nWidthPixel = nWidthPixel ? nWidthPixel : 86;
917 nHeightPixel = nHeightPixel ? nHeightPixel : 17;
919 // despite the <TABLE COLS=n> and <COL WIDTH=x> designation necessary,
920 // as Netscape is not paying attention to them.
921 // column width
922 aStrTD = aStrTD + " ";
923 aStrTD = aStrTD + OOO_STRING_SVTOOLS_HTML_O_width;
924 aStrTD = aStrTD + "=";
925 aStrTD = aStrTD + OString::number(nWidthPixel);
926 // line height
927 aStrTD = aStrTD + " ";
928 aStrTD = aStrTD + OOO_STRING_SVTOOLS_HTML_O_height;
929 aStrTD = aStrTD + "=";
930 aStrTD = aStrTD + OString::number(nHeightPixel);
932 aStrTD = aStrTD + " ";
933 aStrTD = aStrTD + OOO_STRING_SVTOOLS_HTML_O_align;
934 aStrTD = aStrTD + "=";
935 aStrTD = aStrTD + pChar;
937 SvNumberFormatsSupplierObj* pSupplierImpl = m_xFormatter.is() ? SvNumberFormatsSupplierObj::getImplementation(m_xFormatter->getNumberFormatsSupplier()) : nullptr;
938 SvNumberFormatter* pFormatter = pSupplierImpl ? pSupplierImpl->GetNumberFormatter() : nullptr;
939 if(pFormatter)
941 double fVal = 0.0;
945 fVal = m_xFormatter->convertStringToNumber(nFormat,rValue);
946 HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal,nFormat, *pFormatter);
948 catch(const Exception&)
950 HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal,nFormat, *pFormatter);
954 TAG_ON( aStrTD.getStr() );
956 FontOn();
958 bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight );
959 bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant );
960 bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline );
961 bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout );
963 if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold );
964 if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic );
965 if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline );
966 if ( bStrikeout ) TAG_ON( OOO_STRING_SVTOOLS_HTML_strike );
968 if ( rValue.isEmpty() )
969 TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // no completely empty cell
970 else
971 HTMLOutFuncs::Out_String( (*m_pStream), rValue ,m_eDestEnc);
973 if ( bStrikeout ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_strike );
974 if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline );
975 if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic );
976 if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold );
978 FontOff();
980 TAG_OFF_LF( pHtmlTag );
983 void OHTMLImportExport::FontOn()
985 #if OSL_DEBUG_LEVEL > 0
986 m_bCheckFont = true;
987 #endif
989 // <FONT FACE="xxx">
990 OString aStrOut = "<";
991 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_font;
992 aStrOut = aStrOut + " ";
993 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_face;
994 aStrOut = aStrOut + "=";
995 aStrOut = aStrOut + "\"";
996 aStrOut = aStrOut + OUStringToOString(m_aFont.Name,osl_getThreadTextEncoding());
997 // TODO : think about the encoding of the font name
998 aStrOut = aStrOut + "\"";
999 aStrOut = aStrOut + " ";
1000 aStrOut = aStrOut + OOO_STRING_SVTOOLS_HTML_O_color;
1001 aStrOut = aStrOut + "=";
1002 m_pStream->WriteCharPtr( aStrOut.getStr() );
1004 sal_Int32 nColor = 0;
1005 if(m_xObject.is())
1006 m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= nColor;
1007 ::Color aColor(nColor);
1009 HTMLOutFuncs::Out_Color( (*m_pStream), aColor );
1010 m_pStream->WriteCharPtr( ">" );
1013 inline void OHTMLImportExport::FontOff()
1015 #if OSL_DEBUG_LEVEL > 0
1016 OSL_ENSURE(m_bCheckFont,"Kein FontOn() gerufen");
1017 #endif
1018 TAG_OFF( OOO_STRING_SVTOOLS_HTML_font );
1019 #if OSL_DEBUG_LEVEL > 0
1020 m_bCheckFont = false;
1021 #endif
1024 void OHTMLImportExport::IncIndent( sal_Int16 nVal )
1026 sIndent[m_nIndent] = '\t';
1027 m_nIndent = m_nIndent + nVal;
1028 if ( m_nIndent < 0 )
1029 m_nIndent = 0;
1030 else if ( m_nIndent > nIndentMax )
1031 m_nIndent = nIndentMax;
1032 sIndent[m_nIndent] = 0;
1035 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */