Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(492)

Side by Side Diff: chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h

Issue 231733005: Delete the GTK+ port of Chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remerge to ToT Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef CHROME_BROWSER_UI_GTK_OMNIBOX_OMNIBOX_VIEW_GTK_H_
6 #define CHROME_BROWSER_UI_GTK_OMNIBOX_OMNIBOX_VIEW_GTK_H_
7
8 #include <gtk/gtk.h>
9
10 #include <algorithm>
11 #include <string>
12
13 #include "base/basictypes.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string_util.h"
16 #include "chrome/browser/ui/omnibox/omnibox_view.h"
17 #include "chrome/browser/ui/toolbar/toolbar_model.h"
18 #include "content/public/browser/notification_observer.h"
19 #include "content/public/browser/notification_registrar.h"
20 #include "ui/base/gtk/gtk_signal.h"
21 #include "ui/base/gtk/gtk_signal_registrar.h"
22 #include "ui/base/gtk/owned_widget_gtk.h"
23 #include "ui/base/window_open_disposition.h"
24 #include "ui/gfx/rect.h"
25
26 class Browser;
27 class OmniboxPopupView;
28 class Profile;
29
30 namespace gfx {
31 class Font;
32 }
33
34 class GtkThemeService;
35
36 class OmniboxViewGtk : public OmniboxView,
37 public content::NotificationObserver {
38 public:
39 // Modeled like the Windows CHARRANGE. Represent a pair of cursor position
40 // offsets. Since GtkTextIters are invalid after the buffer is changed, we
41 // work in character offsets (not bytes).
42 struct CharRange {
43 CharRange() : cp_min(0), cp_max(0) { }
44 CharRange(int n, int x) : cp_min(n), cp_max(x) { }
45
46 // Returns the start/end of the selection.
47 int selection_min() const { return std::min(cp_min, cp_max); }
48 int selection_max() const { return std::max(cp_min, cp_max); }
49
50 // Work in integers to match the gint GTK APIs.
51 int cp_min; // For a selection: Represents the start.
52 int cp_max; // For a selection: Represents the end (insert position).
53 };
54
55 // profile parameter is introduced for unittests which can not instantiate
56 // browser object and pass NULL to the browser parameter.
57 // In other use case, you should pass browser->profile() object as
58 // profile parameter.
59 OmniboxViewGtk(OmniboxEditController* controller,
60 Browser* browser,
61 Profile* profile,
62 CommandUpdater* command_updater,
63 bool popup_window_mode,
64 GtkWidget* location_bar);
65 virtual ~OmniboxViewGtk();
66
67 // Initialize, create the underlying widgets, etc.
68 void Init();
69
70 // OmniboxView:
71 virtual void SaveStateToTab(content::WebContents* tab) OVERRIDE;
72 virtual void OnTabChanged(const content::WebContents* web_contents) OVERRIDE;
73 virtual void Update() OVERRIDE;
74 virtual base::string16 GetText() const OVERRIDE;
75 virtual void SetWindowTextAndCaretPos(const base::string16& text,
76 size_t caret_pos,
77 bool update_popup,
78 bool notify_text_changed) OVERRIDE;
79 virtual void SetForcedQuery() OVERRIDE;
80 virtual bool IsSelectAll() const OVERRIDE;
81 virtual bool DeleteAtEndPressed() OVERRIDE;
82 virtual void GetSelectionBounds(
83 base::string16::size_type* start,
84 base::string16::size_type* end) const OVERRIDE;
85 virtual void SelectAll(bool reversed) OVERRIDE;
86 virtual void UpdatePopup() OVERRIDE;
87 virtual void SetFocus() OVERRIDE;
88 virtual void ApplyCaretVisibility() OVERRIDE;
89 virtual void OnTemporaryTextMaybeChanged(
90 const base::string16& display_text,
91 bool save_original_selection,
92 bool notify_text_changed) OVERRIDE;
93 virtual bool OnInlineAutocompleteTextMaybeChanged(
94 const base::string16& display_text, size_t user_text_length) OVERRIDE;
95 virtual void OnInlineAutocompleteTextCleared() OVERRIDE;
96 virtual void OnRevertTemporaryText() OVERRIDE;
97 virtual void OnBeforePossibleChange() OVERRIDE;
98 virtual bool OnAfterPossibleChange() OVERRIDE;
99 virtual gfx::NativeView GetNativeView() const OVERRIDE;
100 virtual gfx::NativeView GetRelativeWindowForPopup() const OVERRIDE;
101 virtual void SetGrayTextAutocompletion(
102 const base::string16& suggestion) OVERRIDE;
103 virtual base::string16 GetGrayTextAutocompletion() const OVERRIDE;
104 virtual int GetTextWidth() const OVERRIDE;
105 virtual int GetWidth() const OVERRIDE;
106 virtual bool IsImeComposing() const OVERRIDE;
107
108 // Overridden from content::NotificationObserver:
109 virtual void Observe(int type,
110 const content::NotificationSource& source,
111 const content::NotificationDetails& details) OVERRIDE;
112
113 // Sets the colors of the gray text suggestion view according to the theme.
114 void UpdateGrayTextViewColors();
115
116 // Returns the text view gtk widget. May return NULL if the widget
117 // has already been destroyed.
118 GtkWidget* text_view() {
119 return text_view_;
120 }
121
122 private:
123 friend class OmniboxViewGtkTest;
124
125 CHROMEG_CALLBACK_0(OmniboxViewGtk, void, HandleBeginUserAction,
126 GtkTextBuffer*);
127 CHROMEG_CALLBACK_0(OmniboxViewGtk, void, HandleEndUserAction, GtkTextBuffer*);
128 CHROMEG_CALLBACK_2(OmniboxViewGtk, void, HandleMarkSet, GtkTextBuffer*,
129 GtkTextIter*, GtkTextMark*);
130 // As above, but called after the default handler.
131 CHROMEG_CALLBACK_2(OmniboxViewGtk, void, HandleMarkSetAfter, GtkTextBuffer*,
132 GtkTextIter*, GtkTextMark*);
133 CHROMEG_CALLBACK_3(OmniboxViewGtk, void, HandleInsertText, GtkTextBuffer*,
134 GtkTextIter*, const gchar*, gint);
135 CHROMEG_CALLBACK_0(OmniboxViewGtk, void, HandleKeymapDirectionChanged,
136 GdkKeymap*);
137 CHROMEG_CALLBACK_2(OmniboxViewGtk, void, HandleDeleteRange, GtkTextBuffer*,
138 GtkTextIter*, GtkTextIter*);
139 // Unlike above HandleMarkSet and HandleMarkSetAfter, this handler will always
140 // be connected to the signal.
141 CHROMEG_CALLBACK_2(OmniboxViewGtk, void, HandleMarkSetAlways, GtkTextBuffer*,
142 GtkTextIter*, GtkTextMark*);
143
144 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleKeyPress, GdkEventKey*);
145 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleKeyRelease,
146 GdkEventKey*);
147 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleViewButtonPress,
148 GdkEventButton*);
149 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleViewButtonRelease,
150 GdkEventButton*);
151 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleViewFocusIn,
152 GdkEventFocus*);
153 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleViewFocusOut,
154 GdkEventFocus*);
155 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleViewMoveFocus,
156 GtkDirectionType);
157 CHROMEGTK_CALLBACK_3(OmniboxViewGtk, void, HandleViewMoveCursor,
158 GtkMovementStep, gint, gboolean);
159 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleViewSizeRequest,
160 GtkRequisition*);
161 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandlePopulatePopup, GtkMenu*);
162 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandlePasteAndGo);
163 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleShowURL);
164 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleEditSearchEngines);
165 CHROMEGTK_CALLBACK_6(OmniboxViewGtk, void, HandleDragDataReceived,
166 GdkDragContext*, gint, gint, GtkSelectionData*,
167 guint, guint);
168 CHROMEGTK_CALLBACK_4(OmniboxViewGtk, void, HandleDragDataGet,
169 GdkDragContext*, GtkSelectionData*, guint, guint);
170 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleDragBegin,
171 GdkDragContext*);
172 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleDragEnd,
173 GdkDragContext*);
174 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleBackSpace);
175 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleCopyClipboard);
176 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleCutClipboard);
177 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandlePasteClipboard);
178 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleExposeEvent,
179 GdkEventExpose*);
180 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, gboolean, HandleExposeEventAfter,
181 GdkEventExpose*);
182 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleWidgetDirectionChanged,
183 GtkTextDirection);
184 CHROMEGTK_CALLBACK_2(OmniboxViewGtk, void, HandleDeleteFromCursor,
185 GtkDeleteType, gint);
186 // We connect to this so we can determine our toplevel window, so we can
187 // listen to focus change events on it.
188 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandleHierarchyChanged,
189 GtkWidget*);
190 CHROMEGTK_CALLBACK_1(OmniboxViewGtk, void, HandlePreEditChanged,
191 const gchar*);
192 // Undo/redo operations won't trigger "begin-user-action" and
193 // "end-user-action" signals, so we need to hook into "undo" and "redo"
194 // signals and call OnBeforePossibleChange()/OnAfterPossibleChange() by
195 // ourselves.
196 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleUndoRedo);
197 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandleUndoRedoAfter);
198
199 CHROMEG_CALLBACK_1(OmniboxViewGtk, void, HandleWindowSetFocus,
200 GtkWindow*, GtkWidget*);
201
202 // Callback function called after context menu is closed.
203 CHROMEGTK_CALLBACK_0(OmniboxViewGtk, void, HandlePopupMenuDeactivate);
204
205 // Callback for the PRIMARY selection clipboard.
206 static void ClipboardGetSelectionThunk(GtkClipboard* clipboard,
207 GtkSelectionData* selection_data,
208 guint info,
209 gpointer object);
210 void ClipboardGetSelection(GtkClipboard* clipboard,
211 GtkSelectionData* selection_data,
212 guint info);
213
214 void HandleCopyOrCutClipboard(bool copy);
215
216 // OmniboxView overrides.
217 virtual int GetOmniboxTextLength() const OVERRIDE;
218 virtual void EmphasizeURLComponents() OVERRIDE;
219
220 // Common implementation for performing a drop on the edit view.
221 bool OnPerformDropImpl(const base::string16& text);
222
223 // Sets the colors and font of the text view according to the theme.
224 void OnBrowserThemeChanged();
225
226 // Returns the font used in |text_view_|.
227 gfx::Font GetFont();
228
229 // Take control of the PRIMARY selection clipboard with |text|. Use
230 // |text_buffer_| as the owner, so that this doesn't remove the selection on
231 // it. This makes use of the above callbacks.
232 void OwnPrimarySelection(const std::string& text);
233
234 // Gets the GTK_TEXT_WINDOW_WIDGET coordinates for |text_view_| that bound the
235 // given iters.
236 gfx::Rect WindowBoundsFromIters(GtkTextIter* iter1, GtkTextIter* iter2);
237
238 // Actual implementation of SelectAll(), but also provides control over
239 // whether the PRIMARY selection is set to the selected text (in SelectAll(),
240 // it isn't, but we want set the selection when the user clicks in the entry).
241 void SelectAllInternal(bool reversed, bool update_primary_selection);
242
243 // Get ready to update |text_buffer_|'s highlighting without making changes to
244 // the PRIMARY selection. Removes the clipboard from |text_buffer_| and
245 // blocks the "mark-set" signal handler.
246 void StartUpdatingHighlightedText();
247
248 // Finish updating |text_buffer_|'s highlighting such that future changes will
249 // automatically update the PRIMARY selection. Undoes
250 // StartUpdatingHighlightedText()'s changes.
251 void FinishUpdatingHighlightedText();
252
253 // Get the character indices of the current selection. This honors
254 // direction, cp_max is the insertion point, and cp_min is the bound.
255 CharRange GetSelection() const;
256
257 // Translate from character positions to iterators for the current buffer.
258 void ItersFromCharRange(const CharRange& range,
259 GtkTextIter* iter_min,
260 GtkTextIter* iter_max);
261
262 // Returns true if the caret is at the end of the content.
263 bool IsCaretAtEnd() const;
264
265 // Save |selected_text| as the PRIMARY X selection. Unlike
266 // OwnPrimarySelection(), this won't set an owner or use callbacks.
267 void SavePrimarySelection(const std::string& selected_text);
268
269 // Update the field with |text| and set the selection.
270 void SetTextAndSelectedRange(const base::string16& text,
271 const CharRange& range);
272
273 // Set the selection to |range|.
274 void SetSelectedRange(const CharRange& range);
275
276 // Adjust the text justification according to the text direction of the widget
277 // and |text_buffer_|'s content, to make sure the real text justification is
278 // always in sync with the UI language direction.
279 void AdjustTextJustification();
280
281 // Get the text direction of |text_buffer_|'s content, by searching the first
282 // character that has a strong direction.
283 PangoDirection GetContentDirection();
284
285 // Returns the selected text.
286 std::string GetSelectedText() const;
287
288 // If the selected text parses as a URL OwnPrimarySelection is invoked.
289 void UpdatePrimarySelectionIfValidURL();
290
291 // Retrieves the first and last iterators in the |text_buffer_|, but excludes
292 // the anchor holding the |gray_text_view_| widget.
293 void GetTextBufferBounds(GtkTextIter* start, GtkTextIter* end) const;
294
295 // Validates an iterator in the |text_buffer_|, to make sure it doesn't go
296 // beyond the anchor for holding the |gray_text_view_| widget.
297 void ValidateTextBufferIter(GtkTextIter* iter) const;
298
299 // Adjusts vertical alignment of the |gray_text_view_| in the |text_view_|, to
300 // make sure they have the same baseline.
301 void AdjustVerticalAlignmentOfGrayTextView();
302
303 // The Browser that contains this omnibox.
304 Browser* browser_;
305
306 // The widget we expose, used for vertically centering the real text edit,
307 // since the height will change based on the font / font size, etc.
308 ui::OwnedWidgetGtk alignment_;
309
310 // The actual text entry which will be owned by the alignment_. The
311 // reference will be set to NULL upon destruction to tell if the gtk
312 // widget tree has been destroyed. This is because gtk destroies child
313 // widgets if the parent (alignemtn_)'s refcount does not go down to 0.
314 GtkWidget* text_view_;
315
316 GtkTextTagTable* tag_table_;
317 GtkTextBuffer* text_buffer_;
318 GtkTextTag* faded_text_tag_;
319 GtkTextTag* secure_scheme_tag_;
320 GtkTextTag* security_error_scheme_tag_;
321 GtkTextTag* normal_text_tag_;
322
323 // Objects for the gray suggestion text view.
324 GtkTextTag* gray_text_anchor_tag_;
325
326 // A widget for displaying gray autocompletion text. It'll be attached to a
327 // child anchor in the |text_buffer_| object.
328 GtkWidget* gray_text_view_;
329
330 // A mark to split the content and the gray text anchor. Wherever the end
331 // iterator of the text buffer is required, the iterator to this mark should
332 // be used.
333 GtkTextMark* gray_text_mark_;
334
335 scoped_ptr<OmniboxPopupView> popup_view_;
336
337 // When true, the location bar view is read only and also is has a slightly
338 // different presentation (smaller font size). This is used for popups.
339 bool popup_window_mode_;
340
341 ToolbarModel::SecurityLevel security_level_;
342
343 // Selection at the point where the user started using the
344 // arrows to move around in the popup.
345 CharRange saved_temporary_selection_;
346
347 // Tracking state before and after a possible change.
348 base::string16 text_before_change_;
349 CharRange sel_before_change_;
350
351 // The most-recently-selected text from the entry that was copied to the
352 // clipboard. This is updated on-the-fly as the user selects text. This may
353 // differ from the actual selected text, such as when 'http://' is prefixed to
354 // the text. It is used in cases where we need to make the PRIMARY selection
355 // persist even after the user has unhighlighted the text in the view
356 // (e.g. when they highlight some text and then click to unhighlight it, we
357 // pass this string to SavePrimarySelection()).
358 std::string selected_text_;
359
360 std::string dragged_text_;
361 // When we own the X clipboard, this is the text for it.
362 std::string primary_selection_text_;
363
364 // IDs of the signal handlers for "mark-set" on |text_buffer_|.
365 gulong mark_set_handler_id_;
366 gulong mark_set_handler_id2_;
367
368 // Is the first mouse button currently down? When selection marks get moved,
369 // we use this to determine if the user was highlighting text with the mouse
370 // -- if so, we avoid selecting all the text on mouse-up.
371 bool button_1_pressed_;
372
373 // Supplies colors, et cetera.
374 GtkThemeService* theme_service_;
375
376 content::NotificationRegistrar registrar_;
377
378 // Indicates if Enter key was pressed.
379 //
380 // It's used in the key press handler to detect an Enter key press event
381 // during sync dispatch of "end-user-action" signal so that an unexpected
382 // change caused by the event can be ignored in OnAfterPossibleChange().
383 bool enter_was_pressed_;
384
385 // Indicates if Tab key was pressed.
386 //
387 // It's only used in the key press handler to detect a Tab key press event
388 // during sync dispatch of "move-focus" signal.
389 bool tab_was_pressed_;
390
391 // Indicates if Shift key was pressed.
392 // Used in conjunction with the Tab key to determine if either traversal
393 // needs to move up the results or if the keyword needs to be cleared.
394 bool shift_was_pressed_;
395
396 // Indicates that user requested to paste clipboard.
397 // The actual paste clipboard action might be performed later if the
398 // clipboard is not empty.
399 bool paste_clipboard_requested_;
400
401 // Text to "Paste and go"; set by HandlePopulatePopup() and consumed by
402 // HandlePasteAndGo().
403 base::string16 sanitized_text_for_paste_and_go_;
404
405 // Indicates if an Enter key press is inserted as text.
406 // It's used in the key press handler to determine if an Enter key event is
407 // handled by IME or not.
408 bool enter_was_inserted_;
409
410 // Indicates whether the IME changed the text. It's possible for the IME to
411 // handle a key event but not change the text contents (e.g., when pressing
412 // shift+del with no selection).
413 bool text_changed_;
414
415 // Contains the character range that should have a strikethrough (used for
416 // insecure schemes). If the range is size one or less, no strikethrough
417 // is needed.
418 CharRange strikethrough_;
419
420 // Indicates if the selected text is suggested text or not. If the selection
421 // is not suggested text, that means the user manually made the selection.
422 bool selection_suggested_;
423
424 // Was delete pressed?
425 bool delete_was_pressed_;
426
427 // Was the delete key pressed with an empty selection at the end of the edit?
428 bool delete_at_end_pressed_;
429
430 // Indicates if we are handling a key press event.
431 bool handling_key_press_;
432
433 // Indicates if omnibox's content maybe changed by a key press event, so that
434 // we need to call OnAfterPossibleChange() after handling the event.
435 // This flag should be set for changes directly caused by a key press event,
436 // including changes to content text, selection range and pre-edit string.
437 // Changes caused by function calls like SetUserText() should not affect this
438 // flag.
439 bool content_maybe_changed_by_key_press_;
440
441 // Set this flag to call UpdatePopup() in lost focus and need to update.
442 // Because context menu might take the focus, before setting the flag, check
443 // the focus with model_->has_focus().
444 bool update_popup_without_focus_;
445
446 // On GTK 2.20+ |pre_edit_| and |pre_edit_size_before_change_| will be used.
447 const bool supports_pre_edit_;
448
449 // Stores the text being composed by the input method.
450 base::string16 pre_edit_;
451
452 // Tracking pre-edit state before and after a possible change. We don't need
453 // to track pre-edit_'s content, as it'll be treated as part of text content.
454 size_t pre_edit_size_before_change_;
455
456 // The view that is going to be focused next. Only valid while handling
457 // "focus-out" events.
458 GtkWidget* going_to_focus_;
459
460 ui::GtkSignalRegistrar signals_;
461
462 // The baseline shift to be made to center the text. Positive values move
463 // the text upward.
464 double font_baseline_shift_;
465
466 DISALLOW_COPY_AND_ASSIGN(OmniboxViewGtk);
467 };
468
469 #endif // CHROME_BROWSER_UI_GTK_OMNIBOX_OMNIBOX_VIEW_GTK_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698