File: | home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchflag.cxx |
Warning: | line 558, column 80 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | |||||
10 | #include "rtfdocumentimpl.hxx" | ||||
11 | |||||
12 | #include <com/sun/star/drawing/XDrawPageSupplier.hpp> | ||||
13 | #include <com/sun/star/drawing/XEnhancedCustomShapeDefaulter.hpp> | ||||
14 | #include <com/sun/star/text/RelOrientation.hpp> | ||||
15 | #include <com/sun/star/text/VertOrientation.hpp> | ||||
16 | #include <com/sun/star/lang/XMultiServiceFactory.hpp> | ||||
17 | |||||
18 | #include <filter/msfilter/escherex.hxx> | ||||
19 | |||||
20 | #include <ooxml/resourceids.hxx> | ||||
21 | |||||
22 | #include <sal/log.hxx> | ||||
23 | |||||
24 | #include "rtfsdrimport.hxx" | ||||
25 | #include "rtfskipdestination.hxx" | ||||
26 | |||||
27 | using namespace com::sun::star; | ||||
28 | |||||
29 | namespace writerfilter::rtftok | ||||
30 | { | ||||
31 | RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) | ||||
32 | { | ||||
33 | setNeedSect(true); | ||||
34 | checkUnicode(/*bUnicode =*/true, /*bHex =*/true); | ||||
35 | RTFSkipDestination aSkip(*this); | ||||
36 | int nParam = -1; | ||||
37 | int nSprm = -1; | ||||
38 | |||||
39 | // Underline flags. | ||||
40 | switch (nKeyword) | ||||
| |||||
41 | { | ||||
42 | case RTF_ULD: | ||||
43 | nSprm = NS_ooxml::LN_Value_ST_Underline_dotted; | ||||
44 | break; | ||||
45 | case RTF_ULW: | ||||
46 | nSprm = NS_ooxml::LN_Value_ST_Underline_words; | ||||
47 | break; | ||||
48 | default: | ||||
49 | break; | ||||
50 | } | ||||
51 | if (nSprm
| ||||
52 | { | ||||
53 | auto pValue = new RTFValue(nSprm); | ||||
54 | m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_Underline_val, pValue); | ||||
55 | return RTFError::OK; | ||||
56 | } | ||||
57 | |||||
58 | // Indentation | ||||
59 | switch (nKeyword) | ||||
60 | { | ||||
61 | case RTF_QC: | ||||
62 | nParam = NS_ooxml::LN_Value_ST_Jc_center; | ||||
63 | break; | ||||
64 | case RTF_QJ: | ||||
65 | nParam = NS_ooxml::LN_Value_ST_Jc_both; | ||||
66 | break; | ||||
67 | case RTF_QL: | ||||
68 | nParam = NS_ooxml::LN_Value_ST_Jc_left; | ||||
69 | break; | ||||
70 | case RTF_QR: | ||||
71 | nParam = NS_ooxml::LN_Value_ST_Jc_right; | ||||
72 | break; | ||||
73 | case RTF_QD: | ||||
74 | nParam = NS_ooxml::LN_Value_ST_Jc_distribute; | ||||
75 | break; | ||||
76 | default: | ||||
77 | break; | ||||
78 | } | ||||
79 | if (nParam
| ||||
80 | { | ||||
81 | auto pValue = new RTFValue(nParam); | ||||
82 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_jc, pValue); | ||||
83 | m_bNeedPap = true; | ||||
84 | return RTFError::OK; | ||||
85 | } | ||||
86 | |||||
87 | // Font Alignment | ||||
88 | switch (nKeyword) | ||||
89 | { | ||||
90 | case RTF_FAFIXED: | ||||
91 | case RTF_FAAUTO: | ||||
92 | nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_auto; | ||||
93 | break; | ||||
94 | case RTF_FAHANG: | ||||
95 | nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_top; | ||||
96 | break; | ||||
97 | case RTF_FACENTER: | ||||
98 | nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_center; | ||||
99 | break; | ||||
100 | case RTF_FAROMAN: | ||||
101 | nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_baseline; | ||||
102 | break; | ||||
103 | case RTF_FAVAR: | ||||
104 | nParam = NS_ooxml::LN_Value_doc_ST_TextAlignment_bottom; | ||||
105 | break; | ||||
106 | default: | ||||
107 | break; | ||||
108 | } | ||||
109 | if (nParam
| ||||
110 | { | ||||
111 | auto pValue = new RTFValue(nParam); | ||||
112 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_textAlignment, pValue); | ||||
113 | return RTFError::OK; | ||||
114 | } | ||||
115 | |||||
116 | // Tab kind. | ||||
117 | switch (nKeyword) | ||||
118 | { | ||||
119 | case RTF_TQR: | ||||
120 | nParam = NS_ooxml::LN_Value_ST_TabJc_right; | ||||
121 | break; | ||||
122 | case RTF_TQC: | ||||
123 | nParam = NS_ooxml::LN_Value_ST_TabJc_center; | ||||
124 | break; | ||||
125 | case RTF_TQDEC: | ||||
126 | nParam = NS_ooxml::LN_Value_ST_TabJc_decimal; | ||||
127 | break; | ||||
128 | default: | ||||
129 | break; | ||||
130 | } | ||||
131 | if (nParam
| ||||
132 | { | ||||
133 | auto pValue = new RTFValue(nParam); | ||||
134 | m_aStates.top().getTabAttributes().set(NS_ooxml::LN_CT_TabStop_val, pValue); | ||||
135 | return RTFError::OK; | ||||
136 | } | ||||
137 | |||||
138 | // Tab lead. | ||||
139 | switch (nKeyword) | ||||
140 | { | ||||
141 | case RTF_TLDOT: | ||||
142 | nParam = NS_ooxml::LN_Value_ST_TabTlc_dot; | ||||
143 | break; | ||||
144 | case RTF_TLMDOT: | ||||
145 | nParam = NS_ooxml::LN_Value_ST_TabTlc_middleDot; | ||||
146 | break; | ||||
147 | case RTF_TLHYPH: | ||||
148 | nParam = NS_ooxml::LN_Value_ST_TabTlc_hyphen; | ||||
149 | break; | ||||
150 | case RTF_TLUL: | ||||
151 | case RTF_TLTH: | ||||
152 | nParam = NS_ooxml::LN_Value_ST_TabTlc_underscore; | ||||
153 | break; | ||||
154 | case RTF_TLEQ: | ||||
155 | default: | ||||
156 | break; | ||||
157 | } | ||||
158 | if (nParam
| ||||
159 | { | ||||
160 | auto pValue = new RTFValue(nParam); | ||||
161 | m_aStates.top().getTabAttributes().set(NS_ooxml::LN_CT_TabStop_leader, pValue); | ||||
162 | return RTFError::OK; | ||||
163 | } | ||||
164 | |||||
165 | // Border types | ||||
166 | { | ||||
167 | switch (nKeyword) | ||||
168 | { | ||||
169 | // brdrhair and brdrs are the same, brdrw will make a difference | ||||
170 | // map to values in ooxml/model.xml resource ST_Border | ||||
171 | case RTF_BRDRHAIR: | ||||
172 | case RTF_BRDRS: | ||||
173 | nParam = NS_ooxml::LN_Value_ST_Border_single; | ||||
174 | break; | ||||
175 | case RTF_BRDRDOT: | ||||
176 | nParam = NS_ooxml::LN_Value_ST_Border_dotted; | ||||
177 | break; | ||||
178 | case RTF_BRDRDASH: | ||||
179 | nParam = NS_ooxml::LN_Value_ST_Border_dashed; | ||||
180 | break; | ||||
181 | case RTF_BRDRDB: | ||||
182 | nParam = NS_ooxml::LN_Value_ST_Border_double; | ||||
183 | break; | ||||
184 | case RTF_BRDRTNTHSG: | ||||
185 | nParam = NS_ooxml::LN_Value_ST_Border_thinThickSmallGap; | ||||
186 | break; | ||||
187 | case RTF_BRDRTNTHMG: | ||||
188 | nParam = NS_ooxml::LN_Value_ST_Border_thinThickMediumGap; | ||||
189 | break; | ||||
190 | case RTF_BRDRTNTHLG: | ||||
191 | nParam = NS_ooxml::LN_Value_ST_Border_thinThickLargeGap; | ||||
192 | break; | ||||
193 | case RTF_BRDRTHTNSG: | ||||
194 | nParam = NS_ooxml::LN_Value_ST_Border_thickThinSmallGap; | ||||
195 | break; | ||||
196 | case RTF_BRDRTHTNMG: | ||||
197 | nParam = NS_ooxml::LN_Value_ST_Border_thickThinMediumGap; | ||||
198 | break; | ||||
199 | case RTF_BRDRTHTNLG: | ||||
200 | nParam = NS_ooxml::LN_Value_ST_Border_thickThinLargeGap; | ||||
201 | break; | ||||
202 | case RTF_BRDREMBOSS: | ||||
203 | nParam = NS_ooxml::LN_Value_ST_Border_threeDEmboss; | ||||
204 | break; | ||||
205 | case RTF_BRDRENGRAVE: | ||||
206 | nParam = NS_ooxml::LN_Value_ST_Border_threeDEngrave; | ||||
207 | break; | ||||
208 | case RTF_BRDROUTSET: | ||||
209 | nParam = NS_ooxml::LN_Value_ST_Border_outset; | ||||
210 | break; | ||||
211 | case RTF_BRDRINSET: | ||||
212 | nParam = NS_ooxml::LN_Value_ST_Border_inset; | ||||
213 | break; | ||||
214 | case RTF_BRDRDASHSM: | ||||
215 | nParam = NS_ooxml::LN_Value_ST_Border_dashSmallGap; | ||||
216 | break; | ||||
217 | case RTF_BRDRDASHD: | ||||
218 | nParam = NS_ooxml::LN_Value_ST_Border_dotDash; | ||||
219 | break; | ||||
220 | case RTF_BRDRDASHDD: | ||||
221 | nParam = NS_ooxml::LN_Value_ST_Border_dotDotDash; | ||||
222 | break; | ||||
223 | case RTF_BRDRNONE: | ||||
224 | nParam = NS_ooxml::LN_Value_ST_Border_none; | ||||
225 | break; | ||||
226 | default: | ||||
227 | break; | ||||
228 | } | ||||
229 | if (nParam
| ||||
230 | { | ||||
231 | auto pValue = new RTFValue(nParam); | ||||
232 | putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_val, pValue); | ||||
233 | return RTFError::OK; | ||||
234 | } | ||||
235 | } | ||||
236 | |||||
237 | // Section breaks | ||||
238 | switch (nKeyword) | ||||
239 | { | ||||
240 | case RTF_SBKNONE: | ||||
241 | nParam = NS_ooxml::LN_Value_ST_SectionMark_continuous; | ||||
242 | break; | ||||
243 | case RTF_SBKCOL: | ||||
244 | nParam = NS_ooxml::LN_Value_ST_SectionMark_nextColumn; | ||||
245 | break; | ||||
246 | case RTF_SBKPAGE: | ||||
247 | nParam = NS_ooxml::LN_Value_ST_SectionMark_nextPage; | ||||
248 | break; | ||||
249 | case RTF_SBKEVEN: | ||||
250 | nParam = NS_ooxml::LN_Value_ST_SectionMark_evenPage; | ||||
251 | break; | ||||
252 | case RTF_SBKODD: | ||||
253 | nParam = NS_ooxml::LN_Value_ST_SectionMark_oddPage; | ||||
254 | break; | ||||
255 | default: | ||||
256 | break; | ||||
257 | } | ||||
258 | if (nParam
| ||||
259 | { | ||||
260 | if (m_nResetBreakOnSectBreak != RTF_invalid) | ||||
261 | { | ||||
262 | m_nResetBreakOnSectBreak = nKeyword; | ||||
263 | } | ||||
264 | auto pValue = new RTFValue(nParam); | ||||
265 | m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_type, pValue); | ||||
266 | return RTFError::OK; | ||||
267 | } | ||||
268 | |||||
269 | // Footnote numbering | ||||
270 | switch (nKeyword) | ||||
271 | { | ||||
272 | case RTF_FTNNAR: | ||||
273 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; | ||||
274 | break; | ||||
275 | case RTF_FTNNALC: | ||||
276 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; | ||||
277 | break; | ||||
278 | case RTF_FTNNAUC: | ||||
279 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; | ||||
280 | break; | ||||
281 | case RTF_FTNNRLC: | ||||
282 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; | ||||
283 | break; | ||||
284 | case RTF_FTNNRUC: | ||||
285 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; | ||||
286 | break; | ||||
287 | case RTF_FTNNCHI: | ||||
288 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; | ||||
289 | break; | ||||
290 | default: | ||||
291 | break; | ||||
292 | } | ||||
293 | if (nParam
| ||||
294 | { | ||||
295 | auto pInner = new RTFValue(nParam); | ||||
296 | RTFSprms aAttributes; | ||||
297 | aAttributes.set(NS_ooxml::LN_CT_NumFmt_val, pInner); | ||||
298 | auto pOuter = new RTFValue(aAttributes); | ||||
299 | putNestedSprm(m_aDefaultState.getParagraphSprms(), | ||||
300 | NS_ooxml::LN_EG_SectPrContents_footnotePr, NS_ooxml::LN_CT_FtnProps_numFmt, | ||||
301 | pOuter); | ||||
302 | return RTFError::OK; | ||||
303 | } | ||||
304 | |||||
305 | // Footnote restart type | ||||
306 | switch (nKeyword) | ||||
307 | { | ||||
308 | case RTF_FTNRSTPG: | ||||
309 | nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachPage; | ||||
310 | break; | ||||
311 | case RTF_FTNRESTART: | ||||
312 | nParam = NS_ooxml::LN_Value_ST_RestartNumber_eachSect; | ||||
313 | break; | ||||
314 | case RTF_FTNRSTCONT: | ||||
315 | nParam = NS_ooxml::LN_Value_ST_RestartNumber_continuous; | ||||
316 | break; | ||||
317 | default: | ||||
318 | break; | ||||
319 | } | ||||
320 | if (nParam
| ||||
321 | { | ||||
322 | auto pValue = new RTFValue(nParam); | ||||
323 | putNestedSprm(m_aDefaultState.getParagraphSprms(), | ||||
324 | NS_ooxml::LN_EG_SectPrContents_footnotePr, | ||||
325 | NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue); | ||||
326 | return RTFError::OK; | ||||
327 | } | ||||
328 | |||||
329 | // Endnote numbering | ||||
330 | switch (nKeyword) | ||||
331 | { | ||||
332 | case RTF_AFTNNAR: | ||||
333 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_decimal; | ||||
334 | break; | ||||
335 | case RTF_AFTNNALC: | ||||
336 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter; | ||||
337 | break; | ||||
338 | case RTF_AFTNNAUC: | ||||
339 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperLetter; | ||||
340 | break; | ||||
341 | case RTF_AFTNNRLC: | ||||
342 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman; | ||||
343 | break; | ||||
344 | case RTF_AFTNNRUC: | ||||
345 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_upperRoman; | ||||
346 | break; | ||||
347 | case RTF_AFTNNCHI: | ||||
348 | nParam = NS_ooxml::LN_Value_ST_NumberFormat_chicago; | ||||
349 | break; | ||||
350 | default: | ||||
351 | break; | ||||
352 | } | ||||
353 | if (nParam
| ||||
354 | { | ||||
355 | auto pInner = new RTFValue(nParam); | ||||
356 | RTFSprms aAttributes; | ||||
357 | aAttributes.set(NS_ooxml::LN_CT_NumFmt_val, pInner); | ||||
358 | auto pOuter = new RTFValue(aAttributes); | ||||
359 | putNestedSprm(m_aDefaultState.getParagraphSprms(), NS_ooxml::LN_EG_SectPrContents_endnotePr, | ||||
360 | NS_ooxml::LN_CT_EdnProps_numFmt, pOuter); | ||||
361 | return RTFError::OK; | ||||
362 | } | ||||
363 | |||||
364 | switch (nKeyword) | ||||
365 | { | ||||
366 | case RTF_TRQL: | ||||
367 | nParam = NS_ooxml::LN_Value_ST_Jc_left; | ||||
368 | break; | ||||
369 | case RTF_TRQC: | ||||
370 | nParam = NS_ooxml::LN_Value_ST_Jc_center; | ||||
371 | break; | ||||
372 | case RTF_TRQR: | ||||
373 | nParam = NS_ooxml::LN_Value_ST_Jc_right; | ||||
374 | break; | ||||
375 | default: | ||||
376 | break; | ||||
377 | } | ||||
378 | if (nParam
| ||||
379 | { | ||||
380 | auto pValue = new RTFValue(nParam); | ||||
381 | m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TrPrBase_jc, pValue); | ||||
382 | return RTFError::OK; | ||||
383 | } | ||||
384 | |||||
385 | // Cell Text Flow | ||||
386 | switch (nKeyword) | ||||
387 | { | ||||
388 | case RTF_CLTXLRTB: | ||||
389 | nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTb; | ||||
390 | break; | ||||
391 | case RTF_CLTXTBRL: | ||||
392 | nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRl; | ||||
393 | break; | ||||
394 | case RTF_CLTXBTLR: | ||||
395 | nParam = NS_ooxml::LN_Value_ST_TextDirection_btLr; | ||||
396 | break; | ||||
397 | case RTF_CLTXLRTBV: | ||||
398 | nParam = NS_ooxml::LN_Value_ST_TextDirection_lrTbV; | ||||
399 | break; | ||||
400 | case RTF_CLTXTBRLV: | ||||
401 | nParam = NS_ooxml::LN_Value_ST_TextDirection_tbRlV; | ||||
402 | break; | ||||
403 | default: | ||||
404 | break; | ||||
405 | } | ||||
406 | if (nParam
| ||||
407 | { | ||||
408 | auto pValue = new RTFValue(nParam); | ||||
409 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_textDirection, pValue); | ||||
410 | } | ||||
411 | |||||
412 | // Trivial paragraph flags | ||||
413 | switch (nKeyword) | ||||
414 | { | ||||
415 | case RTF_KEEP: | ||||
416 | if (m_aStates.top().getCurrentBuffer() != &m_aTableBufferStack.back()) | ||||
417 | nParam = NS_ooxml::LN_CT_PPrBase_keepLines; | ||||
418 | break; | ||||
419 | case RTF_KEEPN: | ||||
420 | if (m_aStates.top().getCurrentBuffer() != &m_aTableBufferStack.back()) | ||||
421 | nParam = NS_ooxml::LN_CT_PPrBase_keepNext; | ||||
422 | break; | ||||
423 | case RTF_INTBL: | ||||
424 | { | ||||
425 | m_aStates.top().setCurrentBuffer(&m_aTableBufferStack.back()); | ||||
426 | nParam = NS_ooxml::LN_inTbl; | ||||
427 | } | ||||
428 | break; | ||||
429 | case RTF_PAGEBB: | ||||
430 | nParam = NS_ooxml::LN_CT_PPrBase_pageBreakBefore; | ||||
431 | break; | ||||
432 | default: | ||||
433 | break; | ||||
434 | } | ||||
435 | if (nParam
| ||||
436 | { | ||||
437 | auto pValue = new RTFValue(1); | ||||
438 | m_aStates.top().getParagraphSprms().set(nParam, pValue); | ||||
439 | return RTFError::OK; | ||||
440 | } | ||||
441 | |||||
442 | switch (nKeyword) | ||||
443 | { | ||||
444 | case RTF_FNIL: | ||||
445 | case RTF_FROMAN: | ||||
446 | case RTF_FSWISS: | ||||
447 | case RTF_FMODERN: | ||||
448 | case RTF_FSCRIPT: | ||||
449 | case RTF_FDECOR: | ||||
450 | case RTF_FTECH: | ||||
451 | case RTF_FBIDI: | ||||
452 | // TODO ooxml:CT_Font_family seems to be ignored by the domain mapper | ||||
453 | break; | ||||
454 | case RTF_ANSI: | ||||
455 | m_aStates.top().setCurrentEncoding(RTL_TEXTENCODING_MS_1252(((rtl_TextEncoding) 1))); | ||||
456 | break; | ||||
457 | case RTF_MAC: | ||||
458 | m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_APPLE_ROMAN(((rtl_TextEncoding) 2))); | ||||
459 | m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding()); | ||||
460 | break; | ||||
461 | case RTF_PC: | ||||
462 | m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_IBM_437(((rtl_TextEncoding) 3))); | ||||
463 | m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding()); | ||||
464 | break; | ||||
465 | case RTF_PCA: | ||||
466 | m_aDefaultState.setCurrentEncoding(RTL_TEXTENCODING_IBM_850(((rtl_TextEncoding) 4))); | ||||
467 | m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding()); | ||||
468 | break; | ||||
469 | case RTF_PLAIN: | ||||
470 | { | ||||
471 | m_aStates.top().getCharacterSprms() = getDefaultState().getCharacterSprms(); | ||||
472 | m_aStates.top().setCurrentEncoding(getEncoding(getFontIndex(m_nDefaultFontIndex))); | ||||
473 | m_aStates.top().getCharacterAttributes() = getDefaultState().getCharacterAttributes(); | ||||
474 | m_aStates.top().setCurrentCharacterStyleIndex(-1); | ||||
475 | m_aStates.top().setRunType(RTFParserState::RunType::NONE); | ||||
476 | } | ||||
477 | break; | ||||
478 | case RTF_PARD: | ||||
479 | { | ||||
480 | if (m_bHadPicture) | ||||
481 | dispatchSymbol(RTF_PAR); | ||||
482 | // \pard is allowed between \cell and \row, but in that case it should not reset the fact that we're inside a table. | ||||
483 | // It should not reset the paragraph style, either, so remember the old paragraph style. | ||||
484 | RTFValue::Pointer_t pOldStyle | ||||
485 | = m_aStates.top().getParagraphSprms().find(NS_ooxml::LN_CT_PPrBase_pStyle); | ||||
486 | m_aStates.top().getParagraphSprms() = m_aDefaultState.getParagraphSprms(); | ||||
487 | m_aStates.top().getParagraphAttributes() = m_aDefaultState.getParagraphAttributes(); | ||||
488 | |||||
489 | if (m_nTopLevelCells == 0 && m_nNestedCells == 0) | ||||
490 | { | ||||
491 | // Reset that we're in a table. | ||||
492 | m_aStates.top().setCurrentBuffer(nullptr); | ||||
493 | } | ||||
494 | else | ||||
495 | { | ||||
496 | // We are still in a table. | ||||
497 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_inTbl, new RTFValue(1)); | ||||
498 | if (m_bAfterCellBeforeRow && pOldStyle) | ||||
499 | // And we still have the same paragraph style. | ||||
500 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle, | ||||
501 | pOldStyle); | ||||
502 | // Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering. | ||||
503 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_tabs, | ||||
504 | new RTFValue()); | ||||
505 | } | ||||
506 | resetFrame(); | ||||
507 | |||||
508 | // Reset currently selected paragraph style as well, unless we are in the special "after \cell, before \row" state. | ||||
509 | // By default the style with index 0 is applied. | ||||
510 | if (!m_bAfterCellBeforeRow) | ||||
511 | { | ||||
512 | OUString const aName = getStyleName(0); | ||||
513 | // But only in case it's not a character style. | ||||
514 | if (!aName.isEmpty() | ||||
515 | && getStyleType(0) != NS_ooxml::LN_Value_ST_StyleType_character) | ||||
516 | { | ||||
517 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle, | ||||
518 | new RTFValue(aName)); | ||||
519 | m_aStates.top().setCurrentStyleIndex(0); | ||||
520 | } | ||||
521 | else | ||||
522 | { | ||||
523 | m_aStates.top().setCurrentStyleIndex(-1); | ||||
524 | } | ||||
525 | } | ||||
526 | // Need to send paragraph properties again, if there will be any. | ||||
527 | m_bNeedPap = true; | ||||
528 | break; | ||||
529 | } | ||||
530 | case RTF_SECTD: | ||||
531 | { | ||||
532 | m_aStates.top().getSectionSprms() = m_aDefaultState.getSectionSprms(); | ||||
533 | m_aStates.top().getSectionAttributes() = m_aDefaultState.getSectionAttributes(); | ||||
534 | } | ||||
535 | break; | ||||
536 | case RTF_TROWD: | ||||
537 | { | ||||
538 | // Back these up, in case later we still need this info. | ||||
539 | backupTableRowProperties(); | ||||
540 | resetTableRowProperties(); | ||||
541 | // In case the table definition is in the middle of the row | ||||
542 | // (invalid), make sure table definition is emitted. | ||||
543 | m_bNeedPap = true; | ||||
544 | } | ||||
545 | break; | ||||
546 | case RTF_WIDCTLPAR: | ||||
547 | case RTF_NOWIDCTLPAR: | ||||
548 | { | ||||
549 | auto pValue = new RTFValue(int(nKeyword == RTF_WIDCTLPAR)); | ||||
550 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_widowControl, pValue); | ||||
551 | } | ||||
552 | break; | ||||
553 | case RTF_BOX: | ||||
554 | { | ||||
555 | RTFSprms aAttributes; | ||||
556 | auto pValue = new RTFValue(aAttributes); | ||||
557 | for (int i = 0; i < 4; i++) | ||||
558 | m_aStates.top().getParagraphSprms().set(getParagraphBorder(i), pValue); | ||||
| |||||
559 | m_aStates.top().setBorderState(RTFBorderState::PARAGRAPH_BOX); | ||||
560 | } | ||||
561 | break; | ||||
562 | case RTF_LTRSECT: | ||||
563 | case RTF_RTLSECT: | ||||
564 | { | ||||
565 | auto pValue = new RTFValue(nKeyword == RTF_LTRSECT ? 0 : 1); | ||||
566 | m_aStates.top().setRunType(RTFParserState::RunType::NONE); | ||||
567 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_EG_SectPrContents_textDirection, | ||||
568 | pValue); | ||||
569 | } | ||||
570 | break; | ||||
571 | case RTF_LTRPAR: | ||||
572 | case RTF_RTLPAR: | ||||
573 | { | ||||
574 | auto pValue = new RTFValue(nKeyword == RTF_LTRPAR ? 0 : 1); | ||||
575 | m_aStates.top().setRunType(RTFParserState::RunType::NONE); | ||||
576 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_bidi, pValue); | ||||
577 | } | ||||
578 | break; | ||||
579 | case RTF_LTRROW: | ||||
580 | case RTF_RTLROW: | ||||
581 | m_aStates.top().setRunType(RTFParserState::RunType::NONE); | ||||
582 | m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblPrBase_bidiVisual, | ||||
583 | new RTFValue(int(nKeyword == RTF_RTLROW))); | ||||
584 | break; | ||||
585 | case RTF_LTRCH: | ||||
586 | // dmapper does not support this. | ||||
587 | if (m_aStates.top().getRunType() == RTFParserState::RunType::RTLCH_LTRCH_1) | ||||
588 | m_aStates.top().setRunType(RTFParserState::RunType::RTLCH_LTRCH_2); | ||||
589 | else | ||||
590 | m_aStates.top().setRunType(RTFParserState::RunType::LTRCH_RTLCH_1); | ||||
591 | break; | ||||
592 | case RTF_RTLCH: | ||||
593 | if (m_aStates.top().getRunType() == RTFParserState::RunType::LTRCH_RTLCH_1) | ||||
594 | m_aStates.top().setRunType(RTFParserState::RunType::LTRCH_RTLCH_2); | ||||
595 | else | ||||
596 | m_aStates.top().setRunType(RTFParserState::RunType::RTLCH_LTRCH_1); | ||||
597 | |||||
598 | if (m_aDefaultState.getCurrentEncoding() == RTL_TEXTENCODING_MS_1255(((rtl_TextEncoding) 37))) | ||||
599 | m_aStates.top().setCurrentEncoding(m_aDefaultState.getCurrentEncoding()); | ||||
600 | break; | ||||
601 | case RTF_ULNONE: | ||||
602 | { | ||||
603 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Underline_none); | ||||
604 | m_aStates.top().getCharacterAttributes().set(NS_ooxml::LN_CT_Underline_val, pValue); | ||||
605 | } | ||||
606 | break; | ||||
607 | case RTF_NONSHPPICT: | ||||
608 | case RTF_MMATHPICT: // Picture group used by readers not understanding \moMath group | ||||
609 | m_aStates.top().setDestination(Destination::SKIP); | ||||
610 | break; | ||||
611 | case RTF_CLBRDRT: | ||||
612 | case RTF_CLBRDRL: | ||||
613 | case RTF_CLBRDRB: | ||||
614 | case RTF_CLBRDRR: | ||||
615 | { | ||||
616 | RTFSprms aAttributes; | ||||
617 | RTFSprms aSprms; | ||||
618 | auto pValue = new RTFValue(aAttributes, aSprms); | ||||
619 | switch (nKeyword) | ||||
620 | { | ||||
621 | case RTF_CLBRDRT: | ||||
622 | nParam = NS_ooxml::LN_CT_TcBorders_top; | ||||
623 | break; | ||||
624 | case RTF_CLBRDRL: | ||||
625 | nParam = NS_ooxml::LN_CT_TcBorders_left; | ||||
626 | break; | ||||
627 | case RTF_CLBRDRB: | ||||
628 | nParam = NS_ooxml::LN_CT_TcBorders_bottom; | ||||
629 | break; | ||||
630 | case RTF_CLBRDRR: | ||||
631 | nParam = NS_ooxml::LN_CT_TcBorders_right; | ||||
632 | break; | ||||
633 | default: | ||||
634 | break; | ||||
635 | } | ||||
636 | putNestedSprm(m_aStates.top().getTableCellSprms(), NS_ooxml::LN_CT_TcPrBase_tcBorders, | ||||
637 | nParam, pValue); | ||||
638 | m_aStates.top().setBorderState(RTFBorderState::CELL); | ||||
639 | } | ||||
640 | break; | ||||
641 | case RTF_PGBRDRT: | ||||
642 | case RTF_PGBRDRL: | ||||
643 | case RTF_PGBRDRB: | ||||
644 | case RTF_PGBRDRR: | ||||
645 | { | ||||
646 | RTFSprms aAttributes; | ||||
647 | RTFSprms aSprms; | ||||
648 | auto pValue = new RTFValue(aAttributes, aSprms); | ||||
649 | switch (nKeyword) | ||||
650 | { | ||||
651 | case RTF_PGBRDRT: | ||||
652 | nParam = NS_ooxml::LN_CT_PageBorders_top; | ||||
653 | break; | ||||
654 | case RTF_PGBRDRL: | ||||
655 | nParam = NS_ooxml::LN_CT_PageBorders_left; | ||||
656 | break; | ||||
657 | case RTF_PGBRDRB: | ||||
658 | nParam = NS_ooxml::LN_CT_PageBorders_bottom; | ||||
659 | break; | ||||
660 | case RTF_PGBRDRR: | ||||
661 | nParam = NS_ooxml::LN_CT_PageBorders_right; | ||||
662 | break; | ||||
663 | default: | ||||
664 | break; | ||||
665 | } | ||||
666 | putNestedSprm(m_aStates.top().getSectionSprms(), | ||||
667 | NS_ooxml::LN_EG_SectPrContents_pgBorders, nParam, pValue); | ||||
668 | m_aStates.top().setBorderState(RTFBorderState::PAGE); | ||||
669 | } | ||||
670 | break; | ||||
671 | case RTF_BRDRT: | ||||
672 | case RTF_BRDRL: | ||||
673 | case RTF_BRDRB: | ||||
674 | case RTF_BRDRR: | ||||
675 | { | ||||
676 | RTFSprms aAttributes; | ||||
677 | RTFSprms aSprms; | ||||
678 | auto pValue = new RTFValue(aAttributes, aSprms); | ||||
679 | switch (nKeyword) | ||||
680 | { | ||||
681 | case RTF_BRDRT: | ||||
682 | nParam = getParagraphBorder(0); | ||||
683 | break; | ||||
684 | case RTF_BRDRL: | ||||
685 | nParam = getParagraphBorder(1); | ||||
686 | break; | ||||
687 | case RTF_BRDRB: | ||||
688 | nParam = getParagraphBorder(2); | ||||
689 | break; | ||||
690 | case RTF_BRDRR: | ||||
691 | nParam = getParagraphBorder(3); | ||||
692 | break; | ||||
693 | default: | ||||
694 | break; | ||||
695 | } | ||||
696 | putNestedSprm(m_aStates.top().getParagraphSprms(), NS_ooxml::LN_CT_PrBase_pBdr, nParam, | ||||
697 | pValue); | ||||
698 | m_aStates.top().setBorderState(RTFBorderState::PARAGRAPH); | ||||
699 | } | ||||
700 | break; | ||||
701 | case RTF_CHBRDR: | ||||
702 | { | ||||
703 | RTFSprms aAttributes; | ||||
704 | auto pValue = new RTFValue(aAttributes); | ||||
705 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_bdr, pValue); | ||||
706 | m_aStates.top().setBorderState(RTFBorderState::CHARACTER); | ||||
707 | } | ||||
708 | break; | ||||
709 | case RTF_CLMGF: | ||||
710 | { | ||||
711 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart); | ||||
712 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue); | ||||
713 | } | ||||
714 | break; | ||||
715 | case RTF_CLMRG: | ||||
716 | { | ||||
717 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue); | ||||
718 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_hMerge, pValue); | ||||
719 | } | ||||
720 | break; | ||||
721 | case RTF_CLVMGF: | ||||
722 | { | ||||
723 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_restart); | ||||
724 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue); | ||||
725 | } | ||||
726 | break; | ||||
727 | case RTF_CLVMRG: | ||||
728 | { | ||||
729 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_Merge_continue); | ||||
730 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vMerge, pValue); | ||||
731 | } | ||||
732 | break; | ||||
733 | case RTF_CLVERTALT: | ||||
734 | case RTF_CLVERTALC: | ||||
735 | case RTF_CLVERTALB: | ||||
736 | { | ||||
737 | switch (nKeyword) | ||||
738 | { | ||||
739 | case RTF_CLVERTALT: | ||||
740 | nParam = NS_ooxml::LN_Value_ST_VerticalJc_top; | ||||
741 | break; | ||||
742 | case RTF_CLVERTALC: | ||||
743 | nParam = NS_ooxml::LN_Value_ST_VerticalJc_center; | ||||
744 | break; | ||||
745 | case RTF_CLVERTALB: | ||||
746 | nParam = NS_ooxml::LN_Value_ST_VerticalJc_bottom; | ||||
747 | break; | ||||
748 | default: | ||||
749 | break; | ||||
750 | } | ||||
751 | auto pValue = new RTFValue(nParam); | ||||
752 | m_aStates.top().getTableCellSprms().set(NS_ooxml::LN_CT_TcPrBase_vAlign, pValue); | ||||
753 | } | ||||
754 | break; | ||||
755 | case RTF_TRKEEP: | ||||
756 | { | ||||
757 | auto pValue = new RTFValue(1); | ||||
758 | m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TrPrBase_cantSplit, pValue); | ||||
759 | } | ||||
760 | break; | ||||
761 | case RTF_SECTUNLOCKED: | ||||
762 | { | ||||
763 | auto pValue = new RTFValue(0); | ||||
764 | m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_formProt, pValue); | ||||
765 | } | ||||
766 | break; | ||||
767 | case RTF_PGNBIDIA: | ||||
768 | case RTF_PGNBIDIB: | ||||
769 | // These should be mapped to NS_ooxml::LN_EG_SectPrContents_pgNumType, but dmapper has no API for that at the moment. | ||||
770 | break; | ||||
771 | case RTF_LOCH: | ||||
772 | m_aStates.top().setRunType(RTFParserState::RunType::LOCH); | ||||
773 | break; | ||||
774 | case RTF_HICH: | ||||
775 | m_aStates.top().setRunType(RTFParserState::RunType::HICH); | ||||
776 | break; | ||||
777 | case RTF_DBCH: | ||||
778 | m_aStates.top().setRunType(RTFParserState::RunType::DBCH); | ||||
779 | break; | ||||
780 | case RTF_TITLEPG: | ||||
781 | { | ||||
782 | auto pValue = new RTFValue(1); | ||||
783 | m_aStates.top().getSectionSprms().set(NS_ooxml::LN_EG_SectPrContents_titlePg, pValue); | ||||
784 | } | ||||
785 | break; | ||||
786 | case RTF_SUPER: | ||||
787 | { | ||||
788 | // Make sure character properties are not lost if the document | ||||
789 | // starts with a footnote. | ||||
790 | if (!isStyleSheetImport()) | ||||
791 | { | ||||
792 | checkFirstRun(); | ||||
793 | checkNeedPap(); | ||||
794 | } | ||||
795 | |||||
796 | if (!m_aStates.top().getCurrentBuffer()) | ||||
797 | m_aStates.top().setCurrentBuffer(&m_aSuperBuffer); | ||||
798 | |||||
799 | auto pValue = new RTFValue("superscript"); | ||||
800 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue); | ||||
801 | } | ||||
802 | break; | ||||
803 | case RTF_SUB: | ||||
804 | { | ||||
805 | auto pValue = new RTFValue("subscript"); | ||||
806 | m_aStates.top().getCharacterSprms().set(NS_ooxml::LN_EG_RPrBase_vertAlign, pValue); | ||||
807 | } | ||||
808 | break; | ||||
809 | case RTF_NOSUPERSUB: | ||||
810 | { | ||||
811 | if (m_aStates.top().getCurrentBuffer() == &m_aSuperBuffer) | ||||
812 | { | ||||
813 | replayBuffer(m_aSuperBuffer, nullptr, nullptr); | ||||
814 | m_aStates.top().setCurrentBuffer(nullptr); | ||||
815 | } | ||||
816 | m_aStates.top().getCharacterSprms().erase(NS_ooxml::LN_EG_RPrBase_vertAlign); | ||||
817 | } | ||||
818 | break; | ||||
819 | case RTF_LINEPPAGE: | ||||
820 | case RTF_LINECONT: | ||||
821 | { | ||||
822 | auto pValue = new RTFValue(nKeyword == RTF_LINEPPAGE | ||||
823 | ? NS_ooxml::LN_Value_ST_LineNumberRestart_newPage | ||||
824 | : NS_ooxml::LN_Value_ST_LineNumberRestart_continuous); | ||||
825 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
826 | NS_ooxml::LN_EG_SectPrContents_lnNumType, | ||||
827 | NS_ooxml::LN_CT_LineNumber_restart, pValue); | ||||
828 | } | ||||
829 | break; | ||||
830 | case RTF_AENDDOC: | ||||
831 | // Noop, this is the default in Writer. | ||||
832 | case RTF_AENDNOTES: | ||||
833 | // Noop | ||||
834 | case RTF_AFTNRSTCONT: | ||||
835 | // Noop, this is the default in Writer. | ||||
836 | case RTF_AFTNRESTART: | ||||
837 | // Noop | ||||
838 | case RTF_FTNBJ: | ||||
839 | // Noop, this is the default in Writer. | ||||
840 | break; | ||||
841 | case RTF_ENDDOC: | ||||
842 | { | ||||
843 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_RestartNumber_eachSect); | ||||
844 | putNestedSprm(m_aDefaultState.getParagraphSprms(), | ||||
845 | NS_ooxml::LN_EG_SectPrContents_footnotePr, | ||||
846 | NS_ooxml::LN_EG_FtnEdnNumProps_numRestart, pValue); | ||||
847 | } | ||||
848 | break; | ||||
849 | case RTF_NOLINE: | ||||
850 | eraseNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
851 | NS_ooxml::LN_EG_SectPrContents_lnNumType, | ||||
852 | NS_ooxml::LN_CT_LineNumber_distance); | ||||
853 | break; | ||||
854 | case RTF_FORMSHADE: | ||||
855 | // Noop, this is the default in Writer. | ||||
856 | break; | ||||
857 | case RTF_PNGBLIP: | ||||
858 | m_aStates.top().getPicture().eStyle = RTFBmpStyle::PNG; | ||||
859 | break; | ||||
860 | case RTF_JPEGBLIP: | ||||
861 | m_aStates.top().getPicture().eStyle = RTFBmpStyle::JPEG; | ||||
862 | break; | ||||
863 | case RTF_POSYT: | ||||
864 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
865 | NS_ooxml::LN_Value_doc_ST_YAlign_top); | ||||
866 | break; | ||||
867 | case RTF_POSYB: | ||||
868 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
869 | NS_ooxml::LN_Value_doc_ST_YAlign_bottom); | ||||
870 | break; | ||||
871 | case RTF_POSYC: | ||||
872 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
873 | NS_ooxml::LN_Value_doc_ST_YAlign_center); | ||||
874 | break; | ||||
875 | case RTF_POSYIN: | ||||
876 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
877 | NS_ooxml::LN_Value_doc_ST_YAlign_inside); | ||||
878 | break; | ||||
879 | case RTF_POSYOUT: | ||||
880 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
881 | NS_ooxml::LN_Value_doc_ST_YAlign_outside); | ||||
882 | break; | ||||
883 | case RTF_POSYIL: | ||||
884 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_yAlign, | ||||
885 | NS_ooxml::LN_Value_doc_ST_YAlign_inline); | ||||
886 | break; | ||||
887 | |||||
888 | case RTF_PHMRG: | ||||
889 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, | ||||
890 | NS_ooxml::LN_Value_doc_ST_HAnchor_margin); | ||||
891 | break; | ||||
892 | case RTF_PVMRG: | ||||
893 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, | ||||
894 | NS_ooxml::LN_Value_doc_ST_VAnchor_margin); | ||||
895 | break; | ||||
896 | case RTF_PHPG: | ||||
897 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, | ||||
898 | NS_ooxml::LN_Value_doc_ST_HAnchor_page); | ||||
899 | break; | ||||
900 | case RTF_PVPG: | ||||
901 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, | ||||
902 | NS_ooxml::LN_Value_doc_ST_VAnchor_page); | ||||
903 | break; | ||||
904 | case RTF_PHCOL: | ||||
905 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_hAnchor, | ||||
906 | NS_ooxml::LN_Value_doc_ST_HAnchor_text); | ||||
907 | break; | ||||
908 | case RTF_PVPARA: | ||||
909 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_vAnchor, | ||||
910 | NS_ooxml::LN_Value_doc_ST_VAnchor_text); | ||||
911 | break; | ||||
912 | |||||
913 | case RTF_POSXC: | ||||
914 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
915 | NS_ooxml::LN_Value_doc_ST_XAlign_center); | ||||
916 | break; | ||||
917 | case RTF_POSXI: | ||||
918 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
919 | NS_ooxml::LN_Value_doc_ST_XAlign_inside); | ||||
920 | break; | ||||
921 | case RTF_POSXO: | ||||
922 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
923 | NS_ooxml::LN_Value_doc_ST_XAlign_outside); | ||||
924 | break; | ||||
925 | case RTF_POSXL: | ||||
926 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
927 | NS_ooxml::LN_Value_doc_ST_XAlign_left); | ||||
928 | break; | ||||
929 | case RTF_POSXR: | ||||
930 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_xAlign, | ||||
931 | NS_ooxml::LN_Value_doc_ST_XAlign_right); | ||||
932 | break; | ||||
933 | |||||
934 | case RTF_DPLINE: | ||||
935 | case RTF_DPRECT: | ||||
936 | case RTF_DPELLIPSE: | ||||
937 | case RTF_DPTXBX: | ||||
938 | case RTF_DPPOLYLINE: | ||||
939 | case RTF_DPPOLYGON: | ||||
940 | { | ||||
941 | sal_Int32 nType = 0; | ||||
942 | switch (nKeyword) | ||||
943 | { | ||||
944 | case RTF_DPLINE: | ||||
945 | { | ||||
946 | uno::Reference<drawing::XShape> xShape( | ||||
947 | getModelFactory()->createInstance("com.sun.star.drawing.LineShape"), | ||||
948 | uno::UNO_QUERY); | ||||
949 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
950 | break; | ||||
951 | } | ||||
952 | case RTF_DPPOLYLINE: | ||||
953 | { | ||||
954 | // The reason this is not a simple CustomShape is that in the old syntax we have no ViewBox info. | ||||
955 | uno::Reference<drawing::XShape> xShape( | ||||
956 | getModelFactory()->createInstance("com.sun.star.drawing.PolyLineShape"), | ||||
957 | uno::UNO_QUERY); | ||||
958 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
959 | break; | ||||
960 | } | ||||
961 | case RTF_DPPOLYGON: | ||||
962 | { | ||||
963 | uno::Reference<drawing::XShape> xShape( | ||||
964 | getModelFactory()->createInstance("com.sun.star.drawing.PolyPolygonShape"), | ||||
965 | uno::UNO_QUERY); | ||||
966 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
967 | break; | ||||
968 | } | ||||
969 | case RTF_DPRECT: | ||||
970 | { | ||||
971 | uno::Reference<drawing::XShape> xShape( | ||||
972 | getModelFactory()->createInstance("com.sun.star.drawing.RectangleShape"), | ||||
973 | uno::UNO_QUERY); | ||||
974 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
975 | break; | ||||
976 | } | ||||
977 | case RTF_DPELLIPSE: | ||||
978 | nType = ESCHER_ShpInst_Ellipse3; | ||||
979 | break; | ||||
980 | case RTF_DPTXBX: | ||||
981 | { | ||||
982 | uno::Reference<drawing::XShape> xShape( | ||||
983 | getModelFactory()->createInstance("com.sun.star.text.TextFrame"), | ||||
984 | uno::UNO_QUERY); | ||||
985 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
986 | std::vector<beans::PropertyValue> aDefaults | ||||
987 | = RTFSdrImport::getTextFrameDefaults(false); | ||||
988 | for (const auto& rDefault : aDefaults) | ||||
989 | { | ||||
990 | if (!findPropertyName( | ||||
991 | m_aStates.top().getDrawingObject().getPendingProperties(), | ||||
992 | rDefault.Name)) | ||||
993 | m_aStates.top().getDrawingObject().getPendingProperties().push_back( | ||||
994 | rDefault); | ||||
995 | } | ||||
996 | checkFirstRun(); | ||||
997 | Mapper().startShape(m_aStates.top().getDrawingObject().getShape()); | ||||
998 | m_aStates.top().getDrawingObject().setHadShapeText(true); | ||||
999 | } | ||||
1000 | break; | ||||
1001 | default: | ||||
1002 | break; | ||||
1003 | } | ||||
1004 | if (nType) | ||||
1005 | { | ||||
1006 | uno::Reference<drawing::XShape> xShape( | ||||
1007 | getModelFactory()->createInstance("com.sun.star.drawing.CustomShape"), | ||||
1008 | uno::UNO_QUERY); | ||||
1009 | m_aStates.top().getDrawingObject().setShape(xShape); | ||||
1010 | } | ||||
1011 | uno::Reference<drawing::XDrawPageSupplier> xDrawSupplier(m_xDstDoc, uno::UNO_QUERY); | ||||
1012 | uno::Reference<beans::XPropertySet> xPropertySet( | ||||
1013 | m_aStates.top().getDrawingObject().getShape(), uno::UNO_QUERY); | ||||
1014 | m_aStates.top().getDrawingObject().setPropertySet(xPropertySet); | ||||
1015 | if (xDrawSupplier.is()) | ||||
1016 | { | ||||
1017 | uno::Reference<drawing::XShapes> xShapes = xDrawSupplier->getDrawPage(); | ||||
1018 | if (xShapes.is() && nKeyword != RTF_DPTXBX) | ||||
1019 | { | ||||
1020 | // set default VertOrient before inserting | ||||
1021 | m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue( | ||||
1022 | "VertOrient", uno::makeAny(text::VertOrientation::NONE)); | ||||
1023 | xShapes->add(m_aStates.top().getDrawingObject().getShape()); | ||||
1024 | } | ||||
1025 | } | ||||
1026 | if (nType) | ||||
1027 | { | ||||
1028 | uno::Reference<drawing::XEnhancedCustomShapeDefaulter> xDefaulter( | ||||
1029 | m_aStates.top().getDrawingObject().getShape(), uno::UNO_QUERY); | ||||
1030 | xDefaulter->createCustomShapeDefaults(OUString::number(nType)); | ||||
1031 | } | ||||
1032 | std::vector<beans::PropertyValue>& rPendingProperties | ||||
1033 | = m_aStates.top().getDrawingObject().getPendingProperties(); | ||||
1034 | for (const auto& rPendingProperty : rPendingProperties) | ||||
1035 | m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue( | ||||
1036 | rPendingProperty.Name, rPendingProperty.Value); | ||||
1037 | m_pSdrImport->resolveDhgt(m_aStates.top().getDrawingObject().getPropertySet(), | ||||
1038 | m_aStates.top().getDrawingObject().getDhgt(), | ||||
1039 | /*bOldStyle=*/true); | ||||
1040 | } | ||||
1041 | break; | ||||
1042 | case RTF_DOBXMARGIN: | ||||
1043 | case RTF_DOBYMARGIN: | ||||
1044 | { | ||||
1045 | beans::PropertyValue aPropertyValue; | ||||
1046 | aPropertyValue.Name | ||||
1047 | = (nKeyword == RTF_DOBXMARGIN ? OUStringLiteral(u"HoriOrientRelation") | ||||
1048 | : OUStringLiteral(u"VertOrientRelation")); | ||||
1049 | aPropertyValue.Value <<= text::RelOrientation::PAGE_PRINT_AREA; | ||||
1050 | m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue); | ||||
1051 | } | ||||
1052 | break; | ||||
1053 | case RTF_DOBXPAGE: | ||||
1054 | case RTF_DOBYPAGE: | ||||
1055 | { | ||||
1056 | beans::PropertyValue aPropertyValue; | ||||
1057 | aPropertyValue.Name | ||||
1058 | = (nKeyword == RTF_DOBXPAGE ? OUStringLiteral(u"HoriOrientRelation") | ||||
1059 | : OUStringLiteral(u"VertOrientRelation")); | ||||
1060 | aPropertyValue.Value <<= text::RelOrientation::PAGE_FRAME; | ||||
1061 | m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue); | ||||
1062 | } | ||||
1063 | break; | ||||
1064 | case RTF_DOBYPARA: | ||||
1065 | { | ||||
1066 | beans::PropertyValue aPropertyValue; | ||||
1067 | aPropertyValue.Name = "VertOrientRelation"; | ||||
1068 | aPropertyValue.Value <<= text::RelOrientation::FRAME; | ||||
1069 | m_aStates.top().getDrawingObject().getPendingProperties().push_back(aPropertyValue); | ||||
1070 | } | ||||
1071 | break; | ||||
1072 | case RTF_CONTEXTUALSPACE: | ||||
1073 | { | ||||
1074 | auto pValue = new RTFValue(1); | ||||
1075 | m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_contextualSpacing, | ||||
1076 | pValue); | ||||
1077 | } | ||||
1078 | break; | ||||
1079 | case RTF_LINKSTYLES: | ||||
1080 | { | ||||
1081 | auto pValue = new RTFValue(1); | ||||
1082 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_linkStyles, pValue); | ||||
1083 | } | ||||
1084 | break; | ||||
1085 | case RTF_PNLVLBODY: | ||||
1086 | { | ||||
1087 | auto pValue = new RTFValue(2); | ||||
1088 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_nsid, pValue); | ||||
1089 | } | ||||
1090 | break; | ||||
1091 | case RTF_PNDEC: | ||||
1092 | { | ||||
1093 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_decimal); | ||||
1094 | putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_numFmt, | ||||
1095 | NS_ooxml::LN_CT_NumFmt_val, pValue); | ||||
1096 | } | ||||
1097 | break; | ||||
1098 | case RTF_PNLVLBLT: | ||||
1099 | { | ||||
1100 | m_aStates.top().getTableAttributes().set(NS_ooxml::LN_CT_AbstractNum_nsid, | ||||
1101 | new RTFValue(1)); | ||||
1102 | putNestedAttribute(m_aStates.top().getTableSprms(), NS_ooxml::LN_CT_Lvl_numFmt, | ||||
1103 | NS_ooxml::LN_CT_NumFmt_val, | ||||
1104 | new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_bullet)); | ||||
1105 | } | ||||
1106 | break; | ||||
1107 | case RTF_LANDSCAPE: | ||||
1108 | { | ||||
1109 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_PageOrientation_landscape); | ||||
1110 | putNestedAttribute(m_aDefaultState.getSectionSprms(), | ||||
1111 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, | ||||
1112 | pValue); | ||||
1113 | [[fallthrough]]; // set the default + current value | ||||
1114 | } | ||||
1115 | case RTF_LNDSCPSXN: | ||||
1116 | { | ||||
1117 | auto pValue = new RTFValue(NS_ooxml::LN_Value_ST_PageOrientation_landscape); | ||||
1118 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1119 | NS_ooxml::LN_EG_SectPrContents_pgSz, NS_ooxml::LN_CT_PageSz_orient, | ||||
1120 | pValue); | ||||
1121 | } | ||||
1122 | break; | ||||
1123 | case RTF_SHPBXPAGE: | ||||
1124 | m_aStates.top().getShape().setHoriOrientRelation(text::RelOrientation::PAGE_FRAME); | ||||
1125 | m_aStates.top().getShape().setHoriOrientRelationToken( | ||||
1126 | NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromH_page); | ||||
1127 | break; | ||||
1128 | case RTF_SHPBYPAGE: | ||||
1129 | m_aStates.top().getShape().setVertOrientRelation(text::RelOrientation::PAGE_FRAME); | ||||
1130 | m_aStates.top().getShape().setVertOrientRelationToken( | ||||
1131 | NS_ooxml::LN_Value_wordprocessingDrawing_ST_RelFromV_page); | ||||
1132 | break; | ||||
1133 | case RTF_DPLINEHOLLOW: | ||||
1134 | m_aStates.top().getDrawingObject().setFLine(0); | ||||
1135 | break; | ||||
1136 | case RTF_DPROUNDR: | ||||
1137 | if (m_aStates.top().getDrawingObject().getPropertySet().is()) | ||||
1138 | // Seems this old syntax has no way to specify a custom radius, and this is the default | ||||
1139 | m_aStates.top().getDrawingObject().getPropertySet()->setPropertyValue( | ||||
1140 | "CornerRadius", uno::makeAny(sal_Int32(83))); | ||||
1141 | break; | ||||
1142 | case RTF_NOWRAP: | ||||
1143 | m_aStates.top().getFrame().setSprm(NS_ooxml::LN_CT_FramePr_wrap, | ||||
1144 | NS_ooxml::LN_Value_doc_ST_Wrap_notBeside); | ||||
1145 | break; | ||||
1146 | case RTF_MNOR: | ||||
1147 | m_bMathNor = true; | ||||
1148 | break; | ||||
1149 | case RTF_REVISIONS: | ||||
1150 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_trackRevisions, new RTFValue(1)); | ||||
1151 | break; | ||||
1152 | case RTF_BRDRSH: | ||||
1153 | putBorderProperty(m_aStates, NS_ooxml::LN_CT_Border_shadow, new RTFValue(1)); | ||||
1154 | break; | ||||
1155 | case RTF_NOCOLBAL: | ||||
1156 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_noColumnBalance, new RTFValue(1)); | ||||
1157 | break; | ||||
1158 | case RTF_MARGMIRROR: | ||||
1159 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_mirrorMargins, new RTFValue(1)); | ||||
1160 | break; | ||||
1161 | case RTF_SAUTOUPD: | ||||
1162 | m_aStates.top().getTableSprms().set(NS_ooxml::LN_CT_Style_autoRedefine, | ||||
1163 | new RTFValue(1)); | ||||
1164 | break; | ||||
1165 | case RTF_WIDOWCTRL: | ||||
1166 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_widowControl, new RTFValue(1)); | ||||
1167 | break; | ||||
1168 | case RTF_LINEBETCOL: | ||||
1169 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1170 | NS_ooxml::LN_EG_SectPrContents_cols, NS_ooxml::LN_CT_Columns_sep, | ||||
1171 | new RTFValue(1)); | ||||
1172 | break; | ||||
1173 | case RTF_PGNRESTART: | ||||
1174 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1175 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1176 | NS_ooxml::LN_CT_PageNumber_start, new RTFValue(1)); | ||||
1177 | break; | ||||
1178 | case RTF_PGNUCLTR: | ||||
1179 | { | ||||
1180 | auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_upperLetter); | ||||
1181 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1182 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1183 | NS_ooxml::LN_CT_PageNumber_fmt, pIntValue); | ||||
1184 | } | ||||
1185 | break; | ||||
1186 | case RTF_PGNLCLTR: | ||||
1187 | { | ||||
1188 | auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_lowerLetter); | ||||
1189 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1190 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1191 | NS_ooxml::LN_CT_PageNumber_fmt, pIntValue); | ||||
1192 | } | ||||
1193 | break; | ||||
1194 | case RTF_PGNUCRM: | ||||
1195 | { | ||||
1196 | auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_upperRoman); | ||||
1197 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1198 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1199 | NS_ooxml::LN_CT_PageNumber_fmt, pIntValue); | ||||
1200 | } | ||||
1201 | break; | ||||
1202 | case RTF_PGNLCRM: | ||||
1203 | { | ||||
1204 | auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_lowerRoman); | ||||
1205 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1206 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1207 | NS_ooxml::LN_CT_PageNumber_fmt, pIntValue); | ||||
1208 | } | ||||
1209 | break; | ||||
1210 | case RTF_PGNDEC: | ||||
1211 | { | ||||
1212 | auto pIntValue = new RTFValue(NS_ooxml::LN_Value_ST_NumberFormat_decimal); | ||||
1213 | putNestedAttribute(m_aStates.top().getSectionSprms(), | ||||
1214 | NS_ooxml::LN_EG_SectPrContents_pgNumType, | ||||
1215 | NS_ooxml::LN_CT_PageNumber_fmt, pIntValue); | ||||
1216 | } | ||||
1217 | break; | ||||
1218 | case RTF_HTMAUTSP: | ||||
1219 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Compat_doNotUseHTMLParagraphAutoSpacing, | ||||
1220 | new RTFValue(0)); | ||||
1221 | break; | ||||
1222 | case RTF_DNTBLNSBDB: | ||||
1223 | // tdf#128428 switch off longer space sequence | ||||
1224 | m_aSettingsTableSprms.set(NS_ooxml::LN_CT_Settings_longerSpaceSequence, | ||||
1225 | new RTFValue(0)); | ||||
1226 | break; | ||||
1227 | default: | ||||
1228 | { | ||||
1229 | SAL_INFO("writerfilter", "TODO handle flag '" << keywordToString(nKeyword) << "'")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "writerfilter")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break ; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "TODO handle flag '" << keywordToString(nKeyword) << "'") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchflag.cxx" ":" "1229" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO handle flag '" << keywordToString (nKeyword) << "'"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "TODO handle flag '" << keywordToString (nKeyword) << "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchflag.cxx" ":" "1229" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "TODO handle flag '" << keywordToString(nKeyword ) << "'") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchflag.cxx" ":" "1229" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "TODO handle flag '" << keywordToString (nKeyword) << "'"), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "TODO handle flag '" << keywordToString (nKeyword) << "'"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("writerfilter"), ("/home/maarten/src/libreoffice/core/writerfilter/source/rtftok/rtfdispatchflag.cxx" ":" "1229" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||
1230 | aSkip.setParsed(false); | ||||
1231 | } | ||||
1232 | break; | ||||
1233 | } | ||||
1234 | return RTFError::OK; | ||||
1235 | } | ||||
1236 | |||||
1237 | } // namespace writerfilter | ||||
1238 | |||||
1239 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_TOOLS_REF_HXX |
20 | #define INCLUDED_TOOLS_REF_HXX |
21 | |
22 | #include <sal/config.h> |
23 | #include <cassert> |
24 | #include <tools/toolsdllapi.h> |
25 | #include <utility> |
26 | |
27 | /** |
28 | This implements similar functionality to boost::intrusive_ptr |
29 | */ |
30 | |
31 | namespace tools { |
32 | |
33 | /** T must be a class that extends SvRefBase */ |
34 | template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final { |
35 | public: |
36 | SvRef(): pObj(nullptr) {} |
37 | |
38 | SvRef(SvRef&& rObj) noexcept |
39 | { |
40 | pObj = rObj.pObj; |
41 | rObj.pObj = nullptr; |
42 | } |
43 | |
44 | SvRef(SvRef const & rObj): pObj(rObj.pObj) |
45 | { |
46 | if (pObj != nullptr) pObj->AddNextRef(); |
47 | } |
48 | |
49 | SvRef(T * pObjP): pObj(pObjP) |
50 | { |
51 | if (pObj != nullptr) pObj->AddFirstRef(); |
52 | } |
53 | |
54 | ~SvRef() |
55 | { |
56 | if (pObj != nullptr) pObj->ReleaseRef(); |
57 | } |
58 | |
59 | void clear() |
60 | { |
61 | if (pObj != nullptr) { |
62 | T * pRefObj = pObj; |
63 | pObj = nullptr; |
64 | pRefObj->ReleaseRef(); |
65 | } |
66 | } |
67 | |
68 | SvRef & operator =(SvRef const & rObj) |
69 | { |
70 | if (rObj.pObj != nullptr) { |
71 | rObj.pObj->AddNextRef(); |
72 | } |
73 | T * pRefObj = pObj; |
74 | pObj = rObj.pObj; |
75 | if (pRefObj != nullptr) { |
76 | pRefObj->ReleaseRef(); |
77 | } |
78 | return *this; |
79 | } |
80 | |
81 | SvRef & operator =(SvRef && rObj) |
82 | { |
83 | if (pObj != nullptr) { |
84 | pObj->ReleaseRef(); |
85 | } |
86 | pObj = rObj.pObj; |
87 | rObj.pObj = nullptr; |
88 | return *this; |
89 | } |
90 | |
91 | bool is() const { return pObj != nullptr; } |
92 | |
93 | explicit operator bool() const { return is(); } |
94 | |
95 | T * get() const { return pObj; } |
96 | |
97 | T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 97, __extension__ __PRETTY_FUNCTION__)); return pObj; } |
98 | |
99 | T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail ("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 99, __extension__ __PRETTY_FUNCTION__)); return *pObj; } |
100 | |
101 | bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; } |
102 | bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); } |
103 | |
104 | private: |
105 | T * pObj; |
106 | }; |
107 | |
108 | /** |
109 | * This implements similar functionality to std::make_shared. |
110 | */ |
111 | template<typename T, typename... Args> |
112 | SvRef<T> make_ref(Args&& ... args) |
113 | { |
114 | return SvRef<T>(new T(std::forward<Args>(args)...)); |
115 | } |
116 | |
117 | } |
118 | |
119 | /** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */ |
120 | class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase |
121 | { |
122 | // work around a clang 3.5 optimization bug: if the bNoDelete is *first* |
123 | // it mis-compiles "if (--nRefCount == 0)" and never deletes any object |
124 | unsigned int nRefCount : 31; |
125 | // the only reason this is not bool is because MSVC cannot handle mixed type bitfields |
126 | unsigned int bNoDelete : 1; |
127 | |
128 | protected: |
129 | virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE; |
130 | |
131 | public: |
132 | SvRefBase() : nRefCount(0), bNoDelete(1) {} |
133 | SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {} |
134 | |
135 | SvRefBase & operator=(const SvRefBase &) { return *this; } |
136 | |
137 | void RestoreNoDelete() |
138 | { bNoDelete = 1; } |
139 | |
140 | void AddNextRef() |
141 | { |
142 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 142, __extension__ __PRETTY_FUNCTION__)); |
143 | ++nRefCount; |
144 | } |
145 | |
146 | void AddFirstRef() |
147 | { |
148 | assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) && "Do not add refs to dead objects") ? void (0) : __assert_fail ("nRefCount < (1 << 30) && \"Do not add refs to dead objects\"" , "/home/maarten/src/libreoffice/core/include/tools/ref.hxx", 148, __extension__ __PRETTY_FUNCTION__)); |
149 | if( bNoDelete ) |
150 | bNoDelete = 0; |
151 | ++nRefCount; |
152 | } |
153 | |
154 | void ReleaseRef() |
155 | { |
156 | assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail ("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx" , 156, __extension__ __PRETTY_FUNCTION__)); |
157 | if( --nRefCount == 0 && !bNoDelete) |
158 | { |
159 | // I'm not sure about the original purpose of this line, but right now |
160 | // it serves the purpose that anything that attempts to do an AddRef() |
161 | // after an object is deleted will trip an assert. |
162 | nRefCount = 1 << 30; |
163 | delete this; |
164 | } |
165 | } |
166 | |
167 | unsigned int GetRefCount() const |
168 | { return nRefCount; } |
169 | }; |
170 | |
171 | template<typename T> |
172 | class SvCompatWeakBase; |
173 | |
174 | /** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T. |
175 | */ |
176 | template<typename T> |
177 | class SvCompatWeakHdl final : public SvRefBase |
178 | { |
179 | friend class SvCompatWeakBase<T>; |
180 | T* _pObj; |
181 | |
182 | SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {} |
183 | |
184 | public: |
185 | void ResetWeakBase( ) { _pObj = nullptr; } |
186 | T* GetObj() { return _pObj; } |
187 | }; |
188 | |
189 | /** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame. |
190 | Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted. |
191 | */ |
192 | template<typename T> |
193 | class SvCompatWeakBase |
194 | { |
195 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
196 | |
197 | public: |
198 | /** Does not use initializer due to compiler warnings, |
199 | because the lifetime of the _xHdl object can exceed the lifetime of this class. |
200 | */ |
201 | SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); } |
202 | |
203 | ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); } |
204 | |
205 | SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); } |
206 | }; |
207 | |
208 | /** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak. |
209 | */ |
210 | template<typename T> |
211 | class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef |
212 | { |
213 | tools::SvRef< SvCompatWeakHdl<T> > _xHdl; |
214 | public: |
215 | SvCompatWeakRef( ) {} |
216 | SvCompatWeakRef( T* pObj ) |
217 | { if( pObj ) _xHdl = pObj->GetHdl(); } |
218 | #if defined(__COVERITY__) |
219 | ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {} |
220 | #endif |
221 | SvCompatWeakRef& operator = ( T * pObj ) |
222 | { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; } |
223 | bool is() const |
224 | { return _xHdl.is() && _xHdl->GetObj(); } |
225 | explicit operator bool() const { return is(); } |
226 | T* operator -> () const |
227 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
228 | operator T* () const |
229 | { return _xHdl.is() ? _xHdl->GetObj() : nullptr; } |
230 | }; |
231 | |
232 | #endif |
233 | |
234 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |