wxWidgets/samples/wizard/wizard.cpp
Vadim Zeitlin 3f66f6a5b3 Remove all lines containing cvs/svn "$Id$" keyword.
This keyword is not expanded by Git which means it's not replaced with the
correct revision value in the releases made using git-based scripts and it's
confusing to have lines with unexpanded "$Id$" in the released files. As
expanding them with Git is not that simple (it could be done with git archive
and export-subst attribute) and there are not many benefits in having them in
the first place, just remove all these lines.

If nothing else, this will make an eventual transition to Git simpler.

Closes #14487.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@74602 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2013-07-26 16:02:46 +00:00

514 lines
16 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: wizard.cpp
// Purpose: wxWidgets sample demonstrating wxWizard control
// Author: Vadim Zeitlin
// Modified by: Robert Vazan (sizers)
// Created: 15.08.99
// Copyright: (c) Vadim Zeitlin
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers
#ifndef WX_PRECOMP
#include "wx/frame.h"
#include "wx/stattext.h"
#include "wx/log.h"
#include "wx/app.h"
#include "wx/checkbox.h"
#include "wx/checklst.h"
#include "wx/msgdlg.h"
#include "wx/radiobox.h"
#include "wx/menu.h"
#include "wx/sizer.h"
#endif
#include "wx/textctrl.h"
#include "wx/wizard.h"
#include "wiztest.xpm"
#include "wiztest2.xpm"
#include "../sample.xpm"
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
// ids for menu items
enum
{
Wizard_About = wxID_ABOUT,
Wizard_Quit = wxID_EXIT,
Wizard_RunModal = wxID_HIGHEST,
Wizard_RunNoSizer,
Wizard_RunModeless,
Wizard_LargeWizard,
Wizard_ExpandBitmap
};
// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------
// Define a new application type, each program should derive a class from wxApp
class MyApp : public wxApp
{
public:
// override base class virtuals
virtual bool OnInit();
};
class MyFrame : public wxFrame
{
public:
// ctor(s)
MyFrame(const wxString& title);
// event handlers (these functions should _not_ be virtual)
void OnQuit(wxCommandEvent& event);
void OnAbout(wxCommandEvent& event);
void OnRunWizard(wxCommandEvent& event);
void OnRunWizardNoSizer(wxCommandEvent& event);
void OnRunWizardModeless(wxCommandEvent& event);
void OnWizardCancel(wxWizardEvent& event);
void OnWizardFinished(wxWizardEvent& event);
private:
// any class wishing to process wxWidgets events must use this macro
DECLARE_EVENT_TABLE()
};
// ----------------------------------------------------------------------------
// our wizard
// ----------------------------------------------------------------------------
class MyWizard : public wxWizard
{
public:
MyWizard(wxFrame *frame, bool useSizer = true);
wxWizardPage *GetFirstPage() const { return m_page1; }
private:
wxWizardPageSimple *m_page1;
};
// ----------------------------------------------------------------------------
// some pages for our wizard
// ----------------------------------------------------------------------------
// This shows how to simply control the validity of the user input by just
// overriding TransferDataFromWindow() - of course, in a real program, the
// check wouldn't be so trivial and the data will be probably saved somewhere
// too.
//
// It also shows how to use a different bitmap for one of the pages.
class wxValidationPage : public wxWizardPageSimple
{
public:
wxValidationPage(wxWizard *parent) : wxWizardPageSimple(parent)
{
m_bitmap = wxBitmap(wiztest2_xpm);
m_checkbox = new wxCheckBox(this, wxID_ANY, wxT("&Check me"));
wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
mainSizer->Add(
new wxStaticText(this, wxID_ANY,
wxT("You need to check the checkbox\n")
wxT("below before going to the next page\n")),
0,
wxALL,
5
);
mainSizer->Add(
m_checkbox,
0, // No stretching
wxALL,
5 // Border
);
SetSizerAndFit(mainSizer);
}
virtual bool TransferDataFromWindow()
{
if ( !m_checkbox->GetValue() )
{
wxMessageBox(wxT("Check the checkbox first!"), wxT("No way"),
wxICON_WARNING | wxOK, this);
return false;
}
return true;
}
private:
wxCheckBox *m_checkbox;
};
// This is a more complicated example of validity checking: using events we may
// allow to return to the previous page, but not to proceed. It also
// demonstrates how to intercept [Cancel] button press.
class wxRadioboxPage : public wxWizardPageSimple
{
public:
// directions in which we allow the user to proceed from this page
enum
{
Forward, Backward, Both, Neither
};
wxRadioboxPage(wxWizard *parent) : wxWizardPageSimple(parent)
{
// should correspond to the enum above
// static wxString choices[] = { "forward", "backward", "both", "neither" };
// The above syntax can cause an internal compiler error with gcc.
wxString choices[4];
choices[0] = wxT("forward");
choices[1] = wxT("backward");
choices[2] = wxT("both");
choices[3] = wxT("neither");
m_radio = new wxRadioBox(this, wxID_ANY, wxT("Allow to proceed:"),
wxDefaultPosition, wxDefaultSize,
WXSIZEOF(choices), choices,
1, wxRA_SPECIFY_COLS);
m_radio->SetSelection(Both);
wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
mainSizer->Add(
m_radio,
0, // No stretching
wxALL,
5 // Border
);
SetSizerAndFit(mainSizer);
}
// wizard event handlers
void OnWizardCancel(wxWizardEvent& event)
{
if ( wxMessageBox(wxT("Do you really want to cancel?"), wxT("Question"),
wxICON_QUESTION | wxYES_NO, this) != wxYES )
{
// not confirmed
event.Veto();
}
}
void OnWizardPageChanging(wxWizardEvent& event)
{
int sel = m_radio->GetSelection();
if ( sel == Both )
return;
if ( event.GetDirection() && sel == Forward )
return;
if ( !event.GetDirection() && sel == Backward )
return;
wxMessageBox(wxT("You can't go there"), wxT("Not allowed"),
wxICON_WARNING | wxOK, this);
event.Veto();
}
private:
wxRadioBox *m_radio;
DECLARE_EVENT_TABLE()
};
// This shows how to dynamically (i.e. during run-time) arrange the page order.
class wxCheckboxPage : public wxWizardPage
{
public:
wxCheckboxPage(wxWizard *parent,
wxWizardPage *prev,
wxWizardPage *next)
: wxWizardPage(parent)
{
m_prev = prev;
m_next = next;
wxBoxSizer *mainSizer = new wxBoxSizer(wxVERTICAL);
mainSizer->Add(
new wxStaticText(this, wxID_ANY, wxT("Try checking the box below and\n")
wxT("then going back and clearing it")),
0, // No vertical stretching
wxALL,
5 // Border width
);
m_checkbox = new wxCheckBox(this, wxID_ANY, wxT("&Skip the next page"));
mainSizer->Add(
m_checkbox,
0, // No vertical stretching
wxALL,
5 // Border width
);
#if wxUSE_CHECKLISTBOX
static const wxChar *aszChoices[] =
{
wxT("Zeroth"),
wxT("First"),
wxT("Second"),
wxT("Third"),
wxT("Fourth"),
wxT("Fifth"),
wxT("Sixth"),
wxT("Seventh"),
wxT("Eighth"),
wxT("Nineth")
};
m_checklistbox = new wxCheckListBox
(
this,
wxID_ANY,
wxDefaultPosition,
wxSize(100,100),
wxArrayString(WXSIZEOF(aszChoices), aszChoices)
);
mainSizer->Add(
m_checklistbox,
0, // No vertical stretching
wxALL,
5 // Border width
);
#endif // wxUSE_CHECKLISTBOX
wxSize textSize = wxSize(150, 200);
if (((wxFrame*) wxTheApp->GetTopWindow())->GetMenuBar()->IsChecked(Wizard_LargeWizard))
textSize = wxSize(150, wxGetClientDisplayRect().GetHeight() - 200);
wxTextCtrl* textCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, textSize, wxTE_MULTILINE);
mainSizer->Add(textCtrl, 0, wxALL|wxEXPAND, 5);
SetSizerAndFit(mainSizer);
}
// implement wxWizardPage functions
virtual wxWizardPage *GetPrev() const { return m_prev; }
virtual wxWizardPage *GetNext() const
{
return m_checkbox->GetValue() ? m_next->GetNext() : m_next;
}
private:
wxWizardPage *m_prev,
*m_next;
wxCheckBox *m_checkbox;
#if wxUSE_CHECKLISTBOX
wxCheckListBox *m_checklistbox;
#endif
};
// ============================================================================
// implementation
// ============================================================================
// ----------------------------------------------------------------------------
// event tables and such
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(Wizard_Quit, MyFrame::OnQuit)
EVT_MENU(Wizard_About, MyFrame::OnAbout)
EVT_MENU(Wizard_RunModal, MyFrame::OnRunWizard)
EVT_MENU(Wizard_RunNoSizer, MyFrame::OnRunWizardNoSizer)
EVT_MENU(Wizard_RunModeless, MyFrame::OnRunWizardModeless)
EVT_WIZARD_CANCEL(wxID_ANY, MyFrame::OnWizardCancel)
EVT_WIZARD_FINISHED(wxID_ANY, MyFrame::OnWizardFinished)
END_EVENT_TABLE()
BEGIN_EVENT_TABLE(wxRadioboxPage, wxWizardPageSimple)
EVT_WIZARD_PAGE_CHANGING(wxID_ANY, wxRadioboxPage::OnWizardPageChanging)
EVT_WIZARD_CANCEL(wxID_ANY, wxRadioboxPage::OnWizardCancel)
END_EVENT_TABLE()
IMPLEMENT_APP(MyApp)
// ----------------------------------------------------------------------------
// the application class
// ----------------------------------------------------------------------------
// `Main program' equivalent: the program execution "starts" here
bool MyApp::OnInit()
{
if ( !wxApp::OnInit() )
return false;
MyFrame *frame = new MyFrame(wxT("wxWizard Sample"));
// and show it (the frames, unlike simple controls, are not shown when
// created initially)
frame->Show(true);
// we're done
return true;
}
// ----------------------------------------------------------------------------
// MyWizard
// ----------------------------------------------------------------------------
MyWizard::MyWizard(wxFrame *frame, bool useSizer)
{
SetExtraStyle(wxWIZARD_EX_HELPBUTTON);
Create(frame,wxID_ANY,wxT("Absolutely Useless Wizard"),
wxBitmap(wiztest_xpm),wxDefaultPosition,
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER);
SetIcon(wxICON(sample));
// Allow the bitmap to be expanded to fit the page height
if (frame->GetMenuBar()->IsChecked(Wizard_ExpandBitmap))
SetBitmapPlacement(wxWIZARD_VALIGN_CENTRE);
// Enable scrolling adaptation
if (frame->GetMenuBar()->IsChecked(Wizard_LargeWizard))
SetLayoutAdaptationMode(wxDIALOG_ADAPTATION_MODE_ENABLED);
// a wizard page may be either an object of predefined class
m_page1 = new wxWizardPageSimple(this);
/* wxStaticText *text = */ new wxStaticText(m_page1, wxID_ANY,
wxT("This wizard doesn't help you\nto do anything at all.\n")
wxT("\n")
wxT("The next pages will present you\nwith more useless controls."),
wxPoint(5,5)
);
// ... or a derived class
wxRadioboxPage *page3 = new wxRadioboxPage(this);
wxValidationPage *page4 = new wxValidationPage(this);
// set the page order using a convenience function - could also use
// SetNext/Prev directly as below, but Chain() is shorter, avoids the risk
// of an error and can itself be chained, e.g. you could write
// page3.Chain(page4).Chain(page5) and so on.
page3->Chain(page4);
// this page is not a wxWizardPageSimple, so we use SetNext/Prev to insert
// it into the chain of pages
wxCheckboxPage *page2 = new wxCheckboxPage(this, m_page1, page3);
m_page1->SetNext(page2);
page3->SetPrev(page2);
if ( useSizer )
{
// allow the wizard to size itself around the pages
GetPageAreaSizer()->Add(m_page1);
}
}
// ----------------------------------------------------------------------------
// MyFrame
// ----------------------------------------------------------------------------
MyFrame::MyFrame(const wxString& title)
:wxFrame((wxFrame *)NULL, wxID_ANY, title,
wxDefaultPosition, wxSize(250, 150)) // small frame
{
wxMenu *menuFile = new wxMenu;
menuFile->Append(Wizard_RunModal, wxT("&Run wizard modal...\tCtrl-R"));
menuFile->Append(Wizard_RunNoSizer, wxT("Run wizard &without sizer..."));
menuFile->Append(Wizard_RunModeless, wxT("Run wizard &modeless..."));
menuFile->AppendSeparator();
menuFile->Append(Wizard_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
wxMenu *menuOptions = new wxMenu;
menuOptions->AppendCheckItem(Wizard_LargeWizard, wxT("&Scroll Wizard Pages"));
menuOptions->AppendCheckItem(Wizard_ExpandBitmap, wxT("Si&ze Bitmap To Page"));
wxMenu *helpMenu = new wxMenu;
helpMenu->Append(Wizard_About, wxT("&About\tF1"), wxT("Show about dialog"));
// now append the freshly created menu to the menu bar...
wxMenuBar *menuBar = new wxMenuBar();
menuBar->Append(menuFile, wxT("&File"));
menuBar->Append(menuOptions, wxT("&Options"));
menuBar->Append(helpMenu, wxT("&Help"));
// ... and attach this menu bar to the frame
SetMenuBar(menuBar);
// also create status bar which we use in OnWizardCancel
#if wxUSE_STATUSBAR
CreateStatusBar();
#endif // wxUSE_STATUSBAR
}
void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
// true is to force the frame to close
Close(true);
}
void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
{
wxMessageBox(wxT("Demo of wxWizard class\n")
wxT("(c) 1999, 2000 Vadim Zeitlin"),
wxT("About wxWizard sample"), wxOK | wxICON_INFORMATION, this);
}
void MyFrame::OnRunWizard(wxCommandEvent& WXUNUSED(event))
{
MyWizard wizard(this);
wizard.RunWizard(wizard.GetFirstPage());
}
void MyFrame::OnRunWizardNoSizer(wxCommandEvent& WXUNUSED(event))
{
MyWizard wizard(this, false);
wizard.RunWizard(wizard.GetFirstPage());
}
void MyFrame::OnRunWizardModeless(wxCommandEvent& WXUNUSED(event))
{
MyWizard *wizard = new MyWizard(this);
wizard->ShowPage(wizard->GetFirstPage());
wizard->Show(true);
}
void MyFrame::OnWizardFinished(wxWizardEvent& WXUNUSED(event))
{
wxMessageBox(wxT("The wizard finished successfully."), wxT("Wizard notification"));
}
void MyFrame::OnWizardCancel(wxWizardEvent& WXUNUSED(event))
{
wxMessageBox(wxT("The wizard was cancelled."), wxT("Wizard notification"));
}