OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ | 5 #ifndef VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ |
6 #define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ | 6 #define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <list> | 9 #include <list> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/gtest_prod_util.h" | 12 #include "base/gtest_prod_util.h" |
13 #include "base/string16.h" | 13 #include "base/string16.h" |
14 #include "third_party/skia/include/core/SkColor.h" | 14 #include "third_party/skia/include/core/SkColor.h" |
15 #include "ui/base/ime/composition_text.h" | 15 #include "ui/base/ime/composition_text.h" |
16 #include "ui/gfx/rect.h" | 16 #include "ui/gfx/rect.h" |
17 #include "ui/gfx/render_text.h" | |
17 | 18 |
18 namespace gfx { | 19 namespace gfx { |
20 class Canvas; | |
19 class Font; | 21 class Font; |
22 class RenderText; | |
23 struct StyleRange; | |
20 } // namespace gfx | 24 } // namespace gfx |
21 | 25 |
22 namespace ui { | 26 namespace ui { |
23 class Range; | 27 class Range; |
24 } // namespace ui | 28 } // namespace ui |
25 | 29 |
26 namespace views { | 30 namespace views { |
27 | 31 |
28 class TextStyle; | |
29 typedef std::vector<TextStyle*> TextStyles; | |
30 | |
31 namespace internal { | 32 namespace internal { |
32 // Internal Edit class that keeps track of edits for undo/redo. | 33 // Internal Edit class that keeps track of edits for undo/redo. |
33 class Edit; | 34 class Edit; |
34 | 35 |
35 struct TextStyleRange; | |
36 | |
37 // C++ doesn't allow forward decl enum, so let's define here. | 36 // C++ doesn't allow forward decl enum, so let's define here. |
38 enum MergeType { | 37 enum MergeType { |
39 // The edit should not be merged with next edit. It still may | 38 // The edit should not be merged with next edit. It still may |
40 // be merged with an edit with MERGE_WITH_PREVIOUS. | 39 // be merged with an edit with MERGE_WITH_PREVIOUS. |
41 DO_NOT_MERGE, | 40 DO_NOT_MERGE, |
42 // The edit can be merged with next edit when possible. | 41 // The edit can be merged with next edit when possible. |
43 MERGEABLE, | 42 MERGEABLE, |
44 // Does the edit have to be merged with previous edit? | 43 // Does the edit have to be merged with previous edit? |
45 // This forces the merge even if the previous edit is marked | 44 // This forces the merge even if the previous edit is marked |
46 // as DO_NOT_MERGE. | 45 // as DO_NOT_MERGE. |
47 MERGE_WITH_PREVIOUS, | 46 MERGE_WITH_PREVIOUS, |
48 }; | 47 }; |
49 | 48 |
50 } // namespace internal | 49 } // namespace internal |
51 | 50 |
52 typedef std::vector<internal::TextStyleRange*> TextStyleRanges; | |
53 | |
54 // A model that represents a text content for TextfieldViews. | 51 // A model that represents a text content for TextfieldViews. |
55 // It supports editing, selection and cursor manipulation. | 52 // It supports editing, selection and cursor manipulation. |
56 class TextfieldViewsModel { | 53 class TextfieldViewsModel { |
57 public: | 54 public: |
58 | 55 |
59 // Delegate interface implemented by the textfield view class to provided | 56 // Delegate interface implemented by the textfield view class to provided |
60 // additional functionalities required by the model. | 57 // additional functionalities required by the model. |
61 class Delegate { | 58 class Delegate { |
62 public: | 59 public: |
63 // Called when the current composition text is confirmed or cleared. | 60 // Called when the current composition text is confirmed or cleared. |
64 virtual void OnCompositionTextConfirmedOrCleared() = 0; | 61 virtual void OnCompositionTextConfirmedOrCleared() = 0; |
65 | 62 |
66 protected: | 63 protected: |
67 virtual ~Delegate(); | 64 virtual ~Delegate(); |
68 }; | 65 }; |
69 | 66 |
70 explicit TextfieldViewsModel(Delegate* delegate); | 67 explicit TextfieldViewsModel(Delegate* delegate); |
71 virtual ~TextfieldViewsModel(); | 68 virtual ~TextfieldViewsModel(); |
72 | 69 |
73 // Text fragment info. Used to draw selected text. | |
74 // We may replace this with TextAttribute class | |
75 // in the future to support multi-color text | |
76 // for omnibox. | |
77 struct TextFragment { | |
78 TextFragment(size_t start, size_t end, const views::TextStyle* s) | |
79 : range(start, end), style(s) { | |
80 } | |
81 // The start and end position of text fragment. | |
82 ui::Range range; | |
83 const TextStyle* style; | |
84 }; | |
85 typedef std::vector<TextFragment> TextFragments; | |
86 | |
87 // Gets the text element info. | |
88 void GetFragments(TextFragments* elements); | |
89 | |
90 void set_is_password(bool is_password) { | 70 void set_is_password(bool is_password) { |
91 is_password_ = is_password; | 71 is_password_ = is_password; |
92 } | 72 } |
93 const string16& text() const { return text_; } | |
94 | 73 |
95 // Edit related methods. | 74 // Edit related methods. |
96 | 75 |
97 // Sest the text. Returns true if the text has been modified. The | 76 const string16& GetText() const; |
77 // Sets the text. Returns true if the text has been modified. The | |
98 // current composition text will be confirmed first. Setting | 78 // current composition text will be confirmed first. Setting |
99 // the same text will not add edit history because it's not user | 79 // the same text will not add edit history because it's not user |
100 // visible change nor user-initiated change. This allow a client | 80 // visible change nor user-initiated change. This allow a client |
101 // code to set the same text multiple times without worrying about | 81 // code to set the same text multiple times without worrying about |
102 // messing edit history. | 82 // messing edit history. |
103 bool SetText(const string16& text); | 83 bool SetText(const string16& text); |
104 | 84 |
85 gfx::RenderText* get_render_text() { return render_text_; } | |
oshima
2011/07/23 09:51:12
ditto
msw
2011/07/25 05:09:54
Done.
| |
86 | |
105 // Inserts given |text| at the current cursor position. | 87 // Inserts given |text| at the current cursor position. |
106 // The current composition text will be cleared. | 88 // The current composition text will be cleared. |
107 void InsertText(const string16& text) { | 89 void InsertText(const string16& text) { |
108 InsertTextInternal(text, false); | 90 InsertTextInternal(text, false); |
109 } | 91 } |
110 | 92 |
111 // Inserts a character at the current cursor position. | 93 // Inserts a character at the current cursor position. |
112 void InsertChar(char16 c) { | 94 void InsertChar(char16 c) { |
113 InsertTextInternal(string16(&c, 1), true); | 95 InsertTextInternal(string16(&c, 1), true); |
114 } | 96 } |
(...skipping 21 matching lines...) Expand all Loading... | |
136 | 118 |
137 // Deletes the first character before the current cursor position (as if, the | 119 // Deletes the first character before the current cursor position (as if, the |
138 // the user has pressed backspace key in the textfield). Returns true if | 120 // the user has pressed backspace key in the textfield). Returns true if |
139 // the removal is successful. | 121 // the removal is successful. |
140 // If there is composition text, it'll be deleted instead. | 122 // If there is composition text, it'll be deleted instead. |
141 bool Backspace(); | 123 bool Backspace(); |
142 | 124 |
143 // Cursor related methods. | 125 // Cursor related methods. |
144 | 126 |
145 // Returns the current cursor position. | 127 // Returns the current cursor position. |
146 size_t cursor_pos() const { return cursor_pos_; } | 128 size_t GetCursorPosition() const; |
147 | 129 |
148 // Moves the cursor left by one position (as if, the user has pressed the left | 130 // Moves the cursor, see RenderText for additional details. |
149 // arrow key). If |select| is true, it updates the selection accordingly. | |
150 // The current composition text will be confirmed. | 131 // The current composition text will be confirmed. |
151 void MoveCursorLeft(bool select); | 132 void MoveCursorLeft(gfx::BreakType break_type, bool select); |
152 | 133 void MoveCursorRight(gfx::BreakType break_type, bool select); |
153 // Moves the cursor right by one position (as if, the user has pressed the | |
154 // right arrow key). If |select| is true, it updates the selection | |
155 // accordingly. | |
156 // The current composition text will be confirmed. | |
157 void MoveCursorRight(bool select); | |
158 | |
159 // Moves the cursor left by one word (word boundry is defined by space). | |
160 // If |select| is true, it updates the selection accordingly. | |
161 // The current composition text will be confirmed. | |
162 void MoveCursorToPreviousWord(bool select); | |
163 | |
164 // Moves the cursor right by one word (word boundry is defined by space). | |
165 // If |select| is true, it updates the selection accordingly. | |
166 // The current composition text will be confirmed. | |
167 void MoveCursorToNextWord(bool select); | |
168 | |
169 // Moves the cursor to start of the textfield contents. | |
170 // If |select| is true, it updates the selection accordingly. | |
171 // The current composition text will be confirmed. | |
172 void MoveCursorToHome(bool select); | |
173 | |
174 // Moves the cursor to end of the textfield contents. | |
175 // If |select| is true, it updates the selection accordingly. | |
176 // The current composition text will be confirmed. | |
177 void MoveCursorToEnd(bool select); | |
178 | 134 |
179 // Moves the cursor to the specified |position|. | 135 // Moves the cursor to the specified |position|. |
180 // If |select| is true, it updates the selection accordingly. | 136 // If |select| is true, it updates the selection accordingly. |
181 // The current composition text will be confirmed. | 137 // The current composition text will be confirmed. |
182 bool MoveCursorTo(size_t position, bool select); | 138 bool MoveCursorTo(size_t position, bool select); |
183 | 139 |
140 // Helper function to call MoveCursorTo on the TextfieldViewsModel. | |
141 bool MoveCursorTo(const gfx::Point& point, bool select); | |
142 | |
184 // Returns the bounds of selected text. | 143 // Returns the bounds of selected text. |
185 gfx::Rect GetSelectionBounds(const gfx::Font& font) const; | 144 std::vector<gfx::Rect> GetSelectionBounds() const; |
186 | 145 |
187 // Selection related method | 146 // Selection related method |
188 | 147 |
189 // Returns the selected text. | 148 // Returns the selected text. |
190 string16 GetSelectedText() const; | 149 string16 GetSelectedText() const; |
191 | 150 |
192 void GetSelectedRange(ui::Range* range) const; | 151 void GetSelectedRange(ui::Range* range) const; |
193 | 152 |
194 // The current composition text will be confirmed. The | 153 // The current composition text will be confirmed. The |
195 // selection starts with the range's start position, | 154 // selection starts with the range's start position, |
(...skipping 20 matching lines...) Expand all Loading... | |
216 bool CanRedo(); | 175 bool CanRedo(); |
217 | 176 |
218 // Undo edit. Returns true if undo changed the text. | 177 // Undo edit. Returns true if undo changed the text. |
219 bool Undo(); | 178 bool Undo(); |
220 | 179 |
221 // Redo edit. Returns true if redo changed the text. | 180 // Redo edit. Returns true if redo changed the text. |
222 bool Redo(); | 181 bool Redo(); |
223 | 182 |
224 // Returns visible text. If the field is password, it returns the | 183 // Returns visible text. If the field is password, it returns the |
225 // sequence of "*". | 184 // sequence of "*". |
226 string16 GetVisibleText() const { | 185 string16 GetVisibleText() const; |
227 return GetVisibleText(0U, text_.length()); | |
228 } | |
229 | 186 |
230 // Cuts the currently selected text and puts it to clipboard. Returns true | 187 // Cuts the currently selected text and puts it to clipboard. Returns true |
231 // if text has changed after cutting. | 188 // if text has changed after cutting. |
232 bool Cut(); | 189 bool Cut(); |
233 | 190 |
234 // Copies the currently selected text and puts it to clipboard. | 191 // Copies the currently selected text and puts it to clipboard. |
235 void Copy(); | 192 void Copy(); |
236 | 193 |
237 // Pastes text from the clipboard at current cursor position. Returns true | 194 // Pastes text from the clipboard at current cursor position. Returns true |
238 // if text has changed after pasting. | 195 // if text has changed after pasting. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 | 227 |
271 // Removes current composition text. | 228 // Removes current composition text. |
272 void CancelCompositionText(); | 229 void CancelCompositionText(); |
273 | 230 |
274 // Retrieves the range of current composition text. | 231 // Retrieves the range of current composition text. |
275 void GetCompositionTextRange(ui::Range* range) const; | 232 void GetCompositionTextRange(ui::Range* range) const; |
276 | 233 |
277 // Returns true if there is composition text. | 234 // Returns true if there is composition text. |
278 bool HasCompositionText() const; | 235 bool HasCompositionText() const; |
279 | 236 |
280 TextStyle* CreateTextStyle(); | |
281 | |
282 void ClearAllTextStyles(); | |
283 | |
284 private: | 237 private: |
285 friend class NativeTextfieldViews; | 238 friend class NativeTextfieldViews; |
286 friend class NativeTextfieldViewsTest; | 239 friend class NativeTextfieldViewsTest; |
287 friend class TextfieldViewsModelTest; | 240 friend class TextfieldViewsModelTest; |
288 friend class TextStyle; | |
289 friend class UndoRedo_BasicTest; | 241 friend class UndoRedo_BasicTest; |
290 friend class UndoRedo_CutCopyPasteTest; | 242 friend class UndoRedo_CutCopyPasteTest; |
291 friend class UndoRedo_ReplaceTest; | 243 friend class UndoRedo_ReplaceTest; |
292 friend class internal::Edit; | 244 friend class internal::Edit; |
293 | 245 |
294 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_BasicTest); | 246 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_BasicTest); |
295 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_CutCopyPasteTest); | 247 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_CutCopyPasteTest); |
296 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_ReplaceTest); | 248 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, UndoRedo_ReplaceTest); |
297 FRIEND_TEST_ALL_PREFIXES(TextfieldViewsModelTest, TextStyleTest); | |
298 | 249 |
299 // Returns the visible text given |start| and |end|. | 250 // Returns the visible text given |start| and |end|. |
300 string16 GetVisibleText(size_t start, size_t end) const; | 251 string16 GetVisibleText(size_t start, size_t end) const; |
301 | 252 |
302 // Utility for SelectWord(). Checks whether position pos is at word boundary. | |
303 bool IsPositionAtWordSelectionBoundary(size_t pos); | |
304 | |
305 // Returns the normalized cursor position that does not exceed the | |
306 // text length. | |
307 size_t GetSafePosition(size_t position) const; | |
308 | |
309 // Insert the given |text|. |mergeable| indicates if this insert | 253 // Insert the given |text|. |mergeable| indicates if this insert |
310 // operation can be merged to previous edit in the edit history. | 254 // operation can be merged to previous edit in the edit history. |
311 void InsertTextInternal(const string16& text, bool mergeable); | 255 void InsertTextInternal(const string16& text, bool mergeable); |
312 | 256 |
313 // Replace the current text with the given |text|. |mergeable| | 257 // Replace the current text with the given |text|. |mergeable| |
314 // indicates if this replace operation can be merged to previous | 258 // indicates if this replace operation can be merged to previous |
315 // edit in the edit history. | 259 // edit in the edit history. |
316 void ReplaceTextInternal(const string16& text, bool mergeable); | 260 void ReplaceTextInternal(const string16& text, bool mergeable); |
317 | 261 |
318 // Clears all edit history. | 262 // Clears all edit history. |
(...skipping 23 matching lines...) Expand all Loading... | |
342 // Note that the index is after deletion. | 286 // Note that the index is after deletion. |
343 // 3) Move the cursor to |new_cursor_pos|. | 287 // 3) Move the cursor to |new_cursor_pos|. |
344 void ModifyText(size_t delete_from, | 288 void ModifyText(size_t delete_from, |
345 size_t delete_to, | 289 size_t delete_to, |
346 const string16& new_text, | 290 const string16& new_text, |
347 size_t new_text_insert_at, | 291 size_t new_text_insert_at, |
348 size_t new_cursor_pos); | 292 size_t new_cursor_pos); |
349 | 293 |
350 void ClearComposition(); | 294 void ClearComposition(); |
351 | 295 |
352 void ApplyTextStyle(const TextStyle* style, const ui::Range& range); | |
353 | |
354 static TextStyle* CreateUnderlineStyle(); | |
355 | |
356 // Pointer to a TextfieldViewsModel::Delegate instance, should be provided by | 296 // Pointer to a TextfieldViewsModel::Delegate instance, should be provided by |
357 // the View object. | 297 // the View object. |
358 Delegate* delegate_; | 298 Delegate* delegate_; |
359 | 299 |
360 // The text in utf16 format. | 300 // The stylized text, cursor, selection, and the visual layout model. |
361 string16 text_; | 301 gfx::RenderText* render_text_; |
362 | |
363 // Current cursor position. | |
364 size_t cursor_pos_; | |
365 | |
366 // Selection range. | |
367 size_t selection_start_; | |
368 | |
369 // Composition text range. | |
370 size_t composition_start_; | |
371 size_t composition_end_; | |
372 | 302 |
373 // True if the text is the password. | 303 // True if the text is the password. |
374 bool is_password_; | 304 bool is_password_; |
375 | 305 |
376 typedef std::list<internal::Edit*> EditHistory; | 306 typedef std::list<internal::Edit*> EditHistory; |
377 EditHistory edit_history_; | 307 EditHistory edit_history_; |
378 | 308 |
379 // An iterator that points to the current edit that can be undone. | 309 // An iterator that points to the current edit that can be undone. |
380 // This iterator moves from the |end()|, meaining no edit to undo, | 310 // This iterator moves from the |end()|, meaining no edit to undo, |
381 // to the last element (one before |end()|), meaning no edit to redo. | 311 // to the last element (one before |end()|), meaning no edit to redo. |
382 // There is no edit to undo (== end()) when: | 312 // There is no edit to undo (== end()) when: |
383 // 1) in initial state. (nothing to undo) | 313 // 1) in initial state. (nothing to undo) |
384 // 2) very 1st edit is undone. | 314 // 2) very 1st edit is undone. |
385 // 3) all edit history is removed. | 315 // 3) all edit history is removed. |
386 // There is no edit to redo (== last element or no element) when: | 316 // There is no edit to redo (== last element or no element) when: |
387 // 1) in initial state. (nothing to redo) | 317 // 1) in initial state. (nothing to redo) |
388 // 2) new edit is added. (redo history is cleared) | 318 // 2) new edit is added. (redo history is cleared) |
389 // 3) redone all undone edits. | 319 // 3) redone all undone edits. |
390 EditHistory::iterator current_edit_; | 320 EditHistory::iterator current_edit_; |
391 | 321 |
392 // This manages all styles objects. | |
393 TextStyles text_styles_; | |
394 | |
395 // List of style ranges. Elements in the list never overlap each other. | |
396 // Elements are not sorted at the time of insertion, and gets sorted | |
397 // when it's painted (if necessary). | |
398 TextStyleRanges style_ranges_; | |
399 // True if the style_ranges_ needs to be sorted. | |
400 bool sort_style_ranges_; | |
401 | |
402 // List of style ranges for composition text. | |
403 TextStyleRanges composition_style_ranges_; | |
404 | |
405 DISALLOW_COPY_AND_ASSIGN(TextfieldViewsModel); | 322 DISALLOW_COPY_AND_ASSIGN(TextfieldViewsModel); |
406 }; | 323 }; |
407 | 324 |
408 } // namespace views | 325 } // namespace views |
409 | 326 |
410 #endif // VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ | 327 #endif // VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_ |
OLD | NEW |