1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file. 4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/ui/views/autofill/expanding_textfield.h" 6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/bind.h" 8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/string_split.h" 9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/string_util.h" 10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/strings/utf_string_conversions.h" 11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "chrome/browser/ui/views/autofill/decorated_textfield.h" 12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/views/layout/box_layout.h" 13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace autofill { 15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochnamespace { 17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// The vertical padding between textfields. 19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst int kManualInputRowPadding = 10; 20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// static 24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char ExpandingTextfield::kViewClassName[] = "autofill/ExpandingTextfield"; 25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 26effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochExpandingTextfield::ExpandingTextfield( 27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::string16& default_value, 28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::string16& placeholder, 29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch bool multiline, 30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch views::TextfieldController* controller) 31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch : controller_(controller) { 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.push_back( 33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new DecoratedTextfield(base::string16(), placeholder, this)); 34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (multiline) { 35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.push_back( 36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new DecoratedTextfield(base::string16(), placeholder, this)); 37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetText(default_value); 39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (std::list<DecoratedTextfield*>::iterator iter = textfields_.begin(); 41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != textfields_.end(); ++iter) { 42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddChildView(*iter); 43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kManualInputRowPadding)); 47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 49effb81e5f8246d0db0270817048dc992db66e9fbBen MurdochExpandingTextfield::~ExpandingTextfield() {} 50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetText(const base::string16& text) { 52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.front()->SetText(text); 53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::vector<base::string16> strings; 54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::SplitStringDontTrim(text, '\n', &strings); 55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch size_t i = 0; 57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (std::list<DecoratedTextfield*>::iterator iter = textfields_.begin(); 58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != textfields_.end(); ++iter) { 59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch (*iter)->SetText(i < strings.size() ? strings[i++] : base::string16()); 60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (; i < strings.size(); ++i) { 63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.push_back(new DecoratedTextfield( 64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch strings[i], 65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.front()->GetPlaceholderText(), 66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this)); 67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddChildView(textfields_.back()); 68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PreferredSizeChanged(); 69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbase::string16 ExpandingTextfield::GetText() { 73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::string16 text = textfields_.front()->text(); 74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::list<DecoratedTextfield*>::const_iterator iter = ++textfields_.begin(); 75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch while (iter != textfields_.end()) { 76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch text += base::ASCIIToUTF16("\n") + (*iter++)->text(); 77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::TrimWhitespace(text, base::TRIM_ALL, &text); 79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return text; 80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetInvalid(bool invalid) { 83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.front()->SetInvalid(invalid); 84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetDefaultWidthInCharacters(int chars) { 87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ForEachTextfield(&DecoratedTextfield::set_default_width_in_chars, chars); 88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetPlaceholderText(const base::string16& placeholder) { 91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ForEachTextfield<views::Textfield, const base::string16&>( 92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch &DecoratedTextfield::set_placeholder_text, placeholder); 93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetIcon(const gfx::Image& icon) { 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.front()->SetIcon(icon); 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetTooltipIcon(const base::string16& text) { 100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.front()->SetTooltipIcon(text); 101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::SetEditable(bool editable) { 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ForEachTextfield(&DecoratedTextfield::SetEditable, editable); 105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochconst char* ExpandingTextfield::GetClassName() const { 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return kViewClassName; 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::ContentsChanged(views::Textfield* sender, 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const base::string16& new_contents) { 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (textfields_.size() > 1 && sender == textfields_.back() && 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch !new_contents.empty()) { 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.push_back( 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch new DecoratedTextfield(base::string16(), 117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sender->GetPlaceholderText(), 118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch this)); 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch AddChildView(textfields_.back()); 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch PreferredSizeChanged(); 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch controller_->ContentsChanged(sender, new_contents); 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool ExpandingTextfield::HandleKeyEvent(views::Textfield* sender, 127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ui::KeyEvent& key_event) { 128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return controller_->HandleKeyEvent(sender, key_event); 129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochbool ExpandingTextfield::HandleMouseEvent(views::Textfield* sender, 132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ui::MouseEvent& mouse_event) { 133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch return controller_->HandleMouseEvent(sender, mouse_event); 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochtemplate <typename BaseType, typename Param> 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ExpandingTextfield::ForEachTextfield( 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch void (BaseType::* f)(Param), Param p) const { 139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch for (std::list<DecoratedTextfield*>::const_iterator iter = 140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch textfields_.begin(); 141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch iter != textfields_.end(); ++iter) { 142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch base::Bind(f, base::Unretained(*iter), p).Run(); 143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch } 144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} 145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch} // namespace autofill 147