/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace dbaui; using namespace dbtools; using namespace svx; using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::container; using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::sdbcx; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::util; #define CELL_X 1437 ODatabaseImportExport::ODatabaseImportExport(const svx::ODataAccessDescriptor& _aDataDescriptor, const Reference< XComponentContext >& _rM, const Reference< css::util::XNumberFormatter >& _rxNumberF) :m_bBookmarkSelection( false ) ,m_pStream(nullptr) ,m_xFormatter(_rxNumberF) ,m_xContext(_rM) ,m_nCommandType(CommandType::TABLE) ,m_bNeedToReInitialize(false) ,m_bInInitialize(false) ,m_bCheckOnly(false) { m_eDestEnc = osl_getThreadTextEncoding(); osl_atomic_increment( &m_refCount ); impl_initFromDescriptor( _aDataDescriptor, false ); osl_atomic_decrement( &m_refCount ); } // import data ODatabaseImportExport::ODatabaseImportExport( const ::dbtools::SharedConnection& _rxConnection, const Reference< XNumberFormatter >& _rxNumberF, const Reference< XComponentContext >& _rM ) :m_bBookmarkSelection( false ) ,m_pStream(nullptr) ,m_xConnection(_rxConnection) ,m_xFormatter(_rxNumberF) ,m_xContext(_rM) ,m_nCommandType(css::sdb::CommandType::TABLE) ,m_bNeedToReInitialize(false) ,m_bInInitialize(false) ,m_bCheckOnly(false) { m_eDestEnc = osl_getThreadTextEncoding(); } ODatabaseImportExport::~ODatabaseImportExport() { acquire(); dispose(); } void ODatabaseImportExport::dispose() { // remove me as listener Reference< XComponent > xComponent(m_xConnection, UNO_QUERY); if (xComponent.is()) { Reference< XEventListener> xEvt(this); xComponent->removeEventListener(xEvt); } m_xConnection.clear(); ::comphelper::disposeComponent(m_xRow); m_xObject.clear(); m_xResultSetMetaData.clear(); m_xResultSet.clear(); m_xRow.clear(); m_xRowLocate.clear(); m_xFormatter.clear(); } void SAL_CALL ODatabaseImportExport::disposing( const EventObject& Source ) { Reference xCon(Source.Source,UNO_QUERY); if(m_xConnection.is() && m_xConnection == xCon) { m_xConnection.clear(); dispose(); m_bNeedToReInitialize = true; } } void ODatabaseImportExport::initialize( const ODataAccessDescriptor& _aDataDescriptor ) { impl_initFromDescriptor( _aDataDescriptor, true ); } void ODatabaseImportExport::impl_initFromDescriptor( const ODataAccessDescriptor& _aDataDescriptor, bool _bPlusDefaultInit) { if ( !_bPlusDefaultInit ) { m_sDataSourceName = _aDataDescriptor.getDataSource(); _aDataDescriptor[DataAccessDescriptorProperty::CommandType] >>= m_nCommandType; _aDataDescriptor[DataAccessDescriptorProperty::Command] >>= m_sName; // some additional information if(_aDataDescriptor.has(DataAccessDescriptorProperty::Connection)) { Reference< XConnection > xPureConn( _aDataDescriptor[DataAccessDescriptorProperty::Connection], UNO_QUERY ); m_xConnection.reset( xPureConn, SharedConnection::NoTakeOwnership ); Reference< XEventListener> xEvt(this); Reference< XComponent > xComponent(m_xConnection, UNO_QUERY); if (xComponent.is() && xEvt.is()) xComponent->addEventListener(xEvt); } if ( _aDataDescriptor.has( DataAccessDescriptorProperty::Selection ) ) _aDataDescriptor[ DataAccessDescriptorProperty::Selection ] >>= m_aSelection; if ( _aDataDescriptor.has( DataAccessDescriptorProperty::BookmarkSelection ) ) _aDataDescriptor[ DataAccessDescriptorProperty::BookmarkSelection ] >>= m_bBookmarkSelection; if ( _aDataDescriptor.has( DataAccessDescriptorProperty::Cursor ) ) { _aDataDescriptor[ DataAccessDescriptorProperty::Cursor ] >>= m_xResultSet; m_xRowLocate.set( m_xResultSet, UNO_QUERY ); } if ( m_aSelection.hasElements() ) { if ( !m_xResultSet.is() ) { SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: selection without result set is nonsense!" ); m_aSelection.realloc( 0 ); } } if ( m_aSelection.hasElements() ) { if ( m_bBookmarkSelection && !m_xRowLocate.is() ) { SAL_WARN("dbaccess.ui", "ODatabaseImportExport::impl_initFromDescriptor: no XRowLocate -> no bookmarks!" ); m_aSelection.realloc( 0 ); } } } else initialize(); } void ODatabaseImportExport::initialize() { m_bInInitialize = true; m_bNeedToReInitialize = false; if ( !m_xConnection.is() ) { // we need a connection OSL_ENSURE(!m_sDataSourceName.isEmpty(),"There must be a datsource name!"); Reference xDatabaseContext( DatabaseContext::create(m_xContext), UNO_QUERY_THROW); Reference< XEventListener> xEvt(this); Reference< XConnection > xConnection; SQLExceptionInfo aInfo = ::dbaui::createConnection( m_sDataSourceName, xDatabaseContext, m_xContext, xEvt, xConnection ); m_xConnection.reset( xConnection ); if(aInfo.isValid() && aInfo.getType() == SQLExceptionInfo::TYPE::SQLException) throw *static_cast(aInfo); } Reference xNameAccess; switch(m_nCommandType) { case CommandType::TABLE: { // only for tables Reference xSup(m_xConnection,UNO_QUERY); if(xSup.is()) xNameAccess = xSup->getTables(); } break; case CommandType::QUERY: { Reference xSup(m_xConnection,UNO_QUERY); if(xSup.is()) xNameAccess = xSup->getQueries(); } break; } if(xNameAccess.is() && xNameAccess->hasByName(m_sName)) { xNameAccess->getByName(m_sName) >>= m_xObject; } if(m_xObject.is()) { try { if(m_xObject->getPropertySetInfo()->hasPropertyByName(PROPERTY_FONT)) m_xObject->getPropertyValue(PROPERTY_FONT) >>= m_aFont; // the result set may be already set with the datadescriptor if ( !m_xResultSet.is() ) { m_xResultSet.set( m_xContext->getServiceManager()->createInstanceWithContext("com.sun.star.sdb.RowSet", m_xContext), UNO_QUERY ); Reference< XPropertySet > xProp( m_xResultSet, UNO_QUERY_THROW ); xProp->setPropertyValue( PROPERTY_ACTIVE_CONNECTION, makeAny( m_xConnection.getTyped() ) ); xProp->setPropertyValue( PROPERTY_COMMAND_TYPE, makeAny( m_nCommandType ) ); xProp->setPropertyValue( PROPERTY_COMMAND, makeAny( m_sName ) ); Reference< XRowSet > xRowSet( xProp, UNO_QUERY ); xRowSet->execute(); } if ( !m_xRow.is() && m_xResultSet.is() ) { m_xRow.set( m_xResultSet, UNO_QUERY ); m_xRowLocate.set( m_xResultSet, UNO_QUERY ); m_xResultSetMetaData = Reference(m_xRow,UNO_QUERY_THROW)->getMetaData(); Reference xSup(m_xResultSet,UNO_QUERY_THROW); m_xRowSetColumns.set(xSup->getColumns(),UNO_QUERY_THROW); } } catch(Exception& ) { m_xRow = nullptr; m_xResultSetMetaData = nullptr; ::comphelper::disposeComponent(m_xResultSet); throw; } } if ( m_aFont.Name.isEmpty() ) { vcl::Font aApplicationFont = OutputDevice::GetDefaultFont( DefaultFontType::SANS_UNICODE, Application::GetSettings().GetUILanguageTag().getLanguageType(), GetDefaultFontFlags::OnlyOne ); m_aFont = VCLUnoHelper::CreateFontDescriptor( aApplicationFont ); } m_bInInitialize = false; } bool ODatabaseImportExport::Write() { if ( m_bNeedToReInitialize ) { if ( !m_bInInitialize ) initialize(); } return true; } bool ODatabaseImportExport::Read() { if ( m_bNeedToReInitialize ) { if ( !m_bInInitialize ) initialize(); } return true; } bool ORTFImportExport::Write() { ODatabaseImportExport::Write(); m_pStream->WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RTF ); m_pStream->WriteCharPtr(OOO_STRING_SVTOOLS_RTF_ANSI); if (sal_uInt32 nCpg = rtl_getWindowsCodePageFromTextEncoding(m_eDestEnc); nCpg && nCpg != 65001) { m_pStream->WriteCharPtr(OOO_STRING_SVTOOLS_RTF_ANSICPG).WriteUInt32AsString(nCpg); } m_pStream->WriteCharPtr(SAL_NEWLINE_STRING); bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight ); bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant ); bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline ); bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout ); ::Color aColor; if(m_xObject.is()) m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= aColor; OString aFonts(OUStringToOString(m_aFont.Name, RTL_TEXTENCODING_MS_1252)); if (aFonts.isEmpty()) { OUString aName = Application::GetSettings().GetStyleSettings().GetAppFont().GetFamilyName(); aFonts = OUStringToOString(aName, RTL_TEXTENCODING_MS_1252); } m_pStream->WriteCharPtr( "{\\fonttbl" ); if (!aFonts.isEmpty()) { sal_Int32 nIdx{0}; sal_Int32 nTok{-1}; // to compensate pre-increment do { m_pStream->WriteCharPtr( "\\f" ); m_pStream->WriteInt32AsString(++nTok); m_pStream->WriteCharPtr( "\\fcharset0\\fnil " ); m_pStream->WriteOString( aFonts.getToken(0, ';', nIdx) ); m_pStream->WriteChar( ';' ); } while (nIdx>=0); } m_pStream->WriteChar( '}' ) ; m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); // write the rtf color table m_pStream->WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_COLORTBL ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RED ); m_pStream->WriteUInt32AsString(aColor.GetRed()); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_GREEN ); m_pStream->WriteUInt32AsString(aColor.GetGreen()); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_BLUE ); m_pStream->WriteUInt32AsString(aColor.GetBlue()); m_pStream->WriteCharPtr( ";\\red255\\green255\\blue255;\\red192\\green192\\blue192;}" ) .WriteCharPtr( SAL_NEWLINE_STRING ); static char const aCell1[] = "\\clbrdrl\\brdrs\\brdrcf0\\clbrdrt\\brdrs\\brdrcf0\\clbrdrb\\brdrs\\brdrcf0\\clbrdrr\\brdrs\\brdrcf0\\clshdng10000\\clcfpat2\\cellx"; m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TROWD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRGAPH ); m_pStream->WriteInt32AsString(40); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); if(m_xObject.is()) { Reference xColSup(m_xObject,UNO_QUERY); Reference xColumns = xColSup->getColumns(); Sequence< OUString> aNames(xColumns->getElementNames()); const OUString* pIter = aNames.getConstArray(); sal_Int32 nCount = aNames.getLength(); bool bUseResultMetaData = false; if ( !nCount ) { nCount = m_xResultSetMetaData->getColumnCount(); bUseResultMetaData = true; } for( sal_Int32 i=1; i<=nCount; ++i ) { m_pStream->WriteCharPtr( aCell1 ); m_pStream->WriteInt32AsString(i*CELL_X); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); } // column description m_pStream->WriteChar( '{' ).WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteCharPtr( "\\trrh-270\\pard\\intbl" ); std::unique_ptr pHorzChar(new OString[nCount]); for ( sal_Int32 i=1; i <= nCount; ++i ) { sal_Int32 nAlign = 0; OUString sColumnName; if ( bUseResultMetaData ) sColumnName = m_xResultSetMetaData->getColumnName(i); else { sColumnName = *pIter; Reference xColumn; xColumns->getByName(sColumnName) >>= xColumn; xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign; ++pIter; } const char* pChar; switch( nAlign ) { case 1: pChar = OOO_STRING_SVTOOLS_RTF_QC; break; case 2: pChar = OOO_STRING_SVTOOLS_RTF_QR; break; case 0: default:pChar = OOO_STRING_SVTOOLS_RTF_QL; break; } pHorzChar[i-1] = pChar; // to avoid to always rummage in the ITEMSET later on m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteChar( '{' ); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_QC ); // column header always centered if ( bBold ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_B ); if ( bItalic ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_I ); if ( bUnderline ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_UL ); if ( bStrikeout ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_STRIKE ); m_pStream->WriteCharPtr( "\\fs20\\f0\\cf0\\cb2" ); m_pStream->WriteChar( ' ' ); RTFOutFuncs::Out_String(*m_pStream, sColumnName, m_eDestEnc); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL ); m_pStream->WriteChar( '}' ); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PARD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INTBL ); } m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ROW ); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ).WriteChar( '}' ); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); sal_Int32 k=1; sal_Int32 kk=0; if ( m_aSelection.hasElements() ) { const Any* pSelIter = m_aSelection.getConstArray(); const Any* pEnd = pSelIter + m_aSelection.getLength(); bool bContinue = true; for( ; pSelIter != pEnd && bContinue; ++pSelIter ) { if ( m_bBookmarkSelection ) { bContinue = m_xRowLocate->moveToBookmark( *pSelIter ); } else { sal_Int32 nPos = -1; OSL_VERIFY( *pSelIter >>= nPos ); bContinue = ( m_xResultSet->absolute( nPos ) ); } if ( bContinue ) appendRow( pHorzChar.get(), nCount, k, kk ); } } else { m_xResultSet->beforeFirst(); // set back before the first row while(m_xResultSet->next()) { appendRow(pHorzChar.get(),nCount,k,kk); } } } m_pStream->WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteUChar( 0 ); return ((*m_pStream).GetError() == ERRCODE_NONE); } void ORTFImportExport::appendRow(OString const * pHorzChar,sal_Int32 _nColumnCount,sal_Int32& k,sal_Int32& kk) { ++kk; m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TROWD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRGAPH ); m_pStream->WriteInt32AsString(40); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); static char const aCell2[] = "\\clbrdrl\\brdrs\\brdrcf2\\clbrdrt\\brdrs\\brdrcf2\\clbrdrb\\brdrs\\brdrcf2\\clbrdrr\\brdrs\\brdrcf2\\clshdng10000\\clcfpat1\\cellx"; for ( sal_Int32 i=1; i<=_nColumnCount; ++i ) { m_pStream->WriteCharPtr( aCell2 ); m_pStream->WriteInt32AsString(i*CELL_X); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); } const bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight ); const bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant ); const bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline ); const bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout ); Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY); m_pStream->WriteChar( '{' ); m_pStream->WriteCharPtr( "\\trrh-270\\pard\\intbl" ); for ( sal_Int32 i=1; i <= _nColumnCount; ++i ) { m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteChar( '{' ); m_pStream->WriteOString( pHorzChar[i-1] ); if ( bBold ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_B ); if ( bItalic ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_I ); if ( bUnderline ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_UL ); if ( bStrikeout ) m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_STRIKE ); m_pStream->WriteCharPtr( "\\fs20\\f1\\cf0\\cb1 " ); try { Reference xColumn(m_xRowSetColumns->getByIndex(i-1),UNO_QUERY_THROW); dbtools::FormattedColumnValue aFormatedValue(m_xContext,xRowSet,xColumn); OUString sValue = aFormatedValue.getFormattedValue(); if ( !sValue.isEmpty() ) RTFOutFuncs::Out_String(*m_pStream,sValue,m_eDestEnc); } catch (Exception&) { SAL_WARN("dbaccess.ui","RTF WRITE!"); } m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL ); m_pStream->WriteChar( '}' ); m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PARD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INTBL ); } m_pStream->WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ROW ).WriteCharPtr( SAL_NEWLINE_STRING ); m_pStream->WriteChar( '}' ); ++k; } bool ORTFImportExport::Read() { ODatabaseImportExport::Read(); SvParserState eState = SvParserState::Error; if ( m_pStream ) { tools::SvRef xReader(new ORTFReader((*m_pStream),m_xConnection,m_xFormatter,m_xContext)); if ( isCheckEnabled() ) xReader->enableCheckOnly(); eState = xReader->CallParser(); } return eState != SvParserState::Error; } const sal_Int16 OHTMLImportExport::nCellSpacing = 0; 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"; // Macros for HTML-Export #define TAG_ON( tag ) HTMLOutFuncs::Out_AsciiTag( (*m_pStream), tag ) #define TAG_OFF( tag ) HTMLOutFuncs::Out_AsciiTag( (*m_pStream), tag, false ) #define OUT_LF() m_pStream->WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() ) #define TAG_ON_LF( tag ) (TAG_ON( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() )) #define TAG_OFF_LF( tag ) (TAG_OFF( tag ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( GetIndentStr() )) OHTMLImportExport::OHTMLImportExport(const svx::ODataAccessDescriptor& _aDataDescriptor, const Reference< XComponentContext >& _rM, const Reference< css::util::XNumberFormatter >& _rxNumberF) : ODatabaseImportExport(_aDataDescriptor,_rM,_rxNumberF) ,m_nIndent(0) #if OSL_DEBUG_LEVEL > 0 ,m_bCheckFont(false) #endif { // set HTML configuration m_eDestEnc = SvxHtmlOptions::GetTextEncoding(); strncpy( sIndent, sIndentSource ,std::min(sizeof(sIndent),sizeof(sIndentSource))); sIndent[0] = 0; } bool OHTMLImportExport::Write() { ODatabaseImportExport::Write(); if(m_xObject.is()) { m_pStream->WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype ).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_doctype5 ).WriteChar( '>' ).WriteCharPtr( SAL_NEWLINE_STRING ).WriteCharPtr( SAL_NEWLINE_STRING ); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_html ); WriteHeader(); OUT_LF(); WriteBody(); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_html ); return ((*m_pStream).GetError() == ERRCODE_NONE); } return false; } bool OHTMLImportExport::Read() { ODatabaseImportExport::Read(); SvParserState eState = SvParserState::Error; if ( m_pStream ) { tools::SvRef xReader(new OHTMLReader((*m_pStream),m_xConnection,m_xFormatter,m_xContext)); if ( isCheckEnabled() ) xReader->enableCheckOnly(); xReader->SetTableName(m_sDefaultTableName); eState = xReader->CallParser(); } return eState != SvParserState::Error; } void OHTMLImportExport::WriteHeader() { uno::Reference xDocProps( document::DocumentProperties::create( m_xContext ) ); if (xDocProps.is()) { xDocProps->setTitle(m_sName); } IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_head ); SfxFrameHTMLWriter::Out_DocInfo( (*m_pStream), OUString(), xDocProps, sIndent, osl_getThreadTextEncoding() ); OUT_LF(); IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_head ); } void OHTMLImportExport::WriteBody() { IncIndent(1); m_pStream->WriteCharPtr( "<" ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_style ).WriteCharPtr( " " ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_type ).WriteCharPtr( "=\"text/css\">" ); m_pStream->WriteCharPtr( "" ); IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_style ); OUT_LF(); // default Textcolour black m_pStream->WriteChar( '<' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_body ).WriteChar( ' ' ).WriteCharPtr( OOO_STRING_SVTOOLS_HTML_O_text ).WriteChar( '=' ); ::Color aColor; if(m_xObject.is()) m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= aColor; HTMLOutFuncs::Out_Color( (*m_pStream), aColor ); m_pStream->WriteCharPtr( " " OOO_STRING_SVTOOLS_HTML_O_bgcolor "=" ); HTMLOutFuncs::Out_Color( (*m_pStream), aColor ); m_pStream->WriteChar( '>' ); OUT_LF(); WriteTables(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_body ); } void OHTMLImportExport::WriteTables() { OString aStrOut = OOO_STRING_SVTOOLS_HTML_table " " OOO_STRING_SVTOOLS_HTML_frame "=" OOO_STRING_SVTOOLS_HTML_TF_void; Sequence< OUString> aNames; Reference xColumns; bool bUseResultMetaData = false; if(m_xObject.is()) { Reference xColSup(m_xObject,UNO_QUERY); xColumns = xColSup->getColumns(); aNames = xColumns->getElementNames(); if ( !aNames.hasElements() ) { sal_Int32 nCount = m_xResultSetMetaData->getColumnCount(); aNames.realloc(nCount); for (sal_Int32 i= 0; i < nCount; ++i) aNames[i] = m_xResultSetMetaData->getColumnName(i+1); bUseResultMetaData = true; } } aStrOut += " " OOO_STRING_SVTOOLS_HTML_O_align "=" OOO_STRING_SVTOOLS_HTML_AL_left " " OOO_STRING_SVTOOLS_HTML_O_cellspacing "=" + OString::number(nCellSpacing) + " " OOO_STRING_SVTOOLS_HTML_O_cols "=" + OString::number(aNames.getLength()) + " " OOO_STRING_SVTOOLS_HTML_O_border "=1"; IncIndent(1); TAG_ON( aStrOut.getStr() ); FontOn(); TAG_ON( OOO_STRING_SVTOOLS_HTML_caption ); TAG_ON( OOO_STRING_SVTOOLS_HTML_bold ); m_pStream->WriteOString( OUStringToOString(m_sName, osl_getThreadTextEncoding()) ); // TODO : think about the encoding of the name TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold ); TAG_OFF( OOO_STRING_SVTOOLS_HTML_caption ); FontOff(); OUT_LF(); // IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_thead ); IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow ); if(m_xObject.is()) { std::unique_ptr pFormat(new sal_Int32[aNames.getLength()]); std::unique_ptr pHorJustify(new const char*[aNames.getLength()]); std::unique_ptr pColWidth(new sal_Int32[aNames.getLength()]); sal_Int32 nHeight = 0; m_xObject->getPropertyValue(PROPERTY_ROW_HEIGHT) >>= nHeight; // 1. writing the column description const OUString* pIter = aNames.getConstArray(); const OUString* pEnd = pIter + aNames.getLength(); for( sal_Int32 i=0;pIter != pEnd; ++pIter,++i ) { sal_Int32 nAlign = 0; pFormat[i] = 0; pColWidth[i] = 100; if ( !bUseResultMetaData ) { Reference xColumn; xColumns->getByName(*pIter) >>= xColumn; xColumn->getPropertyValue(PROPERTY_ALIGN) >>= nAlign; pFormat[i] = ::comphelper::getINT32(xColumn->getPropertyValue(PROPERTY_FORMATKEY)); pColWidth[i] = ::comphelper::getINT32(xColumn->getPropertyValue(PROPERTY_WIDTH)); } switch( nAlign ) { case 1: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_center; break; case 2: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_right; break; default: pHorJustify[i] = OOO_STRING_SVTOOLS_HTML_AL_left; break; } if(i == aNames.getLength()-1) IncIndent(-1); WriteCell(pFormat[i],pColWidth[i],nHeight,pHorJustify[i],*pIter,OOO_STRING_SVTOOLS_HTML_tableheader); } IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_thead ); IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody ); // 2. and now the data Reference< XRowSet > xRowSet(m_xRow,UNO_QUERY); sal_Int32 kk=0; m_xResultSet->beforeFirst(); // set back before the first row while(m_xResultSet->next()) { IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tablerow ); ++kk; for(sal_Int32 i=1;i<=aNames.getLength();++i) { if(i == aNames.getLength()) IncIndent(-1); OUString aValue; try { Reference xColumn(m_xRowSetColumns->getByIndex(i-1),UNO_QUERY_THROW); dbtools::FormattedColumnValue aFormatedValue(m_xContext,xRowSet,xColumn); OUString sValue = aFormatedValue.getFormattedValue(); if (!sValue.isEmpty()) { aValue = sValue; } } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION("dbaccess"); } WriteCell(pFormat[i-1],pColWidth[i-1],nHeight,pHorJustify[i-1],aValue,OOO_STRING_SVTOOLS_HTML_tabledata); } TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow ); } } else { IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tablerow ); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_thead ); IncIndent(1); TAG_ON_LF( OOO_STRING_SVTOOLS_HTML_tbody ); } IncIndent(-1); OUT_LF(); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_tbody ); IncIndent(-1); TAG_OFF_LF( OOO_STRING_SVTOOLS_HTML_table ); } void OHTMLImportExport::WriteCell( sal_Int32 nFormat, sal_Int32 nWidthPixel, sal_Int32 nHeightPixel, const char* pChar, const OUString& rValue, const char* pHtmlTag) { OString aStrTD = pHtmlTag; nWidthPixel = nWidthPixel ? nWidthPixel : 86; nHeightPixel = nHeightPixel ? nHeightPixel : 17; // despite the and designation necessary, // as Netscape is not paying attention to them. // column width aStrTD += " " OOO_STRING_SVTOOLS_HTML_O_width "=" + OString::number(nWidthPixel) + // line height " " OOO_STRING_SVTOOLS_HTML_O_height "=" + OString::number(nHeightPixel) + " " OOO_STRING_SVTOOLS_HTML_O_align "=" + pChar; SvNumberFormatsSupplierObj* pSupplierImpl = m_xFormatter.is() ? comphelper::getUnoTunnelImplementation(m_xFormatter->getNumberFormatsSupplier()) : nullptr; SvNumberFormatter* pFormatter = pSupplierImpl ? pSupplierImpl->GetNumberFormatter() : nullptr; if(pFormatter) { double fVal = 0.0; try { fVal = m_xFormatter->convertStringToNumber(nFormat,rValue); HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal,nFormat, *pFormatter); } catch(const Exception&) { HTMLOutFuncs::CreateTableDataOptionsValNum(false, fVal,nFormat, *pFormatter); } } TAG_ON( aStrTD.getStr() ); FontOn(); bool bBold = ( css::awt::FontWeight::BOLD == m_aFont.Weight ); bool bItalic = ( css::awt::FontSlant_ITALIC == m_aFont.Slant ); bool bUnderline = ( css::awt::FontUnderline::NONE != m_aFont.Underline ); bool bStrikeout = ( css::awt::FontStrikeout::NONE != m_aFont.Strikeout ); if ( bBold ) TAG_ON( OOO_STRING_SVTOOLS_HTML_bold ); if ( bItalic ) TAG_ON( OOO_STRING_SVTOOLS_HTML_italic ); if ( bUnderline ) TAG_ON( OOO_STRING_SVTOOLS_HTML_underline ); if ( bStrikeout ) TAG_ON( OOO_STRING_SVTOOLS_HTML_strike ); if ( rValue.isEmpty() ) TAG_ON( OOO_STRING_SVTOOLS_HTML_linebreak ); // no completely empty cell else HTMLOutFuncs::Out_String( (*m_pStream), rValue ,m_eDestEnc); if ( bStrikeout ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_strike ); if ( bUnderline ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_underline ); if ( bItalic ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_italic ); if ( bBold ) TAG_OFF( OOO_STRING_SVTOOLS_HTML_bold ); FontOff(); TAG_OFF_LF( pHtmlTag ); } void OHTMLImportExport::FontOn() { #if OSL_DEBUG_LEVEL > 0 m_bCheckFont = true; #endif // OString aStrOut = "<" OOO_STRING_SVTOOLS_HTML_font " " OOO_STRING_SVTOOLS_HTML_O_face "=" "\"" + OUStringToOString(m_aFont.Name,osl_getThreadTextEncoding()) + // TODO : think about the encoding of the font name "\"" " " OOO_STRING_SVTOOLS_HTML_O_color "="; m_pStream->WriteOString( aStrOut ); ::Color aColor; if(m_xObject.is()) m_xObject->getPropertyValue(PROPERTY_TEXTCOLOR) >>= aColor; HTMLOutFuncs::Out_Color( (*m_pStream), aColor ); m_pStream->WriteCharPtr( ">" ); } inline void OHTMLImportExport::FontOff() { #if OSL_DEBUG_LEVEL > 0 OSL_ENSURE(m_bCheckFont,"No FontOn() called"); #endif TAG_OFF( OOO_STRING_SVTOOLS_HTML_font ); #if OSL_DEBUG_LEVEL > 0 m_bCheckFont = false; #endif } void OHTMLImportExport::IncIndent( sal_Int16 nVal ) { sIndent[m_nIndent] = '\t'; m_nIndent = m_nIndent + nVal; if ( m_nIndent < 0 ) m_nIndent = 0; else if ( m_nIndent > nIndentMax ) m_nIndent = nIndentMax; sIndent[m_nIndent] = 0; } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */