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_VCL_TEXTENG_HXX
20 #define INCLUDED_VCL_TEXTENG_HXX
21 
22 #include <memory>
23 #include <sal/config.h>
24 
25 #include <cstddef>
26 #include <vector>
27 
28 #include <vcl/dllapi.h>
29 #include <vcl/vclptr.hxx>
30 #include <rtl/ustring.hxx>
31 #include <svl/SfxBroadcaster.hxx>
32 #include <tools/lineend.hxx>
33 #include <tools/link.hxx>
34 #include <tools/gen.hxx>
35 #include <tools/color.hxx>
36 #include <vcl/font.hxx>
37 #include <vcl/vclenum.hxx>
38 
39 #include <com/sun/star/lang/Locale.hpp>
40 #include <com/sun/star/uno/Reference.hxx>
41 
42 class TextDoc;
43 class TextView;
44 class TextPaM;
45 class TextSelection;
46 class TEParaPortions;
47 class TextAttrib;
48 class TextCharAttrib;
49 class TextUndo;
50 class TextUndoManager;
51 class IdleFormatter;
52 class TextNode;
53 class OutputDevice;
54 class KeyEvent;
55 class Timer;
56 class SfxUndoManager;
57 class TextLine;
58 struct TEIMEInfos;
59 
60 namespace com::sun::star::i18n {
61     class XBreakIterator;
62     class XExtendedInputSequenceChecker;
63 }
64 
65 class LocaleDataWrapper;
66 
67 typedef std::vector<TextView*> TextViews;
68 
69 class VCL_DLLPUBLIC TextEngine : public SfxBroadcaster
70 {
71     friend class        TextView;
72     friend class        TextSelFunctionSet;
73     friend class        ExtTextEngine;
74 
75     friend class        TextUndo;
76     friend class        TextUndoManager;
77     friend class        TextUndoDelPara;
78     friend class        TextUndoConnectParas;
79     friend class        TextUndoSplitPara;
80     friend class        TextUndoInsertChars;
81     friend class        TextUndoRemoveChars;
82 
83     std::unique_ptr<TextDoc>          mpDoc;
84     std::unique_ptr<TEParaPortions>   mpTEParaPortions;
85     VclPtr<OutputDevice> mpRefDev;
86 
87     std::unique_ptr<TextViews>        mpViews;
88     TextView*           mpActiveView;
89 
90     std::unique_ptr<TextUndoManager>  mpUndoManager;
91 
92     std::unique_ptr<IdleFormatter>    mpIdleFormatter;
93 
94     std::unique_ptr<TEIMEInfos> mpIMEInfos;
95 
96     css::lang::Locale   maLocale;
97     css::uno::Reference< css::i18n::XBreakIterator > mxBreakIterator;
98     css::uno::Reference < css::i18n::XExtendedInputSequenceChecker > mxISC;
99 
100     tools::Rectangle           maInvalidRect;
101 
102     std::unique_ptr<LocaleDataWrapper> mpLocaleDataWrapper;
103 
104     vcl::Font           maFont;
105     Color               maTextColor;
106 
107     sal_Int32           mnMaxTextLen;
108     tools::Long                mnMaxTextWidth;
109     tools::Long                mnCharHeight;
110     tools::Long                mnCurTextWidth;
111     tools::Long                mnCurTextHeight;
112     tools::Long                mnDefTab;
113 
114     TxtAlign            meAlign;
115 
116     bool                mbIsFormatting      : 1;    // semaphore for the Hook's
117     bool                mbFormatted         : 1;
118     bool                mbUpdate            : 1;
119     bool                mbModified          : 1;
120     bool                mbUndoEnabled       : 1;
121     bool                mbIsInUndo          : 1;
122     bool                mbDowning           : 1;
123     bool                mbRightToLeft       : 1;
124     bool                mbHasMultiLineParas : 1;
125 
126     void                CursorMoved( sal_uInt32 nNode );
127     void                TextModified();
128 
129     void                ImpInitDoc();
130     void                ImpRemoveText();
131     TextPaM             ImpDeleteText( const TextSelection& rSel );
132     TextPaM             ImpInsertText( const TextSelection& rSel, sal_Unicode c, bool bOverwrite = false );
133     TextPaM             ImpInsertText( const TextSelection& rSel, const OUString& rText );
134     TextPaM             ImpInsertParaBreak( const TextSelection& rTextSelection );
135     TextPaM             ImpInsertParaBreak( const TextPaM& rPaM );
136     void                ImpRemoveChars( const TextPaM& rPaM, sal_Int32 nChars );
137     TextPaM             ImpConnectParagraphs( sal_uInt32 nLeft, sal_uInt32 nRight );
138     void                ImpRemoveParagraph( sal_uInt32 nPara );
139     void                ImpInitWritingDirections( sal_uInt32 nPara );
140     LocaleDataWrapper*  ImpGetLocaleDataWrapper();
141 
142     // to remain compatible in the minor release we copy the above ImpInsertText
143     // function and add the extra parameter we need but make sure this function
144     // gets not exported. First and second parameter swapped to have a different signature.
145     SAL_DLLPRIVATE TextPaM  ImpInsertText( sal_Unicode c, const TextSelection& rSel, bool bOverwrite, bool bIsUserInput = false );
146     // some other new functions needed that must not be exported to remain compatible
147     SAL_DLLPRIVATE css::uno::Reference< css::i18n::XExtendedInputSequenceChecker > const & GetInputSequenceChecker();
148     SAL_DLLPRIVATE bool IsInputSequenceCheckingRequired( sal_Unicode c, const TextSelection& rCurSel ) const;
149 
150     // broadcast or adjust selections
151     void                ImpParagraphInserted( sal_uInt32 nPara );
152     void                ImpParagraphRemoved( sal_uInt32 nPara );
153     void                ImpCharsRemoved( sal_uInt32 nPara, sal_Int32 nPos, sal_Int32 nChars );
154     void                ImpCharsInserted( sal_uInt32 nPara, sal_Int32 nPos, sal_Int32 nChars );
155 
156     DECL_LINK(    IdleFormatHdl, Timer *, void );
157     void                CheckIdleFormatter();
158     void                IdleFormatAndUpdate( TextView* pCurView, sal_uInt16 nMaxTimerRestarts = 5 );
159 
160     bool                CreateLines( sal_uInt32 nPara );
161     void                CreateAndInsertEmptyLine( sal_uInt32 nPara );
162     void                ImpBreakLine( sal_uInt32 nPara, TextLine* pLine, sal_Int32 nPortionStart, tools::Long nRemainingWidth );
163     std::size_t         SplitTextPortion( sal_uInt32 nPara, sal_Int32 nPos );
164     void                CreateTextPortions( sal_uInt32 nPara, sal_Int32 nStartPos );
165     void                RecalcTextPortion( sal_uInt32 nPara, sal_Int32 nStartPos, sal_Int32 nNewChars );
166     void                SeekCursor( sal_uInt32 nNode, sal_Int32 nPos, vcl::Font& rFont, OutputDevice* pOutDev );
167 
168     void                FormatDoc();
169     void                FormatFullDoc();
170     void                FormatAndUpdate( TextView* pCurView = nullptr );
IsFormatting() const171     bool                IsFormatting() const { return mbIsFormatting; }
172     void                UpdateViews( TextView* pCurView = nullptr );
173 
174     void                ImpPaint( OutputDevice* pOut, const Point& rStartPos, tools::Rectangle const* pPaintArea, TextSelection const* pSelection = nullptr );
175 
IsFormatted() const176     bool                IsFormatted() const { return mbFormatted; }
177 
178     sal_Int32           GetCharPos( sal_uInt32 nPara, std::vector<TextLine>::size_type nLine, tools::Long nDocPosX );
179     tools::Rectangle    GetEditCursor( const TextPaM& rPaM, bool bSpecial, bool bPreferPortionStart = false );
180     sal_Int32           ImpFindIndex( sal_uInt32 nPortion, const Point& rPosInPara );
181     tools::Long                ImpGetPortionXOffset( sal_uInt32 nPara, TextLine const * pLine, std::size_t nTextPortion );
182     tools::Long                ImpGetXPos( sal_uInt32 nPara, TextLine* pLine, sal_Int32 nIndex, bool bPreferPortionStart = false );
183     tools::Long                ImpGetOutputOffset( sal_uInt32 nPara, TextLine* pLine, sal_Int32 nIndex, sal_Int32 nIndex2 );
184     bool                ImpGetRightToLeft( sal_uInt32 nPara, sal_Int32 nPos );
185     static void         ImpInitLayoutMode( OutputDevice* pOutDev );
186     TxtAlign            ImpGetAlign() const;
187 
188     tools::Long                CalcTextHeight();
189     tools::Long                CalcParaHeight( sal_uInt32 nParagraph ) const;
190     tools::Long                CalcTextWidth( sal_uInt32 nPara );
191     tools::Long                CalcTextWidth( sal_uInt32 nPara, sal_Int32 nPortionStart, sal_Int32 nPortionLen);
192     Range               GetInvalidYOffsets( sal_uInt32 nPortion );
193 
194     // for Undo/Redo
195     void                InsertContent( std::unique_ptr<TextNode> pNode, sal_uInt32 nPara );
196     TextPaM             SplitContent( sal_uInt32 nNode, sal_Int32 nSepPos );
197     TextPaM             ConnectContents( sal_uInt32 nLeftNode );
198 
199     // adjust PaM's and selections that were transferred to the API to a valid range
200     void                ValidateSelection( TextSelection& rSel ) const;
201     void                ValidatePaM( TextPaM& rPaM ) const;
202 
203 public:
204                         TextEngine();
205                         virtual ~TextEngine() override;
206                         TextEngine( const TextEngine& ) = delete;
207     TextEngine&         operator=( const TextEngine& ) = delete;
208 
209     void                SetText( const OUString& rStr );
210     OUString            GetText( LineEnd aSeparator = LINEEND_LF ) const;
211     OUString            GetText( const TextSelection& rSel, LineEnd aSeparator = LINEEND_LF ) const;
212     OUString            GetTextLines( LineEnd aSeparator = LINEEND_LF ) const;
213     void                ReplaceText(const TextSelection& rSel, const OUString& rText);
214 
215     sal_Int32           GetTextLen() const;
216     sal_Int32           GetTextLen( const TextSelection& rSel ) const;
217 
218     void                SetFont( const vcl::Font& rFont );
GetFont() const219     const vcl::Font&    GetFont() const { return maFont; }
220 
221     void                SetLeftMargin( sal_uInt16 n );
222 
223     void                SetUpdateMode( bool bUpdate );
GetUpdateMode() const224     bool                GetUpdateMode() const { return mbUpdate; }
225 
226     sal_uInt16          GetViewCount() const;
227     TextView*           GetView( sal_uInt16 nView ) const;
228     void                InsertView( TextView* pTextView );
229     void                RemoveView( TextView* pTextView );
GetActiveView() const230     TextView*           GetActiveView() const { return mpActiveView;}
231     void                SetActiveView( TextView* pView );
232 
233     void                SetMaxTextLen( sal_Int32 nLen );
GetMaxTextLen() const234     sal_Int32           GetMaxTextLen() const { return mnMaxTextLen; }
235 
236     void                SetMaxTextWidth( tools::Long nWidth );
GetMaxTextWidth() const237     tools::Long                GetMaxTextWidth() const { return mnMaxTextWidth; }
238 
239     tools::Long                GetTextHeight() const;
240     tools::Long                CalcTextWidth();
GetCharHeight() const241     tools::Long                GetCharHeight() const { return mnCharHeight; }
242 
243     sal_uInt32          GetParagraphCount() const;
244     OUString            GetText( sal_uInt32 nParagraph ) const;
245     sal_Int32           GetTextLen( sal_uInt32 nParagraph ) const;
246     tools::Long                GetTextHeight( sal_uInt32 nParagraph ) const;
247 
248     void                GetTextPortionRange(const TextPaM& rPaM, sal_Int32& nStart, sal_Int32& nEnd);
249 
250     sal_uInt16          GetLineCount( sal_uInt32 nParagraph ) const;
251     sal_Int32           GetLineLen( sal_uInt32 nParagraph, sal_uInt16 nLine ) const;
252 
253     void                SetRightToLeft( bool bR2L );
IsRightToLeft() const254     bool                IsRightToLeft() const { return mbRightToLeft; }
255 
HasUndoManager() const256     bool                HasUndoManager() const { return mpUndoManager != nullptr; }
257     SfxUndoManager&     GetUndoManager();
258     void                UndoActionStart( sal_uInt16 nId = 0 );
259     void                UndoActionEnd();
260     void                InsertUndo( std::unique_ptr<TextUndo> pUndo, bool bTryMerge = false );
IsInUndo() const261     bool                IsInUndo() const            { return mbIsInUndo; }
SetIsInUndo(bool bInUndo)262     void                SetIsInUndo( bool bInUndo ) { mbIsInUndo = bInUndo; }
263     void                ResetUndo();
264 
265     void                EnableUndo( bool bEnable );
IsUndoEnabled() const266     bool                IsUndoEnabled() const           { return mbUndoEnabled; }
267 
SetModified(bool bModified)268     void                SetModified( bool bModified )   { mbModified = bModified; }
IsModified() const269     bool                IsModified() const              { return mbModified; }
270 
271     bool                Read( SvStream& rInput, const TextSelection* pSel = nullptr );
272 
273     void                Write( SvStream& rOutput );
274 
275     TextPaM             GetPaM( const Point& rDocPos );
276     tools::Rectangle    PaMtoEditCursor( const TextPaM& rPaM, bool bSpecial = false );
277     OUString            GetWord( const TextPaM& rCursorPos, TextPaM* pStartOfWord = nullptr, TextPaM* pEndOfWord = nullptr );
278 
279     const TextAttrib*       FindAttrib( const TextPaM& rPaM, sal_uInt16 nWhich ) const;
280     const TextCharAttrib*   FindCharAttrib( const TextPaM& rPaM, sal_uInt16 nWhich ) const;
281 
282     void                RemoveAttribs( sal_uInt32 nPara );
283     void                SetAttrib( const TextAttrib& rAttr, sal_uInt32 nPara, sal_Int32 nStart, sal_Int32 nEnd );
284 
GetTextAlign() const285     TxtAlign            GetTextAlign() const { return meAlign; }
286     void                SetTextAlign( TxtAlign eAlign );
287 
288     void                Draw( OutputDevice* pDev, const Point& rPos );
289 
290     void                SetLocale( const css::lang::Locale& rLocale );
291     css::lang::Locale const & GetLocale();
292     css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIterator();
293 
294     static bool         DoesKeyChangeText( const KeyEvent& rKeyEvent );
295     static bool         IsSimpleCharInput( const KeyEvent& rKeyEvent );
296 
GetTextColor() const297     const Color&        GetTextColor() const { return maTextColor; }
298 };
299 
300 #endif // INCLUDED_VCL_TEXTENG_HXX
301 
302 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
303