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 #include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h" | 5 #include "chrome/browser/chromeos/input_method/virtual_keyboard_selector.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/stl_util.h" | 8 #include "base/stl_util.h" |
9 | 9 |
10 namespace { | 10 namespace { |
| 11 |
11 const char kDefaultURLPath[] = "index.html"; | 12 const char kDefaultURLPath[] = "index.html"; |
12 const size_t kDefaultURLPathLen = arraysize(kDefaultURLPath) - 1; | 13 const size_t kDefaultURLPathLen = arraysize(kDefaultURLPath) - 1; |
| 14 |
| 15 namespace ime = ::chromeos::input_method; |
| 16 |
| 17 // Selects and returns a virtual keyboard extension from |keyboards| which |
| 18 // supports the |layout|. |
| 19 const ime::VirtualKeyboard* SelectVirtualKeyboardInternal( |
| 20 const std::list<const ime::VirtualKeyboard*>& keyboards, |
| 21 const std::string& layout) { |
| 22 for (std::list<const ime::VirtualKeyboard*>::const_iterator iter = |
| 23 keyboards.begin(); iter != keyboards.end(); ++iter) { |
| 24 const ime::VirtualKeyboard* keyboard = *iter; |
| 25 if (keyboard->IsLayoutSupported(layout)) |
| 26 return keyboard; |
| 27 } |
| 28 return NULL; |
| 29 } |
| 30 |
13 } // namespace | 31 } // namespace |
14 | 32 |
15 namespace chromeos { | 33 namespace chromeos { |
16 namespace input_method { | 34 namespace input_method { |
17 | 35 |
18 VirtualKeyboard::VirtualKeyboard(const GURL& url, | 36 VirtualKeyboard::VirtualKeyboard(const GURL& url, |
19 const std::set<std::string>& supported_layouts, | 37 const std::set<std::string>& supported_layouts, |
20 bool is_system) | 38 bool is_system) |
21 : url_(url), | 39 : url_(url), |
22 supported_layouts_(supported_layouts), | 40 supported_layouts_(supported_layouts), |
23 is_system_(is_system) { | 41 is_system_(is_system) { |
24 } | 42 } |
25 | 43 |
26 VirtualKeyboard::~VirtualKeyboard() { | 44 VirtualKeyboard::~VirtualKeyboard() { |
27 } | 45 } |
28 | 46 |
29 GURL VirtualKeyboard::GetURLForLayout(const std::string& layout) const { | 47 GURL VirtualKeyboard::GetURLForLayout(const std::string& layout) const { |
30 if (layout.empty()) { | 48 if (layout.empty()) { |
31 return url_; | 49 return url_; |
32 } | 50 } |
33 url_canon::Replacements<char> replacements; | 51 url_canon::Replacements<char> replacements; |
34 replacements.SetPath( | 52 replacements.SetPath( |
35 kDefaultURLPath, url_parse::Component(0, kDefaultURLPathLen)); | 53 kDefaultURLPath, url_parse::Component(0, kDefaultURLPathLen)); |
36 // TODO(yusukes): would be better to URL-encode the |layout|? | 54 // TODO(yusukes): would be better to URL-encode the |layout|? |
37 replacements.SetRef(layout.c_str(), url_parse::Component(0, layout.length())); | 55 replacements.SetRef(layout.c_str(), url_parse::Component(0, layout.length())); |
38 return url_.ReplaceComponents(replacements); | 56 return url_.ReplaceComponents(replacements); |
39 } | 57 } |
40 | 58 |
| 59 bool VirtualKeyboard::IsLayoutSupported(const std::string& layout) const { |
| 60 return supported_layouts_.count(layout) > 0; |
| 61 } |
| 62 |
41 VirtualKeyboardSelector::VirtualKeyboardSelector() | 63 VirtualKeyboardSelector::VirtualKeyboardSelector() |
42 : current_(NULL) { | 64 : current_(NULL) { |
43 } | 65 } |
44 | 66 |
45 VirtualKeyboardSelector::~VirtualKeyboardSelector() { | 67 VirtualKeyboardSelector::~VirtualKeyboardSelector() { |
46 STLDeleteElements(&keyboards_); | 68 STLDeleteElements(&keyboards_); |
47 STLDeleteElements(&system_keyboards_); | 69 STLDeleteElements(&system_keyboards_); |
48 } | 70 } |
49 | 71 |
50 void VirtualKeyboardSelector::AddVirtualKeyboard( | 72 bool VirtualKeyboardSelector::AddVirtualKeyboard( |
51 const GURL& url, | 73 const GURL& url, |
52 const std::set<std::string>& supported_layouts, | 74 const std::set<std::string>& supported_layouts, |
53 bool is_system) { | 75 bool is_system) { |
| 76 if (url_to_keyboard_.count(url)) |
| 77 return false; // the URL is already in use. |
| 78 |
54 const VirtualKeyboard* new_keyboard = new VirtualKeyboard(url, | 79 const VirtualKeyboard* new_keyboard = new VirtualKeyboard(url, |
55 supported_layouts, | 80 supported_layouts, |
56 is_system); | 81 is_system); |
57 if (is_system) { | 82 if (is_system) { |
58 system_keyboards_.push_front(new_keyboard); | 83 system_keyboards_.push_front(new_keyboard); |
59 } else { | 84 } else { |
60 keyboards_.push_front(new_keyboard); | 85 keyboards_.push_front(new_keyboard); |
61 } | 86 } |
| 87 |
| 88 url_to_keyboard_.insert(std::make_pair(url, new_keyboard)); |
| 89 return true; |
62 } | 90 } |
63 | 91 |
64 const VirtualKeyboard* VirtualKeyboardSelector::SelectVirtualKeyboard( | 92 const VirtualKeyboard* VirtualKeyboardSelector::SelectVirtualKeyboard( |
65 const std::string& layout) { | 93 const std::string& layout) { |
66 if (layout.empty()) { | 94 if (layout.empty()) { |
67 LOG(ERROR) << "No layout is specified"; | 95 LOG(ERROR) << "No layout is specified"; |
68 return NULL; | 96 return NULL; |
69 } | 97 } |
70 | 98 |
71 // First, check whether the current keyboard supports the layout. | 99 // First, check the user pref. |
72 if (current_ && current_->supported_layouts().count(layout) > 0) { | 100 std::map<std::string, const VirtualKeyboard*>::const_iterator iter = |
| 101 user_preference_.find(layout); |
| 102 if (iter != user_preference_.end() && |
| 103 iter->second->IsLayoutSupported(layout)) { |
| 104 current_ = iter->second; |
73 return current_; | 105 return current_; |
74 } | 106 } |
75 | 107 |
76 const VirtualKeyboard* keyboard = SelectVirtualKeyboardInternal(layout); | 108 // Second, check whether the current keyboard supports the layout. |
| 109 if (current_ && current_->IsLayoutSupported(layout)) { |
| 110 return current_; |
| 111 } |
| 112 |
| 113 const VirtualKeyboard* keyboard = |
| 114 SelectVirtualKeyboardWithoutPreferences(layout); |
77 if (!keyboard) { | 115 if (!keyboard) { |
78 VLOG(1) << "No virtual keyboard for " << layout << " is found"; | 116 VLOG(1) << "No virtual keyboard for " << layout << " is found"; |
79 return NULL; | 117 return NULL; |
80 } | 118 } |
81 | 119 |
82 current_ = keyboard; | 120 current_ = keyboard; |
83 return keyboard; | 121 return keyboard; |
84 } | 122 } |
85 | 123 |
86 const VirtualKeyboard* VirtualKeyboardSelector::SelectVirtualKeyboardInternal( | 124 bool VirtualKeyboardSelector::SetUserPreference( |
| 125 const std::string& layout, const GURL& url) { |
| 126 std::map<GURL, const VirtualKeyboard*>::const_iterator iter = |
| 127 url_to_keyboard_.find(url); |
| 128 if (iter == url_to_keyboard_.end()) { |
| 129 VLOG(1) << "Can't set user preference: unknown URL"; |
| 130 return false; |
| 131 } |
| 132 |
| 133 const VirtualKeyboard* keyboard = iter->second; |
| 134 if (!keyboard->IsLayoutSupported(layout)) { |
| 135 VLOG(1) << "Requested layout is not supported by requested URL"; |
| 136 return false; |
| 137 } |
| 138 |
| 139 RemoveUserPreference(layout); |
| 140 user_preference_.insert(std::make_pair(layout, keyboard)); |
| 141 return true; |
| 142 } |
| 143 |
| 144 void VirtualKeyboardSelector::RemoveUserPreference(const std::string& layout) { |
| 145 user_preference_.erase(layout); |
| 146 } |
| 147 |
| 148 const VirtualKeyboard* |
| 149 VirtualKeyboardSelector::SelectVirtualKeyboardWithoutPreferences( |
87 const std::string& layout) { | 150 const std::string& layout) { |
88 std::list<const VirtualKeyboard*>::const_iterator iter; | 151 const VirtualKeyboard* keyboard = |
89 for (iter = keyboards_.begin(); iter != keyboards_.end(); ++iter) { | 152 SelectVirtualKeyboardInternal(keyboards_, layout); |
90 if ((*iter)->supported_layouts().count(layout) > 0) { | 153 if (!keyboard) |
91 return *iter; | 154 keyboard = SelectVirtualKeyboardInternal(system_keyboards_, layout); |
92 } | 155 return keyboard; |
93 } | |
94 for (iter = system_keyboards_.begin(); | |
95 iter != system_keyboards_.end(); ++iter) { | |
96 if ((*iter)->supported_layouts().count(layout) > 0) { | |
97 return *iter; | |
98 } | |
99 } | |
100 return NULL; | |
101 } | 156 } |
102 | 157 |
103 } // namespace input_method | 158 } // namespace input_method |
104 } // namespace chromeos | 159 } // namespace chromeos |
OLD | NEW |