From: Vadim Zeitlin Date: Tue, 10 Jul 2001 17:28:19 +0000 (+0000) Subject: added cmd line parsing support to wxApp and --theme option to wxUniv X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/bf188f1add12abe2238d51d0568acc2a386e8051 added cmd line parsing support to wxApp and --theme option to wxUniv git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10952 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/docs/latex/wx/app.tex b/docs/latex/wx/app.tex index ec2ac10d7f..4ccfd04f3b 100644 --- a/docs/latex/wx/app.tex +++ b/docs/latex/wx/app.tex @@ -38,10 +38,6 @@ a reference to your application object) to be visible to other files. Constructor. Called implicitly with a definition of a wxApp object. -% VZ: there is no such feature so far... -% The argument is a language identifier; this is an experimental -% feature and will be expanded and documented in future versions. - \membersection{wxApp::\destruct{wxApp}} \func{void}{\destruct{wxApp}}{\void} @@ -234,81 +230,143 @@ If you use this member, you can selectively consume keypress events by calling\r \helpref{wxKeyEvent}{wxkeyevent}, \helpref{wxWindow::OnChar}{wxwindowonchar},\rtfsp \helpref{wxWindow::OnCharHook}{wxwindowoncharhook}, \helpref{wxDialog::OnCharHook}{wxdialogoncharhook} -\membersection{wxApp::OnFatalException}\label{wxapponfatalexception} +\membersection{wxApp::OnCmdLineError}\label{wxapponcmdlineerror} -\func{void}{OnFatalException}{\void} +\func{bool}{OnCmdLineError}{\param{wxCmdLineParser\& }{parser}} -This function may be called if something fatal happens: an unhandled -exception under Win32 or a a fatal signal under Unix, for example. However, -this will not happen by default: you have to explicitly call -\helpref{wxHandleFatalExceptions}{wxhandlefatalexceptions} to enable this. +Called when command line parsing fails (i.e. an incorrect command line option +was specified by the user). The default behaviour is to show the program usage +text and abort the program. -Generally speaking, this function should only show a message to the user and -return. You may attempt to save unsaved data but this is not guaranteed to -work and, in fact, probably won't. +Return {\tt TRUE} to continue normal execution or {\tt FALSE} to return +{\tt FALSE} from \helpref{OnInit}{wxapponinit} thus terminating the program. \wxheading{See also} -\helpref{wxHandleFatalExcetions}{wxhandlefatalexceptions} +\helpref{OnInitCmdLine}{wxapponinitcmdline} -\membersection{wxApp::OnIdle}\label{wxapponidle} +\membersection{wxApp::OnCmdLineHelp}\label{wxapponcmdlinehelp} -\func{void}{OnIdle}{\param{wxIdleEvent\& }{event}} +\func{bool}{OnCmdLineHelp}{\param{wxCmdLineParser\& }{parser}} -Override this member function for any processing which needs to be done -when the application is idle. You should call wxApp::OnIdle from your own function, -since this forwards OnIdle events to windows and also performs garbage collection for -windows whose destruction has been delayed. +Called when the help option ({\tt --help}) was specified on the command line. +The default behaviour is to show the program usage text and abort the program. -wxWindows' strategy for OnIdle processing is as follows. After pending user interface events for an -application have all been processed, wxWindows sends an OnIdle event to the application object. wxApp::OnIdle itself -sends an OnIdle event to each application window, allowing windows to do idle processing such as updating -their appearance. If either wxApp::OnIdle or a window OnIdle function requested more time, by -caling \helpref{wxIdleEvent::RequestMore}{wxidleeventrequestmore}, wxWindows will send another OnIdle -event to the application object. This will occur in a loop until either a user event is found to be -pending, or OnIdle requests no more time. Then all pending user events are processed until the system -goes idle again, when OnIdle is called, and so on. +Return {\tt TRUE} to continue normal execution or {\tt FALSE} to return +{\tt FALSE} from \helpref{OnInit}{wxapponinit} thus terminating the program. \wxheading{See also} -\helpref{wxWindow::OnIdle}{wxwindowonidle}, \helpref{wxIdleEvent}{wxidleevent},\rtfsp -\helpref{wxWindow::SendIdleEvents}{wxappsendidleevents} +\helpref{OnInitCmdLine}{wxapponinitcmdline} -\membersection{wxApp::OnEndSession}\label{wxapponendsession} +\membersection{wxApp::OnCmdLineParsed}\label{wxapponcmdlineparsed} -\func{void}{OnEndSession}{\param{wxCloseEvent\& }{event}} +\func{bool}{OnCmdLineParsed}{\param{wxCmdLineParser\& }{parser}} -This is an event handler function called when the operating system or GUI session is -about to close down. The application has a chance to silently save information, -and can optionally close itself. +Called after the command line had been successfully parsed. You may override +this method to test for the values of the various parameters which could be +set from the command line. -Use the EVT\_END\_SESSION event table macro to handle query end session events. +Don't forget to call the base class version unless you want to suppress +processing of the standard command line options. -The default handler calls \helpref{wxWindow::Close}{wxwindowclose} with a TRUE argument -(forcing the application to close itself silently). +Return {\tt TRUE} to continue normal execution or {\tt FALSE} to return +{\tt FALSE} from \helpref{OnInit}{wxapponinit} thus terminating the program. -\wxheading{Remarks} +\wxheading{See also} -Under X, OnEndSession is called in response to the `die' event. +\helpref{OnInitCmdLine}{wxapponinitcmdline} -Under Windows, OnEndSession is called in response to the WM\_ENDSESSION message. +\membersection{wxApp::OnFatalException}\label{wxapponfatalexception} + +\func{void}{OnFatalException}{\void} + +This function may be called if something fatal happens: an unhandled +exception under Win32 or a a fatal signal under Unix, for example. However, +this will not happen by default: you have to explicitly call +\helpref{wxHandleFatalExceptions}{wxhandlefatalexceptions} to enable this. + +Generally speaking, this function should only show a message to the user and +return. You may attempt to save unsaved data but this is not guaranteed to +work and, in fact, probably won't. \wxheading{See also} -\helpref{wxWindow::Close}{wxwindowclose},\rtfsp -\helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp -\helpref{wxCloseEvent}{wxcloseevent},\rtfsp -\helpref{wxApp::OnQueryEndSession}{wxapponqueryendsession} +\helpref{wxHandleFatalExcetions}{wxhandlefatalexceptions} + +%% VZ: the wxApp event handler are private and should not be documented here! +%% +%%\membersection{wxApp::OnIdle}\label{wxapponidle} +%% +%%\func{void}{OnIdle}{\param{wxIdleEvent\& }{event}} +%% +%%Override this member function for any processing which needs to be done +%%when the application is idle. You should call wxApp::OnIdle from your own function, +%%since this forwards OnIdle events to windows and also performs garbage collection for +%%windows whose destruction has been delayed. +%% +%%wxWindows' strategy for OnIdle processing is as follows. After pending user interface events for an +%%application have all been processed, wxWindows sends an OnIdle event to the application object. wxApp::OnIdle itself +%%sends an OnIdle event to each application window, allowing windows to do idle processing such as updating +%%their appearance. If either wxApp::OnIdle or a window OnIdle function requested more time, by +%%caling \helpref{wxIdleEvent::RequestMore}{wxidleeventrequestmore}, wxWindows will send another OnIdle +%%event to the application object. This will occur in a loop until either a user event is found to be +%%pending, or OnIdle requests no more time. Then all pending user events are processed until the system +%%goes idle again, when OnIdle is called, and so on. +%% +%%\wxheading{See also} +%% +%%\helpref{wxWindow::OnIdle}{wxwindowonidle}, \helpref{wxIdleEvent}{wxidleevent},\rtfsp +%%\helpref{wxWindow::SendIdleEvents}{wxappsendidleevents} +%% +%%\membersection{wxApp::OnEndSession}\label{wxapponendsession} +%% +%%\func{void}{OnEndSession}{\param{wxCloseEvent\& }{event}} +%% +%%This is an event handler function called when the operating system or GUI session is +%%about to close down. The application has a chance to silently save information, +%%and can optionally close itself. +%% +%%Use the EVT\_END\_SESSION event table macro to handle query end session events. +%% +%%The default handler calls \helpref{wxWindow::Close}{wxwindowclose} with a TRUE argument +%%(forcing the application to close itself silently). +%% +%%\wxheading{Remarks} +%% +%%Under X, OnEndSession is called in response to the `die' event. +%% +%%Under Windows, OnEndSession is called in response to the WM\_ENDSESSION message. +%% +%%\wxheading{See also} +%% +%%\helpref{wxWindow::Close}{wxwindowclose},\rtfsp +%%\helpref{wxWindow::OnCloseWindow}{wxwindowonclosewindow},\rtfsp +%%\helpref{wxCloseEvent}{wxcloseevent},\rtfsp +%%\helpref{wxApp::OnQueryEndSession}{wxapponqueryendsession} \membersection{wxApp::OnInit}\label{wxapponinit} \func{bool}{OnInit}{\void} This must be provided by the application, and will usually create the -application's main window, optionally calling \helpref{wxApp::SetTopWindow}{wxappsettopwindow}. +application's main window, optionally calling +\helpref{wxApp::SetTopWindow}{wxappsettopwindow}. + +Notice that if you want to to use the command line processing provided by +wxWindows you have to call the base class version in the derived class +OnInit(). Return TRUE to continue processing, FALSE to exit the application. +\membersection{wxApp::OnInitCmdLine}\label{wxapponinitcmdline} + +\func{void}{OnInitCmdLine}{\param{wxCmdLineParser\& }{parser}} + +Called from \helpref{OnInit}{wxapponinit} and may be used to initialize the +parser with the command line options for this application. The base class +versions adds support for a few standard options only. + \membersection{wxApp::OnQueryEndSession}\label{wxapponqueryendsession} \func{void}{OnQueryEndSession}{\param{wxCloseEvent\& }{event}} diff --git a/include/wx/app.h b/include/wx/app.h index 4756689918..b6db5db471 100644 --- a/include/wx/app.h +++ b/include/wx/app.h @@ -31,6 +31,8 @@ typedef wxObject* (*wxAppInitializerFunction)(); #endif +class WXDLLEXPORT wxCmdLineParser; + // ---------------------------------------------------------------------------- // headers we have to include here // ---------------------------------------------------------------------------- @@ -38,7 +40,7 @@ #include "wx/event.h" // for the base class #if wxUSE_GUI - #include "wx/window.h" // for wxTopLevelWindows + #include "wx/window.h" // for wxTopLevelWindows #endif // wxUSE_GUI #if wxUSE_LOG @@ -63,19 +65,13 @@ public: // the virtual functions which may/must be overridden in the derived class // ----------------------------------------------------------------------- -#ifdef __WXMAC_X__ - virtual ~wxAppBase() {} // Added min for Mac X -#endif + // called during the program initialization, returning FALSE from here // prevents the program from continuing - it's a good place to create // the top level program window and return TRUE. // // Override: always in GUI application, rarely in console ones. -#if wxUSE_GUI - virtual bool OnInit() { return FALSE; }; -#else // !GUI - virtual bool OnInit() { return TRUE; }; -#endif // wxUSE_GUI + virtual bool OnInit(); #if wxUSE_GUI // a platform-dependent version of OnInit(): the code here is likely to @@ -196,6 +192,34 @@ public: #endif // wxUSE_GUI + // cmd line parsing stuff + // ---------------------- + + // all of these methods may be overridden in the derived class to + // customize the command line parsing (by default only a few standard + // options are handled) + // + // you also need to call wxApp::OnInit() from YourApp::OnInit() for all + // this to work + +#if wxUSE_CMDLINE_PARSER + // this one is called from OnInit() to add all supported options + // to the given parser + virtual void OnInitCmdLine(wxCmdLineParser& parser); + + // called after successfully parsing the command line, return TRUE + // to continue and FALSE to exit + virtual bool OnCmdLineParsed(wxCmdLineParser& parser); + + // called if "--help" option was specified, return TRUE to continue + // and FALSE to exit + virtual bool OnCmdLineHelp(wxCmdLineParser& parser); + + // called if incorrect command line options were given, return + // FALSE to abort and TRUE to continue + virtual bool OnCmdLineError(wxCmdLineParser& parser); +#endif // wxUSE_CMDLINE_PARSER + // miscellaneous customization functions // ------------------------------------- @@ -281,6 +305,11 @@ protected: // does any of our windows has focus? bool m_isActive; #endif // wxUSE_GUI + +#ifdef __WXMAC_X__ +public: + virtual ~wxAppBase() {} // Added min for Mac X +#endif }; // ---------------------------------------------------------------------------- @@ -412,7 +441,7 @@ public: extern int wxEntry( int argc, char *argv[] ); \ int main(int argc, char *argv[]) { return wxEntry(argc, argv); } #elif defined(__WXMAC__) && defined(__UNIX__) - // wxMac seems to have a specific wxEntry prototype + // wxMac seems to have a specific wxEntry prototype #define IMPLEMENT_WXWIN_MAIN \ extern int wxEntry( int argc, char *argv[], bool enterLoop = 1 ); \ int main(int argc, char *argv[]) { return wxEntry(argc, argv); } diff --git a/samples/widgets/widgets.cpp b/samples/widgets/widgets.cpp index 5e9204a919..59ee9950f0 100644 --- a/samples/widgets/widgets.cpp +++ b/samples/widgets/widgets.cpp @@ -192,6 +192,9 @@ END_EVENT_TABLE() bool WidgetsApp::OnInit() { + if ( !wxApp::OnInit() ) + return FALSE; + // the reason for having these ifdef's is that I often run two copies of // this sample side by side and it is useful to see which one is which wxString title; diff --git a/src/common/appcmn.cpp b/src/common/appcmn.cpp index 0b7b957dc3..63cfeb9c77 100644 --- a/src/common/appcmn.cpp +++ b/src/common/appcmn.cpp @@ -30,20 +30,22 @@ #ifndef WX_PRECOMP #include "wx/app.h" + #include "wx/intl.h" #include "wx/list.h" #endif +#include "wx/cmdline.h" #include "wx/thread.h" #include "wx/confbase.h" -#ifdef __WXUNIVERSAL__ - #include "wx/univ/theme.h" -#endif // __WXUNIVERSAL__ - // =========================================================================== // implementation // =========================================================================== +// ---------------------------------------------------------------------------- +// initialization and termination +// ---------------------------------------------------------------------------- + wxAppBase::wxAppBase() { wxTheApp = (wxApp *)this; @@ -59,15 +61,11 @@ wxAppBase::wxAppBase() #endif // wxUSE_GUI } -// ---------------------------------------------------------------------------- -// initialization and termination -// ---------------------------------------------------------------------------- - #if wxUSE_GUI bool wxAppBase::OnInitGui() { #ifdef __WXUNIVERSAL__ - if ( !wxTheme::CreateDefault() ) + if ( !wxTheme::Get() && !wxTheme::CreateDefault() ) return FALSE; #endif // __WXUNIVERSAL__ @@ -136,3 +134,127 @@ void wxAppBase::SetActive(bool active, wxWindow * WXUNUSED(lastFocus)) } #endif // wxUSE_GUI + +// ---------------------------------------------------------------------------- +// cmd line parsing +// ---------------------------------------------------------------------------- + +bool wxAppBase::OnInit() +{ +#if wxUSE_CMDLINE_PARSER + wxCmdLineParser parser(argc, argv); + + OnInitCmdLine(parser); + + bool cont; + switch ( parser.Parse() ) + { + case -1: + cont = OnCmdLineHelp(parser); + break; + + case 0: + cont = OnCmdLineParsed(parser); + break; + + default: + cont = OnCmdLineError(parser); + break; + } + + if ( !cont ) + return FALSE; +#endif // wxUSE_CMDLINE_PARSER + + return TRUE; +} + +#if wxUSE_CMDLINE_PARSER + +#define OPTION_VERBOSE _T("verbose") +#define OPTION_THEME _T("theme") + +void wxAppBase::OnInitCmdLine(wxCmdLineParser& parser) +{ + // the standard command line options + static const wxCmdLineEntryDesc cmdLineDesc[] = + { + { + wxCMD_LINE_SWITCH, + _T("h"), + _T("help"), + gettext_noop("show this help message"), + wxCMD_LINE_VAL_NONE, + wxCMD_LINE_OPTION_HELP + }, + +#if wxUSE_LOG + { + wxCMD_LINE_SWITCH, + _T(""), + OPTION_VERBOSE, + gettext_noop("generate verbose log messages") + }, +#endif wxUSE_LOG + +#ifdef __WXUNIVERSAL__ + { + wxCMD_LINE_OPTION, + _T(""), + OPTION_THEME, + gettext_noop("specify the theme to use"), + wxCMD_LINE_VAL_STRING + }, +#endif // __WXUNIVERSAL__ + + // terminator + { wxCMD_LINE_NONE } + }; + + parser.SetDesc(cmdLineDesc); +} + +bool wxAppBase::OnCmdLineParsed(wxCmdLineParser& parser) +{ +#if wxUSE_LOG + if ( parser.Found(OPTION_VERBOSE) ) + { + wxLog::SetVerbose(TRUE); + } +#endif // wxUSE_LOG + +#ifdef __WXUNIVERSAL__ + wxString themeName; + if ( parser.Found(OPTION_THEME, &themeName) ) + { + wxTheme *theme = wxTheme::Create(themeName); + if ( !theme ) + { + wxLogError(_("Unsupported theme '%s'."), themeName.c_str()); + + return FALSE; + } + + wxTheme::Set(theme); + } +#endif // __WXUNIVERSAL__ + + return TRUE; +} + +bool wxAppBase::OnCmdLineHelp(wxCmdLineParser& parser) +{ + parser.Usage(); + + return FALSE; +} + +bool wxAppBase::OnCmdLineError(wxCmdLineParser& parser) +{ + parser.Usage(); + + return FALSE; +} + +#endif // wxUSE_CMDLINE_PARSER + diff --git a/src/common/cmdline.cpp b/src/common/cmdline.cpp index 49f362bfa0..5b3610b102 100644 --- a/src/common/cmdline.cpp +++ b/src/common/cmdline.cpp @@ -64,6 +64,9 @@ struct wxCmdLineOption wxCmdLineParamType typ, int fl) { + wxASSERT_MSG( !shrt.empty() || !lng.empty(), + _T("option should have at least one name") ); + kind = k; shortName = shrt; @@ -240,13 +243,16 @@ void wxCmdLineParserData::SetArguments(const wxString& cmdLine) int wxCmdLineParserData::FindOption(const wxString& name) { - size_t count = m_options.GetCount(); - for ( size_t n = 0; n < count; n++ ) + if ( !name.empty() ) { - if ( m_options[n].shortName == name ) + size_t count = m_options.GetCount(); + for ( size_t n = 0; n < count; n++ ) { - // found - return n; + if ( m_options[n].shortName == name ) + { + // found + return n; + } } } @@ -410,6 +416,9 @@ void wxCmdLineParser::AddParam(const wxString& desc, bool wxCmdLineParser::Found(const wxString& name) const { int i = m_data->FindOption(name); + if ( i == wxNOT_FOUND ) + i = m_data->FindOptionByLongName(name); + wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown switch") ); wxCmdLineOption& opt = m_data->m_options[(size_t)i]; @@ -422,6 +431,9 @@ bool wxCmdLineParser::Found(const wxString& name) const bool wxCmdLineParser::Found(const wxString& name, wxString *value) const { int i = m_data->FindOption(name); + if ( i == wxNOT_FOUND ) + i = m_data->FindOptionByLongName(name); + wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") ); wxCmdLineOption& opt = m_data->m_options[(size_t)i]; @@ -438,6 +450,9 @@ bool wxCmdLineParser::Found(const wxString& name, wxString *value) const bool wxCmdLineParser::Found(const wxString& name, long *value) const { int i = m_data->FindOption(name); + if ( i == wxNOT_FOUND ) + i = m_data->FindOptionByLongName(name); + wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") ); wxCmdLineOption& opt = m_data->m_options[(size_t)i]; @@ -454,6 +469,9 @@ bool wxCmdLineParser::Found(const wxString& name, long *value) const bool wxCmdLineParser::Found(const wxString& name, wxDateTime *value) const { int i = m_data->FindOption(name); + if ( i == wxNOT_FOUND ) + i = m_data->FindOptionByLongName(name); + wxCHECK_MSG( i != wxNOT_FOUND, FALSE, _T("unknown option") ); wxCmdLineOption& opt = m_data->m_options[(size_t)i];