]> git.saurik.com Git - wxWidgets.git/blob - include/wx/log.h
Added time.h so it would compile
[wxWidgets.git] / include / wx / log.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: log.h
3 // Purpose: Assorted wxLogXXX functions, and wxLog (sink for logs)
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 29/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_LOG_H_
13 #define _WX_LOG_H_
14
15 #ifdef __GNUG__
16 #pragma interface "log.h"
17 #endif
18
19 #include <wx/dynarray.h>
20 #include <time.h>
21
22 // ----------------------------------------------------------------------------
23 // constants
24 // ----------------------------------------------------------------------------
25
26 // different standard log levels (you may also define your own)
27 enum
28 {
29 wxLOG_FatalError, // program can't continue, abort immediately
30 wxLOG_Error, // a serious error, user must be informed about it
31 wxLOG_Warning, // user is normally informed about it but may be ignored
32 wxLOG_Message, // normal message (i.e. normal output of a non GUI app)
33 wxLOG_Info, // informational message (a.k.a. 'Verbose')
34 wxLOG_Status, // informational: might go to the status line of GUI app
35 wxLOG_Debug, // never shown to the user, disabled in release mode
36 wxLOG_Trace, // trace messages are also only enabled in debug mode
37 wxLOG_Progress, // used for progress indicator (not yet)
38 wxLOG_User = 100 // user defined levels start here
39 };
40
41 // symbolic trace masks - wxLogTrace("foo", "some trace message...") will be
42 // discarded unless the string "foo" has been added to the list of allowed
43 // ones with AddTraceMask()
44
45 #define wxTRACE_MemAlloc "memalloc" // trace memory allocation (new/delete)
46 #define wxTRACE_Messages "messages" // trace window messages/X callbacks
47 #define wxTRACE_ResAlloc "resalloc" // trace GDI resource allocation
48 #define wxTRACE_RefCount "refcount" // trace various ref counting operations
49
50 #ifdef __WXMSW__
51 #define wxTRACE_OleCalls "ole" // OLE interface calls
52 #endif
53
54 // the trace masks have been superceded by symbolic trace constants, they're
55 // for compatibility only andwill be removed soon - do NOT use them
56
57 // meaning of different bits of the trace mask (which allows selectively
58 // enable/disable some trace messages)
59 #define wxTraceMemAlloc 0x0001 // trace memory allocation (new/delete)
60 #define wxTraceMessages 0x0002 // trace window messages/X callbacks
61 #define wxTraceResAlloc 0x0004 // trace GDI resource allocation
62 #define wxTraceRefCount 0x0008 // trace various ref counting operations
63
64 #ifdef __WXMSW__
65 #define wxTraceOleCalls 0x0100 // OLE interface calls
66 #endif
67
68 typedef unsigned long wxTraceMask;
69 typedef unsigned long wxLogLevel;
70
71 // ----------------------------------------------------------------------------
72 // forward declarations
73 // ----------------------------------------------------------------------------
74
75 class WXDLLEXPORT wxTextCtrl;
76 class WXDLLEXPORT wxLogFrame;
77 class WXDLLEXPORT wxFrame;
78
79 #if wxUSE_IOSTREAMH
80 // N.B. BC++ doesn't have istream.h, ostream.h
81 # include <iostream.h>
82 #else
83 # include <ostream>
84 # if defined(__VISUALC__) || defined(__MWERKS__)
85 using namespace std;
86 # endif
87 #endif
88
89 // ----------------------------------------------------------------------------
90 // derive from this class to redirect (or suppress, or ...) log messages
91 // normally, only a single instance of this class exists but it's not enforced
92 // ----------------------------------------------------------------------------
93
94 class WXDLLEXPORT wxLog
95 {
96 public:
97 // ctor
98 wxLog();
99
100 // these functions allow to completely disable all log messages
101 // is logging disabled now?
102 static bool IsEnabled() { return ms_doLog; }
103 // change the flag state, return the previous one
104 static bool EnableLogging(bool doIt = TRUE)
105 { bool doLogOld = ms_doLog; ms_doLog = doIt; return doLogOld; }
106
107 // static sink function - see DoLog() for function to overload in the
108 // derived classes
109 static void OnLog(wxLogLevel level, const char *szString, time_t t)
110 {
111 if ( IsEnabled() ) {
112 wxLog *pLogger = GetActiveTarget();
113 if ( pLogger )
114 pLogger->DoLog(level, szString, t);
115 }
116 }
117
118 // message buffering
119 // flush shows all messages if they're not logged immediately (FILE
120 // and iostream logs don't need it, but wxGuiLog does to avoid showing
121 // 17 modal dialogs one after another)
122 virtual void Flush();
123 // call to Flush() may be optimized: call it only if this function
124 // returns true (although Flush() also returns immediately if there is
125 // no messages, this functions is more efficient because inline)
126 bool HasPendingMessages() const { return m_bHasMessages; }
127
128 // only one sink is active at each moment
129 // get current log target, will call wxApp::CreateLogTarget() to
130 // create one if none exists
131 static wxLog *GetActiveTarget();
132 // change log target, pLogger may be NULL
133 static wxLog *SetActiveTarget(wxLog *pLogger);
134
135 // functions controlling the default wxLog behaviour
136 // verbose mode is activated by standard command-line '-verbose'
137 // option
138 void SetVerbose(bool bVerbose = TRUE) { m_bVerbose = bVerbose; }
139 // should GetActiveTarget() try to create a new log object if the
140 // current is NULL?
141 static void DontCreateOnDemand() { ms_bAutoCreate = FALSE; }
142
143 // trace mask (see wxTraceXXX constants for details)
144 static void SetTraceMask(wxTraceMask ulMask) { ms_ulTraceMask = ulMask; }
145 // add string trace mask
146 static void AddTraceMask(const wxString& str) { ms_aTraceMasks.Add(str); }
147 // add string trace mask
148 static void RemoveTraceMask(const wxString& str);
149
150 // accessors
151 // gets the verbose status
152 bool GetVerbose() const { return m_bVerbose; }
153 // get trace mask
154 static wxTraceMask GetTraceMask() { return ms_ulTraceMask; }
155 // is this trace mask in the list?
156 static bool IsAllowedTraceMask(const char *mask)
157 { return ms_aTraceMasks.Index(mask) != wxNOT_FOUND; }
158
159 // make dtor virtual for all derived classes
160 virtual ~wxLog() { }
161
162 protected:
163 bool m_bHasMessages; // any messages in the queue?
164 bool m_bVerbose; // FALSE => ignore LogInfo messages
165
166 // the logging functions that can be overriden
167 // default DoLog() prepends the time stamp and a prefix corresponding
168 // to the message to szString and then passes it to DoLogString()
169 virtual void DoLog(wxLogLevel level, const char *szString, time_t t);
170 // default DoLogString does nothing but is not pure virtual because if
171 // you override DoLog() you might not need it at all
172 virtual void DoLogString(const char *szString, time_t t);
173
174 private:
175 // static variables
176 // ----------------
177
178 static wxLog *ms_pLogger; // currently active log sink
179 static bool ms_doLog; // FALSE => all logging disabled
180 static bool ms_bAutoCreate; // create new log targets on demand?
181
182 static wxTraceMask ms_ulTraceMask; // controls wxLogTrace behaviour
183 static wxArrayString ms_aTraceMasks; // more powerful filter for wxLogTrace
184 };
185
186 // ----------------------------------------------------------------------------
187 // "trivial" derivations of wxLog
188 // ----------------------------------------------------------------------------
189
190 // log everything to a "FILE *", stderr by default
191 class WXDLLEXPORT wxLogStderr : public wxLog
192 {
193 public:
194 // redirect log output to a FILE
195 wxLogStderr(FILE *fp = (FILE *) NULL);
196
197 private:
198 // implement sink function
199 virtual void DoLogString(const char *szString, time_t t);
200
201 FILE *m_fp;
202 };
203
204 #if wxUSE_STD_IOSTREAM
205 // log everything to an "ostream", cerr by default
206 class WXDLLEXPORT wxLogStream : public wxLog
207 {
208 public:
209 // redirect log output to an ostream
210 wxLogStream(ostream *ostr = (ostream *) NULL);
211
212 protected:
213 // implement sink function
214 virtual void DoLogString(const char *szString, time_t t);
215
216 // using ptr here to avoid including <iostream.h> from this file
217 ostream *m_ostr;
218 };
219 #endif
220
221 #ifndef wxUSE_NOGUI
222
223 #if wxUSE_STD_IOSTREAM
224 // log everything to a text window (GUI only of course)
225 class WXDLLEXPORT wxLogTextCtrl : public wxLogStream
226 {
227 public:
228 // we just create an ostream from wxTextCtrl and use it in base class
229 wxLogTextCtrl(wxTextCtrl *pTextCtrl);
230 ~wxLogTextCtrl();
231 };
232 #endif
233
234 // ----------------------------------------------------------------------------
235 // GUI log target, the default one for wxWindows programs
236 // ----------------------------------------------------------------------------
237 class WXDLLEXPORT wxLogGui : public wxLog
238 {
239 public:
240 // ctor
241 wxLogGui();
242
243 // show all messages that were logged since the last Flush()
244 virtual void Flush();
245
246 protected:
247 virtual void DoLog(wxLogLevel level, const char *szString, time_t t);
248
249 // empty everything
250 void Clear();
251
252 wxArrayString m_aMessages;
253 wxArrayLong m_aTimes;
254 bool m_bErrors, // do we have any errors?
255 m_bWarnings; // any warnings?
256 };
257
258 // ----------------------------------------------------------------------------
259 // (background) log window: this class forwards all log messages to the log
260 // target which was active when it was instantiated, but also collects them
261 // to the log window. This window has it's own menu which allows the user to
262 // close it, clear the log contents or save it to the file.
263 // ----------------------------------------------------------------------------
264 class WXDLLEXPORT wxLogWindow : public wxLog
265 {
266 public:
267 wxLogWindow(wxFrame *pParent, // the parent frame (can be NULL)
268 const char *szTitle, // the title of the frame
269 bool bShow = TRUE, // show window immediately?
270 bool bPassToOld = TRUE); // pass log messages to the old target?
271 ~wxLogWindow();
272
273 // window operations
274 // show/hide the log window
275 void Show(bool bShow = TRUE);
276 // retrieve the pointer to the frame
277 wxFrame *GetFrame() const;
278
279 // accessors
280 // the previous log target (may be NULL)
281 wxLog *GetOldLog() const { return m_pOldLog; }
282 // are we passing the messages to the previous log target?
283 bool IsPassingMessages() const { return m_bPassMessages; }
284
285 // we can pass the messages to the previous log target (we're in this mode by
286 // default: we collect all messages in the window, but also let the default
287 // processing take place)
288 void PassMessages(bool bDoPass) { m_bPassMessages = bDoPass; }
289
290 // base class virtuals
291 // we don't need it ourselves, but we pass it to the previous logger
292 virtual void Flush();
293
294 // overridables
295 // called immediately after the log frame creation allowing for
296 // any extra initializations
297 virtual void OnFrameCreate(wxFrame *frame);
298 // called right before the log frame is going to be deleted
299 virtual void OnFrameDelete(wxFrame *frame);
300
301 protected:
302 virtual void DoLog(wxLogLevel level, const char *szString, time_t t);
303 virtual void DoLogString(const char *szString, time_t t);
304
305 private:
306 bool m_bPassMessages; // pass messages to m_pOldLog?
307 wxLog *m_pOldLog; // previous log target
308 wxLogFrame *m_pLogFrame; // the log frame
309 };
310
311 #endif // wxUSE_NOGUI
312
313 // ----------------------------------------------------------------------------
314 // /dev/null log target: suppress logging until this object goes out of scope
315 // ----------------------------------------------------------------------------
316
317 // example of usage:
318 /*
319 void Foo() {
320 wxFile file;
321
322 // wxFile.Open() normally complains if file can't be opened, we don't want it
323 wxLogNull logNo;
324 if ( !file.Open("bar") )
325 ... process error ourselves ...
326
327 // ~wxLogNull called, old log sink restored
328 }
329 */
330 class WXDLLEXPORT wxLogNull
331 {
332 public:
333 wxLogNull() { m_flagOld = wxLog::EnableLogging(FALSE); }
334 ~wxLogNull() { (void)wxLog::EnableLogging(m_flagOld); }
335
336 private:
337 bool m_flagOld; // the previous value of the wxLog::ms_doLog
338 };
339
340 // ============================================================================
341 // global functions
342 // ============================================================================
343
344 // ----------------------------------------------------------------------------
345 // Log functions should be used by application instead of stdio, iostream &c
346 // for log messages for easy redirection
347 // ----------------------------------------------------------------------------
348
349 // define wxLog<level>
350 // -------------------
351
352 #define DECLARE_LOG_FUNCTION(level) \
353 extern void WXDLLEXPORT wxLog##level(const char *szFormat, ...)
354 #define DECLARE_LOG_FUNCTION2(level, arg1) \
355 extern void WXDLLEXPORT wxLog##level(arg1, const char *szFormat, ...)
356
357 // a generic function for all levels (level is passes as parameter)
358 DECLARE_LOG_FUNCTION2(Generic, wxLogLevel level);
359
360 // one function per each level
361 DECLARE_LOG_FUNCTION(FatalError);
362 DECLARE_LOG_FUNCTION(Error);
363 DECLARE_LOG_FUNCTION(Warning);
364 DECLARE_LOG_FUNCTION(Message);
365 DECLARE_LOG_FUNCTION(Info);
366 DECLARE_LOG_FUNCTION(Verbose);
367
368 // this function sends the log message to the status line of the top level
369 // application frame, if any
370 DECLARE_LOG_FUNCTION(Status);
371
372 // this one is the same as previous except that it allows to explicitly
373 // specify the frame to which the output should go
374 DECLARE_LOG_FUNCTION2(Status, wxFrame *pFrame);
375
376 // additional one: as wxLogError, but also logs last system call error code
377 // and the corresponding error message if available
378 DECLARE_LOG_FUNCTION(SysError);
379
380 // and another one which also takes the error code (for those broken APIs
381 // that don't set the errno (like registry APIs in Win32))
382 DECLARE_LOG_FUNCTION2(SysError, long lErrCode);
383
384 // debug functions do nothing in release mode
385 #ifdef __WXDEBUG__
386 DECLARE_LOG_FUNCTION(Debug);
387
388 // first king of LogTrace is uncoditional: it doesn't check the level,
389 DECLARE_LOG_FUNCTION(Trace);
390
391 // this second version will only log the message if the mask had been
392 // added to the list of masks with AddTraceMask()
393 DECLARE_LOG_FUNCTION2(Trace, const char *mask);
394
395 // the last one does nothing if all of level bits are not set
396 // in wxLog::GetActive()->GetTraceMask() - it's deprecated in favour of
397 // string identifiers
398 DECLARE_LOG_FUNCTION2(Trace, wxTraceMask mask);
399 #else //!debug
400 // these functions do nothing in release builds
401 inline void wxLogDebug(const char *, ...) { }
402 inline void wxLogTrace(const char *, ...) { }
403 inline void wxLogTrace(wxTraceMask, const char *, ...) { }
404 inline void wxLogTrace(const char *, const char *, ...) { }
405 #endif
406
407
408 // are we in 'verbose' mode?
409 // (note that it's often handy to change this var manually from the
410 // debugger, thus enabling/disabling verbose reporting for some
411 // parts of the program only)
412 WXDLLEXPORT_DATA(extern bool) g_bVerbose;
413
414 // ----------------------------------------------------------------------------
415 // get error code/error message from system in a portable way
416 // ----------------------------------------------------------------------------
417
418 // return the last system error code
419 WXDLLEXPORT unsigned long wxSysErrorCode();
420 // return the error message for given (or last if 0) error code
421 WXDLLEXPORT const char* wxSysErrorMsg(unsigned long nErrCode = 0);
422
423 // ----------------------------------------------------------------------------
424 // debug only logging functions: use them with API name and error code
425 // ----------------------------------------------------------------------------
426
427 #ifdef __WXDEBUG__
428 #define wxLogApiError(api, rc) \
429 wxLogDebug("At %s(%d) '%s' failed with error %lx (%s).", \
430 __FILE__, __LINE__, api, \
431 rc, wxSysErrorMsg(rc))
432 #define wxLogLastError(api) wxLogApiError(api, wxSysErrorCode())
433 #else //!debug
434 inline void wxLogApiError(const char *, long) { }
435 inline void wxLogLastError(const char *) { }
436 #endif //debug/!debug
437
438 #endif // _WX_LOG_H_