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

View file

@ -93,8 +93,23 @@ module.exports =
options.detail ?= ''
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,
options.buttons,
options.cancelId,
[options.title, options.message, options.detail],
options.icon,
window,

View file

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

View file

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

View file

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

View file

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

View file

@ -76,6 +76,11 @@ will be passed via `callback(filename)`
* `message` String - Content of the message box
* `detail` String - Extra information of the message
* `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
Shows a message box, it will block until the message box is closed. It returns