1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <comphelper/diagnose_ex.hxx>
22 #include <tools/stream.hxx>
23 #include <osl/diagnose.h>
24 #include <rtl/tencinfo.h>
25 #include <sal/log.hxx>
26 #include <i18nlangtag/languagetag.hxx>
27 #include <RtfReader.hxx>
28 #include <HtmlReader.hxx>
29 #include <strings.hxx>
30 #include <comphelper/types.hxx>
31 #include <connectivity/dbtools.hxx>
32 #include <com/sun/star/sdb/CommandType.hpp>
33 #include <com/sun/star/sdb/DatabaseContext.hpp>
34 #include <com/sun/star/sdbc/XConnection.hpp>
35 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
36 #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
37 #include <com/sun/star/sdbc/XRowSet.hpp>
38 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
39 #include <com/sun/star/sdb/XQueriesSupplier.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>
52 #include <vcl/svapp.hxx>
53 #include <UITools.hxx>
54 #include <toolkit/helper/vclunohelper.hxx>
55 #include <vcl/outdev.hxx>
56 #include <vcl/settings.hxx>
57 #include <svtools/rtfout.hxx>
58 #include <svtools/htmlcfg.hxx>
59 #include <o3tl/string_view.hxx>
60 #include <connectivity/formattedcolumnvalue.hxx>
63 using namespace dbaui
;
64 using namespace dbtools
;
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::uno
;
68 using namespace ::com::sun::star::beans
;
69 using namespace ::com::sun::star::container
;
70 using namespace ::com::sun::star::sdbc
;
71 using namespace ::com::sun::star::sdb
;
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
;
79 ODatabaseImportExport::ODatabaseImportExport(const svx::ODataAccessDescriptor
& _aDataDescriptor
,
80 const Reference
< XComponentContext
>& _rM
,
81 const Reference
< css::util::XNumberFormatter
>& _rxNumberF
)
82 :m_bBookmarkSelection( false )
84 ,m_xFormatter(_rxNumberF
)
86 ,m_nCommandType(CommandType::TABLE
)
87 ,m_bNeedToReInitialize(false)
88 ,m_bInInitialize(false)
91 m_eDestEnc
= osl_getThreadTextEncoding();
93 osl_atomic_increment( &m_refCount
);
94 impl_initFromDescriptor( _aDataDescriptor
, false );
95 osl_atomic_decrement( &m_refCount
);
99 ODatabaseImportExport::ODatabaseImportExport( ::dbtools::SharedConnection _xConnection
,
100 const Reference
< XNumberFormatter
>& _rxNumberF
, const Reference
< XComponentContext
>& _rM
)
101 :m_bBookmarkSelection( false )
103 ,m_xConnection(std::move(_xConnection
))
104 ,m_xFormatter(_rxNumberF
)
106 ,m_nCommandType(css::sdb::CommandType::TABLE
)
107 ,m_bNeedToReInitialize(false)
108 ,m_bInInitialize(false)
111 m_eDestEnc
= osl_getThreadTextEncoding();
114 ODatabaseImportExport::~ODatabaseImportExport()
120 void ODatabaseImportExport::dispose()
122 // remove me as listener
123 Reference
< XComponent
> xComponent(m_xConnection
, UNO_QUERY
);
126 Reference
< XEventListener
> xEvt(this);
127 xComponent
->removeEventListener(xEvt
);
129 m_xConnection
.clear();
131 ::comphelper::disposeComponent(m_xRow
);
134 m_xResultSetMetaData
.clear();
135 m_xResultSet
.clear();
137 m_xRowLocate
.clear();
138 m_xFormatter
.clear();
141 void SAL_CALL
ODatabaseImportExport::disposing( const EventObject
& Source
)
143 Reference
<XConnection
> xCon(Source
.Source
,UNO_QUERY
);
144 if(m_xConnection
.is() && m_xConnection
== xCon
)
146 m_xConnection
.clear();
148 m_bNeedToReInitialize
= true;
152 void ODatabaseImportExport::initialize( const ODataAccessDescriptor
& _aDataDescriptor
)
154 impl_initFromDescriptor( _aDataDescriptor
, true );
157 void ODatabaseImportExport::impl_initFromDescriptor( const ODataAccessDescriptor
& _aDataDescriptor
, bool _bPlusDefaultInit
)
159 if ( !_bPlusDefaultInit
)
161 m_sDataSourceName
= _aDataDescriptor
.getDataSource();
162 _aDataDescriptor
[DataAccessDescriptorProperty::CommandType
] >>= m_nCommandType
;
163 _aDataDescriptor
[DataAccessDescriptorProperty::Command
] >>= m_sName
;
164 // some additional information
165 if(_aDataDescriptor
.has(DataAccessDescriptorProperty::Connection
))
167 Reference
< XConnection
> xPureConn( _aDataDescriptor
[DataAccessDescriptorProperty::Connection
], UNO_QUERY
);
168 m_xConnection
.reset( xPureConn
, SharedConnection::NoTakeOwnership
);
169 Reference
< XEventListener
> xEvt(this);
170 Reference
< XComponent
> xComponent(m_xConnection
, UNO_QUERY
);
171 if (xComponent
.is() && xEvt
.is())
172 xComponent
->addEventListener(xEvt
);
175 if ( _aDataDescriptor
.has( DataAccessDescriptorProperty::Selection
) )
176 _aDataDescriptor
[ DataAccessDescriptorProperty::Selection
] >>= m_aSelection
;
178 if ( _aDataDescriptor
.has( DataAccessDescriptorProperty::BookmarkSelection
) )
179 _aDataDescriptor
[ DataAccessDescriptorProperty::BookmarkSelection
] >>= m_bBookmarkSelection
;
181 if ( _aDataDescriptor
.has( DataAccessDescriptorProperty::Cursor
) )
183 _aDataDescriptor
[ DataAccessDescriptorProperty::Cursor
] >>= m_xResultSet
;
184 m_xRowLocate
.set( m_xResultSet
, UNO_QUERY
);
187 if ( m_aSelection
.hasElements() )
189 if ( !m_xResultSet
.is() )
191 SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: selection without result set is nonsense!" );
192 m_aSelection
.realloc( 0 );
196 if ( m_aSelection
.hasElements() )
198 if ( m_bBookmarkSelection
&& !m_xRowLocate
.is() )
200 SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: no XRowLocate -> no bookmarks!" );
201 m_aSelection
.realloc( 0 );
209 void ODatabaseImportExport::initialize()
211 m_bInInitialize
= true;
212 m_bNeedToReInitialize
= false;
214 if ( !m_xConnection
.is() )
215 { // we need a connection
216 OSL_ENSURE(!m_sDataSourceName
.isEmpty(),"There must be a datsource name!");
217 Reference
<XNameAccess
> xDatabaseContext( DatabaseContext::create(m_xContext
), UNO_QUERY_THROW
);
218 Reference
< XEventListener
> xEvt(this);
220 Reference
< XConnection
> xConnection
;
221 SQLExceptionInfo aInfo
= ::dbaui::createConnection( m_sDataSourceName
, xDatabaseContext
, m_xContext
, xEvt
, xConnection
);
222 m_xConnection
.reset( xConnection
);
224 if(aInfo
.isValid() && aInfo
.getType() == SQLExceptionInfo::TYPE::SQLException
)
225 throw *static_cast<const SQLException
*>(aInfo
);
228 Reference
<XNameAccess
> xNameAccess
;
229 switch(m_nCommandType
)
231 case CommandType::TABLE
:
234 Reference
<XTablesSupplier
> xSup(m_xConnection
,UNO_QUERY
);
236 xNameAccess
= xSup
->getTables();
239 case CommandType::QUERY
:
241 Reference
<XQueriesSupplier
> xSup(m_xConnection
,UNO_QUERY
);
243 xNameAccess
= xSup
->getQueries();
247 if(xNameAccess
.is() && xNameAccess
->hasByName(m_sName
))
249 xNameAccess
->getByName(m_sName
) >>= m_xObject
;
256 if(m_xObject
->getPropertySetInfo()->hasPropertyByName(PROPERTY_FONT
))
257 m_xObject
->getPropertyValue(PROPERTY_FONT
) >>= m_aFont
;
259 // the result set may be already set with the datadescriptor
260 if ( !m_xResultSet
.is() )
262 m_xResultSet
.set( m_xContext
->getServiceManager()->createInstanceWithContext("com.sun.star.sdb.RowSet", m_xContext
), UNO_QUERY
);
263 Reference
< XPropertySet
> xProp( m_xResultSet
, UNO_QUERY_THROW
);
264 xProp
->setPropertyValue( PROPERTY_ACTIVE_CONNECTION
, Any( m_xConnection
.getTyped() ) );
265 xProp
->setPropertyValue( PROPERTY_COMMAND_TYPE
, Any( m_nCommandType
) );
266 xProp
->setPropertyValue( PROPERTY_COMMAND
, Any( m_sName
) );
267 Reference
< XRowSet
> xRowSet( xProp
, UNO_QUERY
);
270 if ( !m_xRow
.is() && m_xResultSet
.is() )
272 m_xRow
.set( m_xResultSet
, UNO_QUERY
);
273 m_xRowLocate
.set( m_xResultSet
, UNO_QUERY
);
274 m_xResultSetMetaData
= Reference
<XResultSetMetaDataSupplier
>(m_xRow
,UNO_QUERY_THROW
)->getMetaData();
275 Reference
<XColumnsSupplier
> xSup(m_xResultSet
,UNO_QUERY_THROW
);
276 m_xRowSetColumns
.set(xSup
->getColumns(),UNO_QUERY_THROW
);
282 m_xResultSetMetaData
= nullptr;
283 ::comphelper::disposeComponent(m_xResultSet
);
287 if ( m_aFont
.Name
.isEmpty() )
289 vcl::Font aApplicationFont
= OutputDevice::GetDefaultFont(
290 DefaultFontType::SANS_UNICODE
,
291 Application::GetSettings().GetUILanguageTag().getLanguageType(),
292 GetDefaultFontFlags::OnlyOne
294 m_aFont
= VCLUnoHelper::CreateFontDescriptor( aApplicationFont
);
297 m_bInInitialize
= false;
300 bool ODatabaseImportExport::Write()
302 if ( m_bNeedToReInitialize
)
304 if ( !m_bInInitialize
)
310 bool ODatabaseImportExport::Read()
312 if ( m_bNeedToReInitialize
)
314 if ( !m_bInInitialize
)
320 bool ORTFImportExport::Write()
322 ODatabaseImportExport::Write();
323 m_pStream
->WriteChar( '{' ).WriteOString( OOO_STRING_SVTOOLS_RTF_RTF
);
324 m_pStream
->WriteOString(OOO_STRING_SVTOOLS_RTF_ANSI
);
325 if (sal_uInt32 nCpg
= rtl_getWindowsCodePageFromTextEncoding(m_eDestEnc
); nCpg
&& nCpg
!= 65001)
327 m_pStream
->WriteOString(OOO_STRING_SVTOOLS_RTF_ANSICPG
).WriteNumberAsString(nCpg
);
329 m_pStream
->WriteOString(SAL_NEWLINE_STRING
);
331 bool bBold
= ( css::awt::FontWeight::BOLD
== m_aFont
.Weight
);
332 bool bItalic
= ( css::awt::FontSlant_ITALIC
== m_aFont
.Slant
);
333 bool bUnderline
= ( css::awt::FontUnderline::NONE
!= m_aFont
.Underline
);
334 bool bStrikeout
= ( css::awt::FontStrikeout::NONE
!= m_aFont
.Strikeout
);
338 m_xObject
->getPropertyValue(PROPERTY_TEXTCOLOR
) >>= aColor
;
340 OString
aFonts(OUStringToOString(m_aFont
.Name
, RTL_TEXTENCODING_MS_1252
));
341 if (aFonts
.isEmpty())
343 OUString aName
= Application::GetSettings().GetStyleSettings().GetAppFont().GetFamilyName();
344 aFonts
= OUStringToOString(aName
, RTL_TEXTENCODING_MS_1252
);
347 m_pStream
->WriteOString( "{\\fonttbl" );
348 if (!aFonts
.isEmpty())
351 sal_Int32 nTok
{-1}; // to compensate pre-increment
353 m_pStream
->WriteOString( "\\f" );
354 m_pStream
->WriteNumberAsString(++nTok
);
355 m_pStream
->WriteOString( "\\fcharset0\\fnil " );
356 m_pStream
->WriteOString( o3tl::getToken(aFonts
, 0, ';', nIdx
) );
357 m_pStream
->WriteChar( ';' );
360 m_pStream
->WriteChar( '}' ) ;
361 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
362 // write the rtf color table
363 m_pStream
->WriteChar( '{' ).WriteOString( OOO_STRING_SVTOOLS_RTF_COLORTBL
).WriteOString( OOO_STRING_SVTOOLS_RTF_RED
);
364 m_pStream
->WriteNumberAsString(aColor
.GetRed());
365 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_GREEN
);
366 m_pStream
->WriteNumberAsString(aColor
.GetGreen());
367 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_BLUE
);
368 m_pStream
->WriteNumberAsString(aColor
.GetBlue());
370 m_pStream
->WriteOString( ";\\red255\\green255\\blue255;\\red192\\green192\\blue192;}" )
371 .WriteOString( SAL_NEWLINE_STRING
);
373 static char const aCell1
[] = "\\clbrdrl\\brdrs\\brdrcf0\\clbrdrt\\brdrs\\brdrcf0\\clbrdrb\\brdrs\\brdrcf0\\clbrdrr\\brdrs\\brdrcf0\\clshdng10000\\clcfpat2\\cellx";
375 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_TROWD
).WriteOString( OOO_STRING_SVTOOLS_RTF_TRGAPH
);
376 m_pStream
->WriteOString("40");
377 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
381 Reference
<XColumnsSupplier
> xColSup(m_xObject
,UNO_QUERY
);
382 Reference
<XNameAccess
> xColumns
= xColSup
->getColumns();
383 Sequence
< OUString
> aNames(xColumns
->getElementNames());
384 const OUString
* pIter
= aNames
.getConstArray();
386 sal_Int32 nCount
= aNames
.getLength();
387 bool bUseResultMetaData
= false;
390 nCount
= m_xResultSetMetaData
->getColumnCount();
391 bUseResultMetaData
= true;
394 for( sal_Int32 i
=1; i
<=nCount
; ++i
)
396 m_pStream
->WriteOString( aCell1
);
397 m_pStream
->WriteNumberAsString(i
*CELL_X
);
398 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
401 // column description
402 m_pStream
->WriteChar( '{' ).WriteOString( SAL_NEWLINE_STRING
);
403 m_pStream
->WriteOString( "\\trrh-270\\pard\\intbl" );
405 std::unique_ptr
<OString
[]> pHorzChar(new OString
[nCount
]);
407 for ( sal_Int32 i
=1; i
<= nCount
; ++i
)
409 sal_Int32 nAlign
= 0;
410 OUString sColumnName
;
411 if ( bUseResultMetaData
)
412 sColumnName
= m_xResultSetMetaData
->getColumnName(i
);
415 sColumnName
= *pIter
;
416 Reference
<XPropertySet
> xColumn
;
417 xColumns
->getByName(sColumnName
) >>= xColumn
;
418 xColumn
->getPropertyValue(PROPERTY_ALIGN
) >>= nAlign
;
425 case 1: pChar
= OOO_STRING_SVTOOLS_RTF_QC
; break;
426 case 2: pChar
= OOO_STRING_SVTOOLS_RTF_QR
; break;
428 default:pChar
= OOO_STRING_SVTOOLS_RTF_QL
; break;
431 pHorzChar
[i
-1] = pChar
; // to avoid to always rummage in the ITEMSET later on
433 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
434 m_pStream
->WriteChar( '{' );
435 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_QC
); // column header always centered
437 if ( bBold
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_B
);
438 if ( bItalic
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_I
);
439 if ( bUnderline
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_UL
);
440 if ( bStrikeout
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_STRIKE
);
442 m_pStream
->WriteOString( "\\fs20\\f0\\cf0\\cb2" );
443 m_pStream
->WriteChar( ' ' );
444 RTFOutFuncs::Out_String(*m_pStream
, sColumnName
, m_eDestEnc
);
446 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_CELL
);
447 m_pStream
->WriteChar( '}' );
448 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
449 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_PARD
).WriteOString( OOO_STRING_SVTOOLS_RTF_INTBL
);
452 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_ROW
);
453 m_pStream
->WriteOString( SAL_NEWLINE_STRING
).WriteChar( '}' );
454 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
458 if ( m_aSelection
.hasElements() )
460 const Any
* pSelIter
= m_aSelection
.getConstArray();
461 const Any
* pEnd
= pSelIter
+ m_aSelection
.getLength();
463 bool bContinue
= true;
464 for( ; pSelIter
!= pEnd
&& bContinue
; ++pSelIter
)
466 if ( m_bBookmarkSelection
)
468 bContinue
= m_xRowLocate
->moveToBookmark( *pSelIter
);
473 OSL_VERIFY( *pSelIter
>>= nPos
);
474 bContinue
= ( m_xResultSet
->absolute( nPos
) );
478 appendRow( pHorzChar
.get(), nCount
, k
, kk
);
483 m_xResultSet
->beforeFirst(); // set back before the first row
484 while(m_xResultSet
->next())
486 appendRow(pHorzChar
.get(),nCount
,k
,kk
);
491 m_pStream
->WriteChar( '}' ).WriteOString( SAL_NEWLINE_STRING
);
492 m_pStream
->WriteUChar( 0 );
493 return ((*m_pStream
).GetError() == ERRCODE_NONE
);
496 void ORTFImportExport::appendRow(OString
const * pHorzChar
,sal_Int32 _nColumnCount
,sal_Int32
& k
,sal_Int32
& kk
)
499 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_TROWD
).WriteOString( OOO_STRING_SVTOOLS_RTF_TRGAPH
);
500 m_pStream
->WriteOString("40");
501 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
503 static char const aCell2
[] = "\\clbrdrl\\brdrs\\brdrcf2\\clbrdrt\\brdrs\\brdrcf2\\clbrdrb\\brdrs\\brdrcf2\\clbrdrr\\brdrs\\brdrcf2\\clshdng10000\\clcfpat1\\cellx";
505 for ( sal_Int32 i
=1; i
<=_nColumnCount
; ++i
)
507 m_pStream
->WriteOString( aCell2
);
508 m_pStream
->WriteNumberAsString(i
*CELL_X
);
509 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
512 const bool bBold
= ( css::awt::FontWeight::BOLD
== m_aFont
.Weight
);
513 const bool bItalic
= ( css::awt::FontSlant_ITALIC
== m_aFont
.Slant
);
514 const bool bUnderline
= ( css::awt::FontUnderline::NONE
!= m_aFont
.Underline
);
515 const bool bStrikeout
= ( css::awt::FontStrikeout::NONE
!= m_aFont
.Strikeout
);
516 Reference
< XRowSet
> xRowSet(m_xRow
,UNO_QUERY
);
518 m_pStream
->WriteChar( '{' );
519 m_pStream
->WriteOString( "\\trrh-270\\pard\\intbl" );
520 for ( sal_Int32 i
=1; i
<= _nColumnCount
; ++i
)
522 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
523 m_pStream
->WriteChar( '{' );
524 m_pStream
->WriteOString( pHorzChar
[i
-1] );
526 if ( bBold
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_B
);
527 if ( bItalic
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_I
);
528 if ( bUnderline
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_UL
);
529 if ( bStrikeout
) m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_STRIKE
);
531 m_pStream
->WriteOString( "\\fs20\\f1\\cf0\\cb1 " );
535 Reference
<XPropertySet
> xColumn(m_xRowSetColumns
->getByIndex(i
-1),UNO_QUERY_THROW
);
536 dbtools::FormattedColumnValue
aFormatedValue(m_xContext
,xRowSet
,xColumn
);
537 OUString sValue
= aFormatedValue
.getFormattedValue();
538 if ( !sValue
.isEmpty() )
539 RTFOutFuncs::Out_String(*m_pStream
,sValue
,m_eDestEnc
);
543 SAL_WARN("dbaccess.ui","RTF WRITE!");
546 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_CELL
);
547 m_pStream
->WriteChar( '}' );
548 m_pStream
->WriteOString( SAL_NEWLINE_STRING
);
549 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_PARD
).WriteOString( OOO_STRING_SVTOOLS_RTF_INTBL
);
551 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_RTF_ROW
).WriteOString( SAL_NEWLINE_STRING
);
552 m_pStream
->WriteChar( '}' );
556 bool ORTFImportExport::Read()
558 ODatabaseImportExport::Read();
559 SvParserState eState
= SvParserState::Error
;
562 tools::SvRef
<ORTFReader
> xReader(new ORTFReader((*m_pStream
),m_xConnection
,m_xFormatter
,m_xContext
));
563 if ( isCheckEnabled() )
564 xReader
->enableCheckOnly();
565 eState
= xReader
->CallParser();
568 return eState
!= SvParserState::Error
;
571 const sal_Int16
OHTMLImportExport::nCellSpacing
= 0;
572 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";
574 OHTMLImportExport::OHTMLImportExport(const svx::ODataAccessDescriptor
& _aDataDescriptor
,
575 const Reference
< XComponentContext
>& _rM
,
576 const Reference
< css::util::XNumberFormatter
>& _rxNumberF
)
577 : ODatabaseImportExport(_aDataDescriptor
,_rM
,_rxNumberF
)
579 #if OSL_DEBUG_LEVEL > 0
583 // set HTML configuration
584 m_eDestEnc
= RTL_TEXTENCODING_UTF8
;
585 strncpy( sIndent
, sIndentSource
,std::min(sizeof(sIndent
),sizeof(sIndentSource
)));
589 bool OHTMLImportExport::Write()
591 ODatabaseImportExport::Write();
594 m_pStream
->WriteChar( '<' ).WriteOString( OOO_STRING_SVTOOLS_HTML_doctype
).WriteChar( ' ' ).WriteOString( OOO_STRING_SVTOOLS_HTML_doctype5
).WriteChar( '>' ).WriteOString( SAL_NEWLINE_STRING
).WriteOString( SAL_NEWLINE_STRING
);
595 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_html
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
597 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
599 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
600 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_html
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
602 return ((*m_pStream
).GetError() == ERRCODE_NONE
);
607 bool OHTMLImportExport::Read()
609 ODatabaseImportExport::Read();
610 SvParserState eState
= SvParserState::Error
;
613 tools::SvRef
<OHTMLReader
> xReader(new OHTMLReader((*m_pStream
),m_xConnection
,m_xFormatter
,m_xContext
));
614 if ( isCheckEnabled() )
615 xReader
->enableCheckOnly();
616 xReader
->SetTableName(m_sDefaultTableName
);
617 eState
= xReader
->CallParser();
620 return eState
!= SvParserState::Error
;
623 void OHTMLImportExport::WriteHeader()
625 uno::Reference
<document::XDocumentProperties
> xDocProps(
626 document::DocumentProperties::create( m_xContext
) );
627 if (xDocProps
.is()) {
628 xDocProps
->setTitle(m_sName
);
632 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_head
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
634 SfxFrameHTMLWriter::Out_DocInfo( (*m_pStream
), OUString(),
635 xDocProps
, sIndent
);
636 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
638 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
639 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_head
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
642 void OHTMLImportExport::WriteBody()
645 m_pStream
->WriteOString( "<" ).WriteOString( OOO_STRING_SVTOOLS_HTML_style
).WriteOString( " " ).WriteOString( OOO_STRING_SVTOOLS_HTML_O_type
).WriteOString( "=\"text/css\">" );
647 m_pStream
->WriteOString( "<!-- " );
648 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
649 m_pStream
->WriteOString( OOO_STRING_SVTOOLS_HTML_body
).WriteOString( " { " ).WriteOString( "font-family: " ).WriteChar( '"' ).WriteOString( OUStringToOString(m_aFont
.Name
, osl_getThreadTextEncoding()) ).WriteChar( '\"' );
650 // TODO : think about the encoding of the font name
651 m_pStream
->WriteOString( "; " ).WriteOString( "font-size: " );
652 m_pStream
->WriteNumberAsString(m_aFont
.Height
);
653 m_pStream
->WriteChar( '}' );
655 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
656 m_pStream
->WriteOString( " -->" );
658 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
659 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_style
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
660 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
662 // default Textcolour black
663 m_pStream
->WriteChar( '<' ).WriteOString( OOO_STRING_SVTOOLS_HTML_body
).WriteChar( ' ' ).WriteOString( OOO_STRING_SVTOOLS_HTML_O_text
).WriteChar( '=' );
666 m_xObject
->getPropertyValue(PROPERTY_TEXTCOLOR
) >>= aColor
;
667 HTMLOutFuncs::Out_Color( (*m_pStream
), aColor
);
669 m_pStream
->WriteOString( " " OOO_STRING_SVTOOLS_HTML_O_bgcolor
"=" );
670 HTMLOutFuncs::Out_Color( (*m_pStream
), aColor
);
672 m_pStream
->WriteChar( '>' );
673 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
677 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_body
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
680 void OHTMLImportExport::WriteTables()
682 OString aStrOut
= OOO_STRING_SVTOOLS_HTML_table
684 OOO_STRING_SVTOOLS_HTML_frame
686 OOO_STRING_SVTOOLS_HTML_TF_void
;
688 Sequence
< OUString
> aNames
;
689 Reference
<XNameAccess
> xColumns
;
690 bool bUseResultMetaData
= false;
693 Reference
<XColumnsSupplier
> xColSup(m_xObject
,UNO_QUERY
);
694 xColumns
= xColSup
->getColumns();
695 aNames
= xColumns
->getElementNames();
696 if ( !aNames
.hasElements() )
698 sal_Int32 nCount
= m_xResultSetMetaData
->getColumnCount();
699 aNames
.realloc(nCount
);
700 auto aNamesRange
= asNonConstRange(aNames
);
701 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
702 aNamesRange
[i
] = m_xResultSetMetaData
->getColumnName(i
+1);
703 bUseResultMetaData
= true;
708 OOO_STRING_SVTOOLS_HTML_O_align
710 OOO_STRING_SVTOOLS_HTML_AL_left
712 OOO_STRING_SVTOOLS_HTML_O_cellspacing
714 OString::number(nCellSpacing
) +
716 OOO_STRING_SVTOOLS_HTML_O_cols
718 OString::number(aNames
.getLength()) +
720 OOO_STRING_SVTOOLS_HTML_O_border
724 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, aStrOut
);
728 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_caption
);
729 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_bold
);
731 m_pStream
->WriteOString( OUStringToOString(m_sName
, osl_getThreadTextEncoding()) );
732 // TODO : think about the encoding of the name
733 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_bold
, false);
734 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_caption
, false);
737 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
741 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_thead
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
744 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tablerow
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
748 std::unique_ptr
<sal_Int32
[]> pFormat(new sal_Int32
[aNames
.getLength()]);
750 std::unique_ptr
<const char *[]> pHorJustify(new const char*[aNames
.getLength()]);
751 std::unique_ptr
<sal_Int32
[]> pColWidth(new sal_Int32
[aNames
.getLength()]);
753 sal_Int32 nHeight
= 0;
754 m_xObject
->getPropertyValue(PROPERTY_ROW_HEIGHT
) >>= nHeight
;
756 // 1. writing the column description
757 const OUString
* pIter
= aNames
.getConstArray();
758 const OUString
* pEnd
= pIter
+ aNames
.getLength();
760 for( sal_Int32 i
=0;pIter
!= pEnd
; ++pIter
,++i
)
762 sal_Int32 nAlign
= 0;
765 if ( !bUseResultMetaData
)
767 Reference
<XPropertySet
> xColumn
;
768 xColumns
->getByName(*pIter
) >>= xColumn
;
769 xColumn
->getPropertyValue(PROPERTY_ALIGN
) >>= nAlign
;
770 pFormat
[i
] = ::comphelper::getINT32(xColumn
->getPropertyValue(PROPERTY_FORMATKEY
));
771 pColWidth
[i
] = ::comphelper::getINT32(xColumn
->getPropertyValue(PROPERTY_WIDTH
));
776 case 1: pHorJustify
[i
] = OOO_STRING_SVTOOLS_HTML_AL_center
; break;
777 case 2: pHorJustify
[i
] = OOO_STRING_SVTOOLS_HTML_AL_right
; break;
778 default: pHorJustify
[i
] = OOO_STRING_SVTOOLS_HTML_AL_left
; break;
781 if(i
== aNames
.getLength()-1)
784 WriteCell(pFormat
[i
],pColWidth
[i
],nHeight
,pHorJustify
[i
],*pIter
,OOO_STRING_SVTOOLS_HTML_tableheader
);
788 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tablerow
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
789 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_thead
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
792 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tbody
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
794 // 2. and now the data
795 Reference
< XRowSet
> xRowSet(m_xRow
,UNO_QUERY
);
796 m_xResultSet
->beforeFirst(); // set back before the first row
797 while(m_xResultSet
->next())
800 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tablerow
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
802 for(sal_Int32 i
=1;i
<=aNames
.getLength();++i
)
804 if(i
== aNames
.getLength())
810 Reference
<XPropertySet
> xColumn(m_xRowSetColumns
->getByIndex(i
-1),UNO_QUERY_THROW
);
811 dbtools::FormattedColumnValue
aFormatedValue(m_xContext
,xRowSet
,xColumn
);
812 OUString sValue
= aFormatedValue
.getFormattedValue();
813 if (!sValue
.isEmpty())
818 catch( const Exception
& )
820 DBG_UNHANDLED_EXCEPTION("dbaccess");
822 WriteCell(pFormat
[i
-1],pColWidth
[i
-1],nHeight
,pHorJustify
[i
-1],aValue
,OOO_STRING_SVTOOLS_HTML_tabledata
);
824 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tablerow
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
830 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tablerow
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
831 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_thead
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
834 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tbody
).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
838 m_pStream
->WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
839 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_tbody
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
841 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_table
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
844 void OHTMLImportExport::WriteCell( sal_Int32 nFormat
, sal_Int32 nWidthPixel
, sal_Int32 nHeightPixel
, const char* pChar
,
845 const OUString
& rValue
, const char* pHtmlTag
)
847 OString aStrTD
= pHtmlTag
;
849 nWidthPixel
= nWidthPixel
? nWidthPixel
: 86;
850 nHeightPixel
= nHeightPixel
? nHeightPixel
: 17;
852 // despite the <TABLE COLS=n> and <COL WIDTH=x> designation necessary,
853 // as Netscape is not paying attention to them.
856 OOO_STRING_SVTOOLS_HTML_O_width
858 OString::number(nWidthPixel
) +
861 OOO_STRING_SVTOOLS_HTML_O_height
863 OString::number(nHeightPixel
) +
865 OOO_STRING_SVTOOLS_HTML_O_align
869 SvNumberFormatsSupplierObj
* pSupplierImpl
= m_xFormatter
.is() ? comphelper::getFromUnoTunnel
<SvNumberFormatsSupplierObj
>(m_xFormatter
->getNumberFormatsSupplier()) : nullptr;
870 SvNumberFormatter
* pFormatter
= pSupplierImpl
? pSupplierImpl
->GetNumberFormatter() : nullptr;
877 fVal
= m_xFormatter
->convertStringToNumber(nFormat
,rValue
);
878 HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal
,nFormat
, *pFormatter
);
880 catch(const Exception
&)
882 HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal
,nFormat
, *pFormatter
);
886 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, aStrTD
);
890 bool bBold
= ( css::awt::FontWeight::BOLD
== m_aFont
.Weight
);
891 bool bItalic
= ( css::awt::FontSlant_ITALIC
== m_aFont
.Slant
);
892 bool bUnderline
= ( css::awt::FontUnderline::NONE
!= m_aFont
.Underline
);
893 bool bStrikeout
= ( css::awt::FontStrikeout::NONE
!= m_aFont
.Strikeout
);
895 if ( bBold
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_bold
);
896 if ( bItalic
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_italic
);
897 if ( bUnderline
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_underline
);
898 if ( bStrikeout
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_strike
);
900 if ( rValue
.isEmpty() )
901 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_linebreak
); // no completely empty cell
903 HTMLOutFuncs::Out_String( (*m_pStream
), rValue
);
905 if ( bStrikeout
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_strike
, false);
906 if ( bUnderline
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_underline
, false);
907 if ( bItalic
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_italic
, false);
908 if ( bBold
) HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_bold
, false);
912 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, pHtmlTag
, false).WriteOString(SAL_NEWLINE_STRING
).WriteOString(GetIndentStr());
915 void OHTMLImportExport::FontOn()
917 #if OSL_DEBUG_LEVEL > 0
922 OString aStrOut
= "<"
923 OOO_STRING_SVTOOLS_HTML_font
925 OOO_STRING_SVTOOLS_HTML_O_face
928 OUStringToOString(m_aFont
.Name
,osl_getThreadTextEncoding()) +
929 // TODO : think about the encoding of the font name
932 OOO_STRING_SVTOOLS_HTML_O_color
934 m_pStream
->WriteOString( aStrOut
);
938 m_xObject
->getPropertyValue(PROPERTY_TEXTCOLOR
) >>= aColor
;
940 HTMLOutFuncs::Out_Color( (*m_pStream
), aColor
);
941 m_pStream
->WriteOString( ">" );
944 inline void OHTMLImportExport::FontOff()
946 #if OSL_DEBUG_LEVEL > 0
947 OSL_ENSURE(m_bCheckFont
,"No FontOn() called");
949 HTMLOutFuncs::Out_AsciiTag(*m_pStream
, OOO_STRING_SVTOOLS_HTML_font
, false);
950 #if OSL_DEBUG_LEVEL > 0
951 m_bCheckFont
= false;
955 void OHTMLImportExport::IncIndent( sal_Int16 nVal
)
957 sIndent
[m_nIndent
] = '\t';
958 m_nIndent
= m_nIndent
+ nVal
;
961 else if ( m_nIndent
> nIndentMax
)
962 m_nIndent
= nIndentMax
;
963 sIndent
[m_nIndent
] = 0;
966 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */