summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/autocomplete_edit_view_win.h
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/autocomplete/autocomplete_edit_view_win.h')
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h506
1 files changed, 506 insertions, 0 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
new file mode 100644
index 0000000..8157706
--- /dev/null
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h
@@ -0,0 +1,506 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_WIN_H_
+#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_WIN_H_
+
+#include <atlbase.h>
+#include <atlapp.h>
+#include <atlcrack.h>
+#include <atlctrls.h>
+#include <atlmisc.h>
+#include <tom.h> // For ITextDocument, a COM interface to CRichEditCtrl.
+
+#include "app/menus/simple_menu_model.h"
+#include "base/scoped_comptr_win.h"
+#include "base/scoped_ptr.h"
+#include "chrome/browser/autocomplete/autocomplete.h"
+#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/browser/toolbar_model.h"
+#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h"
+#include "chrome/common/page_transition_types.h"
+#include "gfx/font.h"
+#include "webkit/glue/window_open_disposition.h"
+#include "views/controls/menu/menu_2.h"
+
+class AutocompletePopupModel;
+class Profile;
+class TabContents;
+namespace views {
+class View;
+}
+
+class AutocompleteEditController;
+class AutocompleteEditModel;
+class AutocompleteEditView;
+class AutocompletePopupView;
+
+// Provides the implementation of an edit control with a drop-down
+// autocomplete box. The box itself is implemented in autocomplete_popup.cc
+// This file implements the edit box and management for the popup.
+class AutocompleteEditViewWin
+ : public CWindowImpl<AutocompleteEditViewWin,
+ CRichEditCtrl,
+ CWinTraits<WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL |
+ ES_NOHIDESEL> >,
+ public CRichEditCommands<AutocompleteEditViewWin>,
+ public menus::SimpleMenuModel::Delegate,
+ public AutocompleteEditView {
+ public:
+ struct State {
+ State(const CHARRANGE& selection,
+ const CHARRANGE& saved_selection_for_focus_change)
+ : selection(selection),
+ saved_selection_for_focus_change(saved_selection_for_focus_change) {
+ }
+
+ const CHARRANGE selection;
+ const CHARRANGE saved_selection_for_focus_change;
+ };
+
+ DECLARE_WND_CLASS(L"Chrome_AutocompleteEditView");
+
+ AutocompleteEditViewWin(const gfx::Font& font,
+ AutocompleteEditController* controller,
+ ToolbarModel* toolbar_model,
+ views::View* parent_view,
+ HWND hwnd,
+ Profile* profile,
+ CommandUpdater* command_updater,
+ bool popup_window_mode,
+ const views::View* location_bar);
+ ~AutocompleteEditViewWin();
+
+ views::View* parent_view() const { return parent_view_; }
+
+ // Implement the AutocompleteEditView interface.
+ virtual AutocompleteEditModel* model() { return model_.get(); }
+ virtual const AutocompleteEditModel* model() const { return model_.get(); }
+
+ virtual void SaveStateToTab(TabContents* tab);
+
+ virtual void Update(const TabContents* tab_for_state_restoring);
+
+ virtual void OpenURL(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url,
+ size_t selected_line,
+ const std::wstring& keyword);
+
+ virtual std::wstring GetText() const;
+
+ virtual bool IsEditingOrEmpty() const;
+ virtual int GetIcon() const;
+
+ virtual void SetUserText(const std::wstring& text) {
+ SetUserText(text, text, true);
+ }
+ virtual void SetUserText(const std::wstring& text,
+ const std::wstring& display_text,
+ bool update_popup);
+
+ virtual void SetWindowTextAndCaretPos(const std::wstring& text,
+ size_t caret_pos);
+
+ virtual void SetForcedQuery();
+
+ virtual bool IsSelectAll();
+ virtual void SelectAll(bool reversed);
+ virtual void RevertAll();
+
+ virtual void UpdatePopup();
+ virtual void ClosePopup();
+
+ virtual void SetFocus();
+
+ virtual void OnTemporaryTextMaybeChanged(const std::wstring& display_text,
+ bool save_original_selection);
+ virtual bool OnInlineAutocompleteTextMaybeChanged(
+ const std::wstring& display_text, size_t user_text_length);
+ virtual void OnRevertTemporaryText();
+ virtual void OnBeforePossibleChange();
+ virtual bool OnAfterPossibleChange();
+ virtual gfx::NativeView GetNativeView() const;
+ virtual CommandUpdater* GetCommandUpdater();
+
+ // Exposes custom IAccessible implementation to the overall MSAA hierarchy.
+ IAccessible* GetIAccessible();
+
+ void SetDropHighlightPosition(int position);
+ int drop_highlight_position() const { return drop_highlight_position_; }
+
+ // Returns true if a drag a drop session was initiated by this edit.
+ bool in_drag() const { return in_drag_; }
+
+ // Moves the selected text to the specified position.
+ void MoveSelectedText(int new_position);
+
+ // Inserts the text at the specified position.
+ void InsertText(int position, const std::wstring& text);
+
+ // Invokes CanPasteAndGo with the specified text, and if successful navigates
+ // to the appropriate URL. The behavior of this is the same as if the user
+ // typed in the specified text and pressed enter.
+ void PasteAndGo(const std::wstring& text);
+
+ void set_force_hidden(bool force_hidden) { force_hidden_ = force_hidden; }
+
+ // Called before an accelerator is processed to give us a chance to override
+ // it.
+ bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
+
+ // Handler for external events passed in to us. The View that owns us may
+ // send us events that we should treat as if they were events on us.
+ void HandleExternalMsg(UINT msg, UINT flags, const CPoint& screen_point);
+
+ // CWindowImpl
+ BEGIN_MSG_MAP(AutocompleteEdit)
+ MSG_WM_CHAR(OnChar)
+ MSG_WM_CONTEXTMENU(OnContextMenu)
+ MSG_WM_COPY(OnCopy)
+ MSG_WM_CUT(OnCut)
+ MESSAGE_HANDLER_EX(WM_GETOBJECT, OnGetObject)
+ MESSAGE_HANDLER_EX(WM_IME_COMPOSITION, OnImeComposition)
+ MESSAGE_HANDLER_EX(WM_IME_NOTIFY, OnImeNotify)
+ MSG_WM_KEYDOWN(OnKeyDown)
+ MSG_WM_KEYUP(OnKeyUp)
+ MSG_WM_KILLFOCUS(OnKillFocus)
+ MSG_WM_LBUTTONDBLCLK(OnLButtonDblClk)
+ MSG_WM_LBUTTONDOWN(OnLButtonDown)
+ MSG_WM_LBUTTONUP(OnLButtonUp)
+ MSG_WM_MBUTTONDBLCLK(OnMButtonDblClk)
+ MSG_WM_MBUTTONDOWN(OnMButtonDown)
+ MSG_WM_MBUTTONUP(OnMButtonUp)
+ MSG_WM_MOUSEACTIVATE(OnMouseActivate)
+ MSG_WM_MOUSEMOVE(OnMouseMove)
+ MSG_WM_MOUSEWHEEL(OnMouseWheel)
+ MSG_WM_PAINT(OnPaint)
+ MSG_WM_PASTE(OnPaste)
+ MSG_WM_RBUTTONDBLCLK(OnRButtonDblClk)
+ MSG_WM_RBUTTONDOWN(OnRButtonDown)
+ MSG_WM_RBUTTONUP(OnRButtonUp)
+ MSG_WM_SETFOCUS(OnSetFocus)
+ MSG_WM_SETTEXT(OnSetText)
+ MSG_WM_SYSCHAR(OnSysChar) // WM_SYSxxx == WM_xxx with ALT down
+ MSG_WM_SYSKEYDOWN(OnKeyDown)
+ MSG_WM_SYSKEYUP(OnKeyUp)
+ MSG_WM_WINDOWPOSCHANGING(OnWindowPosChanging)
+ DEFAULT_REFLECTION_HANDLER() // avoids black margin area
+ END_MSG_MAP()
+
+ // menus::SimpleMenuModel::Delegate
+ virtual bool IsCommandIdChecked(int command_id) const;
+ virtual bool IsCommandIdEnabled(int command_id) const;
+ virtual bool GetAcceleratorForCommandId(int command_id,
+ menus::Accelerator* accelerator);
+ virtual bool IsLabelForCommandIdDynamic(int command_id) const;
+ virtual std::wstring GetLabelForCommandId(int command_id) const;
+ virtual void ExecuteCommand(int command_id);
+
+ private:
+ enum MouseButton {
+ kLeft = 0,
+ kRight = 1,
+ };
+
+ // This object freezes repainting of the edit until the object is destroyed.
+ // Some methods of the CRichEditCtrl draw synchronously to the screen. If we
+ // don't freeze, the user will see a rapid series of calls to these as
+ // flickers.
+ //
+ // Freezing the control while it is already frozen is permitted; the control
+ // will unfreeze once both freezes are released (the freezes stack).
+ class ScopedFreeze {
+ public:
+ ScopedFreeze(AutocompleteEditViewWin* edit,
+ ITextDocument* text_object_model);
+ ~ScopedFreeze();
+
+ private:
+ AutocompleteEditViewWin* const edit_;
+ ITextDocument* const text_object_model_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedFreeze);
+ };
+
+ // This object suspends placing any operations on the edit's undo stack until
+ // the object is destroyed. If we don't do this, some of the operations we
+ // perform behind the user's back will be undoable by the user, which feels
+ // bizarre and confusing.
+ class ScopedSuspendUndo {
+ public:
+ explicit ScopedSuspendUndo(ITextDocument* text_object_model);
+ ~ScopedSuspendUndo();
+
+ private:
+ ITextDocument* const text_object_model_;
+
+ DISALLOW_COPY_AND_ASSIGN(ScopedSuspendUndo);
+ };
+
+ // Replacement word-breaking proc for the rich edit control.
+ static int CALLBACK WordBreakProc(LPTSTR edit_text,
+ int current_pos,
+ int num_bytes,
+ int action);
+
+ // Returns true if |edit_text| starting at |current_pos| is "://".
+ static bool SchemeEnd(LPTSTR edit_text, int current_pos, int length);
+
+ // Message handlers
+ void OnChar(TCHAR ch, UINT repeat_count, UINT flags);
+ void OnContextMenu(HWND window, const CPoint& point);
+ void OnCopy();
+ void OnCut();
+ LRESULT OnGetObject(UINT uMsg, WPARAM wparam, LPARAM lparam);
+ LRESULT OnImeComposition(UINT message, WPARAM wparam, LPARAM lparam);
+ LRESULT OnImeNotify(UINT message, WPARAM wparam, LPARAM lparam);
+ void OnKeyDown(TCHAR key, UINT repeat_count, UINT flags);
+ void OnKeyUp(TCHAR key, UINT repeat_count, UINT flags);
+ void OnKillFocus(HWND focus_wnd);
+ void OnLButtonDblClk(UINT keys, const CPoint& point);
+ void OnLButtonDown(UINT keys, const CPoint& point);
+ void OnLButtonUp(UINT keys, const CPoint& point);
+ void OnMButtonDblClk(UINT keys, const CPoint& point);
+ void OnMButtonDown(UINT keys, const CPoint& point);
+ void OnMButtonUp(UINT keys, const CPoint& point);
+ LRESULT OnMouseActivate(HWND window, UINT hit_test, UINT mouse_message);
+ void OnMouseMove(UINT keys, const CPoint& point);
+ BOOL OnMouseWheel(UINT flags, short delta, CPoint point);
+ void OnPaint(HDC bogus_hdc);
+ void OnPaste();
+ void OnRButtonDblClk(UINT keys, const CPoint& point);
+ void OnRButtonDown(UINT keys, const CPoint& point);
+ void OnRButtonUp(UINT keys, const CPoint& point);
+ void OnSetFocus(HWND focus_wnd);
+ LRESULT OnSetText(const wchar_t* text);
+ void OnSysChar(TCHAR ch, UINT repeat_count, UINT flags);
+ void OnWindowPosChanging(WINDOWPOS* window_pos);
+
+ // Helper function for OnChar() and OnKeyDown() that handles keystrokes that
+ // could change the text in the edit.
+ void HandleKeystroke(UINT message, TCHAR key, UINT repeat_count, UINT flags);
+
+ // Helper functions for OnKeyDown() that handle accelerators applicable when
+ // we're not read-only and all the time, respectively. These return true if
+ // they handled the key.
+ bool OnKeyDownOnlyWritable(TCHAR key, UINT repeat_count, UINT flags);
+ bool OnKeyDownAllModes(TCHAR key, UINT repeat_count, UINT flags);
+
+ // Like GetSel(), but returns a range where |cpMin| will be larger than
+ // |cpMax| if the cursor is at the start rather than the end of the selection
+ // (in other words, tracks selection direction as well as offsets).
+ // Note the non-Google-style "non-const-ref" argument, which matches GetSel().
+ void GetSelection(CHARRANGE& sel) const;
+
+ // Returns the currently selected text of the edit control.
+ std::wstring GetSelectedText() const;
+
+ // Like SetSel(), but respects the selection direction implied by |start| and
+ // |end|: if |end| < |start|, the effective cursor will be placed at the
+ // beginning of the selection.
+ void SetSelection(LONG start, LONG end);
+
+ // Like SetSelection(), but takes a CHARRANGE.
+ void SetSelectionRange(const CHARRANGE& sel) {
+ SetSelection(sel.cpMin, sel.cpMax);
+ }
+
+ // Places the caret at the given position. This clears any selection.
+ void PlaceCaretAt(size_t pos);
+
+ // Returns true if |sel| represents a forward or backward selection of all the
+ // text.
+ bool IsSelectAllForRange(const CHARRANGE& sel) const;
+
+ // Given an X coordinate in client coordinates, returns that coordinate
+ // clipped to be within the horizontal bounds of the visible text.
+ //
+ // This is used in our mouse handlers to work around quirky behaviors of the
+ // underlying CRichEditCtrl like not supporting triple-click when the user
+ // doesn't click on the text itself.
+ //
+ // |is_triple_click| should be true iff this is the third click of a triple
+ // click. Sadly, we need to clip slightly differently in this case.
+ LONG ClipXCoordToVisibleText(LONG x, bool is_triple_click) const;
+
+ // Parses the contents of the control for the scheme and the host name.
+ // Highlights the scheme in green or red depending on it security level.
+ // If a host name is found, it makes it visually stronger.
+ void EmphasizeURLComponents();
+
+ // Erases the portion of the selection in the font's y-adjustment area. For
+ // some reason the edit draws the selection rect here even though it's not
+ // part of the font.
+ void EraseTopOfSelection(CDC* dc,
+ const CRect& client_rect,
+ const CRect& paint_clip_rect);
+
+ // Draws a slash across the scheme if desired.
+ void DrawSlashForInsecureScheme(HDC hdc,
+ const CRect& client_rect,
+ const CRect& paint_clip_rect);
+
+ // Renders the drop highlight.
+ void DrawDropHighlight(HDC hdc,
+ const CRect& client_rect,
+ const CRect& paint_clip_rect);
+
+ // Internally invoked whenever the text changes in some way.
+ void TextChanged();
+
+ // Returns the current clipboard contents as a string that can be pasted in.
+ // In addition to just getting CF_UNICODETEXT out, this can also extract URLs
+ // from bookmarks on the clipboard.
+ std::wstring GetClipboardText() const;
+
+ // Determines whether the user can "paste and go", given the specified text.
+ bool CanPasteAndGo(const std::wstring& text) const;
+
+ // Getter for the text_object_model_. Note that the pointer returned here is
+ // only valid as long as the AutocompleteEdit is still alive. Also, if the
+ // underlying call fails, this may return NULL.
+ ITextDocument* GetTextObjectModel() const;
+
+ // Invoked during a mouse move. As necessary starts a drag and drop session.
+ void StartDragIfNecessary(const CPoint& point);
+
+ // Invoked during a mouse down. If the mouse location is over the selection
+ // this sets possible_drag_ to true to indicate a drag should start if the
+ // user moves the mouse far enough to start a drag.
+ void OnPossibleDrag(const CPoint& point);
+
+ // Redraws the necessary region for a drop highlight at the specified
+ // position. This does nothing if position is beyond the bounds of the
+ // text.
+ void RepaintDropHighlight(int position);
+
+ // Generates the context menu for the edit field.
+ void BuildContextMenu();
+
+ void SelectAllIfNecessary(MouseButton button, const CPoint& point);
+ void TrackMousePosition(MouseButton button, const CPoint& point);
+
+ scoped_ptr<AutocompleteEditModel> model_;
+
+ scoped_ptr<AutocompletePopupView> popup_view_;
+
+ AutocompleteEditController* controller_;
+
+ // The parent view for the edit, used to align the popup and for
+ // accessibility.
+ views::View* parent_view_;
+
+ ToolbarModel* toolbar_model_;
+
+ // The object that handles additional command functionality exposed on the
+ // edit, such as invoking the keyword editor.
+ CommandUpdater* command_updater_;
+
+ // When true, the location bar view is read only and also is has a slightly
+ // different presentation (font size / color). This is used for popups.
+ bool popup_window_mode_;
+
+ // True if we should prevent attempts to make the window visible when we
+ // handle WM_WINDOWPOSCHANGING. While toggling fullscreen mode, the main
+ // window is hidden, and if the edit is shown it will draw over the main
+ // window when that window reappears.
+ bool force_hidden_;
+
+ // Non-null when the edit is gaining focus from a left click. This is only
+ // needed between when WM_MOUSEACTIVATE and WM_LBUTTONDOWN get processed. It
+ // serves two purposes: first, by communicating to OnLButtonDown() that we're
+ // gaining focus from a left click, it allows us to work even with the
+ // inconsistent order in which various Windows messages get sent (see comments
+ // in OnMouseActivate()). Second, by holding the edit frozen, it ensures that
+ // when we process WM_SETFOCUS the edit won't first redraw itself with the
+ // caret at the beginning, and then have it blink to where the mouse cursor
+ // really is shortly afterward.
+ scoped_ptr<ScopedFreeze> gaining_focus_;
+
+ // When the user clicks to give us focus, we watch to see if they're clicking
+ // or dragging. When they're clicking, we select nothing until mouseup, then
+ // select all the text in the edit. During this process, tracking_click_[X]
+ // is true and click_point_[X] holds the original click location.
+ // At other times, tracking_click_[X] is false, and the contents of
+ // click_point_[X] should be ignored. The arrays hold the state for the
+ // left and right mouse buttons, and are indexed using the MouseButton enum.
+ bool tracking_click_[2];
+ CPoint click_point_[2];
+
+ // We need to know if the user triple-clicks, so track double click points
+ // and times so we can see if subsequent clicks are actually triple clicks.
+ bool tracking_double_click_;
+ CPoint double_click_point_;
+ DWORD double_click_time_;
+
+ // Used to discard unnecessary WM_MOUSEMOVE events after the first such
+ // unnecessary event. See detailed comments in OnMouseMove().
+ bool can_discard_mousemove_;
+
+ // Used to prevent IME message handling in the midst of updating the edit
+ // text. See comments where this is used.
+ bool ignore_ime_messages_;
+
+ // Variables for tracking state before and after a possible change.
+ std::wstring text_before_change_;
+ CHARRANGE sel_before_change_;
+
+ // Set at the same time the model's original_* members are set, and valid in
+ // the same cases.
+ CHARRANGE original_selection_;
+
+ // Holds the user's selection across focus changes. cpMin holds -1 when
+ // there is no saved selection.
+ CHARRANGE saved_selection_for_focus_change_;
+
+ // The context menu for the edit.
+ scoped_ptr<menus::SimpleMenuModel> context_menu_contents_;
+ scoped_ptr<views::Menu2> context_menu_;
+
+ // Font we're using. We keep a reference to make sure the font supplied to
+ // the constructor doesn't go away before we do.
+ gfx::Font font_;
+
+ // Metrics about the font, which we keep so we don't need to recalculate them
+ // every time we paint. |font_y_adjustment_| is the number of pixels we need
+ // to shift the font vertically in order to make its baseline be at our
+ // desired baseline in the edit.
+ int font_x_height_;
+ int font_y_adjustment_;
+
+ // If true, indicates the mouse is down and if the mouse is moved enough we
+ // should start a drag.
+ bool possible_drag_;
+
+ // If true, we're in a call to DoDragDrop.
+ bool in_drag_;
+
+ // If true indicates we've run a drag and drop session. This is used to
+ // avoid starting two drag and drop sessions if the drag is canceled while
+ // the mouse is still down.
+ bool initiated_drag_;
+
+ // Position of the drop highlight. If this is -1, there is no drop highlight.
+ int drop_highlight_position_;
+
+ // Security UI-related data.
+ COLORREF background_color_;
+ ToolbarModel::SecurityLevel security_level_;
+
+ // This interface is useful for accessing the CRichEditCtrl at a low level.
+ mutable ITextDocument* text_object_model_;
+
+ // This contains the scheme char start and stop indexes that should be
+ // striken-out when displaying an insecure scheme.
+ url_parse::Component insecure_scheme_component_;
+
+ // Instance of accessibility information and handling.
+ mutable ScopedComPtr<IAccessible> autocomplete_accessibility_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutocompleteEditViewWin);
+};
+
+#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_EDIT_VIEW_WIN_H_