Line data Source code
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 <com/sun/star/style/NumberingType.hpp>
21 : #include <hintids.hxx>
22 : #include <svtools/htmltokn.h>
23 : #include <svtools/htmlkywd.hxx>
24 : #include <svtools/htmlout.hxx>
25 : #include <svl/urihelper.hxx>
26 : #include <editeng/brushitem.hxx>
27 : #include <editeng/lrspitem.hxx>
28 : #include <vcl/svapp.hxx>
29 : #include <vcl/wrkwin.hxx>
30 : #include <numrule.hxx>
31 : #include <doc.hxx>
32 : #include <docary.hxx>
33 : #include <poolfmt.hxx>
34 : #include <ndtxt.hxx>
35 : #include <paratr.hxx>
36 :
37 : #include "htmlnum.hxx"
38 : #include "wrthtml.hxx"
39 :
40 : #include <SwNodeNum.hxx>
41 : #include <rtl/strbuf.hxx>
42 :
43 : using namespace css;
44 :
45 :
46 0 : void SwHTMLWriter::FillNextNumInfo()
47 : {
48 0 : pNextNumRuleInfo = 0;
49 :
50 0 : sal_uLong nPos = pCurPam->GetPoint()->nNode.GetIndex() + 1;
51 :
52 0 : bool bTable = false;
53 0 : do
54 : {
55 0 : const SwNode* pNd = pDoc->GetNodes()[nPos];
56 0 : if( pNd->IsTextNode() )
57 : {
58 : // Der naechste wird als naechstes ausgegeben.
59 0 : pNextNumRuleInfo = new SwHTMLNumRuleInfo( *pNd->GetTextNode() );
60 :
61 : // Vor einer Tabelle behalten wir erst einmal die alte Ebene bei,
62 : // wenn die gleiche Numerierung hinter der Tabelle
63 : // fortgesetzt wird und dort nicht von vorne numeriert
64 : // wird. Die Tabelle wird ann beim Import so weit eingeruckt,
65 : // wie es der Num-Ebene entspricht.
66 0 : if( bTable &&
67 0 : pNextNumRuleInfo->GetNumRule()==GetNumInfo().GetNumRule() &&
68 0 : !pNextNumRuleInfo->IsRestart() )
69 : {
70 0 : pNextNumRuleInfo->SetDepth( GetNumInfo().GetDepth() );
71 : }
72 : }
73 0 : else if( pNd->IsTableNode() )
74 : {
75 : // Eine Tabelle wird uebersprungen, also den Node
76 : // hinter der Tabelle betrachten.
77 0 : nPos = pNd->EndOfSectionIndex() + 1;
78 0 : bTable = true;
79 : }
80 : else
81 : {
82 : // In allen anderen Faellen ist die Numerierung erstmal
83 : // zu Ende.
84 0 : pNextNumRuleInfo = new SwHTMLNumRuleInfo;
85 : }
86 : }
87 0 : while( !pNextNumRuleInfo );
88 0 : }
89 :
90 15 : void SwHTMLWriter::ClearNextNumInfo()
91 : {
92 15 : delete pNextNumRuleInfo;
93 15 : pNextNumRuleInfo = 0;
94 15 : }
95 :
96 0 : Writer& OutHTML_NumBulListStart( SwHTMLWriter& rWrt,
97 : const SwHTMLNumRuleInfo& rInfo )
98 : {
99 0 : SwHTMLNumRuleInfo& rPrevInfo = rWrt.GetNumInfo();
100 0 : bool bSameRule = rPrevInfo.GetNumRule() == rInfo.GetNumRule();
101 0 : if( bSameRule && rPrevInfo.GetDepth() >= rInfo.GetDepth() &&
102 0 : !rInfo.IsRestart() )
103 : {
104 0 : return rWrt;
105 : }
106 :
107 0 : bool bStartValue = false;
108 0 : if( !bSameRule && rInfo.GetDepth() )
109 : {
110 0 : OUString aName( rInfo.GetNumRule()->GetName() );
111 0 : if( 0 != rWrt.aNumRuleNames.count( aName ) )
112 : {
113 : // The rule has been applied before
114 : sal_Int16 eType = rInfo.GetNumRule()
115 0 : ->Get( rInfo.GetDepth()-1 ).GetNumberingType();
116 0 : if( SVX_NUM_CHAR_SPECIAL != eType && SVX_NUM_BITMAP != eType )
117 : {
118 : // If it's a numbering rule, the current number should be
119 : // exported as start value, but only if there are no nodes
120 : // within the numbering that have a lower level
121 0 : bStartValue = true;
122 0 : if( rInfo.GetDepth() > 1 )
123 : {
124 : sal_uLong nPos =
125 0 : rWrt.pCurPam->GetPoint()->nNode.GetIndex() + 1;
126 : do
127 : {
128 0 : const SwNode* pNd = rWrt.pDoc->GetNodes()[nPos];
129 0 : if( pNd->IsTextNode() )
130 : {
131 0 : const SwTextNode *pTextNd = pNd->GetTextNode();
132 0 : if( !pTextNd->GetNumRule() )
133 : {
134 : // node isn't numbered => check completed
135 0 : break;
136 : }
137 :
138 : OSL_ENSURE(! pTextNd->IsOutline(),
139 : "outline not expected");
140 :
141 0 : if( pTextNd->GetActualListLevel() + 1 <
142 0 : rInfo.GetDepth() )
143 : {
144 : // node is numbered, but level is lower
145 : // => check completed
146 0 : bStartValue = false;
147 0 : break;
148 : }
149 0 : nPos++;
150 : }
151 0 : else if( pNd->IsTableNode() )
152 : {
153 : // skip table
154 0 : nPos = pNd->EndOfSectionIndex() + 1;
155 : }
156 : else
157 : {
158 : // end node or sections start node -> check
159 : // completed
160 0 : break;
161 : }
162 : }
163 0 : while( true );
164 : }
165 : }
166 : }
167 : else
168 : {
169 0 : rWrt.aNumRuleNames.insert( aName );
170 0 : }
171 : }
172 :
173 : OSL_ENSURE( rWrt.nLastParaToken == 0,
174 : "<PRE> wurde nicht vor <OL> beendet." );
175 : sal_uInt16 nPrevDepth =
176 0 : (bSameRule && !rInfo.IsRestart()) ? rPrevInfo.GetDepth() : 0;
177 :
178 0 : for( sal_uInt16 i=nPrevDepth; i<rInfo.GetDepth(); i++ )
179 : {
180 0 : rWrt.OutNewLine(); // <OL>/<UL> in eine neue Zeile
181 :
182 0 : rWrt.aBulletGrfs[i].clear();
183 0 : OStringBuffer sOut;
184 0 : sOut.append('<');
185 0 : const SwNumFormat& rNumFormat = rInfo.GetNumRule()->Get( i );
186 0 : sal_Int16 eType = rNumFormat.GetNumberingType();
187 0 : if( SVX_NUM_CHAR_SPECIAL == eType )
188 : {
189 : // Aufzaehlungs-Liste: <OL>
190 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_unorderlist);
191 :
192 : // den Typ ueber das Bullet-Zeichen bestimmen
193 0 : const sal_Char *pStr = 0;
194 0 : switch( rNumFormat.GetBulletChar() )
195 : {
196 : case HTML_BULLETCHAR_DISC:
197 0 : pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_disc;
198 0 : break;
199 : case HTML_BULLETCHAR_CIRCLE:
200 0 : pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_circle;
201 0 : break;
202 : case HTML_BULLETCHAR_SQUARE:
203 0 : pStr = OOO_STRING_SVTOOLS_HTML_ULTYPE_square;
204 0 : break;
205 : }
206 :
207 0 : if( pStr )
208 : {
209 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_type).
210 0 : append("=\"").append(pStr).append("\"");
211 : }
212 : }
213 0 : else if( SVX_NUM_BITMAP == eType )
214 : {
215 : // Unordered list: <UL>
216 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_unorderlist);
217 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
218 : OutHTML_BulletImage( rWrt,
219 : 0,
220 0 : rNumFormat.GetBrush() );
221 : }
222 : else
223 : {
224 : // Ordered list: <OL>
225 0 : sOut.append(OOO_STRING_SVTOOLS_HTML_orderlist);
226 :
227 : // den Typ ueber das Format bestimmen
228 0 : sal_Char cType = 0;
229 0 : switch( eType )
230 : {
231 : case SVX_NUM_CHARS_UPPER_LETTER:
232 : case SVX_NUM_CHARS_UPPER_LETTER_N:
233 0 : cType = 'A';
234 0 : break;
235 : case SVX_NUM_CHARS_LOWER_LETTER:
236 : case SVX_NUM_CHARS_LOWER_LETTER_N:
237 0 : cType = 'a';
238 0 : break;
239 : case SVX_NUM_ROMAN_UPPER:
240 0 : cType = 'I';
241 0 : break;
242 : case SVX_NUM_ROMAN_LOWER:
243 0 : cType = 'i';
244 0 : break;
245 : }
246 0 : if( cType )
247 : {
248 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_type).
249 0 : append("=\"").append(cType).append("\"");
250 : }
251 :
252 0 : sal_uInt16 nStartVal = rNumFormat.GetStart();
253 0 : if( bStartValue && 1 == nStartVal && i == rInfo.GetDepth()-1 )
254 : {
255 : // #i51089 - TUNING#
256 0 : if ( rWrt.pCurPam->GetNode().GetTextNode()->GetNum() )
257 : {
258 0 : nStartVal = static_cast< sal_uInt16 >( rWrt.pCurPam->GetNode()
259 0 : .GetTextNode()->GetNumberVector()[i] );
260 : }
261 : else
262 : {
263 : OSL_FAIL( "<OutHTML_NumBulListStart(..) - text node has no number." );
264 : }
265 : }
266 0 : if( nStartVal != 1 )
267 : {
268 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_start).
269 0 : append("=\"").append(static_cast<sal_Int32>(nStartVal)).append("\"");
270 : }
271 : }
272 :
273 0 : if (!sOut.isEmpty())
274 0 : rWrt.Strm().WriteCharPtr( sOut.makeStringAndClear().getStr() );
275 :
276 0 : if( rWrt.bCfgOutStyles )
277 0 : OutCSS1_NumBulListStyleOpt( rWrt, *rInfo.GetNumRule(), (sal_uInt8)i );
278 :
279 0 : rWrt.Strm().WriteChar( '>' );
280 :
281 0 : rWrt.IncIndentLevel(); // Inhalt von <OL> einruecken
282 0 : }
283 :
284 0 : return rWrt;
285 : }
286 :
287 0 : Writer& OutHTML_NumBulListEnd( SwHTMLWriter& rWrt,
288 : const SwHTMLNumRuleInfo& rNextInfo )
289 : {
290 0 : SwHTMLNumRuleInfo& rInfo = rWrt.GetNumInfo();
291 0 : bool bSameRule = rNextInfo.GetNumRule() == rInfo.GetNumRule();
292 0 : if( bSameRule && rNextInfo.GetDepth() >= rInfo.GetDepth() &&
293 0 : !rNextInfo.IsRestart() )
294 : {
295 0 : return rWrt;
296 : }
297 :
298 : OSL_ENSURE( rWrt.nLastParaToken == 0,
299 : "<PRE> wurde nicht vor </OL> beendet." );
300 : sal_uInt16 nNextDepth =
301 0 : (bSameRule && !rNextInfo.IsRestart()) ? rNextInfo.GetDepth() : 0;
302 :
303 : // MIB 23.7.97: Die Schleife muss doch rueckwaerts durchlaufen
304 : // werden, weil die Reihenfolge von </OL>/</UL> stimmen muss
305 0 : for( sal_uInt16 i=rInfo.GetDepth(); i>nNextDepth; i-- )
306 : {
307 0 : rWrt.DecIndentLevel(); // Inhalt von <OL> einruecken
308 0 : if( rWrt.bLFPossible )
309 0 : rWrt.OutNewLine(); // </OL>/</UL> in eine neue Zeile
310 :
311 : // es wird also eine Liste angefangen oder beendet:
312 0 : sal_Int16 eType = rInfo.GetNumRule()->Get( i-1 ).GetNumberingType();
313 : const sal_Char *pStr;
314 0 : if( SVX_NUM_CHAR_SPECIAL == eType || SVX_NUM_BITMAP == eType)
315 0 : pStr = OOO_STRING_SVTOOLS_HTML_unorderlist;
316 : else
317 0 : pStr = OOO_STRING_SVTOOLS_HTML_orderlist;
318 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), pStr, false );
319 0 : rWrt.bLFPossible = true;
320 : }
321 :
322 0 : return rWrt;
323 177 : }
324 :
325 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|