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:
PulkoMandy
2023-05-09 18:28:06 +00:00
committed by Adrien Destugues
parent 3d2b8a2045
commit 94457adea2
6 changed files with 218 additions and 5 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ resource app_version {
resource app_flags B_SINGLE_LAUNCH;
resource vector_icon {
resource(1) vector_icon {
$"6E6369660B03000100010001005A02000604BC00000000000000003C00004940"
$"004B000000FF9E063FF7F378D7FFEA97FFFFB94B02000604BC00000000000000"
$"003C00004940004B00000038BC382B279127D253ED53FF2EAA2E020006023A9D"
+1
View File
@@ -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 */