1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <vector>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <com/sun/star/table/XTable.hpp>
30cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <tools/stream.hxx>
33cdf0e10cSrcweir #include <svtools/rtfkeywd.hxx>
34cdf0e10cSrcweir #include <svtools/rtfout.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include <editeng/eeitem.hxx>
37cdf0e10cSrcweir #include <svx/sdtaitm.hxx>
38cdf0e10cSrcweir #include <editeng/wghtitem.hxx>
39cdf0e10cSrcweir #include <editeng/postitem.hxx>
40cdf0e10cSrcweir #include <editeng/udlnitem.hxx>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include "cell.hxx"
43cdf0e10cSrcweir #include "celltypes.hxx"
44cdf0e10cSrcweir #include "svx/svdotable.hxx"
45cdf0e10cSrcweir #include "svx/svdoutl.hxx"
46cdf0e10cSrcweir #include "editeng/editeng.hxx"
47cdf0e10cSrcweir #include "editeng/outlobj.hxx"
48cdf0e10cSrcweir 
49cdf0e10cSrcweir //#include <tablertfexporter.hxx>
50cdf0e10cSrcweir 
51cdf0e10cSrcweir using ::rtl::OUString;
52cdf0e10cSrcweir using namespace ::com::sun::star::uno;
53cdf0e10cSrcweir using namespace ::com::sun::star::table;
54cdf0e10cSrcweir using namespace ::com::sun::star::container;
55cdf0e10cSrcweir using namespace ::com::sun::star::beans;
56cdf0e10cSrcweir 
57cdf0e10cSrcweir namespace sdr { namespace table {
58cdf0e10cSrcweir 
59cdf0e10cSrcweir class SdrTableRtfExporter
60cdf0e10cSrcweir {
61cdf0e10cSrcweir public:
62cdf0e10cSrcweir 	SdrTableRtfExporter( SvStream& rStrmP, SdrTableObj& rObj );
63cdf0e10cSrcweir 	sal_uLong Write();
64cdf0e10cSrcweir 	void WriteRow( const Reference< XPropertySet >& xRowSet, sal_Int32 nRow, const std::vector< sal_Int32 >& aColumnStart );
65cdf0e10cSrcweir 	void WriteCell( sal_Int32 nCol, sal_Int32 nRow );
66cdf0e10cSrcweir 
67cdf0e10cSrcweir private:
68cdf0e10cSrcweir 	SvStream& mrStrm;
69cdf0e10cSrcweir 	SdrTableObj& mrObj;
70cdf0e10cSrcweir 	Reference< XTable > mxTable;
71cdf0e10cSrcweir 	const OUString msSize;
72cdf0e10cSrcweir };
73cdf0e10cSrcweir 
ExportAsRTF(SvStream & rStrm,SdrTableObj & rObj)74cdf0e10cSrcweir void SdrTableObj::ExportAsRTF( SvStream& rStrm, SdrTableObj& rObj )
75cdf0e10cSrcweir {
76cdf0e10cSrcweir 	SdrTableRtfExporter aEx( rStrm, rObj );
77cdf0e10cSrcweir 	aEx.Write();
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
SdrTableRtfExporter(SvStream & rStrm,SdrTableObj & rObj)80cdf0e10cSrcweir SdrTableRtfExporter::SdrTableRtfExporter( SvStream& rStrm, SdrTableObj& rObj )
81cdf0e10cSrcweir : mrStrm( rStrm )
82cdf0e10cSrcweir , mrObj( rObj )
83cdf0e10cSrcweir , mxTable( rObj.getTable() )
84cdf0e10cSrcweir , msSize( RTL_CONSTASCII_USTRINGPARAM("Size") )
85cdf0e10cSrcweir {
86cdf0e10cSrcweir }
87cdf0e10cSrcweir 
HundMMToTwips(long nIn)88cdf0e10cSrcweir long HundMMToTwips( long nIn )
89cdf0e10cSrcweir {
90cdf0e10cSrcweir 	long nRet = OutputDevice::LogicToLogic( nIn, MAP_100TH_MM, MAP_TWIP );
91cdf0e10cSrcweir 	return nRet;
92cdf0e10cSrcweir }
93cdf0e10cSrcweir 
Write()94cdf0e10cSrcweir sal_uLong SdrTableRtfExporter::Write()
95cdf0e10cSrcweir {
96cdf0e10cSrcweir 	mrStrm << '{' << OOO_STRING_SVTOOLS_RTF_RTF;
97cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_ANSI << RTFOutFuncs::sNewLine;
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 	Reference< XTableColumns > xColumns( mxTable->getColumns() );
100cdf0e10cSrcweir 	const sal_Int32 nColCount = xColumns->getCount();
101cdf0e10cSrcweir 
102cdf0e10cSrcweir 	std::vector< sal_Int32 > aColumnStart;
103cdf0e10cSrcweir 	aColumnStart.reserve( nColCount );
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 	// determine right offset of cells
106cdf0e10cSrcweir 	sal_Int32 nPos = 0;
107cdf0e10cSrcweir 	for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ ) try
108cdf0e10cSrcweir 	{
109cdf0e10cSrcweir 		Reference< XPropertySet > xSet( xColumns->getByIndex(nCol), UNO_QUERY_THROW );
110cdf0e10cSrcweir 		sal_Int32 nWidth = 0;
111cdf0e10cSrcweir 		xSet->getPropertyValue( msSize ) >>= nWidth;
112cdf0e10cSrcweir 		nPos += HundMMToTwips( nWidth );
113cdf0e10cSrcweir 		aColumnStart.push_back( nPos );
114cdf0e10cSrcweir 	}
115cdf0e10cSrcweir 	catch( Exception& e )
116cdf0e10cSrcweir 	{
117cdf0e10cSrcweir 		(void)e;
118cdf0e10cSrcweir 		DBG_ERROR("SdrTableRtfExporter::Write(), exception caught!");
119cdf0e10cSrcweir 	}
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	// export rows
122cdf0e10cSrcweir 	Reference< XTableRows > xRows( mxTable->getRows() );
123cdf0e10cSrcweir 	const sal_Int32 nRowCount = xRows->getCount();
124cdf0e10cSrcweir 
125cdf0e10cSrcweir 	for( sal_Int32 nRow = 0; nRow < nRowCount; nRow++ ) try
126cdf0e10cSrcweir 	{
127cdf0e10cSrcweir 		Reference< XPropertySet > xRowSet( xRows->getByIndex(nRow), UNO_QUERY_THROW );
128cdf0e10cSrcweir 		WriteRow( xRowSet, nRow, aColumnStart );
129cdf0e10cSrcweir 	}
130cdf0e10cSrcweir 	catch( Exception& e )
131cdf0e10cSrcweir 	{
132cdf0e10cSrcweir 		(void)e;
133cdf0e10cSrcweir 		DBG_ERROR("SdrTableRtfExporter::Write(), exception caught!");
134cdf0e10cSrcweir 	}
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 	mrStrm << '}' << RTFOutFuncs::sNewLine;
137cdf0e10cSrcweir 	return mrStrm.GetError();
138cdf0e10cSrcweir }
139cdf0e10cSrcweir 
WriteRow(const Reference<XPropertySet> & xRowSet,sal_Int32 nRow,const std::vector<sal_Int32> & aColumnStart)140cdf0e10cSrcweir void SdrTableRtfExporter::WriteRow( const Reference< XPropertySet >& xRowSet, sal_Int32 nRow, const std::vector< sal_Int32 >& aColumnStart )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir 	sal_Int32 nRowHeight = 0;
143cdf0e10cSrcweir 	xRowSet->getPropertyValue( msSize ) >>= nRowHeight;
144cdf0e10cSrcweir 
145cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_TROWD << OOO_STRING_SVTOOLS_RTF_TRGAPH << "30" << OOO_STRING_SVTOOLS_RTF_TRLEFT << "-30";
146cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_TRRH << ByteString::CreateFromInt32( nRowHeight ).GetBuffer();
147cdf0e10cSrcweir 
148cdf0e10cSrcweir 	const sal_Int32 nColCount = mxTable->getColumnCount();
149cdf0e10cSrcweir 	for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
150cdf0e10cSrcweir 	{
151cdf0e10cSrcweir 		CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 		if( !xCell.is() )
154cdf0e10cSrcweir 			continue;
155cdf0e10cSrcweir 
156cdf0e10cSrcweir /*
157cdf0e10cSrcweir 		const sal_Bool bIsMerged = xCell->isMerged();
158cdf0e10cSrcweir 		const sal_Int32 nRowSpan = xCell->getRowSpan();
159cdf0e10cSrcweir 		const sal_Int32 nColSpan = xCell->getColumnSpan();
160cdf0e10cSrcweir 
161cdf0e10cSrcweir 		const sal_Char* pChar;
162cdf0e10cSrcweir 
163cdf0e10cSrcweir 		if( !bIsMerged && ((nRowSpan > 1) || (nColSpan > 1)) )
164cdf0e10cSrcweir 			mrStrm << OOO_STRING_SVTOOLS_RTF_CLMGF; // The first cell in a range of table cells to be merged.
165cdf0e10cSrcweir 
166cdf0e10cSrcweir 		SdrTextVertAdjust eVAdj = xCell->GetTextVerticalAdjust();
167cdf0e10cSrcweir 		switch( eVAdj )
168cdf0e10cSrcweir 		{
169cdf0e10cSrcweir 			case SVX_VER_JUSTIFY_TOP:		pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALT;	break;
170cdf0e10cSrcweir 			case SVX_VER_JUSTIFY_CENTER:	pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALC;	break;
171cdf0e10cSrcweir 			case SVX_VER_JUSTIFY_BOTTOM:	pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB;	break;
172cdf0e10cSrcweir 			case SVX_VER_JUSTIFY_STANDARD:	pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB;	break;	//! Bottom
173cdf0e10cSrcweir 			default:						pChar = NULL;			break;
174cdf0e10cSrcweir 		}
175cdf0e10cSrcweir 		if ( pChar )
176cdf0e10cSrcweir 			mrStrm << pChar;
177cdf0e10cSrcweir */
178cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_CELLX << ByteString::CreateFromInt32( aColumnStart[nCol] ).GetBuffer();
179cdf0e10cSrcweir 		if ( (nCol & 0x0F) == 0x0F )
180cdf0e10cSrcweir 			mrStrm << RTFOutFuncs::sNewLine;		// Zeilen nicht zu lang werden lassen
181cdf0e10cSrcweir 	}
182cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN << OOO_STRING_SVTOOLS_RTF_INTBL << RTFOutFuncs::sNewLine;
183cdf0e10cSrcweir 
184cdf0e10cSrcweir 	sal_uLong nStrmPos = mrStrm.Tell();
185cdf0e10cSrcweir 	for( sal_Int32 nCol = 0; nCol < nColCount; nCol++ )
186cdf0e10cSrcweir 	{
187cdf0e10cSrcweir 		WriteCell( nCol, nRow );
188cdf0e10cSrcweir 		if ( mrStrm.Tell() - nStrmPos > 255 )
189cdf0e10cSrcweir 		{
190cdf0e10cSrcweir 			mrStrm << RTFOutFuncs::sNewLine;
191cdf0e10cSrcweir 			nStrmPos = mrStrm.Tell();
192cdf0e10cSrcweir 		}
193cdf0e10cSrcweir 	}
194cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_ROW << RTFOutFuncs::sNewLine;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 
WriteCell(sal_Int32 nCol,sal_Int32 nRow)198cdf0e10cSrcweir void SdrTableRtfExporter::WriteCell( sal_Int32 nCol, sal_Int32 nRow )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir 	CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	if( !xCell.is() || xCell->isMerged() )
203cdf0e10cSrcweir 	{
204cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_CELL;
205cdf0e10cSrcweir 		return ;
206cdf0e10cSrcweir 	}
207cdf0e10cSrcweir 
208cdf0e10cSrcweir 	String aContent;
209cdf0e10cSrcweir 
210cdf0e10cSrcweir 	OutlinerParaObject* pParaObj = xCell->GetEditOutlinerParaObject();
211cdf0e10cSrcweir 	bool bOwnParaObj = pParaObj != 0;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir 	if( pParaObj == 0 )
214cdf0e10cSrcweir 		pParaObj = xCell->GetOutlinerParaObject();
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 	if(pParaObj)
217cdf0e10cSrcweir 	{
218cdf0e10cSrcweir 		// handle outliner attributes
219cdf0e10cSrcweir 		SdrOutliner& rOutliner = mrObj.ImpGetDrawOutliner();
220cdf0e10cSrcweir 		rOutliner.SetText(*pParaObj);
221cdf0e10cSrcweir 
222cdf0e10cSrcweir 		aContent = rOutliner.GetEditEngine().GetText( LINEEND_LF );
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 		rOutliner.Clear();
225cdf0e10cSrcweir 
226cdf0e10cSrcweir         if( bOwnParaObj )
227cdf0e10cSrcweir             delete pParaObj;
228cdf0e10cSrcweir 	}
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	bool bResetPar, bResetAttr;
231cdf0e10cSrcweir 	bResetPar = bResetAttr = sal_False;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	SdrTextHorzAdjust eHAdj = xCell->GetTextHorizontalAdjust();
234cdf0e10cSrcweir 
235cdf0e10cSrcweir 	const SfxItemSet& rCellSet = xCell->GetItemSet();
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 	const SvxWeightItem&		rWeightItem		= (const SvxWeightItem&)    rCellSet.Get( EE_CHAR_WEIGHT );
238cdf0e10cSrcweir 	const SvxPostureItem&		rPostureItem	= (const SvxPostureItem&)   rCellSet.Get( EE_CHAR_ITALIC );
239cdf0e10cSrcweir 	const SvxUnderlineItem&		rUnderlineItem	= (const SvxUnderlineItem&)	rCellSet.Get( EE_CHAR_UNDERLINE );
240cdf0e10cSrcweir 
241cdf0e10cSrcweir 	const sal_Char* pChar;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir 	switch( eHAdj )
244cdf0e10cSrcweir 	{
245cdf0e10cSrcweir 		case SDRTEXTHORZADJUST_CENTER:	pChar = OOO_STRING_SVTOOLS_RTF_QC;	break;
246cdf0e10cSrcweir 		case SDRTEXTHORZADJUST_BLOCK:	pChar = OOO_STRING_SVTOOLS_RTF_QJ;	break;
247cdf0e10cSrcweir 		case SDRTEXTHORZADJUST_RIGHT:	pChar = OOO_STRING_SVTOOLS_RTF_QR;	break;
248cdf0e10cSrcweir 		case SDRTEXTHORZADJUST_LEFT:
249cdf0e10cSrcweir 		default:						pChar = OOO_STRING_SVTOOLS_RTF_QL;	break;
250cdf0e10cSrcweir 	}
251cdf0e10cSrcweir 	mrStrm << pChar;
252cdf0e10cSrcweir 
253cdf0e10cSrcweir 	if ( rWeightItem.GetWeight() >= WEIGHT_BOLD )
254cdf0e10cSrcweir 	{	// bold
255cdf0e10cSrcweir 		bResetAttr = true;
256cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_B;
257cdf0e10cSrcweir 	}
258cdf0e10cSrcweir 	if ( rPostureItem.GetPosture() != ITALIC_NONE )
259cdf0e10cSrcweir 	{	// italic
260cdf0e10cSrcweir 		bResetAttr = true;
261cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_I;
262cdf0e10cSrcweir 	}
263cdf0e10cSrcweir 	if ( rUnderlineItem.GetLineStyle() != UNDERLINE_NONE )
264cdf0e10cSrcweir 	{	// underline
265cdf0e10cSrcweir 		bResetAttr = true;
266cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_UL;
267cdf0e10cSrcweir 	}
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 	mrStrm << ' ';
270cdf0e10cSrcweir 	RTFOutFuncs::Out_String( mrStrm, aContent );
271cdf0e10cSrcweir 	mrStrm << OOO_STRING_SVTOOLS_RTF_CELL;
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 	if ( bResetPar )
274cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_INTBL;
275cdf0e10cSrcweir 	if ( bResetAttr )
276cdf0e10cSrcweir 		mrStrm << OOO_STRING_SVTOOLS_RTF_PLAIN;
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir } }
280cdf0e10cSrcweir 
281