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