Debugger: add a "don't ask again" checkbox to alerts
This allows, for example, to skip all the "get debug info" alerts when starting a debug session. But it is a generic implementation and will work for all "question" alerts in Debugger. For now, the user choices are not saved, this could be done, but then we need a way to access that setting later. Fixes #14601 Change-Id: Icc49d1b5bc4168d15d7f740d422f464e996f7c9d Reviewed-on: https://review.haiku-os.org/c/haiku/+/6398 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
Adrien Destugues
parent
3d2b8a2045
commit
94457adea2
@@ -22,7 +22,7 @@ resource app_version {
|
||||
|
||||
resource app_flags B_SINGLE_LAUNCH;
|
||||
|
||||
resource vector_icon {
|
||||
resource(1) vector_icon {
|
||||
$"6E6369660B03000100010001005A02000604BC00000000000000003C00004940"
|
||||
$"004B000000FF9E063FF7F378D7FFEA97FFFFB94B02000604BC00000000000000"
|
||||
$"003C00004940004B00000038BC382B279127D253ED53FF2EAA2E020006023A9D"
|
||||
|
||||
@@ -137,6 +137,7 @@ local sources =
|
||||
|
||||
# user_interface/gui/util
|
||||
ActionMenuItem.cpp
|
||||
AlertWithCheckbox.cpp
|
||||
GuiSettingsUtils.cpp
|
||||
SettingsMenu.cpp
|
||||
SignalDispositionMenu.cpp
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <FilePanel.h>
|
||||
#include <Locker.h>
|
||||
|
||||
#include "AlertWithCheckbox.h"
|
||||
#include "GuiTeamUiSettings.h"
|
||||
#include "MessageCodes.h"
|
||||
#include "TeamWindow.h"
|
||||
@@ -129,7 +130,8 @@ GraphicalUserInterface::GraphicalUserInterface()
|
||||
fTeamWindow(NULL),
|
||||
fTeamWindowMessenger(NULL),
|
||||
fFilePanelHandler(NULL),
|
||||
fFilePanel(NULL)
|
||||
fFilePanel(NULL),
|
||||
fDefaultActions(10, true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -271,11 +273,35 @@ GraphicalUserInterface::SynchronouslyAskUser(const char* title,
|
||||
const char* message, const char* choice1, const char* choice2,
|
||||
const char* choice3)
|
||||
{
|
||||
BAlert* alert = new(std::nothrow) BAlert(title, message,
|
||||
choice1, choice2, choice3);
|
||||
// If the user already answered the question and asked for their choice to be remembered,
|
||||
// return the previously made choice again
|
||||
BString key(title);
|
||||
key += choice1;
|
||||
key += choice2;
|
||||
key += choice3;
|
||||
|
||||
for (int i = 0; i < fDefaultActions.CountItems(); i++) {
|
||||
if (fDefaultActions.ItemAt(i)->fKey == key)
|
||||
return fDefaultActions.ItemAt(i)->fDecision;
|
||||
}
|
||||
|
||||
AlertWithCheckbox* alert = new(std::nothrow) AlertWithCheckbox(title, message,
|
||||
"Don't ask again", choice1, choice2, choice3);
|
||||
|
||||
if (alert == NULL)
|
||||
return 0;
|
||||
return alert->Go();
|
||||
|
||||
bool dontAskAgain = false;
|
||||
int result = alert->Go(dontAskAgain);
|
||||
|
||||
if (dontAskAgain) {
|
||||
DefaultAction* defaultAction = new DefaultAction;
|
||||
defaultAction->fKey = key;
|
||||
defaultAction->fDecision = result;
|
||||
fDefaultActions.AddItem(defaultAction);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "UserInterface.h"
|
||||
|
||||
#include "ObjectList.h"
|
||||
#include "String.h"
|
||||
|
||||
|
||||
class BFilePanel;
|
||||
class BHandler;
|
||||
@@ -54,6 +57,12 @@ private:
|
||||
BMessenger* fTeamWindowMessenger;
|
||||
FilePanelHandler* fFilePanelHandler;
|
||||
BFilePanel* fFilePanel;
|
||||
|
||||
struct DefaultAction {
|
||||
BString fKey;
|
||||
int fDecision;
|
||||
};
|
||||
BObjectList<DefaultAction> fDefaultActions;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright 2019-2023, Adrien Destugues, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "AlertWithCheckbox.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <CheckBox.h>
|
||||
#include <ControlLook.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Locale.h>
|
||||
#include <IconUtils.h>
|
||||
#include <Resources.h>
|
||||
#include <StripeView.h>
|
||||
#include <TextView.h>
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "DebugServer"
|
||||
|
||||
|
||||
enum {
|
||||
kButton1Message,
|
||||
kButton2Message,
|
||||
kButton3Message
|
||||
};
|
||||
|
||||
|
||||
AlertWithCheckbox::AlertWithCheckbox(const char* title, const char* messageText,
|
||||
const char* checkboxLabel, const char* label1, const char* label2, const char* label3)
|
||||
:
|
||||
BWindow(BRect(0, 0, 100, 50), title,
|
||||
B_MODAL_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
|
||||
B_CLOSE_ON_ESCAPE | B_NOT_RESIZABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fBitmap(IconSize(), B_RGBA32),
|
||||
fSemaphore(create_sem(0, "AlertWithCheckbox")),
|
||||
fAction(0)
|
||||
{
|
||||
BResources resources;
|
||||
resources.SetToImage(B_TRANSLATION_CONTEXT);
|
||||
size_t size;
|
||||
const uint8* iconData = (const uint8*)resources.LoadResource('VICN', 1,
|
||||
&size);
|
||||
|
||||
// TODO load "info" icon from app_server instead?
|
||||
BIconUtils::GetVectorIcon(iconData, size, &fBitmap);
|
||||
BStripeView *stripeView = new BStripeView(fBitmap);
|
||||
|
||||
BTextView *message = new BTextView("_tv_");
|
||||
message->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
|
||||
rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
|
||||
message->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
|
||||
message->MakeEditable(false);
|
||||
message->MakeSelectable(false);
|
||||
message->SetWordWrap(true);
|
||||
message->SetText(messageText);
|
||||
message->SetExplicitMaxSize(BSize(B_SIZE_UNSET, B_SIZE_UNSET));
|
||||
float width = message->StringWidth("W") * 40;
|
||||
message->SetExplicitMinSize(BSize(width, B_SIZE_UNSET));
|
||||
|
||||
fDontAskAgain = new BCheckBox("checkbox",
|
||||
checkboxLabel, NULL);
|
||||
|
||||
BButton* button1 = new BButton(label1, label1, new BMessage(kButton1Message));
|
||||
BButton* button2 = new BButton(label2, label2, new BMessage(kButton2Message));
|
||||
BButton* button3 = new BButton(label3, label3, new BMessage(kButton3Message));
|
||||
button1->MakeDefault(true);
|
||||
|
||||
BLayoutBuilder::Group<>(this)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(stripeView)
|
||||
.AddGroup(B_VERTICAL)
|
||||
.SetInsets(B_USE_SMALL_SPACING)
|
||||
.Add(message)
|
||||
.AddGroup(B_HORIZONTAL, 0)
|
||||
.Add(fDontAskAgain)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.AddGlue()
|
||||
.Add(button1)
|
||||
.Add(button2)
|
||||
.Add(button3)
|
||||
.End()
|
||||
.End()
|
||||
.End();
|
||||
|
||||
ResizeToPreferred();
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
|
||||
AlertWithCheckbox::~AlertWithCheckbox()
|
||||
{
|
||||
delete_sem(fSemaphore);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AlertWithCheckbox::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch(message->what) {
|
||||
case B_QUIT_REQUESTED:
|
||||
release_sem(fSemaphore);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
fAction = message->what;
|
||||
PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
|
||||
BWindow::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
AlertWithCheckbox::Go(bool& dontAskAgain)
|
||||
{
|
||||
Show();
|
||||
|
||||
// Wait for user to close the window
|
||||
acquire_sem(fSemaphore);
|
||||
dontAskAgain = fDontAskAgain->Value();
|
||||
return fAction;
|
||||
}
|
||||
|
||||
|
||||
BRect
|
||||
AlertWithCheckbox::IconSize()
|
||||
{
|
||||
return BRect(BPoint(0, 0), be_control_look->ComposeIconSize(32));
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2019-2023, Adrien Destugues, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ALERTWITHCHECKBOX_H
|
||||
#define ALERTWITHCHECKBOX_H
|
||||
|
||||
|
||||
#include <Bitmap.h>
|
||||
#include <Window.h>
|
||||
|
||||
|
||||
class BCheckBox;
|
||||
|
||||
|
||||
class AlertWithCheckbox : public BWindow {
|
||||
public:
|
||||
AlertWithCheckbox(const char* title, const char* message, const char* checkBox,
|
||||
const char* button1, const char* button2, const char* button3);
|
||||
~AlertWithCheckbox();
|
||||
|
||||
void MessageReceived(BMessage* message);
|
||||
int32 Go(bool& dontAskAgain);
|
||||
|
||||
private:
|
||||
static BRect IconSize();
|
||||
|
||||
private:
|
||||
BBitmap fBitmap;
|
||||
BCheckBox* fDontAskAgain;
|
||||
sem_id fSemaphore;
|
||||
int32 fAction;
|
||||
};
|
||||
|
||||
|
||||
#endif /* !ALERTWITHCHECKBOX_H */
|
||||
Reference in New Issue
Block a user