1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20 #include <scitems.hxx>
21
22 #include <editeng/wghtitem.hxx>
23 #include <editeng/postitem.hxx>
24 #include <editeng/udlnitem.hxx>
25 #include <editeng/justifyitem.hxx>
26 #include <svtools/rtfout.hxx>
27 #include <svtools/rtfkeywd.hxx>
28 #include <tools/stream.hxx>
29
30 #include <rtfexp.hxx>
31 #include <cellvalue.hxx>
32 #include <document.hxx>
33 #include <patattr.hxx>
34 #include <attrib.hxx>
35 #include <cellform.hxx>
36 #include <editutil.hxx>
37 #include <ftools.hxx>
38
ScExportRTF(SvStream & rStrm,ScDocument * pDoc,const ScRange & rRange,const rtl_TextEncoding)39 void ScFormatFilterPluginImpl::ScExportRTF( SvStream& rStrm, ScDocument* pDoc,
40 const ScRange& rRange, const rtl_TextEncoding /*eNach*/ )
41 {
42 ScRTFExport aEx( rStrm, pDoc, rRange );
43 aEx.Write();
44 }
45
ScRTFExport(SvStream & rStrmP,ScDocument * pDocP,const ScRange & rRangeP)46 ScRTFExport::ScRTFExport( SvStream& rStrmP, ScDocument* pDocP, const ScRange& rRangeP )
47 :
48 ScExportBase( rStrmP, pDocP, rRangeP ),
49 pCellX( new sal_uLong[ pDoc->MaxCol()+2 ] )
50 {
51 }
52
~ScRTFExport()53 ScRTFExport::~ScRTFExport()
54 {
55 }
56
Write()57 void ScRTFExport::Write()
58 {
59 rStrm.WriteChar( '{' ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_RTF );
60 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ANSI ).WriteCharPtr( SAL_NEWLINE_STRING );
61
62 // Data
63 for ( SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); nTab++ )
64 {
65 if ( nTab > aRange.aStart.Tab() )
66 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PAR );
67 WriteTab( nTab );
68 }
69
70 rStrm.WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
71 }
72
WriteTab(SCTAB nTab)73 void ScRTFExport::WriteTab( SCTAB nTab )
74 {
75 rStrm.WriteChar( '{' ).WriteCharPtr( SAL_NEWLINE_STRING );
76 if ( pDoc->HasTable( nTab ) )
77 {
78 memset( &pCellX[0], 0, (pDoc->MaxCol()+2) * sizeof(sal_uLong) );
79 SCCOL nCol;
80 SCCOL nEndCol = aRange.aEnd.Col();
81 for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
82 {
83 pCellX[nCol+1] = pCellX[nCol] + pDoc->GetColWidth( nCol, nTab );
84 }
85
86 SCROW nEndRow = aRange.aEnd.Row();
87 for ( SCROW nRow = aRange.aStart.Row(); nRow <= nEndRow; nRow++ )
88 {
89 WriteRow( nTab, nRow );
90 }
91 }
92 rStrm.WriteChar( '}' ).WriteCharPtr( SAL_NEWLINE_STRING );
93 }
94
WriteRow(SCTAB nTab,SCROW nRow)95 void ScRTFExport::WriteRow( SCTAB nTab, SCROW nRow )
96 {
97 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TROWD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRGAPH ).WriteCharPtr( "30" ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRLEFT ).WriteCharPtr( "-30" );
98 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_TRRH ).WriteOString( OString::number(pDoc->GetRowHeight(nRow, nTab)) );
99 SCCOL nCol;
100 SCCOL nEndCol = aRange.aEnd.Col();
101 for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
102 {
103 const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
104 const ScMergeAttr& rMergeAttr = pAttr->GetItem( ATTR_MERGE );
105 const SvxVerJustifyItem& rVerJustifyItem= pAttr->GetItem( ATTR_VER_JUSTIFY );
106
107 const char* pChar;
108
109 if ( rMergeAttr.GetColMerge() != 0 )
110 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CLMGF );
111 else
112 {
113 const ScMergeFlagAttr& rMergeFlagAttr = pAttr->GetItem( ATTR_MERGE_FLAG );
114 if ( rMergeFlagAttr.IsHorOverlapped() )
115 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CLMRG );
116 }
117
118 switch( rVerJustifyItem.GetValue() )
119 {
120 case SvxCellVerJustify::Top: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALT; break;
121 case SvxCellVerJustify::Center: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALC; break;
122 case SvxCellVerJustify::Bottom: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break;
123 case SvxCellVerJustify::Standard: pChar = OOO_STRING_SVTOOLS_RTF_CLVERTALB; break; //! Bottom
124 default: pChar = nullptr; break;
125 }
126 if ( pChar )
127 rStrm.WriteCharPtr( pChar );
128
129 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELLX ).WriteOString( OString::number(pCellX[nCol+1]) );
130 if ( (nCol & 0x0F) == 0x0F )
131 rStrm.WriteCharPtr( SAL_NEWLINE_STRING ); // Do not let lines get too long
132 }
133 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PARD ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PLAIN ).WriteCharPtr( OOO_STRING_SVTOOLS_RTF_INTBL ).WriteCharPtr( SAL_NEWLINE_STRING );
134
135 sal_uLong nStrmPos = rStrm.Tell();
136 for ( nCol = aRange.aStart.Col(); nCol <= nEndCol; nCol++ )
137 {
138 WriteCell( nTab, nRow, nCol );
139 if ( rStrm.Tell() - nStrmPos > 255 )
140 { // Do not let lines get too long
141 rStrm.WriteCharPtr( SAL_NEWLINE_STRING );
142 nStrmPos = rStrm.Tell();
143 }
144 }
145 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_ROW ).WriteCharPtr( SAL_NEWLINE_STRING );
146 }
147
WriteCell(SCTAB nTab,SCROW nRow,SCCOL nCol)148 void ScRTFExport::WriteCell( SCTAB nTab, SCROW nRow, SCCOL nCol )
149 {
150 const ScPatternAttr* pAttr = pDoc->GetPattern( nCol, nRow, nTab );
151
152 const ScMergeFlagAttr& rMergeFlagAttr = pAttr->GetItem( ATTR_MERGE_FLAG );
153 if ( rMergeFlagAttr.IsHorOverlapped() )
154 {
155 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL );
156 return ;
157 }
158
159 bool bValueData = false;
160 OUString aContent;
161 ScAddress aPos(nCol, nRow, nTab);
162 ScRefCellValue aCell(*pDoc, aPos);
163 switch (aCell.meType)
164 {
165 case CELLTYPE_NONE:
166 bValueData = false;
167 break;
168 case CELLTYPE_EDIT:
169 {
170 bValueData = false;
171 const EditTextObject* pObj = aCell.mpEditText;
172 EditEngine& rEngine = GetEditEngine();
173 rEngine.SetText(*pObj);
174 aContent = rEngine.GetText(); // LineFeed in between paragraphs!
175 }
176 break;
177 default:
178 {
179 bValueData = pDoc->HasValueData(aPos);
180 sal_uInt32 nFormat = pAttr->GetNumberFormat(pFormatter);
181 const Color* pColor;
182 aContent = ScCellFormat::GetString(*pDoc, aPos, nFormat, &pColor, *pFormatter);
183 }
184 }
185
186 bool bResetAttr(false);
187
188 const SvxHorJustifyItem& rHorJustifyItem = pAttr->GetItem( ATTR_HOR_JUSTIFY );
189 const SvxWeightItem& rWeightItem = pAttr->GetItem( ATTR_FONT_WEIGHT );
190 const SvxPostureItem& rPostureItem = pAttr->GetItem( ATTR_FONT_POSTURE );
191 const SvxUnderlineItem& rUnderlineItem = pAttr->GetItem( ATTR_FONT_UNDERLINE );
192
193 const char* pChar;
194
195 switch( rHorJustifyItem.GetValue() )
196 {
197 case SvxCellHorJustify::Standard:
198 pChar = (bValueData ? OOO_STRING_SVTOOLS_RTF_QR : OOO_STRING_SVTOOLS_RTF_QL);
199 break;
200 case SvxCellHorJustify::Center: pChar = OOO_STRING_SVTOOLS_RTF_QC; break;
201 case SvxCellHorJustify::Block: pChar = OOO_STRING_SVTOOLS_RTF_QJ; break;
202 case SvxCellHorJustify::Right: pChar = OOO_STRING_SVTOOLS_RTF_QR; break;
203 case SvxCellHorJustify::Left:
204 case SvxCellHorJustify::Repeat:
205 default: pChar = OOO_STRING_SVTOOLS_RTF_QL; break;
206 }
207 rStrm.WriteCharPtr( pChar );
208
209 if ( rWeightItem.GetWeight() >= WEIGHT_BOLD )
210 { // bold
211 bResetAttr = true;
212 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_B );
213 }
214 if ( rPostureItem.GetPosture() != ITALIC_NONE )
215 { // italic
216 bResetAttr = true;
217 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_I );
218 }
219 if ( rUnderlineItem.GetLineStyle() != LINESTYLE_NONE )
220 { // underline
221 bResetAttr = true;
222 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_UL );
223 }
224
225 rStrm.WriteChar( ' ' );
226 RTFOutFuncs::Out_String( rStrm, aContent );
227 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_CELL );
228
229 if ( bResetAttr )
230 rStrm.WriteCharPtr( OOO_STRING_SVTOOLS_RTF_PLAIN );
231 }
232
233 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
234