• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #ifndef FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
8 #define FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
9 
10 #include <deque>
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include "core/fpdfdoc/cpvt_variabletext.h"
16 #include "core/fpdfdoc/cpvt_wordrange.h"
17 #include "core/fxcrt/bytestring.h"
18 #include "core/fxcrt/fx_codepage_forward.h"
19 #include "core/fxcrt/unowned_ptr.h"
20 #include "core/fxge/dib/fx_dib.h"
21 #include "fpdfsdk/pwl/ipwl_fillernotify.h"
22 
23 class CFX_RenderDevice;
24 class CPWL_Edit;
25 
26 class CPWL_EditImpl {
27  public:
28   class Iterator {
29    public:
30     Iterator(CPWL_EditImpl* pEdit, CPVT_VariableText::Iterator* pVTIterator);
31     ~Iterator();
32 
33     bool NextWord();
34     bool GetWord(CPVT_Word& word) const;
35     bool GetLine(CPVT_Line& line) const;
36     void SetAt(int32_t nWordIndex);
37     void SetAt(const CPVT_WordPlace& place);
38     const CPVT_WordPlace& GetAt() const;
39 
40    private:
41     UnownedPtr<CPWL_EditImpl> m_pEdit;
42     UnownedPtr<CPVT_VariableText::Iterator> m_pVTIterator;
43   };
44 
45   CPWL_EditImpl();
46   ~CPWL_EditImpl();
47 
48   void DrawEdit(CFX_RenderDevice* pDevice,
49                 const CFX_Matrix& mtUser2Device,
50                 FX_COLORREF crTextFill,
51                 const CFX_FloatRect& rcClip,
52                 const CFX_PointF& ptOffset,
53                 const CPVT_WordRange* pRange,
54                 IPWL_FillerNotify* pFillerNotify,
55                 IPWL_FillerNotify::PerWindowData* pSystemData);
56 
57   void SetFontMap(IPVT_FontMap* pFontMap);
58   void SetNotify(CPWL_Edit* pNotify);
59 
60   // Returns an iterator for the contents. Should not be released.
61   Iterator* GetIterator();
62   IPVT_FontMap* GetFontMap();
63   void Initialize();
64 
65   // Set the bounding box of the text area.
66   void SetPlateRect(const CFX_FloatRect& rect);
67   void SetScrollPos(const CFX_PointF& point);
68 
69   // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
70   void SetAlignmentH(int32_t nFormat);
71 
72   // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
73   void SetAlignmentV(int32_t nFormat);
74 
75   // Set the substitution character for hidden text.
76   void SetPasswordChar(uint16_t wSubWord);
77 
78   // Set the maximum number of words in the text.
79   void SetLimitChar(int32_t nLimitChar);
80   void SetCharArray(int32_t nCharArray);
81   void SetMultiLine(bool bMultiLine);
82   void SetAutoReturn(bool bAuto);
83   void SetAutoFontSize(bool bAuto);
84   void SetAutoScroll(bool bAuto);
85   void SetFontSize(float fFontSize);
86   void SetTextOverflow(bool bAllowed);
87   void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
88   void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
89   void OnVK_UP(bool bShift);
90   void OnVK_DOWN(bool bShift);
91   void OnVK_LEFT(bool bShift);
92   void OnVK_RIGHT(bool bShift);
93   void OnVK_HOME(bool bShift, bool bCtrl);
94   void OnVK_END(bool bShift, bool bCtrl);
95   void SetText(const WideString& sText);
96   bool InsertWord(uint16_t word, FX_Charset charset);
97   bool InsertReturn();
98   bool Backspace();
99   bool Delete();
100   bool ClearSelection();
101   bool InsertText(const WideString& sText, FX_Charset charset);
102   void ReplaceAndKeepSelection(const WideString& text);
103   void ReplaceSelection(const WideString& text);
104   bool Redo();
105   bool Undo();
106   CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
107   CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
108   int32_t GetCaret() const;
109   CPVT_WordPlace GetCaretWordPlace() const;
110   WideString GetSelectedText() const;
111   WideString GetText() const;
112   float GetFontSize() const;
113   uint16_t GetPasswordChar() const;
114   CFX_PointF GetScrollPos() const;
115   int32_t GetCharArray() const;
116   CFX_FloatRect GetContentRect() const;
117   WideString GetRangeText(const CPVT_WordRange& range) const;
118   void SetSelection(int32_t nStartChar, int32_t nEndChar);
119   std::pair<int32_t, int32_t> GetSelection() const;
120   void SelectAll();
121   void SelectNone();
122   bool IsSelected() const;
123   void Paint();
124   void EnableRefresh(bool bRefresh);
125   void RefreshWordRange(const CPVT_WordRange& wr);
126   CPVT_WordRange GetWholeWordRange() const;
127   CPVT_WordRange GetSelectWordRange() const;
128   void EnableUndo(bool bUndo);
129   bool IsTextFull() const;
130   bool CanUndo() const;
131   bool CanRedo() const;
132   CPVT_WordRange GetVisibleWordRange() const;
133 
134   ByteString GetPDFWordString(int32_t nFontIndex,
135                               uint16_t Word,
136                               uint16_t SubWord);
137 
138  private:
139   class RefreshState {
140    public:
141     RefreshState();
142     ~RefreshState();
143 
144     void BeginRefresh();
145     void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
146     void NoAnalyse();
147     std::vector<CFX_FloatRect>* GetRefreshRects();
148     void EndRefresh();
149 
150    private:
151     struct LineRect {
LineRectLineRect152       LineRect(const CPVT_WordRange& wrLine, const CFX_FloatRect& rcLine)
153           : m_wrLine(wrLine), m_rcLine(rcLine) {}
154 
155       CPVT_WordRange m_wrLine;
156       CFX_FloatRect m_rcLine;
157     };
158 
159     void Add(const CFX_FloatRect& new_rect);
160 
161     std::vector<LineRect> m_NewLineRects;
162     std::vector<LineRect> m_OldLineRects;
163     std::vector<CFX_FloatRect> m_RefreshRects;
164   };
165 
166   class SelectState {
167    public:
168     SelectState();
169     explicit SelectState(const CPVT_WordRange& range);
170 
171     void Reset();
172     void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
173     void SetEndPos(const CPVT_WordPlace& end);
174 
175     CPVT_WordRange ConvertToWordRange() const;
176     bool IsEmpty() const;
177 
178     CPVT_WordPlace BeginPos;
179     CPVT_WordPlace EndPos;
180   };
181 
182   class UndoItemIface {
183    public:
184     virtual ~UndoItemIface() = default;
185 
186     // Undo/Redo the current undo item and returns the number of additional
187     // items to be processed in |m_UndoItemStack| to fully undo/redo the action.
188     // (An example is UndoReplaceSelection::Undo(), if UndoReplaceSelection
189     // marks the end of a replace action, UndoReplaceSelection::Undo() returns
190     // |undo_remaining_|. The default value of |undo_remaining_| in
191     // UndoReplaceSelection is 3. because 3 more undo items need to be processed
192     // to revert the replace action: insert text, clear selection and the
193     // UndoReplaceSelection which marks the beginning of replace action. If
194     // CPWL_EditImpl::ClearSelection() returns false, the value of
195     // |undo_remaining_| in UndoReplaceSelection needs to be set to 2)
196     // Implementations should return 0 by default.
197     virtual int Undo() = 0;
198     virtual int Redo() = 0;
set_undo_remaining(int undo_remaining)199     void set_undo_remaining(int undo_remaining) {
200       undo_remaining_ = undo_remaining;
201     }
undo_remaining()202     int undo_remaining() const { return undo_remaining_; }
203 
204    private:
205     int undo_remaining_ = 0;
206   };
207 
208   class UndoStack {
209    public:
210     UndoStack();
211     ~UndoStack();
212 
213     void AddItem(std::unique_ptr<UndoItemIface> pItem);
214     void Undo();
215     void Redo();
216     bool CanUndo() const;
217     bool CanRedo() const;
218     // GetLastAddItem() will never return null, so it can only be called after
219     // calling AddItem().
220     UndoItemIface* GetLastAddItem();
221 
222    private:
223     void RemoveHeads();
224     void RemoveTails();
225 
226     std::deque<std::unique_ptr<UndoItemIface>> m_UndoItemStack;
227     size_t m_nCurUndoPos = 0;
228     bool m_bWorking = false;
229   };
230 
231   class Provider;
232   class UndoBackspace;
233   class UndoClear;
234   class UndoDelete;
235   class UndoInsertReturn;
236   class UndoInsertText;
237   class UndoInsertWord;
238   class UndoReplaceSelection;
239 
240   bool IsTextOverflow() const;
241   bool Clear();
242   CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
243                               const WideString& sText,
244                               FX_Charset charset);
245   FX_Charset GetCharSetFromUnicode(uint16_t word, FX_Charset nOldCharset);
246   int32_t GetTotalLines() const;
247   void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
248   bool Delete(bool bAddUndo);
249   bool Clear(bool bAddUndo);
250   bool InsertText(const WideString& sText, FX_Charset charset, bool bAddUndo);
251   bool InsertWord(uint16_t word, FX_Charset charset, bool bAddUndo);
252   bool InsertReturn(bool bAddUndo);
253   bool Backspace(bool bAddUndo);
254   void SetCaret(const CPVT_WordPlace& place);
255 
256   CFX_PointF VTToEdit(const CFX_PointF& point) const;
257 
258   void RearrangeAll();
259   void RearrangePart(const CPVT_WordRange& range);
260   void ScrollToCaret();
261   void SetScrollInfo();
262   void SetScrollPosX(float fx);
263   void SetScrollPosY(float fy);
264   void SetScrollLimit();
265   void SetContentChanged();
266 
267   void PaintInsertText(const CPVT_WordPlace& wpOld,
268                        const CPVT_WordPlace& wpNew);
269 
270   CFX_PointF EditToVT(const CFX_PointF& point) const;
271   CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;
272 
273   void Refresh();
274   void RefreshPushLineRects(const CPVT_WordRange& wr);
275 
276   void SetCaretInfo();
277   void SetCaretOrigin();
278 
279   void AddEditUndoItem(std::unique_ptr<UndoItemIface> pEditUndoItem);
280 
281   bool m_bEnableScroll = false;
282   bool m_bNotifyFlag = false;
283   bool m_bEnableOverflow = false;
284   bool m_bEnableRefresh = true;
285   bool m_bEnableUndo = true;
286   int32_t m_nAlignment = 0;
287   std::unique_ptr<Provider> m_pVTProvider;
288   std::unique_ptr<CPVT_VariableText> m_pVT;  // Must outlive |m_pVTProvider|.
289   UnownedPtr<CPWL_Edit> m_pNotify;
290   CPVT_WordPlace m_wpCaret;
291   CPVT_WordPlace m_wpOldCaret;
292   SelectState m_SelState;
293   CFX_PointF m_ptScrollPos;
294   CFX_PointF m_ptRefreshScrollPos;
295   std::unique_ptr<Iterator> m_pIterator;
296   RefreshState m_Refresh;
297   CFX_PointF m_ptCaret;
298   UndoStack m_Undo;
299   CFX_FloatRect m_rcOldContent;
300 };
301 
302 #endif  // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
303