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 #ifndef INCLUDED_SW_SOURCE_FILTER_INC_MSFILTER_HXX
21 #define INCLUDED_SW_SOURCE_FILTER_INC_MSFILTER_HXX
22 
23 #include <sal/config.h>
24 
25 #include <cstddef>
26 #include <map>
27 #include <vector>
28 #include <memory>
29 #include <swtypes.hxx>
30 #include "wwstyles.hxx"
31 #include <rtl/textenc.h>
32 #include "fltshell.hxx"
33 #include <shellio.hxx>
34 #include <svl/zforlist.hxx>
35 #include <svl/listener.hxx>
36 
37 class SwDoc;
38 class SwPaM;
39 class SwTableNode;
40 class SwNodeIndex;
41 class SwNoTextNode;
42 class SwTextNode;
43 class WW8TabDesc;
44 
45 namespace myImplHelpers
46 {
47 template<class C> class StyleMapperImpl;
48 }
49 
50 class SwTextFormatColl;
51 class SwCharFormat;
52 
53 namespace sw
54 {
55     namespace ms
56     {
57         /** MSOffice appears to set the charset of unicode fonts to MS 932
58 
59             But we do "default", whatever that means.
60 
61             @param eTextEncoding
62                 the OOo encoding to convert from
63 
64             @return
65                 a msoffice equivalent charset identifier
66         */
67         sal_uInt8 rtl_TextEncodingToWinCharset(rtl_TextEncoding eTextEncoding);
68 
69         /** MSOffice appears to set the charset of unicode fonts to MS 932
70 
71             Arial Unicode MS for example is a unicode font, but word sets
72             exported uses of it to the MS 932 charset
73 
74         */
75         sal_uInt8 rtl_TextEncodingToWinCharsetRTF(OUString const& rFontName,
76                 OUString const& rAltName, rtl_TextEncoding eTextEncoding);
77 
78         /** Convert from DTTM to Writer's DateTime
79 
80         */
81         sal_uInt32 DateTime2DTTM( const DateTime& rDT );
82 
83         /** Convert from Word Date/Time field str to Writer's Date Time str
84 
85         */
86         sal_uLong MSDateTimeFormatToSwFormat(OUString& rParams, SvNumberFormatter *pFormatter, LanguageType &rLang, bool bHijri, LanguageType nDocLang);
87 
88         /*Used to identify if the previous token is AM time field*/
89         bool IsPreviousAM(OUString const & rParams, sal_Int32 nPos);
90 
91         /*Used to identify if the next token is PM time field*/
92         bool IsNextPM(OUString const & rParams, sal_Int32 nPos);
93 
94         /** Used by MSDateTimeFormatToSwFormat to identify AM time fields
95 
96         */
97         bool IsNotAM(OUString const & rParams, sal_Int32 nPos);
98 
99         /** Another function used by MSDateTimeFormatToSwFormat
100 
101         */
102         void SwapQuotesInField(OUString &rFormat);
103 
104     }
105 
106     namespace util
107     {
108         /// Redlining Authors, map word author key to writer author value
109         typedef std::map<sal_uInt16, std::size_t> AuthorInfos;
110 
111         /** Clips a value to MAX/MIN 16bit value to make it safe for use
112             as a position value to give to writer. i.e. +-57.8cm. Sometimes
113             we see ridiculous values for positioning in rtf and word document,
114             this captures such ones and clips them to values which are
115             still outside the document, but of a value that doesn't cause
116             problems for writer's layout, e.g. see
117             https://bz.apache.org/ooo/show_bug.cgi?id=i9245
118 
119             @param nIn
120 
121             @return nIn clipped to min/max 16bit value
122         */
123         SwTwips MakeSafePositioningValue(SwTwips nIn);
124 
125         /** Knows which writer style a given word style should be imported as
126 
127             Mapping a word style to a writer style has to consider mapping
128             the word builtin styles like "Normal" as the default root style
129             to our default root style which is called "Default" in english,
130             and "Normal" in german.
131 
132             Additionally it then has to avoid name collisions such as
133 
134             a) styles "Normal" and "Default" in a single document, where
135             we can use the original distinct names "Normal" and "Default" and...
136             b) styles "Normal" and "Default" in a single document, where
137             we can not use the original names, and must come up with an
138             alternative name for one of them...
139 
140             And it needs to report to the importer if the style being mapped to
141             was already in existence, for the cut and paste/insert file mode we
142             should not modify the returned style if it is already in use as it
143             is does not belong to us to change.
144         */
145         class ParaStyleMapper
146         {
147         private:
148             //I hate these things stupid pImpl things, but it's warranted here
149              std::unique_ptr<::myImplHelpers::StyleMapperImpl<SwTextFormatColl> > mpImpl;
150         public:
151             explicit ParaStyleMapper(SwDoc &rDoc);
152             ~ParaStyleMapper();
153 
154             /** StyleResult
155                 StyleResult is a std::pair of a pointer to a style and a flag
156                 which is true if the style existed previously in the document.
157             */
158             typedef std::pair<SwTextFormatColl*, bool> StyleResult;
159 
160             /** Get the writer style which the word style should map to
161 
162                 @param rName
163                 The name of the word style
164 
165                 @param eSti
166                 The style id of the word style, we are really only interested
167                 in knowing if the style has either a builtin standard id, or is
168                 a user defined style.
169 
170                 @return
171                 The equivalent writer style packaged as a StyleResult to use
172                 for this word style.
173 
174                 It will only return a failure in the pathological case of
175                 catastrophic failure elsewhere of there exist already styles
176                 rName and WW-rName[0..SAL_MAX_INT32], which is both unlikely
177                 and impossible.
178             */
179             StyleResult GetStyle(const OUString& rName, ww::sti eSti);
180         };
181 
182         /** Knows which writer style a given word style should be imported as
183 
184             Mapping a word style to a writer style has to consider mapping
185             the word builtin styles like "Normal" as the default root style
186             to our default root style which is called "Default" in english,
187             and "Normal" in german.
188 
189             Additionally it then has to avoid name collisions such as
190 
191             a) styles "Normal" and "Default" in a single document, where
192             we can use the original distinct names "Normal" and "Default" and...
193             b) styles "Normal" and "Default" in a single document, where
194             we can not use the original names, and must come up with an
195             alternative name for one of them...
196 
197             And it needs to report to the importer if the style being mapped to
198             was already in existence, for the cut and paste/insert file mode we
199             should not modify the returned style if it is already in use as it
200             is does not belong to us to change.
201         */
202         class CharStyleMapper
203         {
204         private:
205             //I hate these things stupid pImpl things, but it's warranted here
206             std::unique_ptr<::myImplHelpers::StyleMapperImpl<SwCharFormat>> mpImpl;
207         public:
208             explicit CharStyleMapper(SwDoc &rDoc);
209             ~CharStyleMapper();
210 
211             /** StyleResult
212                 StyleResult is a std::pair of a pointer to a style and a flag
213                 which is true if the style existed previously in the document.
214             */
215             typedef std::pair<SwCharFormat*, bool> StyleResult;
216 
217             /** Get the writer style which the word style should map to
218 
219                 @param rName
220                 The name of the word style
221 
222                 @param eSti
223                 The style id of the word style, we are really only interested
224                 in knowing if the style has either a builtin standard id, or is
225                 a user defined style.
226 
227                 @return
228                 The equivalent writer style packaged as a StyleResult to use
229                 for this word style.
230 
231                 It will only return a failure in the pathological case of
232                 catastrophic failure elsewhere of there exist already styles
233                 rName and WW-rName[0..SAL_MAX_INT32], which is both unlikely
234                 and impossible.
235             */
236             StyleResult GetStyle(const OUString& rName, ww::sti eSti);
237         };
238 
239         /** Find suitable names for exporting this font
240 
241             Given a fontname description find the best primary and secondary
242             fallback font to use from MSWord's persp font
243 
244             @see #i10242#/#i19164# for examples
245         */
246         class FontMapExport
247         {
248         public:
249             OUString msPrimary;
250             OUString msSecondary;
251             explicit FontMapExport(const OUString &rFontDescription);
252         };
253 
254         class InsertedTableListener: public SvtListener
255         {
256             SwTableNode* m_pTableNode;
257         public:
258             explicit InsertedTableListener(SwTableNode& rNode);
259             SwTableNode* GetTableNode();
260             virtual void Notify(const SfxHint&) override;
261         };
262 
263         /** Handle requirements for table formatting in insert->file mode.
264 
265             When inserting a table into a document which already has been
266             formatted and laid out (e.g using insert->file) then tables
267             must be handled in a special way, (or so previous comments and
268             code in the filters leads me to believe).
269 
270             Before the document is finalized the new tables need to have
271             their layout frms deleted and recalculated. This TableManager
272             detects the necessity to do this, and all tables inserted into
273             a document should be registered with this manager with
274             InsertTable, and before finalization DelAndMakeTableFrames should
275             be called.
276 
277             @see #i25782# for examples
278         */
279         class InsertedTablesManager
280         {
281         public:
282             typedef std::map<std::unique_ptr<InsertedTableListener>, SwNodeIndex*> TableMap;
283             void DelAndMakeTableFrames();
284             void InsertTable(SwTableNode &rTableNode, SwPaM &rPaM);
285             explicit InsertedTablesManager(const SwDoc &rDoc);
286         private:
287             bool const mbHasRoot;
288             TableMap maTables;
289         };
290 
291         class RedlineStack
292         {
293         private:
294             std::vector<std::unique_ptr<SwFltStackEntry>> maStack;
295             SwDoc &mrDoc;
296 
297             RedlineStack(RedlineStack const&) = delete;
298             RedlineStack& operator=(RedlineStack const&) = delete;
299 
300         public:
RedlineStack(SwDoc & rDoc)301             explicit RedlineStack(SwDoc &rDoc) : mrDoc(rDoc) {}
302             enum class MoveAttrsMode { Default, FieldmarkInserted };
303             void MoveAttrs(const SwPosition& rPos, MoveAttrsMode eMode = MoveAttrsMode::Default);
304             void open(const SwPosition& rPos, const SfxPoolItem& rAttr);
305             bool close(const SwPosition& rPos, RedlineType eType);
306             void close(const SwPosition& rPos, RedlineType eType,
307                 WW8TabDesc* pTabDesc );
308             void closeall(const SwPosition& rPos);
309             ~RedlineStack();
310         };
311 
312         class SetInDocAndDelete
313         {
314         private:
315             SwDoc &mrDoc;
316         public:
SetInDocAndDelete(SwDoc & rDoc)317             explicit SetInDocAndDelete(SwDoc &rDoc) : mrDoc(rDoc) {}
318             void operator()(std::unique_ptr<SwFltStackEntry> & pEntry);
319         private:
320             SetInDocAndDelete& operator=(const SetInDocAndDelete&) = delete;
321         };
322 
323         class SetEndIfOpen       //Subclass from something ?
324         {
325         private:
326             const SwPosition &mrPos;
327         public:
SetEndIfOpen(const SwPosition & rPos)328             explicit SetEndIfOpen(const SwPosition &rPos) : mrPos(rPos) {}
operator ()(const std::unique_ptr<SwFltStackEntry> & pEntry) const329                 void operator()(const std::unique_ptr<SwFltStackEntry> & pEntry) const
330             {
331                 if (pEntry->bOpen)
332                     pEntry->SetEndPos(mrPos);
333             }
334         private:
335             SetEndIfOpen& operator=(const SetEndIfOpen&) = delete;
336         };
337 
338         class CompareRedlines
339         {
340         public:
341             bool operator()(const std::unique_ptr<SwFltStackEntry> & pOneE, const std::unique_ptr<SwFltStackEntry> & pTwoE)
342                 const;
343         };
344 
345         class WrtRedlineAuthor
346         {
347         protected:
348             std::vector<OUString> maAuthors; // Array of Sw - Bookmarknames
349 
350         private:
351             WrtRedlineAuthor(WrtRedlineAuthor const&) = delete;
352             WrtRedlineAuthor& operator=(WrtRedlineAuthor const&) = delete;
353 
354         public:
355             WrtRedlineAuthor() = default;
~WrtRedlineAuthor()356             virtual ~WrtRedlineAuthor() {}
357 
358             sal_uInt16 AddName( const OUString& rNm );
359             virtual void Write(Writer &rWrt) = 0;
360         };
361 
362         struct CharRunEntry
363         {
364             sal_Int32 mnEndPos;
365             sal_uInt16 mnScript;
366             rtl_TextEncoding meCharSet;
367             bool mbRTL;
CharRunEntrysw::util::CharRunEntry368             CharRunEntry(sal_Int32 nEndPos, sal_uInt16 nScript,
369                 rtl_TextEncoding eCharSet, bool bRTL)
370             : mnEndPos(nEndPos), mnScript(nScript), meCharSet(eCharSet),
371             mbRTL(bRTL)
372             {
373             }
374         };
375 
376         typedef std::vector<CharRunEntry> CharRuns;
377 
378         /** Collect the ranges of Text which share
379 
380             Word generally requires characters which share the same direction,
381             the same script, and occasionally (depending on the format) the
382             same charset to be exported in independent chunks.
383 
384             So this function finds these ranges and returns a STL container
385             of CharRuns
386 
387             @param rTextNd
388                 The TextNode we want to ranges from
389 
390             @return STL container of CharRuns which describe the shared
391             direction, script and optionally script of the contiguous sequences
392             of characters
393 
394             @see #i22537# for example
395         */
396         CharRuns GetPseudoCharRuns(const SwTextNode& rTextNd);
397     }
398 }
399 
400 #endif
401 
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
403