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