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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1738 - (show annotations) (download)
Wed May 14 15:24:22 2008 UTC (15 years, 11 months ago) by capela
File size: 8544 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 setLogging(false);
104
105 // No more notifications.
106 if (m_pStdoutNotifier)
107 delete m_pStdoutNotifier;
108
109 // No need to delete child widgets, Qt does it all for us.
110 }
111
112
113 void Messages::showEvent ( QShowEvent *pEvent )
114 {
115 QDockWidget::showEvent(pEvent);
116 emit visibilityChanged(isVisible());
117 }
118
119
120 // Own stdout/stderr socket notifier slot.
121 void Messages::stdoutNotify ( int fd )
122 {
123 #if !defined(WIN32)
124 char achBuffer[1024];
125 int cchBuffer = ::read(fd, achBuffer, sizeof(achBuffer) - 1);
126 if (cchBuffer > 0) {
127 achBuffer[cchBuffer] = (char) 0;
128 appendStdoutBuffer(achBuffer);
129 }
130 #endif
131 }
132
133
134 // Stdout buffer handler -- now splitted by complete new-lines...
135 void Messages::appendStdoutBuffer ( const QString& s )
136 {
137 m_sStdoutBuffer.append(s);
138
139 int iLength = m_sStdoutBuffer.lastIndexOf('\n');
140 if (iLength > 0) {
141 QString sTemp = m_sStdoutBuffer.left(iLength);
142 m_sStdoutBuffer.remove(0, iLength + 1);
143 QStringList list = sTemp.split('\n');
144 QStringListIterator iter(list);
145 while (iter.hasNext())
146 appendMessagesText(iter.next());
147 }
148 }
149
150
151 // Stdout flusher -- show up any unfinished line...
152 void Messages::flushStdoutBuffer (void)
153 {
154 if (!m_sStdoutBuffer.isEmpty()) {
155 appendMessagesText(m_sStdoutBuffer);
156 m_sStdoutBuffer.truncate(0);
157 }
158 }
159
160
161 // Stdout capture accessors.
162 bool Messages::isCaptureEnabled (void)
163 {
164 return (bool) (m_pStdoutNotifier != NULL);
165 }
166
167 void Messages::setCaptureEnabled ( bool bCapture )
168 {
169 // Flush current buffer.
170 flushStdoutBuffer();
171
172 #if !defined(WIN32)
173 // Destroy if already enabled.
174 if (!bCapture && m_pStdoutNotifier) {
175 delete m_pStdoutNotifier;
176 m_pStdoutNotifier = NULL;
177 // Close the notification pipes.
178 if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
179 ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
180 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
181 }
182 if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
183 ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
184 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
185 }
186 }
187 // Are we going to make up the capture?
188 if (bCapture && m_pStdoutNotifier == NULL && ::pipe(m_fdStdout) == 0) {
189 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDOUT_FILENO);
190 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDERR_FILENO);
191 m_pStdoutNotifier = new QSocketNotifier(
192 m_fdStdout[QSAMPLER_MESSAGES_FDREAD], QSocketNotifier::Read, this);
193 QObject::connect(m_pStdoutNotifier,
194 SIGNAL(activated(int)),
195 SLOT(stdoutNotify(int)));
196 }
197 #endif
198 }
199
200
201 // Message font accessors.
202 QFont Messages::messagesFont (void)
203 {
204 return m_pMessagesTextView->font();
205 }
206
207 void Messages::setMessagesFont ( const QFont& font )
208 {
209 m_pMessagesTextView->setFont(font);
210 }
211
212
213 // Maximum number of message lines accessors.
214 int Messages::messagesLimit (void)
215 {
216 return m_iMessagesLimit;
217 }
218
219 void Messages::setMessagesLimit ( int iMessagesLimit )
220 {
221 m_iMessagesLimit = iMessagesLimit;
222 m_iMessagesHigh = iMessagesLimit + (iMessagesLimit / 3);
223 }
224
225 // Messages logging stuff.
226 bool Messages::isLogging (void) const
227 {
228 return (m_pMessagesLog != NULL);
229 }
230
231 void Messages::setLogging ( bool bEnabled, const QString& sFilename )
232 {
233 if (m_pMessagesLog) {
234 appendMessages(tr("Logging stopped --- %1 ---")
235 .arg(QDateTime::currentDateTime().toString()));
236 m_pMessagesLog->close();
237 delete m_pMessagesLog;
238 m_pMessagesLog = NULL;
239 }
240
241 if (bEnabled) {
242 m_pMessagesLog = new QFile(sFilename);
243 if (m_pMessagesLog->open(QIODevice::Text | QIODevice::Append)) {
244 appendMessages(tr("Logging started --- %1 ---")
245 .arg(QDateTime::currentDateTime().toString()));
246 } else {
247 delete m_pMessagesLog;
248 m_pMessagesLog = NULL;
249 }
250 }
251 }
252
253
254 // Messages log output method.
255 void Messages::appendMessagesLog ( const QString& s )
256 {
257 if (m_pMessagesLog) {
258 QTextStream(m_pMessagesLog) << s << endl;
259 m_pMessagesLog->flush();
260 }
261 }
262
263 // Messages widget output method.
264 void Messages::appendMessagesLine ( const QString& s )
265 {
266 // Check for message line limit...
267 if (m_iMessagesLines > m_iMessagesHigh) {
268 m_pMessagesTextView->setUpdatesEnabled(false);
269 QTextCursor textCursor(m_pMessagesTextView->document()->begin());
270 while (m_iMessagesLines > m_iMessagesLimit) {
271 // Move cursor extending selection
272 // from start to next line-block...
273 textCursor.movePosition(
274 QTextCursor::NextBlock, QTextCursor::KeepAnchor);
275 m_iMessagesLines--;
276 }
277 // Remove the excessive line-blocks...
278 textCursor.removeSelectedText();
279 m_pMessagesTextView->setUpdatesEnabled(true);
280 }
281
282 m_pMessagesTextView->append(s);
283 m_iMessagesLines++;
284 }
285
286
287 // The main utility methods.
288 void Messages::appendMessages ( const QString& s )
289 {
290 appendMessagesColor(s, "#999999");
291 }
292
293 void Messages::appendMessagesColor ( const QString& s, const QString &c )
294 {
295 QString sText = QTime::currentTime().toString("hh:mm:ss.zzz") + ' ' + s;
296
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