diff options
author | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 07:47:09 +0000 |
---|---|---|
committer | nona@chromium.org <nona@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-06 07:47:09 +0000 |
commit | dbc37da08e32918f1a1b9355932b2ba2b6859296 (patch) | |
tree | 0ad994ea4dcb70dab308e48e0a8e3a3c1369126b /chrome/browser/chromeos/input_method | |
parent | b9403ef2a9c148b4bbbce3f64881231f3999aa06 (diff) | |
download | chromium_src-dbc37da08e32918f1a1b9355932b2ba2b6859296.zip chromium_src-dbc37da08e32918f1a1b9355932b2ba2b6859296.tar.gz chromium_src-dbc37da08e32918f1a1b9355932b2ba2b6859296.tar.bz2 |
Support mozc suggest window on ChromeOS.
Ordinal IME shows candidate window under the cursor, but Mozc should show
"suggest window"(same view but different location) and it's location is sent
by mozc-engine.
BUG=chromium-os:21356
TEST=manually confirmed it works fine and no conflict with other CJK engine.
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=112452
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=112965
Review URL: http://codereview.chromium.org/8505051
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113158 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/input_method')
7 files changed, 272 insertions, 121 deletions
diff --git a/chrome/browser/chromeos/input_method/candidate_window.cc b/chrome/browser/chromeos/input_method/candidate_window.cc index 85078ff..e8a4593 100644 --- a/chrome/browser/chromeos/input_method/candidate_window.cc +++ b/chrome/browser/chromeos/input_method/candidate_window.cc @@ -833,7 +833,8 @@ CandidateWindowView::CandidateWindowView(views::Widget* parent_frame) footer_area_(NULL), previous_shortcut_column_width_(0), previous_candidate_column_width_(0), - previous_annotation_column_width_(0) { + previous_annotation_column_width_(0), + is_suggestion_window_location_available_(false) { } CandidateWindowView::~CandidateWindowView() { @@ -935,6 +936,24 @@ void CandidateWindowView::ShowLookupTable() { bool CandidateWindowView::ShouldUpdateCandidateViews( const InputMethodLookupTable& old_table, const InputMethodLookupTable& new_table) { + + // Check if mozc lookup table location is changed. + if (old_table.mozc_candidates.has_window_location() || + new_table.mozc_candidates.has_window_location()) { + + if (!old_table.mozc_candidates.IsInitialized() || + !new_table.mozc_candidates.IsInitialized()) { + return true; + } + + std::string old_serialized_msg; + std::string new_serialized_msg; + + old_table.mozc_candidates.SerializeToString(&old_serialized_msg); + new_table.mozc_candidates.SerializeToString(&new_serialized_msg); + return old_serialized_msg != new_serialized_msg; + } + // Check if most table contents are identical. if (old_table.page_size == new_table.page_size && old_table.orientation == new_table.orientation && @@ -959,6 +978,24 @@ void CandidateWindowView::UpdateCandidates( // Initialize candidate views if necessary. MaybeInitializeCandidateViews(new_lookup_table); + // Store mozc specific window location. + if (new_lookup_table.mozc_candidates.has_window_location() && + new_lookup_table.mozc_candidates.window_location() == + mozc::commands::Candidates::COMPOSITION) { + DCHECK(new_lookup_table.mozc_candidates.has_composition_rectangle()); + suggestion_window_location_.set_x( + new_lookup_table.mozc_candidates.composition_rectangle().x()); + suggestion_window_location_.set_y( + new_lookup_table.mozc_candidates.composition_rectangle().y()); + suggestion_window_location_.set_width( + new_lookup_table.mozc_candidates.composition_rectangle().width()); + suggestion_window_location_.set_height( + new_lookup_table.mozc_candidates.composition_rectangle().height()); + is_suggestion_window_location_available_ = true; + } else { + is_suggestion_window_location_available_ = false; + } + // Compute the index of the current page. const int current_page_index = ComputePageIndex(new_lookup_table); if (current_page_index < 0) { @@ -1183,8 +1220,16 @@ void CandidateWindowView::CommitCandidate() { } void CandidateWindowView::ResizeAndMoveParentFrame() { - const int x = cursor_location_.x(); - const int y = cursor_location_.y(); + // If rendering operation comes from mozc-engine, uses mozc specific location, + // otherwise lookup table is shown under the cursor. + const int x = is_suggestion_window_location_available_ ? + suggestion_window_location_.x() : cursor_location_.x(); + // To avoid lookup-table overlapping, uses maximum y-position of mozc specific + // location and cursor location, because mozc-engine does not consider about + // multi-line composition. + const int y = is_suggestion_window_location_available_ ? + std::max(suggestion_window_location_.y(), cursor_location_.y()) : + cursor_location_.y(); const int height = cursor_location_.height(); const int horizontal_offset = GetHorizontalOffset(); diff --git a/chrome/browser/chromeos/input_method/candidate_window_view.h b/chrome/browser/chromeos/input_method/candidate_window_view.h index fcbc758..06e3120c 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_view.h +++ b/chrome/browser/chromeos/input_method/candidate_window_view.h @@ -177,6 +177,16 @@ class CandidateWindowView : public views::View { // The last cursor location. gfx::Rect cursor_location_; + // This location is used by suggestion window rendering which is mostly used + // by ibus-mozc. The suggestion window should be aligned with the composition + // text as opposed to the cursor. In case of ibus-mozc, suggestion window + // location is calculated by engine and it carried by update_lookup_table + // signal as additional information. This value is available when + // is_suggestion_window_available is true. + gfx::Rect suggestion_window_location_; + + bool is_suggestion_window_location_available_; + DISALLOW_COPY_AND_ASSIGN(CandidateWindowView); }; diff --git a/chrome/browser/chromeos/input_method/candidate_window_view_unittest.cc b/chrome/browser/chromeos/input_method/candidate_window_view_unittest.cc index f3e62f9..5dcd303 100644 --- a/chrome/browser/chromeos/input_method/candidate_window_view_unittest.cc +++ b/chrome/browser/chromeos/input_method/candidate_window_view_unittest.cc @@ -1,14 +1,68 @@ // Copyright (c) 2011 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. +// TODO(nona): Add unittests for UpdateCandidates. #include "chrome/browser/chromeos/input_method/candidate_window_view.h" +#include <string> + #include "testing/gtest/include/gtest/gtest.h" namespace chromeos { namespace input_method { +namespace { + +void ClearInputMethodLookupTable(InputMethodLookupTable* table) { + table->visible = false; + table->cursor_absolute_index = 0; + table->page_size = 10; + table->candidates.clear(); + table->orientation = InputMethodLookupTable::kVertical; + table->labels.clear(); + table->annotations.clear(); + table->mozc_candidates.Clear(); +} + +void InitializeMozcCandidates(InputMethodLookupTable* table) { + table->mozc_candidates.Clear(); + table->mozc_candidates.set_position(0); + table->mozc_candidates.set_size(0); +} + +void SetCaretRectIntoMozcCandidates( + InputMethodLookupTable* table, + mozc::commands::Candidates::CandidateWindowLocation location, + int x, + int y, + int width, + int height) { + table->mozc_candidates.set_window_location(location); + mozc::commands::Rectangle *rect = + table->mozc_candidates.mutable_composition_rectangle(); + rect->set_x(x); + rect->set_y(y); + rect->set_width(width); + rect->set_height(height); +} + +void AppendCandidateIntoMozcCandidates(InputMethodLookupTable* table, + std::string value) { + mozc::commands::Candidates::Candidate *candidate = + table->mozc_candidates.add_candidate(); + + int current_entry_count = table->mozc_candidates.candidate_size(); + candidate->set_index(current_entry_count); + candidate->set_value(value); + candidate->set_id(current_entry_count); + candidate->set_information_id(current_entry_count); + + +} + +} // namespace + TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) { // This test verifies the process of judging update lookup-table or not. // This judgement is handled by ShouldUpdateCandidateViews, which returns true @@ -28,6 +82,9 @@ TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) { InputMethodLookupTable old_table; InputMethodLookupTable new_table; + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + old_table.visible = true; old_table.cursor_absolute_index = 0; old_table.page_size = 1; @@ -119,5 +176,160 @@ TEST(CandidateWindowViewTest, ShouldUpdateCandidateViewsTest) { new_table)); } +TEST(CandidateWindowViewTest, MozcSuggestWindowShouldUpdateTest) { + // ShouldUpdateCandidateViews method should also judge with consideration of + // the mozc specific candidate information. Following tests verify them. + const char* kSampleCandidate1 = "Sample Candidate 1"; + const char* kSampleCandidate2 = "Sample Candidate 2"; + + const int kCaretPositionX1 = 10; + const int kCaretPositionY1 = 20; + const int kCaretPositionWidth1 = 30; + const int kCaretPositionHeight1 = 40; + + const int kCaretPositionX2 = 15; + const int kCaretPositionY2 = 25; + const int kCaretPositionWidth2 = 35; + const int kCaretPositionHeight2 = 45; + + InputMethodLookupTable old_table; + InputMethodLookupTable new_table; + + // State chagne from using non-mozc candidate to mozc candidate. + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + old_table.candidates.push_back(kSampleCandidate1); + InitializeMozcCandidates(&new_table); + AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&new_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); + + // State change from using mozc candidate to non-mozc candidate + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + InitializeMozcCandidates(&old_table); + AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&old_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + new_table.candidates.push_back(kSampleCandidate1); + + EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); + + // State change from using mozc candidate to mozc candidate + + // No change + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + InitializeMozcCandidates(&old_table); + AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&old_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + InitializeMozcCandidates(&new_table); + AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&new_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + EXPECT_FALSE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); + // Position change only + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + InitializeMozcCandidates(&old_table); + AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&old_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + InitializeMozcCandidates(&new_table); + AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&new_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX2, + kCaretPositionY2, + kCaretPositionWidth2, + kCaretPositionHeight2); + + EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); + // Candidate contents only + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + InitializeMozcCandidates(&old_table); + AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&old_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + InitializeMozcCandidates(&new_table); + AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate2); + SetCaretRectIntoMozcCandidates(&new_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); + + // Both candidate and position + ClearInputMethodLookupTable(&old_table); + ClearInputMethodLookupTable(&new_table); + + InitializeMozcCandidates(&old_table); + AppendCandidateIntoMozcCandidates(&old_table, kSampleCandidate1); + SetCaretRectIntoMozcCandidates(&old_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX1, + kCaretPositionY1, + kCaretPositionWidth1, + kCaretPositionHeight1); + + InitializeMozcCandidates(&new_table); + AppendCandidateIntoMozcCandidates(&new_table, kSampleCandidate2); + SetCaretRectIntoMozcCandidates(&new_table, + mozc::commands::Candidates::COMPOSITION, + kCaretPositionX2, + kCaretPositionY2, + kCaretPositionWidth2, + kCaretPositionHeight2); + + EXPECT_TRUE(CandidateWindowView::ShouldUpdateCandidateViews(old_table, + new_table)); +} + } // namespace input_method } // namespace chromeos diff --git a/chrome/browser/chromeos/input_method/ibus_ui_controller.cc b/chrome/browser/chromeos/input_method/ibus_ui_controller.cc index f64d7b9..f48113e 100644 --- a/chrome/browser/chromeos/input_method/ibus_ui_controller.cc +++ b/chrome/browser/chromeos/input_method/ibus_ui_controller.cc @@ -11,7 +11,7 @@ #include <sstream> #include "base/logging.h" #include "base/string_util.h" -#include "third_party/mozc/session/commands.pb.h" +#include "third_party/mozc/session/candidates_lite.pb.h" namespace chromeos { namespace input_method { diff --git a/chrome/browser/chromeos/input_method/ibus_ui_controller.h b/chrome/browser/chromeos/input_method/ibus_ui_controller.h index 27e443a..77966d3 100644 --- a/chrome/browser/chromeos/input_method/ibus_ui_controller.h +++ b/chrome/browser/chromeos/input_method/ibus_ui_controller.h @@ -15,7 +15,7 @@ #include "base/basictypes.h" #include "base/observer_list.h" -#include "third_party/mozc/session/commands.pb.h" +#include "third_party/mozc/session/candidates_lite.pb.h" namespace chromeos { namespace input_method { diff --git a/chrome/browser/chromeos/input_method/input_method.gyp b/chrome/browser/chromeos/input_method/input_method.gyp index c9beba8..5b40aeb 100644 --- a/chrome/browser/chromeos/input_method/input_method.gyp +++ b/chrome/browser/chromeos/input_method/input_method.gyp @@ -37,88 +37,5 @@ ], }, }, - { - 'target_name': 'litify_mozc_proto_files', - 'type': 'none', - 'actions': [ - { - 'action_name': 'litify_config_proto', - 'inputs': [ - '../../../../third_party/mozc/session/config.proto', - ], - 'outputs': [ - '<(input_method_out_dir)/mozc/session/config.proto', - ], - 'action': [ - 'python', - 'litify_proto_file.py', - '../../../../third_party/mozc/session/config.proto', - '<(input_method_out_dir)/mozc/session/config.proto', - ], - }, - { - 'action_name': 'litify_commands_proto', - 'inputs': [ - '../../../../third_party/mozc/session/commands.proto', - ], - 'outputs': [ - '<(input_method_out_dir)/mozc/session/commands.proto', - ], - 'action': [ - 'python', - 'litify_proto_file.py', - '../../../../third_party/mozc/session/commands.proto', - '<(input_method_out_dir)/mozc/session/commands.proto', - ], - }, - ], - }, - { - # Protobuf compiler / generator for the mozc inputmethod commands - # protocol buffer. - 'target_name': 'mozc_commands_proto', - 'type': 'static_library', - 'sources': [ - '<(input_method_out_dir)/mozc/session/config.proto', - '<(input_method_out_dir)/mozc/session/commands.proto', - ], - 'rules': [ - { - 'rule_name': 'genproto', - 'extension': 'proto', - 'inputs': [ - '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - ], - 'outputs': [ - '<(protoc_out_dir)/third_party/mozc/session/<(RULE_INPUT_ROOT).pb.h', - '<(protoc_out_dir)/third_party/mozc/session/<(RULE_INPUT_ROOT).pb.cc', - ], - 'action': [ - '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)', - '--proto_path=<(input_method_out_dir)/mozc', - '<(input_method_out_dir)/mozc/session/<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)', - '--cpp_out=<(protoc_out_dir)/third_party/mozc', - ], - 'message': 'Generating C++ code from <(RULE_INPUT_PATH)', - 'process_outputs_as_sources': 1, - }, - ], - 'dependencies': [ - 'litify_mozc_proto_files', - '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite', - '../../../../third_party/protobuf/protobuf.gyp:protoc#host', - ], - 'include_dirs': [ - '<(protoc_out_dir)/third_party/mozc', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - '<(protoc_out_dir)/third_party/mozc', - ] - }, - 'export_dependent_settings': [ - '../../../../third_party/protobuf/protobuf.gyp:protobuf_lite', - ], - }, ] } diff --git a/chrome/browser/chromeos/input_method/litify_proto_file.py b/chrome/browser/chromeos/input_method/litify_proto_file.py deleted file mode 100755 index c62d4f6..0000000 --- a/chrome/browser/chromeos/input_method/litify_proto_file.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env python -# Copyright (c) 2011 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. - -"""Litify a .proto file. - -This program add a line - "option optimize_for = LITE_RUNTIME;" -to the input .proto file. - -Run it like: - litify_proto_file.py input.proto output.proto -""" - -import fileinput -import sys - - -def main(argv): - if len(argv) != 3: - print 'Usage: litify_proto_file.py [input] [output]' - return 1 - output_file = open(sys.argv[2], 'w') - for line in fileinput.input(sys.argv[1]): - output_file.write(line) - - output_file.write("\noption optimize_for = LITE_RUNTIME;\n") - return 0 - - -if __name__ == '__main__': - sys.exit(main(sys.argv)) |