Home | History | Annotate | Download | only in tab_contents
      1 // Copyright (c) 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_TAB_CONTENTS_SPELLING_MENU_OBSERVER_H_
      6 #define CHROME_BROWSER_TAB_CONTENTS_SPELLING_MENU_OBSERVER_H_
      7 
      8 #include <vector>
      9 
     10 #include "base/compiler_specific.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/prefs/pref_member.h"
     13 #include "base/strings/string16.h"
     14 #include "base/timer/timer.h"
     15 #include "chrome/browser/spellchecker/spelling_service_client.h"
     16 #include "chrome/browser/tab_contents/render_view_context_menu_observer.h"
     17 
     18 class RenderViewContextMenuProxy;
     19 struct SpellCheckResult;
     20 
     21 // An observer that listens to events from the RenderViewContextMenu class and
     22 // shows suggestions from the Spelling ("do you mean") service to a context menu
     23 // while we show it. This class implements two interfaces:
     24 // * RenderViewContextMenuObserver
     25 //   This interface is used for adding a menu item and update it while showing.
     26 // * net::URLFetcherDelegate
     27 //   This interface is used for sending a JSON_RPC request to the Spelling
     28 //   service and retrieving its response.
     29 // These interfaces allow this class to make a JSON-RPC call to the Spelling
     30 // service in the background and update the context menu while showing. The
     31 // following snippet describes how to add this class to the observer list of the
     32 // RenderViewContextMenu class.
     33 //
     34 //   void RenderViewContextMenu::InitMenu() {
     35 //     spelling_menu_observer_.reset(new SpellingMenuObserver(this));
     36 //     if (spelling_menu_observer_.get())
     37 //       observers_.AddObserver(spelling_menu_observer.get());
     38 //   }
     39 //
     40 class SpellingMenuObserver : public RenderViewContextMenuObserver {
     41  public:
     42   explicit SpellingMenuObserver(RenderViewContextMenuProxy* proxy);
     43   virtual ~SpellingMenuObserver();
     44 
     45   // RenderViewContextMenuObserver implementation.
     46   virtual void InitMenu(const content::ContextMenuParams& params) OVERRIDE;
     47   virtual bool IsCommandIdSupported(int command_id) OVERRIDE;
     48   virtual bool IsCommandIdChecked(int command_id) OVERRIDE;
     49   virtual bool IsCommandIdEnabled(int command_id) OVERRIDE;
     50   virtual void ExecuteCommand(int command_id) OVERRIDE;
     51   virtual void OnMenuCancel() OVERRIDE;
     52 
     53   // A callback function called when the Spelling service finishes checking a
     54   // misspelled word.
     55   void OnTextCheckComplete(
     56       SpellingServiceClient::ServiceType type,
     57       bool success,
     58       const string16& text,
     59       const std::vector<SpellCheckResult>& results);
     60 
     61  private:
     62   // The callback function for base::RepeatingTimer<SpellingMenuClient>. This
     63   // function updates the "loading..." animation in the context-menu item.
     64   void OnAnimationTimerExpired();
     65 
     66   // The interface to add a context-menu item and update it. This class uses
     67   // this interface to avoid accesing context-menu items directly.
     68   RenderViewContextMenuProxy* proxy_;
     69 
     70   // Suggested words from the local spellchecker. If the spelling service
     71   // returns a word in this list, we hide the context-menu item to prevent
     72   // showing the same word twice.
     73   std::vector<string16> suggestions_;
     74 
     75   // The string used for animation until we receive a response from the Spelling
     76   // service. The current animation just adds periods at the end of this string:
     77   //   'Loading' -> 'Loading.' -> 'Loading..' -> 'Loading...' (-> 'Loading')
     78   string16 loading_message_;
     79   size_t loading_frame_;
     80 
     81   // A flag represending whether a JSON-RPC call to the Spelling service
     82   // finished successfully and its response had a suggestion not included in the
     83   // ones provided by the local spellchecker. When this flag is true, we enable
     84   // the context-menu item so users can choose it.
     85   bool succeeded_;
     86 
     87   // The misspelled word. When we choose the "Add to dictionary" item, we add
     88   // this word to the custom-word dictionary.
     89   string16 misspelled_word_;
     90 
     91   // The hash identifier for the misspelled word. Used for collecting user
     92   // feedback to spellcheck suggestions.
     93   uint32 misspelling_hash_;
     94 
     95   // The string representing the result of this call. This string is a
     96   // suggestion when this call finished successfully. Otherwise it is error
     97   // text. Until we receive a response from the Spelling service, this string
     98   // stores the input string. (Since the Spelling service sends only misspelled
     99   // words, we replace these misspelled words in the input text with the
    100   // suggested words to create suggestion text.
    101   string16 result_;
    102 
    103   // The URLFetcher object used for sending a JSON-RPC request.
    104   scoped_ptr<SpellingServiceClient> client_;
    105 
    106   // A timer used for loading animation.
    107   base::RepeatingTimer<SpellingMenuObserver> animation_timer_;
    108 
    109   // Flag indicating whether online spelling correction service is enabled. When
    110   // this variable is true and we right-click a misspelled word, we send a
    111   // JSON-RPC request to the service and retrieve suggestions.
    112   BooleanPrefMember integrate_spelling_service_;
    113 
    114   // Flag indicating whether automatic spelling correction is enabled.
    115   BooleanPrefMember autocorrect_spelling_;
    116 
    117   DISALLOW_COPY_AND_ASSIGN(SpellingMenuObserver);
    118 };
    119 
    120 #endif  // CHROME_BROWSER_TAB_CONTENTS_SPELLING_MENU_OBSERVER_H_
    121