/[svn]/qsampler/trunk/src/qsamplerMessages.cpp
ViewVC logotype

Contents of /qsampler/trunk/src/qsamplerMessages.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1739 - (show annotations) (download)
Wed May 14 17:37:45 2008 UTC (15 years, 11 months ago) by capela
File size: 8469 byte(s)
- Messages file logging makes its first long overdue appearance,
  with user configurable settings in View/Options.../Server/Logging.

1 // qsamplerMessages.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2008, rncbc aka Rui Nuno Capela. All rights reserved.
5 Copyright (C) 2007, Christian Schoenebeck
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 *****************************************************************************/
22
23 #include "qsamplerAbout.h"
24 #include "qsamplerMessages.h"
25
26 #include <QSocketNotifier>
27
28 #include <QFile>
29 #include <QTextEdit>
30 #include <QTextCursor>
31 #include <QTextStream>
32 #include <QTextBlock>
33 #include <QScrollBar>
34 #include <QDateTime>
35 #include <QIcon>
36
37 #if !defined(WIN32)
38 #include <unistd.h>
39 #endif
40
41
42 namespace QSampler {
43
44 // The default maximum number of message lines.
45 #define QSAMPLER_MESSAGES_MAXLINES 1000
46
47 // Notification pipe descriptors
48 #define QSAMPLER_MESSAGES_FDNIL -1
49 #define QSAMPLER_MESSAGES_FDREAD 0
50 #define QSAMPLER_MESSAGES_FDWRITE 1
51
52 //-------------------------------------------------------------------------
53 // QSampler::Messages - Messages log dockable window.
54 //
55
56 // Constructor.
57 Messages::Messages ( QWidget *pParent )
58 : QDockWidget(pParent)
59 {
60 // Surely a name is crucial (e.g.for storing geometry settings)
61 QDockWidget::setObjectName("qsamplerMessages");
62
63 // Intialize stdout capture stuff.
64 m_pStdoutNotifier = NULL;
65 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
66 m_fdStdout[QSAMPLER_MESSAGES_FDWRITE] = QSAMPLER_MESSAGES_FDNIL;
67
68 // Create local text view widget.
69 m_pMessagesTextView = new QTextEdit(this);
70 // QFont font(m_pMessagesTextView->font());
71 // font.setFamily("Fixed");
72 // m_pMessagesTextView->setFont(font);
73 m_pMessagesTextView->setLineWrapMode(QTextEdit::NoWrap);
74 m_pMessagesTextView->setReadOnly(true);
75 m_pMessagesTextView->setUndoRedoEnabled(false);
76 // m_pMessagesTextView->setTextFormat(Qt::LogText);
77
78 // Initialize default message limit.
79 m_iMessagesLines = 0;
80 setMessagesLimit(QSAMPLER_MESSAGES_MAXLINES);
81
82 m_pMessagesLog = NULL;
83
84 // Prepare the dockable window stuff.
85 QDockWidget::setWidget(m_pMessagesTextView);
86 QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
87 QDockWidget::setAllowedAreas(
88 Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
89 // Some specialties to this kind of dock window...
90 QDockWidget::setMinimumHeight(120);
91
92 // Finally set the default caption and tooltip.
93 const QString& sCaption = tr("Messages");
94 QDockWidget::setWindowTitle(sCaption);
95 // QDockWidget::setWindowIcon(QIcon(":/icons/qsamplerMessages.png"));
96 QDockWidget::setToolTip(sCaption);
97 }
98
99
100 // Destructor.
101 Messages::~Messages (void)
102 {
103 // Turn off and close logging.
104 setLogging(false);
105
106 // No more notifications.
107 if (m_pStdoutNotifier)
108 delete m_pStdoutNotifier;
109
110 // No need to delete child widgets, Qt does it all for us.
111 }
112
113
114 void Messages::showEvent ( QShowEvent *pEvent )
115 {
116 QDockWidget::showEvent(pEvent);
117 emit visibilityChanged(isVisible());
118 }
119
120
121 // Own stdout/stderr socket notifier slot.
122 void Messages::stdoutNotify ( int fd )
123 {
124 #if !defined(WIN32)
125 char achBuffer[1024];
126 int cchBuffer = ::read(fd, achBuffer, sizeof(achBuffer) - 1);
127 if (cchBuffer > 0) {
128 achBuffer[cchBuffer] = (char) 0;
129 appendStdoutBuffer(achBuffer);
130 }
131 #endif
132 }
133
134
135 // Stdout buffer handler -- now splitted by complete new-lines...
136 void Messages::appendStdoutBuffer ( const QString& s )
137 {
138 m_sStdoutBuffer.append(s);
139
140 int iLength = m_sStdoutBuffer.lastIndexOf('\n');
141 if (iLength > 0) {
142 QString sTemp = m_sStdoutBuffer.left(iLength);
143 m_sStdoutBuffer.remove(0, iLength + 1);
144 QStringList list = sTemp.split('\n');
145 QStringListIterator iter(list);
146 while (iter.hasNext())
147 appendMessagesText(iter.next());
148 }
149 }
150
151
152 // Stdout flusher -- show up any unfinished line...
153 void Messages::flushStdoutBuffer (void)
154 {
155 if (!m_sStdoutBuffer.isEmpty()) {
156 appendMessagesText(m_sStdoutBuffer);
157 m_sStdoutBuffer.truncate(0);
158 }
159 }
160
161
162 // Stdout capture accessors.
163 bool Messages::isCaptureEnabled (void)
164 {
165 return (bool) (m_pStdoutNotifier != NULL);
166 }
167
168 void Messages::setCaptureEnabled ( bool bCapture )
169 {
170 // Flush current buffer.
171 flushStdoutBuffer();
172
173 #if !defined(WIN32)
174 // Destroy if already enabled.
175 if (!bCapture && m_pStdoutNotifier) {
176 delete m_pStdoutNotifier;
177 m_pStdoutNotifier = NULL;
178 // Close the notification pipes.
179 if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
180 ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
181 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
182 }
183 if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
184 ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
185 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
186 }
187 }
188 // Are we going to make up the capture?
189 if (bCapture && m_pStdoutNotifier == NULL && ::pipe(m_fdStdout) == 0) {
190 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDOUT_FILENO);
191 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDERR_FILENO);
192 m_pStdoutNotifier = new QSocketNotifier(
193 m_fdStdout[QSAMPLER_MESSAGES_FDREAD], QSocketNotifier::Read, this);
194 QObject::connect(m_pStdoutNotifier,
195 SIGNAL(activated(int)),
196 SLOT(stdoutNotify(int)));
197 }
198 #endif
199 }
200
201
202 // Message font accessors.
203 QFont Messages::messagesFont (void)
204 {
205 return m_pMessagesTextView->font();
206 }
207
208 void Messages::setMessagesFont ( const QFont& font )
209 {
210 m_pMessagesTextView->setFont(font);
211 }
212
213
214 // Maximum number of message lines accessors.
215 int Messages::messagesLimit (void)
216 {
217 return m_iMessagesLimit;
218 }
219
220 void Messages::setMessagesLimit ( int iMessagesLimit )
221 {
222 m_iMessagesLimit = iMessagesLimit;
223 m_iMessagesHigh = iMessagesLimit + (iMessagesLimit / 3);
224 }
225
226 // Messages logging stuff.
227 bool Messages::isLogging (void) const
228 {
229 return (m_pMessagesLog != NULL);
230 }
231
232 void Messages::setLogging ( bool bEnabled, const QString& sFilename )
233 {
234 if (m_pMessagesLog) {
235 appendMessages(tr("Logging stopped --- %1 ---")
236 .arg(QDateTime::currentDateTime().toString()));
237 m_pMessagesLog->close();
238 delete m_pMessagesLog;
239 m_pMessagesLog = NULL;
240 }
241
242 if (bEnabled) {
243 m_pMessagesLog = new QFile(sFilename);
244 if (m_pMessagesLog->open(QIODevice::Text | QIODevice::Append)) {
245 appendMessages(tr("Logging started --- %1 ---")
246 .arg(QDateTime::currentDateTime().toString()));
247 } else {
248 delete m_pMessagesLog;
249 m_pMessagesLog = NULL;
250 }
251 }
252 }
253
254
255 // Messages log output method.
256 void Messages::appendMessagesLog ( const QString& s )
257 {
258 if (m_pMessagesLog) {
259 QTextStream(m_pMessagesLog) << s << endl;
260 m_pMessagesLog->flush();
261 }
262 }
263
264 // Messages widget output method.
265 void Messages::appendMessagesLine ( const QString& s )
266 {
267 // Check for message line limit...
268 if (m_iMessagesLines > m_iMessagesHigh) {
269 m_pMessagesTextView->setUpdatesEnabled(false);
270 QTextCursor textCursor(m_pMessagesTextView->document()->begin());
271 while (m_iMessagesLines > m_iMessagesLimit) {
272 // Move cursor extending selection
273 // from start to next line-block...
274 textCursor.movePosition(
275 QTextCursor::NextBlock, QTextCursor::KeepAnchor);
276 m_iMessagesLines--;
277 }
278 // Remove the excessive line-blocks...
279 textCursor.removeSelectedText();
280 m_pMessagesTextView->setUpdatesEnabled(true);
281 }
282
283 m_pMessagesTextView->append(s);
284 m_iMessagesLines++;
285 }
286
287
288 // The main utility methods.
289 void Messages::appendMessages ( const QString& s )
290 {
291 appendMessagesColor(s, "#999999");
292 }
293
294 void Messages::appendMessagesColor ( const QString& s, const QString &c )
295 {
296 QString sText = QTime::currentTime().toString("hh:mm:ss.zzz") + ' ' + s;
297 appendMessagesLine("<font color=\"" + c + "\">" + sText + "</font>");
298 appendMessagesLog(sText);
299 }
300
301 void Messages::appendMessagesText ( const QString& s )
302 {
303 appendMessagesLine(s);
304 appendMessagesLog(s);
305 }
306
307
308 // History reset.
309 void Messages::clear (void)
310 {
311 m_iMessagesLines = 0;
312 m_pMessagesTextView->clear();
313 }
314
315 } // namespace QSampler
316
317
318 // end of qsamplerMessages.cpp

  ViewVC Help
Powered by ViewVC