00001 #ifndef QDEBUGSTREAM_H
00002 #define QDEBUGSTREAM_H
00003
00004
00005
00006
00007
00008 #include <iostream>
00009 #include <streambuf>
00010 #include <string>
00011 #include <QMutex>
00012 #include <QMutexLocker>
00013 #include <QString>
00014 #include <QMainWindow>
00015 #include <QApplication>
00016
00017 #include "qtextedit.h"
00018
00019 #include <QCustomEvent>
00020
00021
00022 const QEvent::Type DEBUG_STREAM_EVENT = static_cast<QEvent::Type>(QEvent::User + 1);
00023
00024
00025 class DebugStreamEvent : public QEvent
00026 {
00027 public:
00028 DebugStreamEvent(const QString& outputText):
00029 QEvent(DEBUG_STREAM_EVENT),
00030 m_outputText(outputText)
00031 {
00032 }
00033
00034 QString getOutputText() const
00035 {
00036 return m_outputText;
00037 }
00038
00039 private:
00040 QString m_outputText;
00041 };
00042
00043 class QDebugStream : public std::basic_streambuf<char>
00044 {
00045 public:
00046 QDebugStream(std::ostream &stream, QMainWindow* mainWindow) : m_stream(stream)
00047 {
00048 m_mainWindow = mainWindow;
00049 m_old_buf = stream.rdbuf();
00050 stream.rdbuf(this);
00051 }
00052 ~QDebugStream()
00053 {
00054
00055 QMutexLocker locker(&m_mutex);
00056 if (!m_string.empty()) {
00057
00058 QString appendString = m_string.c_str();
00059 QApplication::postEvent(m_mainWindow, new DebugStreamEvent(appendString));
00060
00061 }
00062
00063 m_stream.rdbuf(m_old_buf);
00064 }
00065
00066 protected:
00067 virtual int_type overflow(int_type v)
00068 {
00069 QMutexLocker locker(&m_mutex);
00070 if (v == '\n')
00071 {
00072 QString appendString = m_string.c_str();
00073
00074 QApplication::postEvent(m_mainWindow, new DebugStreamEvent(appendString));
00075
00076
00077
00078
00079
00080 m_string.erase(m_string.begin(), m_string.end());
00081 }
00082 else
00083 m_string += v;
00084
00085 return v;
00086 }
00087
00088 virtual std::streamsize xsputn(const char *p, std::streamsize n)
00089 {
00090 QMutexLocker locker(&m_mutex);
00091
00092 m_string.append(p, p + n);
00093
00094 std::string::size_type pos = 0;
00095 while (pos != std::string::npos)
00096 {
00097 pos = m_string.find('\n');
00098 if (pos != std::string::npos)
00099 {
00100 std::string tmp(m_string.begin(), m_string.begin() + pos);
00101 QString appendString = tmp.c_str();
00102 QApplication::postEvent(m_mainWindow, new DebugStreamEvent(appendString));
00103
00104 qDebug() << appendString;
00105
00106
00107
00108
00109
00110
00111 m_string.erase(m_string.begin(), m_string.begin() + pos + 1);
00112 }
00113 }
00114
00115 return n;
00116 }
00117
00118 private:
00119 std::ostream &m_stream;
00120 std::streambuf *m_old_buf;
00121 std::string m_string;
00122 QMainWindow* m_mainWindow;
00123 QMutex m_mutex;
00124 };
00125
00126 #endif // QDEBUGSTREAM_H