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/document/XDocumentPropertiesSupplier.hpp>
21 #include <com/sun/star/document/XDocumentProperties.hpp>
22 #include <com/sun/star/frame/XModel.hpp>
23 #include <osl/diagnose.h>
24 #include <docsh.hxx>
25 #include <IDocumentFieldsAccess.hxx>
26 #include <svtools/htmltokn.h>
27 #include <svl/zforlist.hxx>
28 #include <unotools/useroptions.hxx>
29 #include <fmtfld.hxx>
30 #include <ndtxt.hxx>
31 #include <doc.hxx>
32 #include <fldbas.hxx>
33 #include <docufld.hxx>
34 #include <flddat.hxx>
35 #include "htmlfld.hxx"
36 #include "swhtml.hxx"
37
38 using namespace nsSwDocInfoSubType;
39 using namespace ::com::sun::star;
40
41 namespace {
42
43 struct HTMLNumFormatTableEntry
44 {
45 const char *pName;
46 NfIndexTableOffset eFormat;
47 };
48
49 }
50
51 HTMLOptionEnum<SwFieldIds> const aHTMLFieldTypeTable[] =
52 {
53 { OOO_STRING_SW_HTML_FT_author, SwFieldIds::Author },
54 { OOO_STRING_SW_HTML_FT_sender, SwFieldIds::ExtUser },
55 { "DATE", SwFieldIds::Date },
56 { "TIME", SwFieldIds::Time },
57 { OOO_STRING_SW_HTML_FT_datetime, SwFieldIds::DateTime },
58 { OOO_STRING_SW_HTML_FT_page, SwFieldIds::PageNumber },
59 { OOO_STRING_SW_HTML_FT_docinfo, SwFieldIds::DocInfo },
60 { OOO_STRING_SW_HTML_FT_docstat, SwFieldIds::DocStat },
61 { OOO_STRING_SW_HTML_FT_filename, SwFieldIds::Filename },
62 { nullptr, SwFieldIds(0) }
63 };
64
65 HTMLNumFormatTableEntry const aHTMLDateFieldFormatTable[] =
66 {
67 { "SSYS", NF_DATE_SYSTEM_SHORT },
68 { "LSYS", NF_DATE_SYSTEM_LONG },
69 { "DMY", NF_DATE_SYS_DDMMYY, },
70 { "DMYY", NF_DATE_SYS_DDMMYYYY, },
71 { "DMMY", NF_DATE_SYS_DMMMYY, },
72 { "DMMYY", NF_DATE_SYS_DMMMYYYY, },
73 { "DMMMY", NF_DATE_DIN_DMMMMYYYY },
74 { "DMMMYY", NF_DATE_DIN_DMMMMYYYY },
75 { "DDMMY", NF_DATE_SYS_NNDMMMYY },
76 { "DDMMMY", NF_DATE_SYS_NNDMMMMYYYY },
77 { "DDMMMYY", NF_DATE_SYS_NNDMMMMYYYY },
78 { "DDDMMMY", NF_DATE_SYS_NNNNDMMMMYYYY },
79 { "DDDMMMYY", NF_DATE_SYS_NNNNDMMMMYYYY },
80 { "MY", NF_DATE_SYS_MMYY },
81 { "MD", NF_DATE_DIN_MMDD },
82 { "YMD", NF_DATE_DIN_YYMMDD },
83 { "YYMD", NF_DATE_DIN_YYYYMMDD },
84 { nullptr, NF_NUMERIC_START }
85 };
86
87 HTMLNumFormatTableEntry const aHTMLTimeFieldFormatTable[] =
88 {
89 { "SYS", NF_TIME_HHMMSS },
90 { "SSMM24", NF_TIME_HHMM },
91 { "SSMM12", NF_TIME_HHMMAMPM },
92 { nullptr, NF_NUMERIC_START }
93 };
94
95 HTMLOptionEnum<SvxNumType> const aHTMLPageNumFieldFormatTable[] =
96 {
97 { OOO_STRING_SW_HTML_FF_uletter, SVX_NUM_CHARS_UPPER_LETTER },
98 { OOO_STRING_SW_HTML_FF_lletter, SVX_NUM_CHARS_LOWER_LETTER },
99 { OOO_STRING_SW_HTML_FF_uroman, SVX_NUM_ROMAN_UPPER },
100 { OOO_STRING_SW_HTML_FF_lroman, SVX_NUM_ROMAN_LOWER },
101 { OOO_STRING_SW_HTML_FF_arabic, SVX_NUM_ARABIC },
102 { OOO_STRING_SW_HTML_FF_none, SVX_NUM_NUMBER_NONE },
103 { OOO_STRING_SW_HTML_FF_char, SVX_NUM_CHAR_SPECIAL },
104 { OOO_STRING_SW_HTML_FF_page, SVX_NUM_PAGEDESC },
105 { OOO_STRING_SW_HTML_FF_ulettern, SVX_NUM_CHARS_UPPER_LETTER_N },
106 { OOO_STRING_SW_HTML_FF_llettern, SVX_NUM_CHARS_LOWER_LETTER_N },
107 { nullptr, SvxNumType(0) }
108 };
109
110 HTMLOptionEnum<SwExtUserSubType> const aHTMLExtUsrFieldSubTable[] =
111 {
112 { OOO_STRING_SW_HTML_FS_company, EU_COMPANY },
113 { OOO_STRING_SW_HTML_FS_firstname, EU_FIRSTNAME },
114 { OOO_STRING_SW_HTML_FS_name, EU_NAME },
115 { OOO_STRING_SW_HTML_FS_shortcut, EU_SHORTCUT },
116 { OOO_STRING_SW_HTML_FS_street, EU_STREET },
117 { OOO_STRING_SW_HTML_FS_country, EU_COUNTRY },
118 { OOO_STRING_SW_HTML_FS_zip, EU_ZIP },
119 { OOO_STRING_SW_HTML_FS_city, EU_CITY },
120 { OOO_STRING_SW_HTML_FS_title, EU_TITLE },
121 { OOO_STRING_SW_HTML_FS_position, EU_POSITION },
122 { OOO_STRING_SW_HTML_FS_pphone, EU_PHONE_PRIVATE },
123 { OOO_STRING_SW_HTML_FS_cphone, EU_PHONE_COMPANY },
124 { OOO_STRING_SW_HTML_FS_fax, EU_FAX },
125 { OOO_STRING_SW_HTML_FS_email, EU_EMAIL },
126 { OOO_STRING_SW_HTML_FS_state, EU_STATE },
127 { nullptr, SwExtUserSubType(0) }
128 };
129
130 HTMLOptionEnum<SwAuthorFormat> const aHTMLAuthorFieldFormatTable[] =
131 {
132 { OOO_STRING_SW_HTML_FF_name, AF_NAME },
133 { OOO_STRING_SW_HTML_FF_shortcut, AF_SHORTCUT },
134 { nullptr, SwAuthorFormat(0) }
135 };
136
137 HTMLOptionEnum<SwPageNumSubType> const aHTMLPageNumFieldSubTable[] =
138 {
139 { OOO_STRING_SW_HTML_FS_random, PG_RANDOM },
140 { OOO_STRING_SW_HTML_FS_next, PG_NEXT },
141 { OOO_STRING_SW_HTML_FS_prev, PG_PREV },
142 { nullptr, SwPageNumSubType(0) }
143 };
144
145 // UGLY: these are extensions of nsSwDocInfoSubType (in inc/docufld.hxx)
146 // these are necessary for importing document info fields written by
147 // older versions of OOo (< 3.0) which did not have DI_CUSTOM fields
148 const SwDocInfoSubType DI_INFO1 = DI_SUBTYPE_END + 1;
149 const SwDocInfoSubType DI_INFO2 = DI_SUBTYPE_END + 2;
150 const SwDocInfoSubType DI_INFO3 = DI_SUBTYPE_END + 3;
151 const SwDocInfoSubType DI_INFO4 = DI_SUBTYPE_END + 4;
152
153 HTMLOptionEnum<sal_uInt16> const aHTMLDocInfoFieldSubTable[] =
154 {
155 { OOO_STRING_SW_HTML_FS_title, DI_TITLE },
156 { OOO_STRING_SW_HTML_FS_theme, DI_SUBJECT },
157 { OOO_STRING_SW_HTML_FS_keys, DI_KEYS },
158 { OOO_STRING_SW_HTML_FS_comment, DI_COMMENT },
159 { "INFO1", DI_INFO1 },
160 { "INFO2", DI_INFO2 },
161 { "INFO3", DI_INFO3 },
162 { "INFO4", DI_INFO4 },
163 { OOO_STRING_SW_HTML_FS_custom, DI_CUSTOM },
164 { OOO_STRING_SW_HTML_FS_create, DI_CREATE },
165 { OOO_STRING_SW_HTML_FS_change, DI_CHANGE },
166 { nullptr, 0 }
167 };
168
169 HTMLOptionEnum<sal_uInt16> const aHTMLDocInfoFieldFormatTable[] =
170 {
171 { OOO_STRING_SW_HTML_FF_author, DI_SUB_AUTHOR },
172 { OOO_STRING_SW_HTML_FF_time, DI_SUB_TIME },
173 { OOO_STRING_SW_HTML_FF_date, DI_SUB_DATE },
174 { nullptr, 0 }
175 };
176
177 HTMLOptionEnum<SwDocStatSubType> const aHTMLDocStatFieldSubTable[] =
178 {
179 { OOO_STRING_SW_HTML_FS_page, DS_PAGE },
180 { OOO_STRING_SW_HTML_FS_para, DS_PARA },
181 { OOO_STRING_SW_HTML_FS_word, DS_WORD },
182 { OOO_STRING_SW_HTML_FS_char, DS_CHAR },
183 { OOO_STRING_SW_HTML_FS_tbl, DS_TBL },
184 { OOO_STRING_SW_HTML_FS_grf, DS_GRF },
185 { OOO_STRING_SW_HTML_FS_ole, DS_OLE },
186 { nullptr, SwDocStatSubType(0) }
187 };
188
189 HTMLOptionEnum<SwFileNameFormat> const aHTMLFileNameFieldFormatTable[] =
190 {
191 { OOO_STRING_SW_HTML_FF_name, FF_NAME },
192 { OOO_STRING_SW_HTML_FF_pathname, FF_PATHNAME },
193 { OOO_STRING_SW_HTML_FF_path, FF_PATH },
194 { OOO_STRING_SW_HTML_FF_name_noext, FF_NAME_NOEXT },
195 { nullptr, SwFileNameFormat(0) }
196 };
197
GetNumType(const OUString & rStr,SvxNumType nDfltType)198 SvxNumType SwHTMLParser::GetNumType( const OUString& rStr, SvxNumType nDfltType )
199 {
200 const HTMLOptionEnum<SvxNumType> *pOptEnums = aHTMLPageNumFieldFormatTable;
201 while( pOptEnums->pName )
202 {
203 if( rStr.equalsIgnoreAsciiCaseAscii( pOptEnums->pName ) )
204 return pOptEnums->nValue;
205 pOptEnums++;
206 }
207 return nDfltType;
208 }
209
NewField()210 void SwHTMLParser::NewField()
211 {
212 bool bKnownType = false, bFixed = false,
213 bHasNumFormat = false, bHasNumValue = false;
214 SwFieldIds nType = SwFieldIds::Database;
215 OUString aValue, aNumFormat, aNumValue, aName;
216 const HTMLOption *pSubOption=nullptr, *pFormatOption=nullptr;
217
218 const HTMLOptions& rHTMLOptions = GetOptions();
219 size_t i;
220
221 for ( i = rHTMLOptions.size(); i; )
222 {
223 const HTMLOption& rOption = rHTMLOptions[--i];
224 switch( rOption.GetToken() )
225 {
226 case HtmlOptionId::TYPE:
227 bKnownType = rOption.GetEnum( nType, aHTMLFieldTypeTable );
228 break;
229 case HtmlOptionId::SUBTYPE:
230 pSubOption = &rOption;
231 break;
232 case HtmlOptionId::FORMAT:
233 pFormatOption = &rOption;
234 break;
235 case HtmlOptionId::NAME:
236 aName = rOption.GetString();
237 break;
238 case HtmlOptionId::VALUE:
239 aValue = rOption.GetString();
240 break;
241 case HtmlOptionId::SDNUM:
242 aNumFormat = rOption.GetString();
243 bHasNumFormat = true;
244 break;
245 case HtmlOptionId::SDVAL:
246 aNumValue = rOption.GetString();
247 bHasNumValue = true;
248 break;
249 case HtmlOptionId::SDFIXED:
250 bFixed = true;
251 break;
252 default: break;
253 }
254 }
255
256 if( !bKnownType )
257 return;
258
259 // Author and sender are only inserted as a variable field if the document
260 // was last changed by ourself or nobody changed it and it was created
261 // by ourself. Otherwise it will be a fixed field.
262 if( !bFixed &&
263 (SwFieldIds::ExtUser == nType ||
264 SwFieldIds::Author == nType) )
265 {
266 SvtUserOptions aOpt;
267 const OUString& rUser = aOpt.GetFullName();
268 SwDocShell *pDocShell(m_xDoc->GetDocShell());
269 OSL_ENSURE(pDocShell, "no SwDocShell");
270 if (pDocShell) {
271 uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
272 pDocShell->GetModel(), uno::UNO_QUERY_THROW);
273 uno::Reference<document::XDocumentProperties> xDocProps(
274 xDPS->getDocumentProperties());
275 OSL_ENSURE(xDocProps.is(), "Doc has no DocumentProperties");
276 const OUString& rChanged = xDocProps->getModifiedBy();
277 const OUString& rCreated = xDocProps->getAuthor();
278 if( rUser.isEmpty() ||
279 (!rChanged.isEmpty() ? rUser != rChanged : rUser != rCreated) )
280 bFixed = true;
281 }
282 }
283
284 SwFieldIds nWhich = nType;
285 if( SwFieldIds::Date==nType || SwFieldIds::Time==nType )
286 nWhich = SwFieldIds::DateTime;
287
288 SwFieldType* pType = m_xDoc->getIDocumentFieldsAccess().GetSysFieldType( nWhich );
289 std::unique_ptr<SwField> xNewField;
290 bool bInsOnEndTag = false;
291
292 switch( nType )
293 {
294 case SwFieldIds::ExtUser:
295 if( pSubOption )
296 {
297 SwExtUserSubType nSub;
298 sal_uLong nFormat = 0;
299 if( bFixed )
300 {
301 nFormat |= AF_FIXED;
302 bInsOnEndTag = true;
303 }
304 if( pSubOption->GetEnum( nSub, aHTMLExtUsrFieldSubTable ) )
305 xNewField.reset(new SwExtUserField(static_cast<SwExtUserFieldType*>(pType), nSub, nFormat));
306 }
307 break;
308
309 case SwFieldIds::Author:
310 {
311 SwAuthorFormat nFormat = AF_NAME;
312 if( pFormatOption )
313 pFormatOption->GetEnum( nFormat, aHTMLAuthorFieldFormatTable );
314 if( bFixed )
315 {
316 nFormat = static_cast<SwAuthorFormat>(static_cast<int>(nFormat) | AF_FIXED);
317 bInsOnEndTag = true;
318 }
319
320 xNewField.reset(new SwAuthorField(static_cast<SwAuthorFieldType*>(pType), nFormat));
321 }
322 break;
323
324 case SwFieldIds::Date:
325 case SwFieldIds::Time:
326 {
327 sal_uInt32 nNumFormat = 0;
328 DateTime aDateTime( DateTime::SYSTEM );
329 sal_Int64 nTime = aDateTime.GetTime();
330 sal_Int32 nDate = aDateTime.GetDate();
331 sal_uInt16 nSub = 0;
332 bool bValidFormat = false;
333 HTMLNumFormatTableEntry const * pFormatTable;
334
335 if( SwFieldIds::Date==nType )
336 {
337 nSub = DATEFLD;
338 pFormatTable = aHTMLDateFieldFormatTable;
339 if( !aValue.isEmpty() )
340 nDate = aValue.toInt32();
341 }
342 else
343 {
344 nSub = TIMEFLD;
345 pFormatTable = aHTMLTimeFieldFormatTable;
346 if( !aValue.isEmpty() )
347 nTime = static_cast<sal_uLong>(aValue.toInt32());
348 }
349 if( !aValue.isEmpty() )
350 nSub |= FIXEDFLD;
351
352 SvNumberFormatter *pFormatter = m_xDoc->GetNumberFormatter();
353 if( pFormatOption )
354 {
355 const OUString& rFormat = pFormatOption->GetString();
356 for( int k = 0; pFormatTable[k].pName; ++k )
357 {
358 if( rFormat.equalsIgnoreAsciiCaseAscii( pFormatTable[k].pName ) )
359 {
360 nNumFormat = pFormatter->GetFormatIndex(
361 pFormatTable[k].eFormat, LANGUAGE_SYSTEM);
362 bValidFormat = true;
363 break;
364 }
365 }
366 }
367 if( !bValidFormat )
368 nNumFormat = pFormatter->GetFormatIndex( pFormatTable[i].eFormat,
369 LANGUAGE_SYSTEM);
370
371 xNewField.reset(new SwDateTimeField(static_cast<SwDateTimeFieldType *>(pType), nSub, nNumFormat));
372
373 if (nSub & FIXEDFLD)
374 static_cast<SwDateTimeField *>(xNewField.get())->SetDateTime(DateTime(Date(nDate), tools::Time(nTime)));
375 }
376 break;
377
378 case SwFieldIds::DateTime:
379 if( bHasNumFormat )
380 {
381 sal_uInt16 nSub = 0;
382
383 SvNumberFormatter *pFormatter = m_xDoc->GetNumberFormatter();
384 sal_uInt32 nNumFormat;
385 LanguageType eLang;
386 double dValue = GetTableDataOptionsValNum(
387 nNumFormat, eLang, aNumValue, aNumFormat,
388 *m_xDoc->GetNumberFormatter() );
389 SvNumFormatType nFormatType = pFormatter->GetType( nNumFormat );
390 switch( nFormatType )
391 {
392 case SvNumFormatType::DATE: nSub = DATEFLD; break;
393 case SvNumFormatType::TIME: nSub = TIMEFLD; break;
394 default: break;
395 }
396
397 if( nSub )
398 {
399 if( bHasNumValue )
400 nSub |= FIXEDFLD;
401
402 xNewField.reset(new SwDateTimeField(static_cast<SwDateTimeFieldType *>(pType), nSub, nNumFormat));
403 if (bHasNumValue)
404 static_cast<SwDateTimeField*>(xNewField.get())->SetValue(dValue);
405 }
406 }
407 break;
408
409 case SwFieldIds::PageNumber:
410 if( pSubOption )
411 {
412 SwPageNumSubType nSub;
413 if( pSubOption->GetEnum( nSub, aHTMLPageNumFieldSubTable ) )
414 {
415 SvxNumType nFormat = SVX_NUM_PAGEDESC;
416 if( pFormatOption )
417 pFormatOption->GetEnum( nFormat, aHTMLPageNumFieldFormatTable );
418
419 short nOff = 0;
420
421 if( nFormat!=SVX_NUM_CHAR_SPECIAL && !aValue.isEmpty() )
422 nOff = static_cast<short>(aValue.toInt32());
423 else if( nSub == PG_NEXT )
424 nOff = 1;
425 else if( nSub == PG_PREV )
426 nOff = -1;
427
428 if( nFormat==SVX_NUM_CHAR_SPECIAL &&
429 nSub==PG_RANDOM )
430 nFormat = SVX_NUM_PAGEDESC;
431
432 xNewField.reset(new SwPageNumberField(static_cast<SwPageNumberFieldType*>(pType), nSub, nFormat, nOff));
433 if (nFormat == SVX_NUM_CHAR_SPECIAL)
434 static_cast<SwPageNumberField*>(xNewField.get())->SetUserString(aValue);
435 }
436 }
437 break;
438
439 case SwFieldIds::DocInfo:
440 if( pSubOption )
441 {
442 sal_uInt16 nSub;
443 if( pSubOption->GetEnum( nSub, aHTMLDocInfoFieldSubTable ) )
444 {
445 sal_uInt16 nExtSub = 0;
446 if( DI_CREATE==static_cast<SwDocInfoSubType>(nSub) ||
447 DI_CHANGE==static_cast<SwDocInfoSubType>(nSub) )
448 {
449 nExtSub = DI_SUB_AUTHOR;
450 if( pFormatOption )
451 pFormatOption->GetEnum( nExtSub, aHTMLDocInfoFieldFormatTable );
452 nSub |= nExtSub;
453 }
454
455 sal_uInt32 nNumFormat = 0;
456 double dValue = 0;
457 if( bHasNumFormat && (DI_SUB_DATE==nExtSub || DI_SUB_TIME==nExtSub) )
458 {
459 LanguageType eLang;
460 dValue = GetTableDataOptionsValNum(
461 nNumFormat, eLang, aNumValue, aNumFormat,
462 *m_xDoc->GetNumberFormatter() );
463 bFixed &= bHasNumValue;
464 }
465 else
466 bHasNumValue = false;
467
468 if( nSub >= DI_INFO1 && nSub <= DI_INFO4 && aName.isEmpty() )
469 {
470 // backward compatibility for OOo 2:
471 // map to names stored in AddMetaUserDefined
472 aName = m_InfoNames[nSub - DI_INFO1];
473 nSub = DI_CUSTOM;
474 }
475
476 if( bFixed )
477 {
478 nSub |= DI_SUB_FIXED;
479 bInsOnEndTag = true;
480 }
481
482 xNewField.reset(new SwDocInfoField(static_cast<SwDocInfoFieldType *>(pType), nSub, aName, nNumFormat));
483 if (bHasNumValue)
484 static_cast<SwDocInfoField*>(xNewField.get())->SetValue(dValue);
485 }
486 }
487 break;
488
489 case SwFieldIds::DocStat:
490 if( pSubOption )
491 {
492 SwDocStatSubType nSub;
493 if( pSubOption->GetEnum( nSub, aHTMLDocStatFieldSubTable ) )
494 {
495 SvxNumType nFormat = SVX_NUM_ARABIC;
496 if( pFormatOption )
497 pFormatOption->GetEnum( nFormat, aHTMLPageNumFieldFormatTable );
498 xNewField.reset(new SwDocStatField(static_cast<SwDocStatFieldType*>(pType), nSub, nFormat));
499 m_bUpdateDocStat |= (DS_PAGE != nSub);
500 }
501 }
502 break;
503
504 case SwFieldIds::Filename:
505 {
506 SwFileNameFormat nFormat = FF_NAME;
507 if( pFormatOption )
508 pFormatOption->GetEnum( nFormat, aHTMLFileNameFieldFormatTable );
509 if( bFixed )
510 {
511 nFormat = static_cast<SwFileNameFormat>(static_cast<int>(nFormat) | FF_FIXED);
512 bInsOnEndTag = true;
513 }
514
515 xNewField.reset(new SwFileNameField(static_cast<SwFileNameFieldType*>(pType), nFormat));
516 }
517 break;
518 default:
519 ;
520 }
521
522 if (!xNewField)
523 return;
524
525 if (bInsOnEndTag)
526 {
527 m_xField = std::move(xNewField);
528 }
529 else
530 {
531 m_xDoc->getIDocumentContentOperations().InsertPoolItem(*m_pPam, SwFormatField(*xNewField));
532 xNewField.reset();
533 }
534 m_bInField = true;
535 }
536
EndField()537 void SwHTMLParser::EndField()
538 {
539 if (m_xField)
540 {
541 switch (m_xField->Which())
542 {
543 case SwFieldIds::DocInfo:
544 OSL_ENSURE( static_cast<SwDocInfoField*>(m_xField.get())->IsFixed(),
545 "Field DocInfo should not have been saved" );
546 static_cast<SwDocInfoField*>(m_xField.get())->SetExpansion( m_aContents );
547 break;
548
549 case SwFieldIds::ExtUser:
550 OSL_ENSURE( static_cast<SwExtUserField*>(m_xField.get())->IsFixed(),
551 "Field ExtUser should not have been saved" );
552 static_cast<SwExtUserField*>(m_xField.get())->SetExpansion( m_aContents );
553 break;
554
555 case SwFieldIds::Author:
556 OSL_ENSURE( static_cast<SwAuthorField*>(m_xField.get())->IsFixed(),
557 "Field Author should not have been saved" );
558 static_cast<SwAuthorField*>(m_xField.get())->SetExpansion( m_aContents );
559 break;
560
561 case SwFieldIds::Filename:
562 OSL_ENSURE( static_cast<SwFileNameField*>(m_xField.get())->IsFixed(),
563 "Field FileName should not have been saved" );
564 static_cast<SwFileNameField*>(m_xField.get())->SetExpansion( m_aContents );
565 break;
566 default: break;
567 }
568
569 m_xDoc->getIDocumentContentOperations().InsertPoolItem( *m_pPam, SwFormatField(*m_xField) );
570 m_xField.reset();
571 }
572
573 m_bInField = false;
574 m_aContents.clear();
575 }
576
InsertFieldText()577 void SwHTMLParser::InsertFieldText()
578 {
579 if (m_xField)
580 {
581 // append the current text part to the text
582 m_aContents += aToken;
583 }
584 }
585
InsertCommentText(const char * pTag)586 void SwHTMLParser::InsertCommentText( const char *pTag )
587 {
588 bool bEmpty = m_aContents.isEmpty();
589 if( !bEmpty )
590 m_aContents += "\n";
591
592 m_aContents += aToken;
593 if( bEmpty && pTag )
594 {
595 m_aContents = OUString::Concat("HTML: <") + OUStringChar(*pTag) + ">" + m_aContents;
596 }
597 }
598
InsertComment(const OUString & rComment,const char * pTag)599 void SwHTMLParser::InsertComment( const OUString& rComment, const char *pTag )
600 {
601 OUString aComment( rComment );
602 if( pTag )
603 {
604 aComment += "</" +
605 OUString::createFromAscii(pTag) +
606 ">";
607 }
608
609 // MIB 24.06.97: If a PostIt should be insert after a space, we
610 // will insert before the space. Then there are less problems
611 // during formatting. (bug #40483#)
612 const sal_Int32 nPos = m_pPam->GetPoint()->nContent.GetIndex();
613 SwTextNode *pTextNd = m_pPam->GetNode().GetTextNode();
614 bool bMoveFwd = false;
615 if (nPos>0 && pTextNd && (' ' == pTextNd->GetText()[nPos-1]))
616 {
617 bMoveFwd = true;
618
619 sal_uLong nNodeIdx = m_pPam->GetPoint()->nNode.GetIndex();
620 const sal_Int32 nIdx = m_pPam->GetPoint()->nContent.GetIndex();
621 for( auto i = m_aSetAttrTab.size(); i > 0; )
622 {
623 HTMLAttr *pAttr = m_aSetAttrTab[--i];
624 if( pAttr->GetStartParagraphIdx() != nNodeIdx ||
625 pAttr->GetStartContent() != nIdx )
626 break;
627
628 if( RES_TXTATR_FIELD == pAttr->m_pItem->Which() &&
629 SwFieldIds::Script == static_cast<const SwFormatField *>(pAttr->m_pItem.get())->GetField()->GetTyp()->Which() )
630 {
631 bMoveFwd = false;
632 break;
633 }
634 }
635
636 if( bMoveFwd )
637 m_pPam->Move( fnMoveBackward );
638 }
639
640 SwPostItField aPostItField(
641 static_cast<SwPostItFieldType*>(m_xDoc->getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Postit )),
642 OUString(), aComment, OUString(), OUString(), DateTime(DateTime::SYSTEM));
643 InsertAttr( SwFormatField( aPostItField ), false );
644
645 if( bMoveFwd )
646 m_pPam->Move( fnMoveForward );
647 }
648
649 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
650