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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2583 - (show annotations) (download)
Fri May 30 21:03:25 2014 UTC (9 years, 10 months ago) by capela
File size: 8170 byte(s)
- Remove messages stdout/err capture redundant code.
1 // qsamplerMessages.cpp
2 //
3 /****************************************************************************
4 Copyright (C) 2004-2014, 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 //-------------------------------------------------------------------------
54 // QSampler::Messages - Messages log dockable window.
55 //
56
57 // Constructor.
58 Messages::Messages ( QWidget *pParent )
59 : QDockWidget(pParent)
60 {
61 // Surely a name is crucial (e.g.for storing geometry settings)
62 QDockWidget::setObjectName("qsamplerMessages");
63
64 // Intialize stdout capture stuff.
65 m_pStdoutNotifier = NULL;
66 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
67 m_fdStdout[QSAMPLER_MESSAGES_FDWRITE] = QSAMPLER_MESSAGES_FDNIL;
68
69 // Create local text view widget.
70 m_pMessagesTextView = new QTextEdit(this);
71 // QFont font(m_pMessagesTextView->font());
72 // font.setFamily("Fixed");
73 // m_pMessagesTextView->setFont(font);
74 m_pMessagesTextView->setLineWrapMode(QTextEdit::NoWrap);
75 m_pMessagesTextView->setReadOnly(true);
76 m_pMessagesTextView->setUndoRedoEnabled(false);
77 // m_pMessagesTextView->setTextFormat(Qt::LogText);
78
79 // Initialize default message limit.
80 m_iMessagesLines = 0;
81 setMessagesLimit(QSAMPLER_MESSAGES_MAXLINES);
82
83 m_pMessagesLog = NULL;
84
85 // Prepare the dockable window stuff.
86 QDockWidget::setWidget(m_pMessagesTextView);
87 QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
88 QDockWidget::setAllowedAreas(
89 Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
90 // Some specialties to this kind of dock window...
91 QDockWidget::setMinimumHeight(120);
92
93 // Finally set the default caption and tooltip.
94 const QString& sCaption = tr("Messages");
95 QDockWidget::setWindowTitle(sCaption);
96 // QDockWidget::setWindowIcon(QIcon(":/icons/qsamplerMessages.png"));
97 QDockWidget::setToolTip(sCaption);
98 }
99
100
101 // Destructor.
102 Messages::~Messages (void)
103 {
104 // Turn off and close logging.
105 setLogging(false);
106
107 // No more notifications.
108 if (m_pStdoutNotifier)
109 delete m_pStdoutNotifier;
110
111 // No need to delete child widgets, Qt does it all for us.
112 }
113
114
115 // Own stdout/stderr socket notifier slot.
116 void Messages::stdoutNotify ( int fd )
117 {
118 #if !defined(WIN32)
119 char achBuffer[1024];
120 const int cchBuffer = ::read(fd, achBuffer, sizeof(achBuffer) - 1);
121 if (cchBuffer > 0) {
122 achBuffer[cchBuffer] = (char) 0;
123 appendStdoutBuffer(achBuffer);
124 }
125 #endif
126 }
127
128
129 // Stdout buffer handler -- now splitted by complete new-lines...
130 void Messages::appendStdoutBuffer ( const QString& s )
131 {
132 m_sStdoutBuffer.append(s);
133
134 const int iLength = m_sStdoutBuffer.lastIndexOf('\n');
135 if (iLength > 0) {
136 const QString& sTemp = m_sStdoutBuffer.left(iLength);
137 m_sStdoutBuffer.remove(0, iLength + 1);
138 QStringList list = sTemp.split('\n');
139 QStringListIterator iter(list);
140 while (iter.hasNext())
141 appendMessagesText(iter.next());
142 }
143 }
144
145
146 // Stdout flusher -- show up any unfinished line...
147 void Messages::flushStdoutBuffer (void)
148 {
149 if (!m_sStdoutBuffer.isEmpty()) {
150 appendMessagesText(m_sStdoutBuffer);
151 m_sStdoutBuffer.truncate(0);
152 }
153 }
154
155
156 // Stdout capture accessors.
157 bool Messages::isCaptureEnabled (void)
158 {
159 return (m_pStdoutNotifier != NULL);
160 }
161
162 void Messages::setCaptureEnabled ( bool bCapture )
163 {
164 // Flush current buffer.
165 flushStdoutBuffer();
166
167 #if !defined(WIN32)
168 // Destroy if already enabled.
169 if (!bCapture && m_pStdoutNotifier) {
170 delete m_pStdoutNotifier;
171 m_pStdoutNotifier = NULL;
172 // Close the notification pipes.
173 if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
174 ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
175 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
176 }
177 }
178 // Are we going to make up the capture?
179 if (bCapture && m_pStdoutNotifier == NULL && ::pipe(m_fdStdout) == 0) {
180 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDOUT_FILENO);
181 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDERR_FILENO);
182 m_pStdoutNotifier = new QSocketNotifier(
183 m_fdStdout[QSAMPLER_MESSAGES_FDREAD], QSocketNotifier::Read, this);
184 QObject::connect(m_pStdoutNotifier,
185 SIGNAL(activated(int)),
186 SLOT(stdoutNotify(int)));
187 }
188 #endif
189 }
190
191
192 // Message font accessors.
193 QFont Messages::messagesFont (void)
194 {
195 return m_pMessagesTextView->font();
196 }
197
198 void Messages::setMessagesFont ( const QFont& font )
199 {
200 m_pMessagesTextView->setFont(font);
201 }
202
203
204 // Maximum number of message lines accessors.
205 int Messages::messagesLimit (void)
206 {
207 return m_iMessagesLimit;
208 }
209
210 void Messages::setMessagesLimit ( int iMessagesLimit )
211 {
212 m_iMessagesLimit = iMessagesLimit;
213 m_iMessagesHigh = iMessagesLimit + (iMessagesLimit / 3);
214 }
215
216 // Messages logging stuff.
217 bool Messages::isLogging (void) const
218 {
219 return (m_pMessagesLog != NULL);
220 }
221
222 void Messages::setLogging ( bool bEnabled, const QString& sFilename )
223 {
224 if (m_pMessagesLog) {
225 appendMessages(tr("Logging stopped --- %1 ---")
226 .arg(QDateTime::currentDateTime().toString()));
227 m_pMessagesLog->close();
228 delete m_pMessagesLog;
229 m_pMessagesLog = NULL;
230 }
231
232 if (bEnabled) {
233 m_pMessagesLog = new QFile(sFilename);
234 if (m_pMessagesLog->open(QIODevice::Text | QIODevice::Append)) {
235 appendMessages(tr("Logging started --- %1 ---")
236 .arg(QDateTime::currentDateTime().toString()));
237 } else {
238 delete m_pMessagesLog;
239 m_pMessagesLog = NULL;
240 }
241 }
242 }
243
244
245 // Messages log output method.
246 void Messages::appendMessagesLog ( const QString& s )
247 {
248 if (m_pMessagesLog) {
249 QTextStream(m_pMessagesLog) << s << endl;
250 m_pMessagesLog->flush();
251 }
252 }
253
254 // Messages widget output method.
255 void Messages::appendMessagesLine ( const QString& s )
256 {
257 // Check for message line limit...
258 if (m_iMessagesLines > m_iMessagesHigh) {
259 m_pMessagesTextView->setUpdatesEnabled(false);
260 QTextCursor textCursor(m_pMessagesTextView->document()->begin());
261 while (m_iMessagesLines > m_iMessagesLimit) {
262 // Move cursor extending selection
263 // from start to next line-block...
264 textCursor.movePosition(
265 QTextCursor::NextBlock, QTextCursor::KeepAnchor);
266 m_iMessagesLines--;
267 }
268 // Remove the excessive line-blocks...
269 textCursor.removeSelectedText();
270 m_pMessagesTextView->setUpdatesEnabled(true);
271 }
272
273 m_pMessagesTextView->append(s);
274 m_iMessagesLines++;
275 }
276
277
278 // The main utility methods.
279 void Messages::appendMessages ( const QString& s )
280 {
281 appendMessagesColor(s, "#999999");
282 }
283
284 void Messages::appendMessagesColor ( const QString& s, const QString &c )
285 {
286 const QString& sText
287 = QTime::currentTime().toString("hh:mm:ss.zzz") + ' ' + s;
288 appendMessagesLine("<font color=\"" + c + "\">" + sText + "</font>");
289 appendMessagesLog(sText);
290 }
291
292 void Messages::appendMessagesText ( const QString& s )
293 {
294 appendMessagesLine(s);
295 appendMessagesLog(s);
296 }
297
298
299 // History reset.
300 void Messages::clear (void)
301 {
302 m_iMessagesLines = 0;
303 m_pMessagesTextView->clear();
304 }
305
306 } // namespace QSampler
307
308
309 // end of qsamplerMessages.cpp

  ViewVC Help
Powered by ViewVC