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 #pragma once
21 
22 #include <memory>
23 #include <string_view>
24 
25 #include "ftools.hxx"
26 #include <rangelst.hxx>
27 #include "xladdress.hxx"
28 #include "xeroot.hxx"
29 #include "xlstring.hxx"
30 
31 // Export progress bar ========================================================
32 
33 class ScfProgressBar;
34 
35 /** The main progress bar for the export filter.
36 
37     This class encapsulates creation and initialization of sub progress
38     segments. The Activate***Segment() functions activate a specific segment
39     of the main progress bar. The implementation of these functions contain the
40     calculation of the needed size of the segment. Following calls of the
41     Progress() function increase the currently activated sub segment.
42  */
43 class XclExpProgressBar : protected XclExpRoot
44 {
45 public:
46     explicit            XclExpProgressBar( const XclExpRoot& rRoot );
47     virtual             ~XclExpProgressBar() override;
48 
49     /** Initializes all segments and sub progress bars. */
50     void                Initialize();
51 
52     /** Increases the number of existing ROW records by 1. */
53     void                IncRowRecordCount();
54 
55     /** Activates the progress segment to create ROW records. */
56     void                ActivateCreateRowsSegment();
57     /** Activates the progress segment to finalize ROW records. */
58     void                ActivateFinalRowsSegment();
59 
60     /** Increases the currently activated (sub) progress bar by 1 step. */
61     void                Progress();
62 
63 private:
64     typedef std::unique_ptr< ScfProgressBar > ScfProgressBarPtr;
65 
66     ScfProgressBarPtr   mxProgress;         /// Progress bar implementation.
67     ScfProgressBar*     mpSubProgress;      /// Current sub progress bar.
68 
69     ScfProgressBar*     mpSubRowCreate;     /// Sub progress bar for creating table rows.
70     ScfInt32Vec         maSubSegRowCreate;  /// Segment ID's for all sheets in sub progress bar.
71 
72     ScfProgressBar*     mpSubRowFinal;      /// Sub progress bar for finalizing ROW records.
73     sal_Int32           mnSegRowFinal;      /// Progress segment for finalizing ROW records.
74 
75     std::size_t         mnRowCount;         /// Number of created ROW records.
76 };
77 
78 // Calc->Excel cell address/range conversion ==================================
79 
80 /** Provides functions to convert Calc cell addresses to Excel cell addresses. */
81 class XclExpAddressConverter : public XclAddressConverterBase
82 {
83 public:
84     explicit            XclExpAddressConverter( const XclExpRoot& rRoot );
85 
86     // cell address -----------------------------------------------------------
87 
88     /** Checks if the passed Calc cell address is valid.
89         @param rScPos  The Calc cell address to check.
90         @param bWarn  true = Sets the internal flag that produces a warning box
91             after loading/saving the file, if the cell address is not valid.
92         @return  true = Cell address in rScPos is valid. */
93     bool                CheckAddress( const ScAddress& rScPos, bool bWarn );
94 
95     /** Converts the passed Calc cell address to an Excel cell address.
96         @param rXclPos  (Out) The converted Excel cell address, if valid.
97         @param rScPos  The Calc cell address to convert.
98         @param bWarn  true = Sets the internal flag that produces a warning box
99             after loading/saving the file, if the cell address is not valid.
100         @return  true = Cell address returned in rXclPos is valid. */
101     bool                ConvertAddress( XclAddress& rXclPos,
102                             const ScAddress& rScPos, bool bWarn );
103 
104     /** Returns a valid cell address by moving it into allowed dimensions.
105         @param rScPos  The Calc cell address to convert.
106         @param bWarn  true = Sets the internal flag that produces a warning box
107             after loading/saving the file, if the cell address is invalid.
108         @return  The converted Excel cell address. */
109     XclAddress          CreateValidAddress( const ScAddress& rScPos, bool bWarn );
110 
111     // cell range -------------------------------------------------------------
112 
113     /** Checks if the passed cell range is valid (checks start and end position).
114         @param rScRange  The Calc cell range to check.
115         @param bWarn  true = Sets the internal flag that produces a warning box
116             after loading/saving the file, if the cell range is not valid.
117         @return  true = Cell range in rScRange is valid. */
118     bool                CheckRange( const ScRange& rScRange, bool bWarn );
119 
120     /** Checks and eventually crops the cell range to valid dimensions.
121         @descr  The start position of the range will not be modified.
122         @param rScRange  (In/out) The cell range to validate.
123         @param bWarn  true = Sets the internal flag that produces a warning box
124             after loading/saving the file, if the cell range contains invalid
125             cells. If the range is partly valid, this function sets the warning
126             flag, corrects the range and returns true.
127         @return  true = Cell range in rScRange is valid (original or cropped). */
128     bool                ValidateRange( ScRange& rScRange, bool bWarn );
129 
130     /** Converts the passed Calc cell range to an Excel cell range.
131         @param rXclRange  (Out) The converted Excel cell range, if valid.
132         @param rScRange  The Calc cell range to convert.
133         @param bWarn  true = Sets the internal flag that produces a warning box
134             after loading/saving the file, if the cell range contains invalid cells.
135         @return  true = Cell range returned in rXclRange is valid (original or cropped). */
136     bool                ConvertRange( XclRange& rXclRange, const ScRange& rScRange, bool bWarn );
137 
138     // cell range list --------------------------------------------------------
139 
140     /** Checks and eventually crops the cell ranges to valid dimensions.
141         @descr  The start position of the ranges will not be modified. Cell
142             ranges that fit partly into valid dimensions are cropped
143             accordingly. Cell ranges that do not fit at all, are removed from
144             the cell range list.
145         @param rScRanges  (In/out) The cell range list to check.
146         @param bWarn  true = Sets the internal flag that produces a warning box
147             after loading/saving the file, if at least one of the cell ranges
148             contains invalid cells. */
149     void                ValidateRangeList( ScRangeList& rScRanges, bool bWarn );
150 
151     /** Converts the passed Calc cell range list to an Excel cell range list.
152         @descr  The start position of the ranges will not be modified. Cell
153             ranges that fit partly into valid dimensions are cropped
154             accordingly. Cell ranges that do not fit at all, are not inserted
155             into the Excel cell range list.
156         @param rXclRanges  (Out) The converted Excel cell range list.
157         @param rScRanges  The Calc cell range list to convert.
158         @param bWarn  true = Sets the internal flag that produces a warning box
159             after loading/saving the file, if at least one of the cell ranges
160             contains invalid cells. */
161     void                ConvertRangeList( XclRangeList& rXclRanges,
162                             const ScRangeList& rScRanges, bool bWarn );
163 };
164 
165 // EditEngine->String conversion ==============================================
166 
167 class SvxURLField;
168 class XclExpHyperlink;
169 
170 /** Helper to create HLINK records during creation of formatted cell strings.
171 
172     In Excel it is not possible to have more than one hyperlink in a cell. This
173     helper detects multiple occurrences of hyperlinks and fills a string which
174     is used to create a cell note containing all URLs. Only cells containing
175     one hyperlink are exported as hyperlink cells.
176  */
177 class XclExpHyperlinkHelper : protected XclExpRoot
178 {
179 public:
180     typedef rtl::Reference< XclExpHyperlink > XclExpHyperlinkRef;
181 
182     explicit            XclExpHyperlinkHelper( const XclExpRoot& rRoot, const ScAddress& rScPos );
183                         virtual ~XclExpHyperlinkHelper() override;
184 
185     /** Processes the passed URL field (tries to create a HLINK record).
186         @return  The representation string of the URL field. */
187     OUString ProcessUrlField( const SvxURLField& rUrlField );
188 
189     /** Returns true, if a single HLINK record has been created. */
190     bool                HasLinkRecord() const;
191     /** Returns the created single HLINk record, or an empty reference. */
192     XclExpHyperlinkRef  GetLinkRecord() const;
193 
194     /** Returns true, if multiple URLs have been processed. */
HasMultipleUrls() const195     bool         HasMultipleUrls() const { return mbMultipleUrls; }
196     /** Returns a string containing all processed URLs. */
GetUrlList() const197     const OUString& GetUrlList() const { return maUrlList; }
198 
199 private:
200     XclExpHyperlinkRef  mxLinkRec;          /// Created HLINK record.
201     ScAddress           maScPos;            /// Cell position to set at the HLINK record.
202     OUString            maUrlList;          /// List with all processed URLs.
203     bool                mbMultipleUrls;     /// true = Multiple URL fields processed.
204 };
205 
206 class EditEngine;
207 class EditTextObject;
208 class SdrTextObj;
209 class ScPatternAttr;
210 
211 /** This class provides methods to create an XclExpString.
212     @descr  The string can be created from an edit engine text object or
213     directly from a Calc edit cell. */
214 class XclExpStringHelper
215 {
216 public:
217     /** removes copy constructor */
218     XclExpStringHelper(const XclExpStringHelper &) = delete;
219     /** remove copy-assignment operator */
220     const XclExpStringHelper& operator=(const XclExpStringHelper&) = delete;
221     /** We don't want anybody to instantiate this class, since it is just a
222         collection of static methods */
223     XclExpStringHelper() = delete;
224 
225     /** Creates a new unformatted string from the passed string.
226         @descr  Creates a Unicode string or a byte string, depending on the
227                 current BIFF version contained in the passed XclExpRoot object.
228         @param rString  The source string.
229         @param nFlags  Modifiers for string export.
230         @param nMaxLen  The maximum number of characters to store in this string.
231         @return  The new string object (shared pointer). */
232     static XclExpStringRef CreateString(
233                             const XclExpRoot& rRoot,
234                             const OUString& rString,
235                             XclStrFlags nFlags = XclStrFlags::NONE,
236                             sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
237 
238     /** Creates a new unformatted string from the passed character.
239         @descr  Creates a Unicode string or a byte string, depending on the
240                 current BIFF version contained in the passed XclExpRoot object.
241         @param cChar  The source character. The NUL character is explicitly allowed.
242         @param nFlags  Modifiers for string export.
243         @param nMaxLen  The maximum number of characters to store in this string.
244         @return  The new string object (shared pointer). */
245     static XclExpStringRef CreateString(
246                             const XclExpRoot& rRoot,
247                             sal_Unicode cChar,
248                             XclStrFlags nFlags = XclStrFlags::NONE,
249                             sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
250 
251     /** Appends an unformatted string to an Excel string object.
252         @descr  Selects the correct Append() function depending on the current
253                 BIFF version contained in the passed XclExpRoot object.
254         @param rXclString  The Excel string object.
255         @param rString  The source string. */
256     static void         AppendString(
257                             XclExpString& rXclString,
258                             const XclExpRoot& rRoot,
259                             const OUString& rString );
260 
261     /** Appends a character to an Excel string object.
262         @descr  Selects the correct Append() function depending on the current
263                 BIFF version contained in the passed XclExpRoot object.
264         @param rXclString  The Excel string object.
265         @param rString  The source string. */
266     static void         AppendChar(
267                             XclExpString& rXclString,
268                             const XclExpRoot& rRoot,
269                             sal_Unicode cChar );
270 
271     /** Creates a new formatted string from a Calc string cell.
272         @descr  Creates a Unicode string or a byte string, depending on the
273                 current BIFF version contained in the passed XclExpRoot object.
274                 May create a formatted string object, if the cell text contains
275                 different script types.
276         @param rStringCell  The Calc string cell object.
277         @param pCellAttr  The set item containing the cell formatting.
278         @param nFlags  Modifiers for string export.
279         @param nMaxLen  The maximum number of characters to store in this string.
280         @return  The new string object (shared pointer). */
281     static XclExpStringRef CreateCellString(
282                             const XclExpRoot& rRoot,
283                             const OUString& rString,
284                             const ScPatternAttr* pCellAttr,
285                             XclStrFlags nFlags = XclStrFlags::NONE,
286                             sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
287 
288     /** Creates a new formatted string from a Calc edit cell.
289         @descr  Creates a Unicode string or a byte string, depending on the
290                 current BIFF version contained in the passed XclExpRoot object.
291         @param rEditCell  The Calc edit cell object.
292         @param pCellAttr  The set item containing the cell formatting.
293         @param rLinkHelper  Helper object for hyperlink conversion.
294         @param nFlags  Modifiers for string export.
295         @param nMaxLen  The maximum number of characters to store in this string.
296         @return  The new string object (shared pointer). */
297     static XclExpStringRef CreateCellString(
298                             const XclExpRoot& rRoot,
299                             const EditTextObject& rEditText,
300                             const ScPatternAttr* pCellAttr,
301                             XclExpHyperlinkHelper& rLinkHelper,
302                             XclStrFlags nFlags = XclStrFlags::NONE,
303                             sal_uInt16 nMaxLen = EXC_STR_MAXLEN );
304 
305     /** Creates a new formatted string from a drawing text box.
306         @descr  Creates a Unicode string or a byte string, depending on the
307                 current BIFF version contained in the passed XclExpRoot object.
308         @param rTextObj  The text box object.
309         @param nFlags  Modifiers for string export.
310         @return  The new string object (shared pointer). */
311     static XclExpStringRef CreateString(
312                             const XclExpRoot& rRoot,
313                             const SdrTextObj& rTextObj,
314                             XclStrFlags nFlags = XclStrFlags::NONE );
315 
316     /** Creates a new formatted string from an edit text string.
317         @param rEditObj  The edittext object.
318         @param nFlags  Modifiers for string export.
319         @return  The new string object. */
320     static XclExpStringRef CreateString(
321                             const XclExpRoot& rRoot,
322                             const EditTextObject& rEditObj,
323                             XclStrFlags nFlags = XclStrFlags::NONE );
324 
325     /** Returns the script type first text portion different to WEAK, or the system
326         default script type, if there is only weak script in the passed string. */
327     static sal_Int16    GetLeadingScriptType( const XclExpRoot& rRoot, const OUString& rString );
328 };
329 
330 // Header/footer conversion ===================================================
331 
332 /** Converts edit engine text objects to an Excel header/footer string.
333     @descr  Header/footer content is divided into three parts: Left, center and
334     right portion. All formatting information will be encoded in the Excel string
335     using special character sequences. A control sequence starts with the ampersand
336     character.
337 
338     Supported control sequences:
339     &L                      start of left portion
340     &C                      start of center portion
341     &R                      start of right portion
342     &P                      current page number
343     &N                      page count
344     &D                      current date
345     &T                      current time
346     &A                      table name
347     &F                      file name without path
348     &Z                      file path without file name
349     &Z&F                    file path and name
350     &U                      underlining on/off
351     &E                      double underlining on/off
352     &S                      strikeout characters on/off
353     &X                      superscript on/off
354     &Y                      subscript on/off
355     &"fontname,fontstyle"   use font with name 'fontname' and style 'fontstyle'
356     &fontheight             set font height in points ('fontheight' is a decimal value)
357 
358     Known but unsupported control sequences:
359     &G                      picture
360  */
361 class XclExpHFConverter : protected XclExpRoot
362 {
363 public:
364     /** delete copy constructor */
365     XclExpHFConverter(const XclExpHFConverter&) = delete;
366     /** delete copy-assignment operator */
367     const XclExpHFConverter& operator=(const XclExpHFConverter&) = delete;
368 
369     explicit            XclExpHFConverter( const XclExpRoot& rRoot );
370 
371     /** Generates the header/footer string from the passed edit engine text objects. */
372     void                GenerateString(
373                             const EditTextObject* pLeftObj,
374                             const EditTextObject* pCenterObj,
375                             const EditTextObject* pRightObj );
376 
377     /** Returns the last generated header/footer string. */
GetHFString() const378     const OUString& GetHFString() const { return maHFString; }
379     /** Returns the total height of the last generated header/footer in twips. */
GetTotalHeight() const380     sal_Int32    GetTotalHeight() const { return mnTotalHeight; }
381 
382 private:
383     /** Converts the text object contents and stores it in the passed string. */
384     void                AppendPortion(
385                             const EditTextObject* pTextObj,
386                             sal_Unicode cPortionCode );
387 
388 private:
389     EditEngine&         mrEE;           /// The header/footer edit engine.
390     OUString            maHFString;     /// The last generated header/footer string.
391     sal_Int32           mnTotalHeight;  /// Total height of the last header/footer (twips).
392 };
393 
394 // URL conversion =============================================================
395 
396 /** This class contains static methods to encode a file URL.
397     @descr  Excel stores URLs in a format that contains special control characters,
398     i.e. for directory separators or volume names. */
399 class XclExpUrlHelper
400 {
401 public:
402     /** delete copy constructor */
403     XclExpUrlHelper(const XclExpUrlHelper&) = delete;
404     /** delete copy-assignment operator */
405     const XclExpUrlHelper& operator=(const XclExpUrlHelper&) = delete;
406     /** We don't want anybody to instantiate this class, since it is just a
407         collection of static methods. */
408     XclExpUrlHelper() = delete;
409 
410     /** Encodes and returns the URL passed in rAbsUrl to an Excel like URL.
411         @param pTableName  Optional pointer to a table name to be encoded in this URL. */
412     static OUString EncodeUrl( const XclExpRoot& rRoot, const OUString& rAbsUrl, const OUString* pTableName = nullptr );
413     /** Encodes and returns the passed DDE link to an Excel like DDE link. */
414     static OUString EncodeDde( std::u16string_view rApplic, std::u16string_view rTopic );
415 };
416 
417 class ScMatrix;
418 
419 /** Contains cached values in a 2-dimensional array. */
420 class XclExpCachedMatrix
421 {
422     void            GetDimensions( SCSIZE & nCols, SCSIZE & nRows ) const;
423 public:
424     /** Constructs and fills a new matrix.
425         @param rMatrix  The Calc value matrix. */
426     explicit        XclExpCachedMatrix( const ScMatrix& rMatrix );
427                    ~XclExpCachedMatrix();
428 
429     /** Returns the byte count of all contained data. */
430     std::size_t     GetSize() const;
431     /** Writes the complete matrix to stream. */
432     void            Save( XclExpStream& rStrm ) const;
433 
434 private:
435     const ScMatrix& mrMatrix;
436 };
437 
438 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
439