- new implementation of the FloppyConfigDialog based on ParamDialog

* floppy device type selection wasn't present in the old version
  * "Create Image" button for creating floppy image with selected name and type
  * after selecting image file with "Browse", the media type is set to "auto"
    and the status is "inserted".
This commit is contained in:
Volker Ruppert 2009-03-27 22:22:07 +00:00
parent 2a4a481b0e
commit 394881ead6
4 changed files with 109 additions and 418 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxdialog.cc,v 1.110 2009-03-20 16:23:46 vruppert Exp $
// $Id: wxdialog.cc,v 1.111 2009-03-27 22:22:07 vruppert Exp $
/////////////////////////////////////////////////////////////////
// Define BX_PLUGGABLE in files that can be compiled into plugins. For
@ -151,241 +151,6 @@ void LogMsgAskDialog::ShowHelp()
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this);
}
//////////////////////////////////////////////////////////////////////
// FloppyConfigDialog implementation
//////////////////////////////////////////////////////////////////////
// Structure:
// vertSizer:
// instructions
// radioSizer (vert):
// phys0
// phys1
// diskImageSizer (horiz):
// disk image file
// filename
// browse button
// create button
// capacitySizer (horizontal):
// capacity text
// capacity choice box
// hint text
// buttonSizer:
// cancel button
// ok button
// help button
//
// all events go to OnEvent method
BEGIN_EVENT_TABLE(FloppyConfigDialog, wxDialog)
EVT_BUTTON(-1, FloppyConfigDialog::OnEvent)
EVT_TEXT(-1, FloppyConfigDialog::OnEvent)
EVT_CHOICE(-1, FloppyConfigDialog::OnEvent)
END_EVENT_TABLE()
FloppyConfigDialog::FloppyConfigDialog(
wxWindow* parent,
wxWindowID id)
: wxDialog (parent, id, wxT(""), wxDefaultPosition, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
validate = NULL;
n_rbtns = 0;
wxButton *btn;
vertSizer = new wxBoxSizer (wxVERTICAL);
instr = new wxStaticText (this, -1, FLOPPY_CONFIG_INSTRS);
radioSizer = new wxBoxSizer (wxVERTICAL);
diskImageSizer = new wxBoxSizer (wxHORIZONTAL);
capacitySizer = new wxBoxSizer (wxHORIZONTAL);
wxStaticText *hint = new wxStaticText (this, -1, FLOPPY_CONFIG_HINT);
buttonSizer = new wxBoxSizer (wxHORIZONTAL);
// add top level components to vertSizer
vertSizer->Add (instr, 0, wxTOP|wxLEFT, 30);
vertSizer->Add (radioSizer, 0, wxLEFT, 50);
vertSizer->Add (capacitySizer, 0, wxTOP|wxLEFT, 30);
vertSizer->Add (hint, 0, wxTOP|wxLEFT, 30);
vertSizer->Add (buttonSizer, 0, wxALIGN_RIGHT|wxTOP, 30);
// contents of capacitySizer
wxStaticText *captext = new wxStaticText(this, -1, FLOPPY_CONFIG_CAP);
capacity = new wxChoice(this, ID_Capacity);
capacitySizer->Add(captext, 0, wxALL, 5);
capacitySizer->Add(capacity, 0, wxALL|wxADJUST_MINSIZE, 5);
// contents of buttonSizer
btn = new wxButton(this, wxID_HELP, wxT("Help"));
buttonSizer->Add(btn, 0, wxALL, 5);
// use wxID_CANCEL because pressing ESC produces this same code
btn = new wxButton(this, wxID_CANCEL, wxT("Cancel"));
buttonSizer->Add(btn, 0, wxALL, 5);
CreateBtn = new wxButton(this, ID_Create, wxT("Create Image"));
buttonSizer->Add(CreateBtn, 0, wxALL, 5);
btn = new wxButton(this, wxID_OK, wxT("Ok"));
buttonSizer->Add(btn, 0, wxALL, 5);
// create filename and diskImageRadioBtn so that we can tweak them before
// Init comes. However don't add it to any sizer yet because it needs to go
// in after the last radio button.
filename = new wxTextCtrl (this, ID_FilenameText, wxT(""), wxDefaultPosition, longTextSize);
diskImageRadioBtn = new wxRadioButton (this, ID_Filename, FLOPPY_CONFIG_DISKIMG);
// the radioSizer contents will be added by successive calls to
// AddRadio(). The diskImageSizer will be added last, in Init().
}
void FloppyConfigDialog::AddRadio (
const wxString& description,
const wxString& filename)
{
if (n_rbtns >= FLOPPY_MAX_RBTNS) {
wxLogError(wxT("AddRadio failed: increase FLOPPY_MAX_RBTNS in wxdialog.h"));
return;
}
rbtn[n_rbtns] = new wxRadioButton(this, -1, description);
equivalentFilename[n_rbtns] = filename;
radioSizer->Add(rbtn[n_rbtns]);
n_rbtns++;
}
void FloppyConfigDialog::SetDriveName(wxString name)
{
SetTitle(wxString(FLOPPY_CONFIG_TITLE) + name);
ChangeStaticText(vertSizer, instr, wxString(FLOPPY_CONFIG_INSTRS) + name +
wxT("."));
}
void FloppyConfigDialog::SetCapacityChoices(const char *choices[])
{
int i = 0;
while (choices[i] != NULL) {
capacity->Append(wxString(choices[i], wxConvUTF8));
i++;
}
}
void FloppyConfigDialog::SetCapacity(int cap)
{
capacity->SetSelection(cap);
CreateBtn->Enable(floppy_type_n_sectors[cap] > 0);
}
void FloppyConfigDialog::Init()
{
// add contents of diskImageSizer
diskImageSizer->Add(diskImageRadioBtn);
diskImageSizer->Add(filename, 1, wxGROW);
wxButton *btn = new wxButton (this, ID_Browse, BTNLABEL_BROWSE);
diskImageSizer->Add(btn, 0, wxALL, 5);
radioSizer->Add(diskImageSizer);
SetAutoLayout(TRUE);
SetSizer(vertSizer);
vertSizer->Fit(this);
wxSize size = vertSizer->GetMinSize();
int margin = 5;
SetSizeHints (size.GetWidth() + margin, size.GetHeight() + margin);
Center();
}
int
FloppyConfigDialog::GetRadio () {
int i;
for (i=0; i<n_rbtns; i++) {
if (rbtn[i]->GetValue())
return i;
}
if (diskImageRadioBtn->GetValue()) {
return i;
}
wxLogError(wxT("GetRadio() found nothing selected"));
return 0;
}
void
FloppyConfigDialog::SetRadio (int n) {
if (n < n_rbtns) {
rbtn[n]->SetValue (TRUE);
} else {
diskImageRadioBtn->SetValue (TRUE);
}
}
void FloppyConfigDialog::SetFilename (wxString f) {
// search equivalentFilename[] for matches. if it matches, select the
// radio button instead.
for (int i=0; i<n_rbtns; i++) {
if (!f.Cmp(equivalentFilename[i])) {
rbtn[i]->SetValue(TRUE);
return; // leaving filename text field unchanged
}
}
filename->SetValue(f);
diskImageRadioBtn->SetValue(TRUE);
}
wxString
FloppyConfigDialog::GetFilename()
{
int n = GetRadio();
if (n < n_rbtns) {
return equivalentFilename[n];
} else {
return filename->GetValue();
}
}
void FloppyConfigDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId ();
switch (id) {
case ID_FilenameText:
// when you type into the filename field, ensure that the radio
// button associated with that field is chosen.
diskImageRadioBtn->SetValue (TRUE);
break;
case wxID_OK:
// probably should validate before allowing ok
if (validate!=NULL && !(*validate)(this))
return; // validation failed, don't leave yet
EndModal (wxID_OK);
break;
case ID_Browse:
if (BrowseTextCtrl(filename)) {
capacity->SetSelection(capacity->FindString(wxT("auto")));
}
break;
case ID_Capacity:
{
int cap = capacity->GetSelection();
CreateBtn->Enable(floppy_type_n_sectors[cap] > 0);
}
break;
case ID_Create:
{
int cap = capacity->GetSelection();
char name[1024];
strncpy(name, filename->GetValue().mb_str(wxConvUTF8), sizeof(name));
if (CreateImage (0, floppy_type_n_sectors[cap], name)) {
wxString msg(wxT("Created a "));
msg += capacity->GetString(cap);
msg += wxT(" disk image called '");
msg += filename->GetValue();
msg += wxT("'.");
wxMessageBox(msg, wxT("Image Created"), wxOK | wxICON_INFORMATION, this);
}
}
break;
case wxID_CANCEL:
EndModal(wxID_CANCEL);
break;
case wxID_HELP:
ShowHelp();
break;
}
}
void FloppyConfigDialog::ShowHelp()
{
wxMessageBox(MSG_NO_HELP, MSG_NO_HELP_CAPTION, wxOK | wxICON_ERROR, this);
}
//////////////////////////////////////////////////////////////////////
// AdvancedLogOptionsDialog implementation
//////////////////////////////////////////////////////////////////////
@ -1612,6 +1377,87 @@ void CpuRegistersDialog::OnEvent(wxCommandEvent& event)
}
}
//////////////////////////////////////////////////////////////////////
// FloppyConfigDialog implementation
//////////////////////////////////////////////////////////////////////
// all events go to OnEvent method
BEGIN_EVENT_TABLE(FloppyConfigDialog, wxDialog)
EVT_BUTTON(-1, FloppyConfigDialog::OnEvent)
EVT_CHECKBOX(-1, FloppyConfigDialog::OnEvent)
EVT_CHOICE(-1, FloppyConfigDialog::OnEvent)
EVT_TEXT(-1, FloppyConfigDialog::OnEvent)
END_EVENT_TABLE()
FloppyConfigDialog::FloppyConfigDialog(
wxWindow* parent,
wxWindowID id)
: ParamDialog(parent, id)
{
createButton = AddButton(ID_Create, wxT("Create Image"));
AddDefaultButtons();
}
void FloppyConfigDialog::Setup(bx_list_c *list)
{
int devtype_id, path_id, media_id, status_id;
devtype_id = list->get_by_name("devtype")->get_id();
path_id = list->get_by_name("path")->get_id();
media_id = list->get_by_name("type")->get_id();
status_id = list->get_by_name("status")->get_id();
AddParam(list);
pstrDevice = (ParamStruct*) paramHash->Get(devtype_id);
pstrPath = (ParamStruct*) paramHash->Get(path_id);
pstrMedia = (ParamStruct*) paramHash->Get(media_id);
pstrStatus = (ParamStruct*) paramHash->Get(status_id);
}
void FloppyConfigDialog::OnEvent(wxCommandEvent& event)
{
int id = event.GetId();
if (isGeneratedId(id)) {
ParamStruct *pstr = (ParamStruct*) idHash->Get(id);
if (pstr == NULL) {
wxLogDebug(wxT("ParamStruct not found for id=%d"), id);
return;
}
if (id == pstr->id) {
if ((pstr == pstrDevice) || (pstr == pstrMedia)) {
int val1 = pstrDevice->u.choice->GetSelection() + ((bx_param_num_c*)pstrDevice->param)->get_min();
int val2 = pstrMedia->u.choice->GetSelection() + ((bx_param_num_c*)pstrMedia->param)->get_min();
createButton->Enable((val1 != BX_FDD_NONE) && (val2 != BX_FLOPPY_NONE));
} else if ((pstr == pstrPath) && (!pstrPath->u.text->IsModified())) {
pstrMedia->u.choice->SetSelection(pstrMedia->u.choice->FindString(wxT("auto")));
pstrStatus->u.checkbox->SetValue(1);
}
}
ParamDialog::OnEvent(event);
} else {
switch (id) {
case ID_Create:
{
int cap = pstrMedia->u.choice->GetSelection();
char name[1024];
strncpy(name, pstrPath->u.text->GetValue().mb_str(wxConvUTF8), sizeof(name));
if ((floppy_type_n_sectors[cap] > 0) && (strlen(name) > 0) && (strcmp(name, "none"))) {
if (CreateImage (0, floppy_type_n_sectors[cap], name)) {
wxString msg(wxT("Created a "));
msg += pstrMedia->u.choice->GetString(cap);
msg += wxT(" disk image called '");
msg += pstrPath->u.text->GetValue();
msg += wxT("'.");
wxMessageBox(msg, wxT("Image Created"), wxOK | wxICON_INFORMATION, this);
}
}
}
break;
default:
ParamDialog::OnEvent(event);
}
}
}
//////////////////////////////////////////////////////////////////////
// LogOptionsDialog implementation
//////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
////////////////////////////////////////////////////////////////////
// $Id: wxdialog.h,v 1.73 2009-03-20 16:23:46 vruppert Exp $
// $Id: wxdialog.h,v 1.74 2009-03-27 22:22:07 vruppert Exp $
////////////////////////////////////////////////////////////////////
//
// wxWidgets dialogs for Bochs
@ -101,115 +101,6 @@ public:
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////
// FloppyConfigDialog is a modal dialog box that asks the user
// what physical device or disk image should be used for emulation.
//
// +-----Configure Floppy Drive A----------------------------------+
// | |
// | Bochs can use a real floppy drive as Disk A, or use an |
// | image file. |
// | |
// | [ ] None/Disabled |
// | [X] Physical floppy drive A: |
// | [ ] Physical floppy drive B: |
// | [ ] Disk image: [_____________________________] [Browse] |
// | |
// | What is the capacity of this disk? [1.44 MB] |
// | |
// | Hint: To create a disk image, choose the name and capacity |
// | above, then click Ok. |
// | |
// | [ Help ] [ Cancel ] [ Create Image ] [ Ok ] |
// +---------------------------------------------------------------+
// To use this dialog:
// After constructor, use AddRadio() to add radio buttons, SetFilename()
// to fill in the disk image filename, SetCapacity() to set the capacity.
// Then call ShowModal() to display it. Return value is wxID_OK or
// wxID_CANCEL. If you set a validation function, then it will be called when
// ok is pressed, and will get a chance to veto the "Ok" if it returns false.
// After ShowModal() returns, use GetFilename and GetCapacity to see what the
// user did. If the validation function sets parameters, this may be
// unnecessary.
//
// Volker reminded me that I wasn't paying much attention to
// the distinction between configuring the device (pre-boot) and
// configuring the media which can be done anytime. Here's a proposal
// to fix that... -Bryce
// +-----Configure Floppy Drive A----------------------------------+
// | |
// | +-- Device -----------------------------------------------+ |
// | | | |
// | | [ ] Enable Emulated Drive A | |
// | | | |
// | | Drive capacity [1.44 MB] | |
// | | | |
// | +---------------------------------------------------------+ |
// | |
// | +-- Media: Where does the data come from? ----------------+ |
// | | | |
// | | Bochs can use a physical floppy drive as the data | |
// | | source, or use an image file. | |
// | | | |
// | | [X] Physical floppy drive A: | |
// | | [ ] Physical floppy drive B: | |
// | | [ ] Disk image: [_________________________] [Browse] | |
// | | | |
// | | Media size [1.44 MB] | |
// | | | |
// | | Hint: To create a disk image, choose the name and | |
// | | capacity above, then click Ok. | |
// | | [ Create Image ] | |
// | +---------------------------------------------------------+ |
// | |
// | [ Help ] [ Cancel ] [ Ok ] |
// +---------------------------------------------------------------+
//////////////////////////////////////////////////////////////////////
class FloppyConfigDialog: public wxDialog
{
public:
#define FLOPPY_CONFIG_TITLE wxT("Configure ")
#define FLOPPY_CONFIG_INSTRS wxT("Select the device or image to use when simulating ")
#define FLOPPY_CONFIG_CAP wxT("What is the capacity of this disk?")
#define FLOPPY_CONFIG_HINT wxT("To create a disk image, choose the file name and capacity, then click on \"Create Image\".\n\n" \
"Clicking OK signals a media change for this drive.")
#define FLOPPY_CONFIG_DISKIMG wxT("Disk image: ")
private:
void Init(); // called automatically by ShowModal()
void ShowHelp();
wxStaticText *instr;
#define FLOPPY_MAX_RBTNS 4
wxRadioButton *rbtn[FLOPPY_MAX_RBTNS];
wxString equivalentFilename[FLOPPY_MAX_RBTNS];
int n_rbtns;
wxButton *CreateBtn;
wxRadioButton *diskImageRadioBtn;
wxTextCtrl *filename;
wxChoice *capacity;
wxBoxSizer *vertSizer, *radioSizer, *diskImageSizer, *capacitySizer, *buttonSizer;
typedef bool (*validateFunc_t)(FloppyConfigDialog *dialog);
validateFunc_t validate;
public:
FloppyConfigDialog(wxWindow* parent, wxWindowID id);
void OnEvent(wxCommandEvent& event);
void OnTextEvent(wxCommandEvent& event);
int ShowModal() { Init(); return wxDialog::ShowModal(); }
void SetRadio(int val);
void SetFilename(wxString f);
// Use char* instead of wxString because the array we use is already
// expressed as a char *[].
void SetCapacityChoices(const char *choices[]);
void SetCapacity(int cap);
int GetRadio();
int GetCapacity() { return capacity->GetSelection(); }
wxString GetFilename();
void SetDriveName(wxString name);
void SetValidateFunc(validateFunc_t v) { validate = v; }
void AddRadio(const wxString& description, const wxString& filename);
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////////////
// AdvancedLogOptionsDialog
////////////////////////////////////////////////////////////////////////////
@ -387,7 +278,6 @@ private:
wxTextCtrl *serialDelay, *pasteDelay, *mappingFile;
wxCheckBox *enableKeymap;
int genId();
bool isGeneratedId(int id);
bool isShowing;
int nbuttons;
bool runtime;
@ -404,6 +294,7 @@ protected:
void EnableParam(int param_id, bool enabled);
void ProcessDependentList(ParamStruct *pstrChanged, bool enabled);
bool CopyGuiToParam();
bool isGeneratedId(int id);
public:
ParamDialog(wxWindow* parent, wxWindowID id);
virtual ~ParamDialog();
@ -428,6 +319,24 @@ public:
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////////////
// FloppyConfigDialog
////////////////////////////////////////////////////////////////////////////
//
// the new FloppyConfigDialog is based on ParamDialog. It allows the user to
// configure the floppy settings and to create a floppy image if necessary.
class FloppyConfigDialog : public ParamDialog
{
private:
wxButton *createButton;
ParamStruct *pstrDevice, *pstrPath, *pstrMedia, *pstrStatus;
public:
FloppyConfigDialog(wxWindow* parent, wxWindowID id);
void Setup(bx_list_c *list);
void OnEvent(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
////////////////////////////////////////////////////////////////////////////
// LogOptionsDialog
////////////////////////////////////////////////////////////////////////////

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.cc,v 1.161 2009-03-25 18:33:42 vruppert Exp $
// $Id: wxmain.cc,v 1.162 2009-03-27 22:22:07 vruppert Exp $
/////////////////////////////////////////////////////////////////
//
// wxmain.cc implements the wxWidgets frame, toolbar, menus, and dialogs.
@ -1280,68 +1280,14 @@ void MyFrame::OnLogMsg(BxEvent *be)
sim_thread->SendSyncResponse(be); // only for case #2
}
bool MyFrame::editFloppyValidate(FloppyConfigDialog *dialog)
{
// haven't done anything with this 'feature'
return true;
}
void MyFrame::editFloppyConfig(int drive)
{
FloppyConfigDialog dlg(this, -1);
dlg.SetDriveName(wxString(drive==0? BX_FLOPPY0_NAME : BX_FLOPPY1_NAME, wxConvUTF8));
dlg.SetCapacityChoices(floppy_type_names);
dlg.SetTitle(wxString(drive==0? BX_FLOPPY0_NAME : BX_FLOPPY1_NAME, wxConvUTF8));
bx_list_c *list = (bx_list_c*) SIM->get_param((drive==0)? BXPN_FLOPPYA : BXPN_FLOPPYB);
if (!list) { wxLogError(wxT("floppy object param is null")); return; }
bx_param_filename_c *fname = (bx_param_filename_c*) list->get_by_name("path");
bx_param_enum_c *disktype = (bx_param_enum_c *) list->get_by_name("type");
bx_param_bool_c *status = (bx_param_bool_c *) list->get_by_name("status");
if (fname->get_type() != BXT_PARAM_STRING
|| disktype->get_type() != BXT_PARAM_ENUM
|| status->get_type() != BXT_PARAM_BOOL) {
wxLogError(wxT("floppy params have wrong type"));
return;
}
if (sim_thread == NULL) {
dlg.AddRadio(wxT("Not Present"), wxT(""));
}
dlg.AddRadio(wxT("Ejected"), wxT("none"));
#if defined(__linux__)
dlg.AddRadio(wxT("Physical floppy drive /dev/fd0"), wxT("/dev/fd0"));
dlg.AddRadio(wxT("Physical floppy drive /dev/fd1"), wxT("/dev/fd1"));
#elif defined(WIN32)
dlg.AddRadio(wxT("Physical floppy drive A:"), wxT("A:"));
dlg.AddRadio(wxT("Physical floppy drive B:"), wxT("B:"));
#else
// add your favorite operating system here
#endif
dlg.SetCapacity(disktype->get() - disktype->get_min());
dlg.SetFilename(wxString(fname->getptr(), wxConvUTF8));
dlg.SetValidateFunc(editFloppyValidate);
if (disktype->get() == BX_FLOPPY_NONE) {
dlg.SetRadio(0);
} else if ((status->get() == 0) || (!strcmp("none", fname->getptr()))) {
dlg.SetRadio((sim_thread == NULL)?1:0);
} else {
// otherwise the SetFilename() should have done the right thing.
}
int n = dlg.ShowModal();
if (n==wxID_OK) {
char filename[1024];
wxString fn(dlg.GetFilename());
strncpy(filename, fn.mb_str(wxConvUTF8), sizeof(filename));
fname->set(filename);
disktype->set(disktype->get_min() + dlg.GetCapacity());
if (sim_thread == NULL) {
if (dlg.GetRadio() == 0) {
disktype->set(BX_FLOPPY_NONE);
}
} else {
if (dlg.GetRadio() > 0) {
status->set(1);
}
}
}
dlg.Setup(list);
dlg.SetRuntimeFlag(sim_thread != NULL);
dlg.ShowModal();
}
void MyFrame::editFirstCdrom()

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////
// $Id: wxmain.h,v 1.59 2008-02-05 22:57:41 sshwarts Exp $
// $Id: wxmain.h,v 1.60 2009-03-27 22:22:07 vruppert Exp $
/////////////////////////////////////////////////////////////////
// This file defines variables and classes that the wxWidgets .cc files
// share. It should be included only by wx.cc and wxmain.cc.
@ -9,7 +9,6 @@
class MyFrame;
class MyPanel;
class SimThread;
class FloppyConfigDialog;
class ParamDialog;
#if BX_DEBUGGER
class DebugLogDialog;
@ -83,17 +82,9 @@ enum
ID_Debugger,
ID_Help,
// dialog box: FloppyConfigDialog
ID_None,
ID_Physical_A,
ID_Physical_B,
ID_Filename,
ID_FilenameText,
ID_Browse,
ID_Capacity,
ID_Create,
// dialog box: LogOptions
ID_Advanced,
ID_Browse2,
ID_Browse,
// dialog box: CpuRegistersDialog
ID_Debug_Continue,
ID_Debug_Stop,
@ -198,7 +189,6 @@ public:
void DebugCommand(wxString string);
void DebugCommand(const char *cmd);
#endif
static bool editFloppyValidate(FloppyConfigDialog *dialog);
void editFloppyConfig(int drive);
void editFirstCdrom();
void OnToolbarClick(wxCommandEvent& event);