OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 "ui/views/window/dialog_client_view.h" | 5 #include "ui/views/window/dialog_client_view.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
10 #include "ui/base/material_design/material_design_controller.h" | 10 #include "ui/base/material_design/material_design_controller.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 // Doing this now ensures this accelerator will have lower priority than | 80 // Doing this now ensures this accelerator will have lower priority than |
81 // one set by the contents view. | 81 // one set by the contents view. |
82 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); | 82 AddAccelerator(ui::Accelerator(ui::VKEY_ESCAPE, ui::EF_NONE)); |
83 button_row_container_ = new ButtonRowContainer(this); | 83 button_row_container_ = new ButtonRowContainer(this); |
84 AddChildView(button_row_container_); | 84 AddChildView(button_row_container_); |
85 } | 85 } |
86 | 86 |
87 DialogClientView::~DialogClientView() {} | 87 DialogClientView::~DialogClientView() {} |
88 | 88 |
89 void DialogClientView::AcceptWindow() { | 89 void DialogClientView::AcceptWindow() { |
90 // Only notify the delegate once. See |delegate_allowed_close_|'s comment. | 90 CloseWithDelegateMethod(&DialogDelegate::Accept, true); |
91 if (!delegate_allowed_close_ && GetDialogDelegate()->Accept()) { | |
92 delegate_allowed_close_ = true; | |
93 GetWidget()->Close(); | |
94 } | |
95 } | 91 } |
96 | 92 |
97 void DialogClientView::CancelWindow() { | 93 void DialogClientView::CancelWindow() { |
98 // Only notify the delegate once. See |delegate_allowed_close_|'s comment. | 94 CloseWithDelegateMethod(&DialogDelegate::Cancel, true); |
99 if (!delegate_allowed_close_ && GetDialogDelegate()->Cancel()) { | |
100 delegate_allowed_close_ = true; | |
101 GetWidget()->Close(); | |
102 } | |
103 } | 95 } |
104 | 96 |
105 void DialogClientView::UpdateDialogButtons() { | 97 void DialogClientView::UpdateDialogButtons() { |
106 SetupLayout(); | 98 SetupLayout(); |
107 InvalidateLayout(); | 99 InvalidateLayout(); |
108 } | 100 } |
109 | 101 |
110 /////////////////////////////////////////////////////////////////////////////// | 102 /////////////////////////////////////////////////////////////////////////////// |
111 // DialogClientView, ClientView overrides: | 103 // DialogClientView, ClientView overrides: |
112 | 104 |
113 bool DialogClientView::CanClose() { | 105 bool DialogClientView::CanClose() { |
| 106 if (delegate_allowed_close_) { |
| 107 DCHECK(!asking_delegate_whether_to_close_); |
| 108 return true; |
| 109 } |
| 110 |
| 111 // The delegate may perform an action that causes the Widget to lose focus and |
| 112 // (for some bubbles) attempt to close again. Widget::Close() has protection |
| 113 // against multiple calls to Widget::Close(), but that method is above |
| 114 // CanClose() in the stack: CanClose() has not yet told the first |
| 115 // Widget::Close() whether it may proceed, so that protection can't be used. |
| 116 // Detect this situation and always return false from the nested call to |
| 117 // CanClose() so that Widget::Close() bails out early. |
| 118 if (asking_delegate_whether_to_close_) |
| 119 return false; |
| 120 |
114 // If the dialog is closing but no Accept or Cancel action has been performed | 121 // If the dialog is closing but no Accept or Cancel action has been performed |
115 // before, it's a Close action. | 122 // before, it's a Close action. |
116 if (!delegate_allowed_close_) | 123 CloseWithDelegateMethod(&DialogDelegate::Close, false); |
117 delegate_allowed_close_ = GetDialogDelegate()->Close(); | |
118 return delegate_allowed_close_; | 124 return delegate_allowed_close_; |
119 } | 125 } |
120 | 126 |
121 DialogClientView* DialogClientView::AsDialogClientView() { | 127 DialogClientView* DialogClientView::AsDialogClientView() { |
122 return this; | 128 return this; |
123 } | 129 } |
124 | 130 |
125 const DialogClientView* DialogClientView::AsDialogClientView() const { | 131 const DialogClientView* DialogClientView::AsDialogClientView() const { |
126 return this; | 132 return this; |
127 } | 133 } |
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
412 UpdateDialogButton(&cancel_button_, ui::DIALOG_BUTTON_CANCEL); | 418 UpdateDialogButton(&cancel_button_, ui::DIALOG_BUTTON_CANCEL); |
413 | 419 |
414 if (extra_view_) | 420 if (extra_view_) |
415 return; | 421 return; |
416 | 422 |
417 extra_view_ = GetDialogDelegate()->CreateExtraView(); | 423 extra_view_ = GetDialogDelegate()->CreateExtraView(); |
418 if (extra_view_) | 424 if (extra_view_) |
419 extra_view_->SetGroup(kButtonGroup); | 425 extra_view_->SetGroup(kButtonGroup); |
420 } | 426 } |
421 | 427 |
| 428 void DialogClientView::CloseWithDelegateMethod(bool (DialogDelegate::*method)(), |
| 429 bool close) { |
| 430 DCHECK(!asking_delegate_whether_to_close_); |
| 431 |
| 432 // Only notify the delegate once. See |delegate_allowed_close_|'s comment. |
| 433 if (delegate_allowed_close_) |
| 434 return; |
| 435 |
| 436 { |
| 437 base::AutoReset<bool> auto_reset(&asking_delegate_whether_to_close_, true); |
| 438 delegate_allowed_close_ = (GetDialogDelegate()->*method)(); |
| 439 } |
| 440 if (close && delegate_allowed_close_) |
| 441 GetWidget()->Close(); |
| 442 } |
| 443 |
422 } // namespace views | 444 } // namespace views |
OLD | NEW |