]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxMessageOutput as per the discussion on wx-dev.
authorMattia Barbon <mbarbon@cpan.org>
Wed, 24 Jul 2002 19:29:53 +0000 (19:29 +0000)
committerMattia Barbon <mbarbon@cpan.org>
Wed, 24 Jul 2002 19:29:53 +0000 (19:29 +0000)
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

distrib/msw/tmake/filelist.txt
include/wx/app.h
include/wx/cmdline.h
include/wx/msgout.h [new file with mode: 0755]
src/common/appcmn.cpp
src/common/cmdline.cpp
src/common/init.cpp
src/common/msgout.cpp [new file with mode: 0755]

index 55aa75f1f4a96299da03c9bf05c3b2dfc7f67bbd..739604f88813757c2bcc0166f0cda035b662ffb9 100644 (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
index fc770fe7f55f31be13c90342cb8c5fe8da0a8218..68eeec84efc90a26784e1ed22a68727a55e0eb70 100644 (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.
index 412c5e63b9ae41c81c6795bd3d118ed24fc1bc66..01e4ffc269faac74af4e09197ccfc913c0952ce1 100644 (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();
 
diff --git a/include/wx/msgout.h b/include/wx/msgout.h
new file mode 100755 (executable)
index 0000000..2576f19
--- /dev/null
@@ -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_
index 665e19c19a6d91ae52db5cc70facd489e49043b0..1018cbae7c58828f3002f4e3445b59068f1911e0 100644 (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);
 
index 5d8a6f374ca2ad7b4cbe213e91651e36f239c6b1..1c74dfdb5ecdb3ad65d7f0aff6da1f6ee4dfba32 100644 (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]
-                 << wxString(_T(' '), lenMax - len) << _T('\t')
-                 << descOptions[n]
-                 << _T('\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;
 }
 
 // ----------------------------------------------------------------------------
index 41b3d29330f87cd820ffa60a49845aff2794fe44..bdbed9efd0b3525d896c293d602e465b06e4f854 100644 (file)
@@ -109,6 +109,7 @@ bool WXDLLEXPORT wxInitialize()
         return FALSE;
     }
 
+    wxTheApp->DoInit();
     gs_nInitCount++;
 
     return TRUE;
diff --git a/src/common/msgout.cpp b/src/common/msgout.cpp
new file mode 100755 (executable)
index 0000000..c677a6b
--- /dev/null
@@ -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