Merge pull request #2146 from atom/cancel-id

Add "cancelId" option for showMessageBox
This commit is contained in:
Cheng Zhao 2015-07-08 10:08:39 +08:00
commit fdc01b8ba8
7 changed files with 52 additions and 28 deletions

View file

@ -41,6 +41,7 @@ namespace {
void ShowMessageBox(int type, void ShowMessageBox(int type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::vector<std::string>& texts, const std::vector<std::string>& texts,
const gfx::ImageSkia& icon, const gfx::ImageSkia& icon,
atom::NativeWindow* window, atom::NativeWindow* window,
@ -57,11 +58,12 @@ void ShowMessageBox(int type,
if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(), if (mate::Converter<atom::MessageBoxCallback>::FromV8(args->isolate(),
peek, peek,
&callback)) { &callback)) {
atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, title, atom::ShowMessageBox(window, (atom::MessageBoxType)type, buttons, cancel_id,
message, detail, icon, callback); title, message, detail, icon, callback);
} else { } else {
int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type, int chosen = atom::ShowMessageBox(window, (atom::MessageBoxType)type,
buttons, title, message, detail, icon); buttons, cancel_id, title, message,
detail, icon);
args->Return(chosen); args->Return(chosen);
} }
} }

View file

@ -93,8 +93,23 @@ module.exports =
options.detail ?= '' options.detail ?= ''
options.icon ?= null options.icon ?= null
# Choose a default button to get selected when dialog is cancelled.
unless options.cancelId?
options.cancelId = 0
for text, i in options.buttons
if text.toLowerCase() in ['cancel', 'no']
options.cancelId = i
break
# On OS X the "Cancel" is always get selected when dialog is cancelled.
if process.platform is 'darwin'
for text, i in options.buttons when text is 'Cancel'
options.cancelId = i
break
binding.showMessageBox messageBoxType, binding.showMessageBox messageBoxType,
options.buttons, options.buttons,
options.cancelId,
[options.title, options.message, options.detail], [options.title, options.message, options.detail],
options.icon, options.icon,
window, window,

View file

@ -32,6 +32,7 @@ typedef base::Callback<void(int code)> MessageBoxCallback;
int ShowMessageBox(NativeWindow* parent_window, int ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
@ -40,6 +41,7 @@ int ShowMessageBox(NativeWindow* parent_window,
void ShowMessageBox(NativeWindow* parent_window, void ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,

View file

@ -29,12 +29,13 @@ class GtkMessageBox {
GtkMessageBox(NativeWindow* parent_window, GtkMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon) const gfx::ImageSkia& icon)
: dialog_scope_(parent_window), : dialog_scope_(parent_window),
cancel_id_(0) { cancel_id_(cancel_id) {
// Create dialog. // Create dialog.
dialog_ = gtk_message_dialog_new( dialog_ = gtk_message_dialog_new(
nullptr, // parent nullptr, // parent
@ -92,19 +93,16 @@ class GtkMessageBox {
const char* TranslateToStock(int id, const std::string& text) { const char* TranslateToStock(int id, const std::string& text) {
std::string lower = base::StringToLowerASCII(text); std::string lower = base::StringToLowerASCII(text);
if (lower == "cancel") { if (lower == "cancel")
cancel_id_ = id;
return GTK_STOCK_CANCEL; return GTK_STOCK_CANCEL;
} else if (lower == "no") { else if (lower == "no")
cancel_id_ = id;
return GTK_STOCK_NO; return GTK_STOCK_NO;
} else if (lower == "ok") { else if (lower == "ok")
return GTK_STOCK_OK; return GTK_STOCK_OK;
} else if (lower == "yes") { else if (lower == "yes")
return GTK_STOCK_YES; return GTK_STOCK_YES;
} else { else
return text.c_str(); return text.c_str();
}
} }
void Show() { void Show() {
@ -163,29 +161,31 @@ void GtkMessageBox::OnResponseDialog(GtkWidget* widget, int response) {
int ShowMessageBox(NativeWindow* parent, int ShowMessageBox(NativeWindow* parent,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon) { const gfx::ImageSkia& icon) {
return GtkMessageBox(parent, type, buttons, title, message, detail, return GtkMessageBox(parent, type, buttons, cancel_id, title, message, detail,
icon).RunSynchronous(); icon).RunSynchronous();
} }
void ShowMessageBox(NativeWindow* parent, void ShowMessageBox(NativeWindow* parent,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon, const gfx::ImageSkia& icon,
const MessageBoxCallback& callback) { const MessageBoxCallback& callback) {
(new GtkMessageBox(parent, type, buttons, title, message, detail, (new GtkMessageBox(parent, type, buttons, cancel_id, title, message, detail,
icon))->RunAsynchronous(callback); icon))->RunAsynchronous(callback);
} }
void ShowErrorBox(const base::string16& title, const base::string16& content) { void ShowErrorBox(const base::string16& title, const base::string16& content) {
if (Browser::Get()->is_ready()) { if (Browser::Get()->is_ready()) {
GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, { "OK" }, "Error", GtkMessageBox(nullptr, MESSAGE_BOX_TYPE_ERROR, { "OK" }, 0, "Error",
base::UTF16ToUTF8(title).c_str(), base::UTF16ToUTF8(title).c_str(),
base::UTF16ToUTF8(content).c_str(), base::UTF16ToUTF8(content).c_str(),
gfx::ImageSkia()).RunSynchronous(); gfx::ImageSkia()).RunSynchronous();

View file

@ -94,6 +94,7 @@ void SetReturnCode(int* ret_code, int result) {
int ShowMessageBox(NativeWindow* parent_window, int ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
@ -125,6 +126,7 @@ int ShowMessageBox(NativeWindow* parent_window,
void ShowMessageBox(NativeWindow* parent_window, void ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,

View file

@ -43,6 +43,7 @@ class MessageDialog : public views::WidgetDelegate,
MessageDialog(NativeWindow* parent_window, MessageDialog(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
@ -85,6 +86,7 @@ class MessageDialog : public views::WidgetDelegate,
gfx::ImageSkia icon_; gfx::ImageSkia icon_;
bool delete_on_close_; bool delete_on_close_;
int cancel_id_;
int result_; int result_;
base::string16 title_; base::string16 title_;
@ -125,12 +127,14 @@ class MessageDialogClientView : public views::ClientView {
MessageDialog::MessageDialog(NativeWindow* parent_window, MessageDialog::MessageDialog(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon) const gfx::ImageSkia& icon)
: icon_(icon), : icon_(icon),
delete_on_close_(false), delete_on_close_(false),
cancel_id_(cancel_id),
result_(-1), result_(-1),
title_(base::UTF8ToUTF16(title)), title_(base::UTF8ToUTF16(title)),
parent_(parent_window), parent_(parent_window),
@ -203,18 +207,10 @@ void MessageDialog::Close() {
} }
int MessageDialog::GetResult() const { int MessageDialog::GetResult() const {
// When the dialog is closed without choosing anything, we think the user if (result_ == -1)
// chose 'Cancel', otherwise we think the default behavior is chosen. return cancel_id_;
if (result_ == -1) { else
for (size_t i = 0; i < buttons_.size(); ++i)
if (LowerCaseEqualsASCII(buttons_[i]->GetText(), "cancel")) {
return i;
}
return 0;
} else {
return result_; return result_;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -337,12 +333,13 @@ void MessageDialog::ButtonPressed(views::Button* sender,
int ShowMessageBox(NativeWindow* parent_window, int ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
const gfx::ImageSkia& icon) { const gfx::ImageSkia& icon) {
MessageDialog dialog( MessageDialog dialog(
parent_window, type, buttons, title, message, detail, icon); parent_window, type, buttons, cancel_id, title, message, detail, icon);
{ {
base::MessageLoop::ScopedNestableTaskAllower allow( base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoopForUI::current()); base::MessageLoopForUI::current());
@ -357,6 +354,7 @@ int ShowMessageBox(NativeWindow* parent_window,
void ShowMessageBox(NativeWindow* parent_window, void ShowMessageBox(NativeWindow* parent_window,
MessageBoxType type, MessageBoxType type,
const std::vector<std::string>& buttons, const std::vector<std::string>& buttons,
int cancel_id,
const std::string& title, const std::string& title,
const std::string& message, const std::string& message,
const std::string& detail, const std::string& detail,
@ -364,7 +362,7 @@ void ShowMessageBox(NativeWindow* parent_window,
const MessageBoxCallback& callback) { const MessageBoxCallback& callback) {
// The dialog would be deleted when the dialog is closed. // The dialog would be deleted when the dialog is closed.
MessageDialog* dialog = new MessageDialog( MessageDialog* dialog = new MessageDialog(
parent_window, type, buttons, title, message, detail, icon); parent_window, type, buttons, cancel_id, title, message, detail, icon);
dialog->set_callback(callback); dialog->set_callback(callback);
dialog->Show(); dialog->Show();
} }

View file

@ -76,6 +76,11 @@ will be passed via `callback(filename)`
* `message` String - Content of the message box * `message` String - Content of the message box
* `detail` String - Extra information of the message * `detail` String - Extra information of the message
* `icon` [NativeImage](native-image.md) * `icon` [NativeImage](native-image.md)
* `cancelId` Integer - The value will be returned when user cancels the dialog
instead of clicking the buttons of the dialog. By default it is the index
of the buttons that have "cancel" or "no" as label, or 0 if there is no such
buttons. On OS X the index of "Cancel" button will always be used as
`cancelId`, not matter whether it is already specified.
* `callback` Function * `callback` Function
Shows a message box, it will block until the message box is closed. It returns Shows a message box, it will block until the message box is closed. It returns