Added wxMessageOutput as per the discussion on wx-dev.
Added wxApp::DoInit to initialize the global wxMessageOutput instance. Changed wxCommandLineParser to use wxMessageOutput. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@16267 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -202,6 +202,7 @@ memory.cpp Common Base
|
||||
menucmn.cpp Common
|
||||
mimecmn.cpp Common Win32Only,Base
|
||||
module.cpp Common Base
|
||||
msgout.cpp Common Base
|
||||
mstream.cpp Common Base
|
||||
nbkbase.cpp Common
|
||||
object.cpp Common Base
|
||||
@@ -891,6 +892,7 @@ mimetype.h WXH Base
|
||||
minifram.h WXH
|
||||
module.h WXH Base
|
||||
msgdlg.h WXH
|
||||
msgout.h WXH Base
|
||||
mslu.cpp MSW
|
||||
mstream.h WXH Base
|
||||
notebook.h WXH
|
||||
|
@@ -108,6 +108,10 @@ public:
|
||||
// Override: always in GUI application, rarely in console ones.
|
||||
virtual bool OnInit();
|
||||
|
||||
// initializes wxMessageOutput; other responsibilities
|
||||
// may be added later
|
||||
virtual void DoInit();
|
||||
|
||||
#if wxUSE_GUI
|
||||
// a platform-dependent version of OnInit(): the code here is likely to
|
||||
// depend on the toolkit. default version does nothing.
|
||||
|
@@ -202,6 +202,9 @@ public:
|
||||
static wxArrayString ConvertStringToArgs(const wxChar *cmdline);
|
||||
|
||||
private:
|
||||
// get usage string
|
||||
wxString GetUsageString();
|
||||
|
||||
// common part of all ctors
|
||||
void Init();
|
||||
|
||||
|
78
include/wx/msgout.h
Executable file
78
include/wx/msgout.h
Executable file
@@ -0,0 +1,78 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/msgout.h
|
||||
// Purpose: wxMessageOutput class. Shows a message to the user
|
||||
// Author: Mattia Barbon
|
||||
// Modified by:
|
||||
// Created: 17.07.02
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) wxWindows team
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_MSGOUT_H_
|
||||
#define _WX_MSGOUT_H_
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma interface "msgout.h"
|
||||
#endif
|
||||
|
||||
#include "wx/defs.h"
|
||||
#include "wx/wxchar.h"
|
||||
|
||||
class WXDLLEXPORT wxMessageOutput
|
||||
{
|
||||
public:
|
||||
virtual ~wxMessageOutput() {};
|
||||
|
||||
// show a message to the user
|
||||
virtual void Printf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2 = 0;
|
||||
// gets the current wxMessageOutput object
|
||||
static wxMessageOutput* Get();
|
||||
// sets the global wxMessageOutput instance; returns the previous one
|
||||
static wxMessageOutput* Set(wxMessageOutput* msgout);
|
||||
private:
|
||||
static wxMessageOutput* ms_msgOut;
|
||||
};
|
||||
|
||||
// sends output to stderr
|
||||
class WXDLLEXPORT wxMessageOutputStderr : public wxMessageOutput
|
||||
{
|
||||
public:
|
||||
wxMessageOutputStderr() {};
|
||||
|
||||
virtual void Printf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2;
|
||||
};
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
||||
// shows output in a message box
|
||||
class WXDLLEXPORT wxMessageOutputMessageBox : public wxMessageOutput
|
||||
{
|
||||
public:
|
||||
wxMessageOutputMessageBox() {};
|
||||
|
||||
virtual void Printf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2;
|
||||
};
|
||||
|
||||
#ifdef __WXMOTIF__
|
||||
|
||||
// use wxLog; this is only required for wxMotif, so we put this code
|
||||
// inside wxUSE_GUI; it will work even without GUI
|
||||
class WXDLLEXPORT wxMessageOutputLog : public wxMessageOutput
|
||||
{
|
||||
public:
|
||||
wxMessageOutputLog() {};
|
||||
|
||||
virtual void Printf(const wxChar* format, ...) ATTRIBUTE_PRINTF_2;
|
||||
};
|
||||
|
||||
#endif // __WXMOTIF__
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
#endif
|
||||
// _WX_MSGOUT_H_
|
@@ -42,6 +42,7 @@
|
||||
#include "wx/confbase.h"
|
||||
#include "wx/tokenzr.h"
|
||||
#include "wx/utils.h"
|
||||
#include "wx/msgout.h"
|
||||
|
||||
#if wxUSE_GUI
|
||||
#include "wx/artprov.h"
|
||||
@@ -188,12 +189,27 @@ int wxAppBase::FilterEvent(wxEvent& WXUNUSED(event))
|
||||
return -1;
|
||||
}
|
||||
|
||||
void wxAppBase::DoInit()
|
||||
{
|
||||
if(wxMessageOutput::Get()) return;
|
||||
#if wxUSE_GUI
|
||||
#ifdef __WXMOTIF__
|
||||
wxMessageOutput::Set(new wxMessageOutputLog);
|
||||
#else
|
||||
wxMessageOutput::Set(new wxMessageOutputMessageBox);
|
||||
#endif
|
||||
#else
|
||||
wxMessageOutput::Set(new wxMessageOutputStderr);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// cmd line parsing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
bool wxAppBase::OnInit()
|
||||
{
|
||||
DoInit();
|
||||
#if wxUSE_CMDLINE_PARSER
|
||||
wxCmdLineParser parser(argc, argv);
|
||||
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "wx/datetime.h"
|
||||
#include "wx/msgout.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private functions
|
||||
@@ -513,6 +514,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
size_t currentParam = 0; // the index in m_paramDesc
|
||||
|
||||
size_t countParam = m_data->m_paramDesc.GetCount();
|
||||
wxString errorMsg;
|
||||
|
||||
Reset();
|
||||
|
||||
@@ -559,7 +561,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
optInd = m_data->FindOptionByLongName(name);
|
||||
if ( optInd == wxNOT_FOUND )
|
||||
{
|
||||
wxLogError(_("Unknown long option '%s'"), name.c_str());
|
||||
errorMsg << wxString::Format(_("Unknown long option '%s'"), name.c_str()) << "\n";
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -568,7 +570,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
|
||||
// Print the argument including leading "--"
|
||||
name.Prepend( wxT("--") );
|
||||
wxLogError(_("Unknown option '%s'"), name.c_str());
|
||||
errorMsg << wxString::Format(_("Unknown option '%s'"), name.c_str()) << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -589,7 +591,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
{
|
||||
// we couldn't find a valid option name in the
|
||||
// beginning of this string
|
||||
wxLogError(_("Unknown option '%s'"), name.c_str());
|
||||
errorMsg << wxString::Format(_("Unknown option '%s'"), name.c_str()) << "\n";
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -661,7 +663,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
|
||||
if ( *p++ != _T('=') )
|
||||
{
|
||||
wxLogError(_("Option '%s' requires a value, '=' expected."), name.c_str());
|
||||
errorMsg << wxString::Format(_("Option '%s' requires a value, '=' expected."), name.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -681,8 +683,8 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
if ( ++n == count )
|
||||
{
|
||||
// ... but there is none
|
||||
wxLogError(_("Option '%s' requires a value."),
|
||||
name.c_str());
|
||||
errorMsg << wxString::Format(_("Option '%s' requires a value."),
|
||||
name.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -698,8 +700,8 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
// not depending on the option style
|
||||
if ( opt.flags & wxCMD_LINE_NEEDS_SEPARATOR )
|
||||
{
|
||||
wxLogError(_("Separator expected after the option '%s'."),
|
||||
name.c_str());
|
||||
errorMsg << wxString::Format(_("Separator expected after the option '%s'."),
|
||||
name.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -728,8 +730,8 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError(_("'%s' is not a correct numeric value for option '%s'."),
|
||||
value.c_str(), name.c_str());
|
||||
errorMsg << wxString::Format(_("'%s' is not a correct numeric value for option '%s'."),
|
||||
value.c_str(), name.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -742,8 +744,8 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
const wxChar *res = dt.ParseDate(value);
|
||||
if ( !res || *res )
|
||||
{
|
||||
wxLogError(_("Option '%s': '%s' cannot be converted to a date."),
|
||||
name.c_str(), value.c_str());
|
||||
errorMsg << wxString::Format(_("Option '%s': '%s' cannot be converted to a date."),
|
||||
name.c_str(), value.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -783,7 +785,7 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
}
|
||||
else
|
||||
{
|
||||
wxLogError(_("Unexpected parameter '%s'"), arg.c_str());
|
||||
errorMsg << wxString::Format(_("Unexpected parameter '%s'"), arg.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -811,8 +813,8 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
opt.longName.c_str());
|
||||
}
|
||||
|
||||
wxLogError(_("The value for the option '%s' must be specified."),
|
||||
optName.c_str());
|
||||
errorMsg << wxString::Format(_("The value for the option '%s' must be specified."),
|
||||
optName.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
@@ -832,17 +834,21 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
|
||||
if ( !(param.flags & wxCMD_LINE_PARAM_OPTIONAL) )
|
||||
{
|
||||
wxLogError(_("The required parameter '%s' was not specified."),
|
||||
param.description.c_str());
|
||||
errorMsg << wxString::Format(_("The required parameter '%s' was not specified."),
|
||||
param.description.c_str()) << "\n";
|
||||
|
||||
ok = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !ok && showUsage )
|
||||
if ( !ok && errorMsg.length() != 0 )
|
||||
{
|
||||
Usage();
|
||||
wxString usage;
|
||||
wxMessageOutput* msgOut = wxMessageOutput::Get();
|
||||
if ( showUsage ) usage = GetUsageString();
|
||||
if ( msgOut )
|
||||
msgOut->Printf( wxT("%s%s"), usage.c_str(), errorMsg.c_str() );
|
||||
}
|
||||
|
||||
return ok ? 0 : helpRequested ? -1 : 1;
|
||||
@@ -853,11 +859,20 @@ int wxCmdLineParser::Parse(bool showUsage)
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxCmdLineParser::Usage()
|
||||
{
|
||||
wxString usage = GetUsageString();
|
||||
wxMessageOutput* msgOut = wxMessageOutput::Get();
|
||||
if ( msgOut )
|
||||
msgOut->Printf( wxT("%s"), usage.c_str() );
|
||||
}
|
||||
|
||||
wxString wxCmdLineParser::GetUsageString()
|
||||
{
|
||||
wxString appname = wxTheApp->GetAppName();
|
||||
if ( !appname )
|
||||
{
|
||||
wxCHECK_RET( !m_data->m_arguments.IsEmpty(), _T("no program name") );
|
||||
wxCHECK_MSG( !m_data->m_arguments.IsEmpty(), wxEmptyString,
|
||||
_T("no program name") );
|
||||
|
||||
appname = wxFileNameFromPath(m_data->m_arguments[0]);
|
||||
wxStripExtension(appname);
|
||||
@@ -866,9 +881,15 @@ void wxCmdLineParser::Usage()
|
||||
// we construct the brief cmd line desc on the fly, but not the detailed
|
||||
// help message below because we want to align the options descriptions
|
||||
// and for this we must first know the longest one of them
|
||||
wxString brief;
|
||||
wxString usage;
|
||||
wxArrayString namesOptions, descOptions;
|
||||
brief.Printf(_("Usage: %s"), appname.c_str());
|
||||
|
||||
if ( !!m_data->m_logo )
|
||||
{
|
||||
usage << m_data->m_logo << _T('\n');
|
||||
}
|
||||
|
||||
usage << wxString::Format(_("Usage: %s"), appname.c_str());
|
||||
|
||||
// the switch char is usually '-' but this can be changed with
|
||||
// SetSwitchChars() and then the first one of possible chars is used
|
||||
@@ -881,19 +902,19 @@ void wxCmdLineParser::Usage()
|
||||
{
|
||||
wxCmdLineOption& opt = m_data->m_options[n];
|
||||
|
||||
brief << _T(' ');
|
||||
usage << _T(' ');
|
||||
if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
|
||||
{
|
||||
brief << _T('[');
|
||||
usage << _T('[');
|
||||
}
|
||||
|
||||
if ( !opt.shortName.empty() )
|
||||
{
|
||||
brief << chSwitch << opt.shortName;
|
||||
usage << chSwitch << opt.shortName;
|
||||
}
|
||||
else if ( areLongOptionsEnabled && !opt.longName.empty() )
|
||||
{
|
||||
brief << _T("--") << opt.longName;
|
||||
usage << _T("--") << opt.longName;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -925,13 +946,13 @@ void wxCmdLineParser::Usage()
|
||||
{
|
||||
wxString val;
|
||||
val << _T('<') << GetTypeName(opt.type) << _T('>');
|
||||
brief << _T(' ') << val;
|
||||
usage << _T(' ') << val;
|
||||
option << (!opt.longName ? _T(':') : _T('=')) << val;
|
||||
}
|
||||
|
||||
if ( !(opt.flags & wxCMD_LINE_OPTION_MANDATORY) )
|
||||
{
|
||||
brief << _T(']');
|
||||
usage << _T(']');
|
||||
}
|
||||
|
||||
namesOptions.Add(option);
|
||||
@@ -943,37 +964,26 @@ void wxCmdLineParser::Usage()
|
||||
{
|
||||
wxCmdLineParam& param = m_data->m_paramDesc[n];
|
||||
|
||||
brief << _T(' ');
|
||||
usage << _T(' ');
|
||||
if ( param.flags & wxCMD_LINE_PARAM_OPTIONAL )
|
||||
{
|
||||
brief << _T('[');
|
||||
usage << _T('[');
|
||||
}
|
||||
|
||||
brief << param.description;
|
||||
usage << param.description;
|
||||
|
||||
if ( param.flags & wxCMD_LINE_PARAM_MULTIPLE )
|
||||
{
|
||||
brief << _T("...");
|
||||
usage << _T("...");
|
||||
}
|
||||
|
||||
if ( param.flags & wxCMD_LINE_PARAM_OPTIONAL )
|
||||
{
|
||||
brief << _T(']');
|
||||
usage << _T(']');
|
||||
}
|
||||
}
|
||||
|
||||
if ( !!m_data->m_logo )
|
||||
{
|
||||
wxLogMessage(m_data->m_logo);
|
||||
}
|
||||
|
||||
// in console mode we want to show the brief usage message first, then the
|
||||
// detailed one but in GUI build we give the details first and then the
|
||||
// summary - like this, the brief message appears in the wxLogGui dialog,
|
||||
// as expected
|
||||
#if !wxUSE_GUI
|
||||
wxLogMessage(brief);
|
||||
#endif // !wxUSE_GUI
|
||||
usage << _T('\n');
|
||||
|
||||
// now construct the detailed help message
|
||||
size_t len, lenMax = 0;
|
||||
@@ -985,22 +995,16 @@ void wxCmdLineParser::Usage()
|
||||
lenMax = len;
|
||||
}
|
||||
|
||||
wxString detailed;
|
||||
for ( n = 0; n < count; n++ )
|
||||
{
|
||||
len = namesOptions[n].length();
|
||||
detailed << namesOptions[n]
|
||||
usage << namesOptions[n]
|
||||
<< wxString(_T(' '), lenMax - len) << _T('\t')
|
||||
<< descOptions[n]
|
||||
<< _T('\n');
|
||||
}
|
||||
|
||||
wxLogMessage(detailed);
|
||||
|
||||
// do it now if not done above
|
||||
#if wxUSE_GUI
|
||||
wxLogMessage(brief);
|
||||
#endif // wxUSE_GUI
|
||||
return usage;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@@ -109,6 +109,7 @@ bool WXDLLEXPORT wxInitialize()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wxTheApp->DoInit();
|
||||
gs_nInitCount++;
|
||||
|
||||
return TRUE;
|
||||
|
123
src/common/msgout.cpp
Executable file
123
src/common/msgout.cpp
Executable file
@@ -0,0 +1,123 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: common/msgout.cpp
|
||||
// Purpose: wxMessageOutput implementation
|
||||
// Author: Mattia Barbon
|
||||
// Modified by:
|
||||
// Created: 17.07.02
|
||||
// RCS-ID: $Id$
|
||||
// Copyright: (c) the wxWindows team
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ============================================================================
|
||||
// declarations
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// headers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#ifdef __GNUG__
|
||||
#pragma implementation "msgout.h"
|
||||
#endif
|
||||
|
||||
// For compilers that support precompilation, includes "wx.h".
|
||||
#include "wx/wxprec.h"
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/string.h"
|
||||
#include "wx/ffile.h"
|
||||
#include "wx/app.h"
|
||||
#if wxUSE_GUI
|
||||
#include "wx/msgdlg.h"
|
||||
#endif // wxUSE_GUI
|
||||
#endif
|
||||
|
||||
#include "wx/msgout.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// ===========================================================================
|
||||
// implementation
|
||||
// ===========================================================================
|
||||
|
||||
wxMessageOutput* wxMessageOutput::ms_msgOut = 0;
|
||||
|
||||
wxMessageOutput* wxMessageOutput::Get()
|
||||
{
|
||||
return ms_msgOut;
|
||||
}
|
||||
|
||||
wxMessageOutput* wxMessageOutput::Set(wxMessageOutput* msgout)
|
||||
{
|
||||
wxMessageOutput* old = ms_msgOut;
|
||||
ms_msgOut = msgout;
|
||||
return old;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxMessageOutputStderr
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void wxMessageOutputStderr::Printf(const wxChar* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
wxString out;
|
||||
|
||||
out.PrintfV(format, args);
|
||||
va_end(args);
|
||||
|
||||
fprintf(stderr, "%s", out.mb_str());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxMessageOutputMessageBox
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_GUI
|
||||
|
||||
void wxMessageOutputMessageBox::Printf(const wxChar* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
wxString out;
|
||||
|
||||
out.PrintfV(format, args);
|
||||
va_end(args);
|
||||
|
||||
#ifndef __WXMSW__
|
||||
out.Replace("\t"," ");
|
||||
#endif
|
||||
::wxMessageBox(out);
|
||||
}
|
||||
|
||||
#endif // wxUSE_GUI
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// wxMessageOutputLog
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#if wxUSE_GUI && defined(__WXMOTIF__)
|
||||
|
||||
void wxMessageOutputLog::Printf(const wxChar* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
wxString out;
|
||||
|
||||
out.PrintfV(format, args);
|
||||
va_end(args);
|
||||
|
||||
out.Replace("\t"," ");
|
||||
// under Motif, wxMessageDialog needs a parent window, so we use
|
||||
// wxLog, which is better than nothing
|
||||
::wxLogMessage("%s", out.c_str());
|
||||
}
|
||||
|
||||
#endif // wxUSE_GUI
|
Reference in New Issue
Block a user