blob: df3531256eefcc081a06c58448de4ce079941c5e [file] [log] [blame]
// 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.
#include "views/controls/message_box_view.h"
#include "base/i18n/rtl.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "ui/base/message_box_flags.h"
#include "views/controls/button/checkbox.h"
#include "views/controls/image_view.h"
#include "views/controls/label.h"
#include "views/controls/textfield/textfield.h"
#include "views/layout/grid_layout.h"
#include "views/layout/layout_constants.h"
#include "views/views_delegate.h"
#include "views/window/client_view.h"
static const int kDefaultMessageWidth = 320;
namespace views {
///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, public:
MessageBoxView::MessageBoxView(int dialog_flags,
const std::wstring& message,
const std::wstring& default_prompt,
int message_width)
: message_label_(new Label(message)),
prompt_field_(NULL),
icon_(NULL),
checkbox_(NULL),
message_width_(message_width),
ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)) {
Init(dialog_flags, default_prompt);
}
MessageBoxView::MessageBoxView(int dialog_flags,
const std::wstring& message,
const std::wstring& default_prompt)
: message_label_(new Label(message)),
prompt_field_(NULL),
icon_(NULL),
checkbox_(NULL),
message_width_(kDefaultMessageWidth),
ALLOW_THIS_IN_INITIALIZER_LIST(focus_grabber_factory_(this)) {
Init(dialog_flags, default_prompt);
}
MessageBoxView::~MessageBoxView() {}
std::wstring MessageBoxView::GetInputText() {
if (prompt_field_)
return UTF16ToWideHack(prompt_field_->text());
return std::wstring();
}
bool MessageBoxView::IsCheckBoxSelected() {
return checkbox_ ? checkbox_->checked() : false;
}
void MessageBoxView::SetIcon(const SkBitmap& icon) {
if (!icon_)
icon_ = new ImageView();
icon_->SetImage(icon);
icon_->SetBounds(0, 0, icon.width(), icon.height());
ResetLayoutManager();
}
void MessageBoxView::SetCheckBoxLabel(const std::wstring& label) {
if (!checkbox_)
checkbox_ = new Checkbox(label);
else
checkbox_->SetLabel(label);
ResetLayoutManager();
}
void MessageBoxView::SetCheckBoxSelected(bool selected) {
if (!checkbox_)
return;
checkbox_->SetChecked(selected);
}
///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, View overrides:
void MessageBoxView::ViewHierarchyChanged(bool is_add,
View* parent,
View* child) {
if (child == this && is_add) {
if (prompt_field_)
prompt_field_->SelectAll();
}
}
bool MessageBoxView::AcceleratorPressed(
const Accelerator& accelerator) {
// We only accepts Ctrl-C.
DCHECK(accelerator.key_code() == 'C' && accelerator.IsCtrlDown());
// We must not intercept Ctrl-C when we have a text box and it's focused.
if (prompt_field_ && prompt_field_->HasFocus())
return false;
if (!ViewsDelegate::views_delegate)
return false;
ui::Clipboard* clipboard = ViewsDelegate::views_delegate->GetClipboard();
if (!clipboard)
return false;
ui::ScopedClipboardWriter scw(clipboard);
scw.WriteText(WideToUTF16Hack(message_label_->GetText()));
return true;
}
///////////////////////////////////////////////////////////////////////////////
// MessageBoxView, private:
void MessageBoxView::Init(int dialog_flags,
const std::wstring& default_prompt) {
message_label_->SetMultiLine(true);
message_label_->SetAllowCharacterBreak(true);
if (dialog_flags & ui::MessageBoxFlags::kAutoDetectAlignment) {
// Determine the alignment and directionality based on the first character
// with strong directionality.
base::i18n::TextDirection direction =
base::i18n::GetFirstStrongCharacterDirection(
WideToUTF16(message_label_->GetText()));
Label::Alignment alignment;
if (direction == base::i18n::RIGHT_TO_LEFT)
alignment = Label::ALIGN_RIGHT;
else
alignment = Label::ALIGN_LEFT;
// In addition, we should set the RTL alignment mode as
// AUTO_DETECT_ALIGNMENT so that the alignment will not be flipped around
// in RTL locales.
message_label_->set_rtl_alignment_mode(Label::AUTO_DETECT_ALIGNMENT);
message_label_->SetHorizontalAlignment(alignment);
} else {
message_label_->SetHorizontalAlignment(Label::ALIGN_LEFT);
}
if (dialog_flags & ui::MessageBoxFlags::kFlagHasPromptField) {
prompt_field_ = new Textfield;
prompt_field_->SetText(WideToUTF16Hack(default_prompt));
}
ResetLayoutManager();
}
void MessageBoxView::ResetLayoutManager() {
// Initialize the Grid Layout Manager used for this dialog box.
GridLayout* layout = GridLayout::CreatePanel(this);
SetLayoutManager(layout);
gfx::Size icon_size;
if (icon_)
icon_size = icon_->GetPreferredSize();
// Add the column set for the message displayed at the top of the dialog box.
// And an icon, if one has been set.
const int message_column_view_set_id = 0;
ColumnSet* column_set = layout->AddColumnSet(message_column_view_set_id);
if (icon_) {
column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, 0,
GridLayout::FIXED, icon_size.width(),
icon_size.height());
column_set->AddPaddingColumn(0, kUnrelatedControlHorizontalSpacing);
}
column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
GridLayout::FIXED, message_width_, 0);
// Column set for prompt Textfield, if one has been set.
const int textfield_column_view_set_id = 1;
if (prompt_field_) {
column_set = layout->AddColumnSet(textfield_column_view_set_id);
if (icon_) {
column_set->AddPaddingColumn(
0, icon_size.width() + kUnrelatedControlHorizontalSpacing);
}
column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
GridLayout::USE_PREF, 0, 0);
}
// Column set for checkbox, if one has been set.
const int checkbox_column_view_set_id = 2;
if (checkbox_) {
column_set = layout->AddColumnSet(checkbox_column_view_set_id);
if (icon_) {
column_set->AddPaddingColumn(
0, icon_size.width() + kUnrelatedControlHorizontalSpacing);
}
column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
GridLayout::USE_PREF, 0, 0);
}
layout->StartRow(0, message_column_view_set_id);
if (icon_)
layout->AddView(icon_);
layout->AddView(message_label_);
if (prompt_field_) {
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, textfield_column_view_set_id);
layout->AddView(prompt_field_);
}
if (checkbox_) {
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
layout->StartRow(0, checkbox_column_view_set_id);
layout->AddView(checkbox_);
}
layout->AddPaddingRow(0, kRelatedControlVerticalSpacing);
}
} // namespace views