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:
Mattia Barbon
2002-07-24 19:29:53 +00:00
parent 53d838be50
commit 74698d3a22
8 changed files with 287 additions and 56 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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
View 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_

View File

@@ -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);

View File

@@ -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;
}
// ----------------------------------------------------------------------------

View File

@@ -109,6 +109,7 @@ bool WXDLLEXPORT wxInitialize()
return FALSE;
}
wxTheApp->DoInit();
gs_nInitCount++;
return TRUE;

123
src/common/msgout.cpp Executable file
View 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