- add LogOptionsDialog that lets you decide whether to ignore, report,

die, or ask the user for each type of event.  It has a button that
  will lead to the "advanced" dialog, which doesn't exist yet.
- in gui/wxdialog.h, sketch a few more dialogs to be done soon
- modified: gui/wxdialog.cc gui/wxdialog.h gui/wxmain.cc gui/wxmain.h
This commit is contained in:
Bryce Denney 2002-09-02 17:03:14 +00:00
parent 1cda50d9f2
commit 0268014110
4 changed files with 431 additions and 60 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxdialog.cc,v 1.16 2002-09-01 21:24:14 bdenney Exp $
// $Id: wxdialog.cc,v 1.17 2002-09-02 17:03:07 bdenney Exp $
/////////////////////////////////////////////////////////////////
//
// misc/wxdialog.cc
@ -1000,6 +1000,169 @@ void NetConfigDialog::ShowHelp ()
}
//////////////////////////////////////////////////////////////////////
// LogOptionsDialog implementation
//////////////////////////////////////////////////////////////////////
// Structure:
// vertSizer:
// prompt
// gridSizer 2 columns:
// "debug"
// action[0] = wxChoice
// "info"
// action[1] = wxChoice
// "error"
// action[2] = wxChoice
// "panic"
// action[3] = wxChoice
// buttonSizer:
// advanced
// help
// cancel
// ok
// all events go to OnEvent method
BEGIN_EVENT_TABLE(LogOptionsDialog, wxDialog)
EVT_BUTTON(-1, LogOptionsDialog::OnEvent)
EVT_CHECKBOX(-1, LogOptionsDialog::OnEvent)
EVT_TEXT(-1, LogOptionsDialog::OnEvent)
END_EVENT_TABLE()
LogOptionsDialog::LogOptionsDialog(
wxWindow* parent,
wxWindowID id)
: wxDialog (parent, id, "", wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
static char *names[] = LOG_OPTS_NAMES;
static char *choices[] = LOG_OPTS_CHOICES;
static int integers[LOG_OPTS_N_CHOICES_NORMAL] = {0, 1, 2, 3};
SetTitle (LOG_OPTS_TITLE);
vertSizer = new wxBoxSizer (wxVERTICAL);
// top level objects
wxStaticText *text = new wxStaticText (this, -1, LOG_OPTS_PROMPT);
vertSizer->Add (text, 0, wxALL, 20);
gridSizer = new wxFlexGridSizer (2);
vertSizer->Add (gridSizer, 1, wxLEFT, 40);
text = new wxStaticText (this, -1, LOG_OPTS_ADV);
vertSizer->Add (text, 0, wxALL, 20);
buttonSizer = new wxBoxSizer (wxHORIZONTAL);
vertSizer->Add (buttonSizer, 0, wxALIGN_RIGHT);
// figure out how wide the wxChoice boxes need to be for longest string
int choiceWidth;
#if 1
// Calculate length of longest choice, to help decide how wide the
// wxChoice controls should be. Otherwise they are sized according to
// the initial choice string, which may not be the longest.
wxString longest (choices[LOG_OPTS_LONGEST_CHOICE]);
wxClientDC dc (this);
wxCoord w, h;
dc.GetTextExtent (longest, &w, &h);
wxLogDebug ("extent of '%s' is %d,%d", longest.c_str (), w, h);
choiceWidth = w * 3 / 2; // 50% wider than longest string
#else
choiceWidth = 150; // hardcoded width, yuck.
#endif
// gridSizer contents
gridSizer->AddGrowableCol (1);
for (int evtype=0; evtype<LOG_OPTS_N_TYPES; evtype++) {
gridSizer->Add (new wxStaticText (this, -1, names[evtype]), 0, wxALL, 5);
gridSizer->Add (action[evtype] = new wxChoice (this, -1), 1, wxALL|wxGROW, 5);
// fill in the choices in the wxChoice field
int lastChoice = 0; // remember the index of the last choice
for (int choice=0; choice<LOG_OPTS_N_CHOICES_NORMAL; choice++) {
// the exclude expression allows some choices to not be available
// for some times. For example, it would be stupid to ignore a panic.
if (!LOG_OPTS_EXCLUDE (evtype, choice)) {
action[evtype]->Append (choices[choice], &integers[choice]);
// the client data is an int* that points to the choice number.
// This is what will be returned by GetAction().
lastChoice++;
}
}
wxSize sizenow = action[evtype]->GetSize ();
action[evtype]->SetSizeHints (choiceWidth, sizenow.GetHeight ());
action[evtype]->SetSelection (lastChoice-1);
}
// buttonSizer contents
wxButton *btn;
btn = new wxButton (this, ID_Advanced, BTNLABEL_ADVANCED);
buttonSizer->Add (btn, 0, wxALL, 5);
btn = new wxButton (this, wxHELP, BTNLABEL_HELP);
buttonSizer->Add (btn, 0, wxALL, 5);
// use wxID_CANCEL because pressing ESC produces this same code
btn = new wxButton (this, wxID_CANCEL, BTNLABEL_CANCEL);
buttonSizer->Add (btn, 0, wxALL, 5);
btn = new wxButton (this, wxOK, BTNLABEL_OK);
buttonSizer->Add (btn, 0, wxALL, 5);
}
void LogOptionsDialog::Init()
{
// lay it out!
SetAutoLayout(TRUE);
SetSizer(vertSizer);
vertSizer->Fit (this);
wxSize size = vertSizer->GetMinSize ();
printf ("minsize is %d,%d\n", size.GetWidth(), size.GetHeight ());
int margin = 5;
SetSizeHints (size.GetWidth () + margin, size.GetHeight () + margin);
Center ();
}
void LogOptionsDialog::SetAction (int evtype, int a) {
// find the choice whose client data matches "a".
int i = 0;
int *ptr;
wxLogDebug ("SetAction type=%d a=%d", evtype, a);
while ((ptr = (int*) action[evtype]->GetClientData (i)) != NULL) {
if (a == *ptr) { // found it!
action[evtype]->SetSelection (i);
return;
}
i++;
}
// this can happen if one of the choices that is excluded by
// LOG_OPTS_EXCLUDE() is used, for example.
wxLogDebug ("SetAction type=%d a=%d not found", evtype, a);
}
int LogOptionsDialog::GetAction (int evtype) {
int sel = action[evtype]->GetSelection ();
int *ptrToChoice = (int*)action[evtype]->GetClientData (sel);
return *ptrToChoice;
}
void LogOptionsDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId ();
printf ("you pressed button id=%d\n", id);
switch (id) {
case ID_Advanced:
wxMessageBox ("The advanced dialog is not implemented yet.");
break;
case wxOK:
EndModal (wxOK);
break;
case wxID_CANCEL:
EndModal (wxCANCEL);
break;
case wxHELP:
ShowHelp();
break;
default:
event.Skip ();
}
}
void LogOptionsDialog::ShowHelp ()
{
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR );
}
/////////////////////////////////////////////////////////////////
// utility
/////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////
// $Id: wxdialog.h,v 1.16 2002-09-01 21:24:14 bdenney Exp $
// $Id: wxdialog.h,v 1.17 2002-09-02 17:03:11 bdenney Exp $
////////////////////////////////////////////////////////////////////
//
// wxWindows dialogs for Bochs
@ -16,19 +16,23 @@
#define BTNLABEL_CANCEL "Cancel"
#define BTNLABEL_OK "Ok"
#define BTNLABEL_CREATE_IMG "Create Image"
#define BTNLABEL_ADVANCED "Advanced"
////////////////////////////////////////////////////////////////////
// LogMsgAskDialog is a modal dialog box that shows the user a
// simulation error message and asks if they want to continue or
// not. It looks something like this:
// -------------------------------------------------------------
// Context: Hard Drive
// Message: could not open hard drive image file '30M.sample'
//
// [ ] Don't ask about future messages like this
// +----- PANIC ---------------------------------------------------+
// | |
// | Context: Hard Drive |
// | Message: could not open hard drive image file '30M.sample' |
// | |
// | [ ] Don't ask about future messages like this |
// | |
// | [Continue] [Die] [Dump Core] [Debugger] [Help] |
// +---------------------------------------------------------------+
//
// [Continue] [Die] [Dump Core] [Debugger] [Help]
// -------------------------------------------------------------
// To use this dialog:
// After constructor, use SetContext, SetMessage, EnableButton to
// determine what will be displayed. Then call n = ShowModal(). The return
@ -386,6 +390,126 @@ public:
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////////////
// ConfigMemoryDialog
////////////////////////////////////////////////////////////////////////////
//
// +--- Configure Memory ----------------------------------------------+
// | |
// | +--- Standard Options ------------------------------------------+ |
// | | | |
// | | Memory size (megabytes): [_____] | |
// | | ROM BIOS image: [________________] [Browse] | |
// | | ROM BIOS address: [______] | |
// | | VGA BIOS image: [________________] [Browse] | |
// | | VGA BIOS address: 0xc0000 | |
// | | | |
// | +---------------------------------------------------------------+ |
// | |
// | +--- Optional ROM images ---------------------------------------+ |
// | | | |
// | | Optional ROM image #1: [________________] [Browse] | |
// | | address: [______] | |
// | | | |
// | | Optional ROM image #2: [________________] [Browse] | |
// | | address: [______] | |
// | | | |
// | | Optional ROM image #3: [________________] [Browse] | |
// | | address: [______] | |
// | | | |
// | | Optional ROM image #4: [________________] [Browse] | |
// | | address: [______] | |
// | | | |
// | +---------------------------------------------------------------+ |
// | [ Help ] [ Cancel ] [ Ok ] |
// +-------------------------------------------------------------------+
////////////////////////////////////////////////////////////////////////////
// ConfigSoundDialog
////////////////////////////////////////////////////////////////////////////
//
// +--- Configure Sound -------------------------------------------+
// | |
// | Bochs can emulate a Sound Blaster 16. Would you like |
// | to enable it? |
// | |
// | Enable [X] |
// | |
// | DMA timer: [_________] |
// | |
// | Midi mode [ 1 ] Output file [_________________] [Browse] |
// | Wave mode [ 1 ] Output file [_________________] [Browse] |
// | Log mode [ 1 ] Output file [_________________] [Browse] |
// | |
// | [ Help ] [ Cancel ] [ Ok ] |
// +---------------------------------------------------------------+
////////////////////////////////////////////////////////////////////////////
// LogOptionsDialog
////////////////////////////////////////////////////////////////////////////
// LogOptionsDialog allows the user to decide how Bochs will
// behave for each type of log event.
//
// +---- Configure events -----------------------------------+
// | |
// | How should Bochs respond to each type of event? |
// | |
// | Debug events: [ignore] |
// | Info events: [ignore] |
// | Error events: [report] |
// | Panic events: [ask ] |
// | |
// | For additional control over how each device responds |
// | to events, press the "Advanced" button. |
// | |
// | [ Advanced ] [ Help ] [ Cancel ] [ Ok ] |
// +---------------------------------------------------------+
// To use this dialog:
// After constructor, call SetAction(eventtype, action) to set initial
// value for each choice field. The eventtype is 0 to LOG_OPTS_N_TYPES-1,
// representing the types listed in LOG_OPTS_NAMES. The choice field is 0 to
// LOG_OPTS_N_CHOICES-1, representing the actions listed in LOG_OPTS_CHOICES.
// Then call ShowModal(), which will return wxOK or wxCANCEL. Afterward,
// the GetAction(eventtype) method will tell what was selected in each
// choice box.
class LogOptionsDialog: public wxDialog
{
private:
#define LOG_OPTS_TITLE "Configure Log Events"
#define LOG_OPTS_PROMPT "How should Bochs respond to each type of event?"
#define LOG_OPTS_NAMES { "Debug events: ", "Info events: ", "Error events: ", "Panic events: " }
#define LOG_OPTS_N_TYPES 4
#define LOG_OPTS_CHOICES { "ignore", "report in log file", "ask user what to do", "end simulation", "no change" }
#define LOG_OPTS_N_CHOICES_NORMAL 4
#define LOG_OPTS_N_CHOICES 5 // number of choices, including "no change"
#define LOG_OPTS_NO_CHANGE 5 // index of "no change"
// LOG_OPTS_CHOICES is the index of the longest string in LOG_OPTS_CHOICES
// array, used to determine dialog geometry
#define LOG_OPTS_LONGEST_CHOICE 2
// normally all choices are available for all event types. The exclude
// expression allows some choices to be eliminated if they don't make any
// sense. For example, it would be stupid to ignore a panic.
#define LOG_OPTS_EXCLUDE(type,choice) ( \
/* can't die or ask, on debug or info events */ \
(type <= 1 && (choice==2 || choice==3)) \
/* can't ignore panics or errors */ \
|| (type >= 2 && choice==0) \
)
#define LOG_OPTS_ADV "For additional control over how each device responds to events, press the \"Advanced\" button."
void Init (); // called automatically by ShowModal()
void ShowHelp ();
wxBoxSizer *vertSizer, *buttonSizer;
wxFlexGridSizer *gridSizer;
wxChoice *action[LOG_OPTS_N_TYPES];
public:
LogOptionsDialog(wxWindow* parent, wxWindowID id);
void OnEvent (wxCommandEvent& event);
int ShowModal() { Init(); return wxDialog::ShowModal(); }
int GetAction (int evtype);
void SetAction (int evtype, int action);
DECLARE_EVENT_TABLE()
};
/**************************************************************************
Everything else in here is a comment!
@ -497,10 +621,10 @@ Or if you choose the CD-ROM, you get to edit the settings for it.
| [Help] [Cancel] [Ok] |
+---------------------------------------------------------------------------+
The CD-ROM media can still be configured. In this context we can just show the
Media section. The same code can be written to serve both purposes. This is
the dialog that would appear when you click the CD-ROM button on the toolbar
at runtime.
The CD-ROM media can still be configured during the simulation. In this
context we can just show the Media section. The same code can be written to
serve both purposes. This is the dialog that would appear when you click the
CD-ROM button on the toolbar at runtime.
+-- CD-ROM Media -----------------------------+
| |
@ -590,39 +714,6 @@ let you go right to the configure screen for that disk drive.
| [ Help ] [ Cancel ] [ Ok ] |
+---------------------------------------------------------------+
////////////////////////////////////////////////////////////////////////////
// ConfigMemoryDialog
////////////////////////////////////////////////////////////////////////////
This edits options related to RAM and ROM, similar to the text menu
1. Memory size in megabytes: 4
2. Name of VGA BIOS image:
3. Name of ROM BIOS image:
4. ROM BIOS address: 0x00000
5. Name of optional ROM image #1 :
6. optional ROM #1 address: 0x00000
7. Name of optional ROM image #2 :
8. optional ROM #2 address: 0x00000
9. Name of optional ROM image #3 :
10. optional ROM #3 address: 0x00000
11. Name of optional ROM image #4 :
12. optional ROM #4 address: 0x00000
////////////////////////////////////////////////////////////////////////////
// ConfigSoundDialog
////////////////////////////////////////////////////////////////////////////
This edits options related to sound blaster emulation, similar to the
text menu
1. SB16 is present: yes
2. Midi file: /dev/midi00
3. Wave file: /dev/dsp
4. Log file: sb16.log
5. Midi mode: 1
6. Wave mode: 1
7. Log mode: 2
8. DMA timer: 600000
////////////////////////////////////////////////////////////////////////////
// ConfigKeyboardDialog
////////////////////////////////////////////////////////////////////////////
@ -667,21 +758,86 @@ sort of a grid with parameter name, and value(editable) in different columns
lets you choose which events you want to write to the log, which you
want to ignore, etc. You can do this at a high level, like
Event type Action
panic ask
error report
info ignore
debug ignore
+---- Configure events -----------------------------------+
| |
| How should Bochs respond to each type of event? |
| |
| Debug events: [ignore] |
| Info events: [ignore] |
| Error events: [report] |
| Panic events: [ask ] |
| |
| For additional control over how each device responds |
| to events, press the "Advanced" button. |
| |
| [ Advanced ] [ Help ] [ Cancel ] [ Ok ] |
+---------------------------------------------------------+
This sets up the default actions for all devices. The advanced
dialog lets you set different actions per device. I have two
attempts at the advanced dialog. The first creates a large
grid of wxChoice controls which choose between
ignore/report/ask/die. There will be enough rows in this
table that a scrolling subwindow will be needed to fit
all the devices.
Or when you want more control:
+---- Advanced event configuration -----------------------+
| |
| This table determines how Bochs will respond to each |
| kind of event coming from a particular source. For |
| example if you are having problems with the keyboard, |
| you could ask for debug and info events from the |
| keyboard to be reported. |
| |
| [Apply defaults for all devices] |
+-------------------------------------------------------+-+
| Device Debug Info Error Panic |^|
| -------- -------- ------- -------- --------- |||
| Keyboard [ignore] [ignore] [report] [report] |||
| VGA [ignore] [ignore] [report] [report] |||
| NE2000 [ignore] [ignore] [report] [report] |||
| Sound [ignore] [ignore] [report] [report] |v|
+---------------------------------------------------------+
| [ Help ] [ Cancel ] [ Ok ] |
+-------------------------------------------------------+-+
panic error info debug
----- ------ ----- -----
keyboard ask report report report
vga ask report report report
network ask report report ignore
cpu ask report report ignore
sound ask report report ignore
Try #2 for the advanced event configuration dialog.
It shows the selection of the default actions again
at the top, with some explanation. Then at bottom, you
can select a device in the list box and edit the settings
for that device individually. It would be possible to
allow selection of multiple devices and then edit several
devices at once.
+---- Advanced event configuration ---------------------+-+
| |
| +--- Default Actions -------------+ |
| First choose the | | |
| default actions | Debug events: [ignore] | |
| that apply to all | Info events: [ignore] | |
| event sources. | Error events: [report] | |
| | Panic events: [ask ] | |
| | | |
| | [Copy to All Devices] | |
| +---------------------------------+ |
| |
| Then, if you want you can edit the actions for |
| individual devices. For example if you are having |
| problems with the keyboard, you could ask for debug |
| and info events from the keyboard to be reported. |
| |
| Select Device: |
| +-------------+-+ +--- Actions for VGA -------------+ |
| | CPU |^| | | |
| | Interrupts ||| | Debug events: [ignore] | |
| |*VGA*********||| | Info events: [ignore] | |
| | Keyboard ||| | Error events: [report] | |
| | Mouse ||| | Panic events: [ask ] | |
| | Floppy Disk |v| | | |
| +-------------+-+ +---------------------------------+ |
| |
| [ Help ] [ Cancel ] [ Ok ] |
+---------------------------------------------------------+
////////////////////////////////////////////////////////////////////////////
// CpuRegistersDialog

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.22 2002-09-01 21:24:14 bdenney Exp $
// $Id: wxmain.cc,v 1.23 2002-09-02 17:03:13 bdenney Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWindows frame, toolbar, menus, and dialogs.
@ -149,6 +149,7 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(ID_Edit_Cdrom, MyFrame::OnOtherEvent)
EVT_MENU(ID_Edit_Boot, MyFrame::OnEditBoot)
EVT_MENU(ID_Edit_Network, MyFrame::OnEditNet)
EVT_MENU(ID_Log_Prefs, MyFrame::OnLogPrefs)
// toolbar events
EVT_TOOL(ID_Edit_FD_0, MyFrame::OnToolbarClick)
EVT_TOOL(ID_Edit_FD_1, MyFrame::OnToolbarClick)
@ -427,6 +428,54 @@ void MyFrame::OnEditNet(wxCommandEvent& WXUNUSED(event))
}
}
void MyFrame::OnLogPrefs(wxCommandEvent& WXUNUSED(event))
{
// Ideally I would use the siminterface methods to fill in the fields
// of the LogOptionsDialog, but in fact several things are hardcoded.
// At least I can verify that the expected numbers are the same.
wxASSERT (SIM->get_max_log_level() == LOG_OPTS_N_TYPES);
LogOptionsDialog dlg (this, -1);
// The inital values of the dialog are complicated. If the panic action
// for all modules is "ask", then clearly the inital value in the dialog
// for panic action should be "ask". This informs the user what the
// previous value was, and if they click Ok it won't do any harm. But if
// some devices are set to "ask" and others are set to "report", then the
// initial value should be "no change". With "no change", clicking on Ok
// will not destroy the settings for individual devices. You would only
// start to see "no change" if you've been messing around in the advanced
// menu already.
for (int level=0; level<SIM->get_max_log_level(); level++) {
int mod = 0;
int first = SIM->get_log_action (mod, level);
bool consensus = true;
// now compare all others to first. If all match, then use "first" as
// the initial value.
for (mod=1; mod<SIM->get_n_log_modules (); mod++) {
if (first != SIM->get_log_action (mod, level)) {
consensus = false;
break;
}
}
if (consensus)
dlg.SetAction (level, first);
else
dlg.SetAction (level, LOG_OPTS_NO_CHANGE);
}
int n = dlg.ShowModal (); // show the dialog!
if (n == wxOK) {
for (int level=0; level < SIM->get_max_log_level (); level++) {
// ask the dialog what action the user chose for this type of event
int action = dlg.GetAction (level);
if (action != LOG_OPTS_NO_CHANGE) {
// apply that action to all modules (devices)
for (int i=0; i<SIM->get_n_log_modules (); i++)
SIM->set_log_action (i, level, action);
}
}
}
}
void MyFrame::OnQuit(wxCommandEvent& event)
{
Close( TRUE );

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.h,v 1.14 2002-09-01 19:38:08 bdenney Exp $
// $Id: wxmain.h,v 1.15 2002-09-02 17:03:14 bdenney Exp $
/////////////////////////////////////////////////////////////////
// This file defines variables and classes that the wxWindows .cc files
// share. It should be included only by wx.cc and wxmain.cc.
@ -81,6 +81,8 @@ enum
ID_SPT,
ID_Megs,
ID_ComputeGeometry,
// dialog box: LogOptions
ID_Advanced
};
@ -132,6 +134,7 @@ public:
void OnSim2CIEvent(wxCommandEvent& event);
void OnEditBoot(wxCommandEvent& event);
void OnEditNet(wxCommandEvent& event);
void OnLogPrefs(wxCommandEvent& event);
void OnOtherEvent(wxCommandEvent& event);
static bool editFloppyValidate (FloppyConfigDialog *dialog);
void editFloppyConfig (int drive);