android: Update app icon to new startcenter icon
[LibreOffice.git] / dbaccess / source / ui / misc / TokenWriter.cxx
blob8d898fe24e1f4111d4e0cec6a87716d1a5111202
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 <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>
51 #include <utility>
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>
61 #include <memory>
63 using namespace dbaui;
64 using namespace dbtools;
65 using namespace svx;
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;
77 #define CELL_X 1437
79 ODatabaseImportExport::ODatabaseImportExport(const svx::ODataAccessDescriptor& _aDataDescriptor,
80 const Reference< XComponentContext >& _rM,
81 const Reference< css::util::XNumberFormatter >& _rxNumberF)
82 :m_bBookmarkSelection( false )
83 ,m_pStream(nullptr)
84 ,m_xFormatter(_rxNumberF)
85 ,m_xContext(_rM)
86 ,m_nCommandType(CommandType::TABLE)
87 ,m_bNeedToReInitialize(false)
88 ,m_bInInitialize(false)
89 ,m_bCheckOnly(false)
91 m_eDestEnc = osl_getThreadTextEncoding();
93 osl_atomic_increment( &m_refCount );
94 impl_initFromDescriptor( _aDataDescriptor, false );
95 osl_atomic_decrement( &m_refCount );
98 // import data
99 ODatabaseImportExport::ODatabaseImportExport( ::dbtools::SharedConnection _xConnection,
100 const Reference< XNumberFormatter >& _rxNumberF, const Reference< XComponentContext >& _rM )
101 :m_bBookmarkSelection( false )
102 ,m_pStream(nullptr)
103 ,m_xConnection(std::move(_xConnection))
104 ,m_xFormatter(_rxNumberF)
105 ,m_xContext(_rM)
106 ,m_nCommandType(css::sdb::CommandType::TABLE)
107 ,m_bNeedToReInitialize(false)
108 ,m_bInInitialize(false)
109 ,m_bCheckOnly(false)
111 m_eDestEnc = osl_getThreadTextEncoding();
114 ODatabaseImportExport::~ODatabaseImportExport()
116 acquire();
117 dispose();
120 void ODatabaseImportExport::dispose()
122 // remove me as listener
123 Reference< XComponent > xComponent(m_xConnection, UNO_QUERY);
124 if (xComponent.is())
126 Reference< XEventListener> xEvt(this);
127 xComponent->removeEventListener(xEvt);
129 m_xConnection.clear();
131 ::comphelper::disposeComponent(m_xRow);
133 m_xObject.clear();
134 m_xResultSetMetaData.clear();
135 m_xResultSet.clear();
136 m_xRow.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();
147 dispose();
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 );
205 else
206 initialize();
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:
233 // only for tables
234 Reference<XTablesSupplier> xSup(m_xConnection,UNO_QUERY);
235 if(xSup.is())
236 xNameAccess = xSup->getTables();
238 break;
239 case CommandType::QUERY:
241 Reference<XQueriesSupplier> xSup(m_xConnection,UNO_QUERY);
242 if(xSup.is())
243 xNameAccess = xSup->getQueries();
245 break;
247 if(xNameAccess.is() && xNameAccess->hasByName(m_sName))
249 xNameAccess->getByName(m_sName) >>= m_xObject;
252 if(m_xObject.is())
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 );
268 xRowSet->execute();
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);
279 catch(Exception& )
281 m_xRow = nullptr;
282 m_xResultSetMetaData = nullptr;
283 ::comphelper::disposeComponent(m_xResultSet);
284 throw;
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 )
305 initialize();
307 return true;
310 bool ODatabaseImportExport::Read()
312 if ( m_bNeedToReInitialize )
314 if ( !m_bInInitialize )
315 initialize();
317 return true;
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 );
336 ::Color aColor;
337 if(m_xObject.is())
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())
350 sal_Int32 nIdx{0};
351 sal_Int32 nTok{-1}; // to compensate pre-increment
352 do {
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( ';' );
358 } while (nIdx>=0);
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 );
379 if(m_xObject.is())
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;
388 if ( !nCount )
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);
413 else
415 sColumnName = *pIter;
416 Reference<XPropertySet> xColumn;
417 xColumns->getByName(sColumnName) >>= xColumn;
418 xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign;
419 ++pIter;
422 const char* pChar;
423 switch( nAlign )
425 case 1: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
426 case 2: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
427 case 0:
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 );
456 sal_Int32 k=1;
457 sal_Int32 kk=0;
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 );
470 else
472 sal_Int32 nPos = -1;
473 OSL_VERIFY( *pSelIter >>= nPos );
474 bContinue = ( m_xResultSet->absolute( nPos ) );
477 if ( bContinue )
478 appendRow( pHorzChar.get(), nCount, k, kk );
481 else
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)
498 ++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);
541 catch (Exception&)
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( '}' );
553 ++k;
556 bool ORTFImportExport::Read()
558 ODatabaseImportExport::Read();
559 SvParserState eState = SvParserState::Error;
560 if ( m_pStream )
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)
578 ,m_nIndent(0)
579 #if OSL_DEBUG_LEVEL > 0
580 ,m_bCheckFont(false)
581 #endif
583 // set HTML configuration
584 m_eDestEnc = RTL_TEXTENCODING_UTF8;
585 strncpy( sIndent, sIndentSource ,std::min(sizeof(sIndent),sizeof(sIndentSource)));
586 sIndent[0] = 0;
589 bool OHTMLImportExport::Write()
591 ODatabaseImportExport::Write();
592 if(m_xObject.is())
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());
596 WriteHeader();
597 m_pStream->WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
598 WriteBody();
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);
604 return false;
607 bool OHTMLImportExport::Read()
609 ODatabaseImportExport::Read();
610 SvParserState eState = SvParserState::Error;
611 if ( m_pStream )
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);
631 IncIndent(1);
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());
637 IncIndent(-1);
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()
644 IncIndent(1);
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( " -->" );
657 IncIndent(-1);
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( '=' );
664 ::Color aColor;
665 if(m_xObject.is())
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());
675 WriteTables();
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;
691 if(m_xObject.is())
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;
707 aStrOut += " "
708 OOO_STRING_SVTOOLS_HTML_O_align
710 OOO_STRING_SVTOOLS_HTML_AL_left
712 OOO_STRING_SVTOOLS_HTML_O_cellspacing
713 "=" +
714 OString::number(nCellSpacing) +
716 OOO_STRING_SVTOOLS_HTML_O_cols
717 "=" +
718 OString::number(aNames.getLength()) +
720 OOO_STRING_SVTOOLS_HTML_O_border
721 "=1";
723 IncIndent(1);
724 HTMLOutFuncs::Out_AsciiTag(*m_pStream, aStrOut);
726 FontOn();
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);
736 FontOff();
737 m_pStream->WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
738 // </FONT>
740 IncIndent(1);
741 HTMLOutFuncs::Out_AsciiTag(*m_pStream, OOO_STRING_SVTOOLS_HTML_thead).WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
743 IncIndent(1);
744 HTMLOutFuncs::Out_AsciiTag(*m_pStream, OOO_STRING_SVTOOLS_HTML_tablerow).WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
746 if(m_xObject.is())
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;
763 pFormat[i] = 0;
764 pColWidth[i] = 100;
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));
774 switch( nAlign )
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)
782 IncIndent(-1);
784 WriteCell(pFormat[i],pColWidth[i],nHeight,pHorJustify[i],*pIter,OOO_STRING_SVTOOLS_HTML_tableheader);
787 IncIndent(-1);
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());
791 IncIndent(1);
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())
799 IncIndent(1);
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())
805 IncIndent(-1);
807 OUString aValue;
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())
815 aValue = sValue;
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());
827 else
829 IncIndent(-1);
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());
833 IncIndent(1);
834 HTMLOutFuncs::Out_AsciiTag(*m_pStream, OOO_STRING_SVTOOLS_HTML_tbody).WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
837 IncIndent(-1);
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());
840 IncIndent(-1);
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.
854 // column width
855 aStrTD += " "
856 OOO_STRING_SVTOOLS_HTML_O_width
857 "=" +
858 OString::number(nWidthPixel) +
859 // line height
861 OOO_STRING_SVTOOLS_HTML_O_height
862 "=" +
863 OString::number(nHeightPixel) +
865 OOO_STRING_SVTOOLS_HTML_O_align
866 "=" +
867 pChar;
869 SvNumberFormatsSupplierObj* pSupplierImpl = m_xFormatter.is() ? comphelper::getFromUnoTunnel<SvNumberFormatsSupplierObj>(m_xFormatter->getNumberFormatsSupplier()) : nullptr;
870 SvNumberFormatter* pFormatter = pSupplierImpl ? pSupplierImpl->GetNumberFormatter() : nullptr;
871 if(pFormatter)
873 double fVal = 0.0;
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);
888 FontOn();
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
902 else
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);
910 FontOff();
912 HTMLOutFuncs::Out_AsciiTag(*m_pStream, pHtmlTag, false).WriteOString(SAL_NEWLINE_STRING).WriteOString(GetIndentStr());
915 void OHTMLImportExport::FontOn()
917 #if OSL_DEBUG_LEVEL > 0
918 m_bCheckFont = true;
919 #endif
921 // <FONT FACE="xxx">
922 OString aStrOut = "<"
923 OOO_STRING_SVTOOLS_HTML_font
925 OOO_STRING_SVTOOLS_HTML_O_face
927 "\"" +
928 OUStringToOString(m_aFont.Name,osl_getThreadTextEncoding()) +
929 // TODO : think about the encoding of the font name
930 "\""
932 OOO_STRING_SVTOOLS_HTML_O_color
933 "=";
934 m_pStream->WriteOString( aStrOut );
936 ::Color aColor;
937 if(m_xObject.is())
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");
948 #endif
949 HTMLOutFuncs::Out_AsciiTag(*m_pStream, OOO_STRING_SVTOOLS_HTML_font, false);
950 #if OSL_DEBUG_LEVEL > 0
951 m_bCheckFont = false;
952 #endif
955 void OHTMLImportExport::IncIndent( sal_Int16 nVal )
957 sIndent[m_nIndent] = '\t';
958 m_nIndent = m_nIndent + nVal;
959 if ( m_nIndent < 0 )
960 m_nIndent = 0;
961 else if ( m_nIndent > nIndentMax )
962 m_nIndent = nIndentMax;
963 sIndent[m_nIndent] = 0;
966 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */