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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3759 - (hide annotations) (download)
Sat Mar 28 00:28:13 2020 UTC (4 years, 1 month ago) by capela
File size: 9244 byte(s)
- Early fixing to build for Qt >= 5.15.0. (bis)
1 capela 94 // qsamplerMessages.cpp
2     //
3     /****************************************************************************
4 capela 3758 Copyright (C) 2004-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5 capela 1464 Copyright (C) 2007, Christian Schoenebeck
6 capela 94
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 capela 920 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 capela 94
21     *****************************************************************************/
22    
23 capela 1465 #include "qsamplerAbout.h"
24 capela 94 #include "qsamplerMessages.h"
25    
26 capela 1465 #include <QSocketNotifier>
27 capela 1738
28     #include <QFile>
29 capela 1465 #include <QTextEdit>
30     #include <QTextCursor>
31 capela 1738 #include <QTextStream>
32 capela 1465 #include <QTextBlock>
33 schoenebeck 1461 #include <QScrollBar>
34 capela 1465 #include <QDateTime>
35     #include <QIcon>
36 schoenebeck 1461
37 capela 3358 #if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
38 capela 115 #include <unistd.h>
39 capela 2669 #include <fcntl.h>
40 capela 115 #endif
41    
42 capela 1558
43 capela 3759 // Deprecated QTextStreamFunctions/Qt namespaces workaround.
44     #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
45     #define endl Qt::endl
46     #endif
47    
48    
49 capela 1558 namespace QSampler {
50    
51 capela 94 // The default maximum number of message lines.
52     #define QSAMPLER_MESSAGES_MAXLINES 1000
53    
54     // Notification pipe descriptors
55     #define QSAMPLER_MESSAGES_FDNIL -1
56     #define QSAMPLER_MESSAGES_FDREAD 0
57     #define QSAMPLER_MESSAGES_FDWRITE 1
58    
59 capela 2582
60 capela 94 //-------------------------------------------------------------------------
61 capela 1558 // QSampler::Messages - Messages log dockable window.
62 capela 94 //
63    
64     // Constructor.
65 capela 1558 Messages::Messages ( QWidget *pParent )
66 capela 1739 : QDockWidget(pParent)
67 capela 94 {
68 capela 1465 // Surely a name is crucial (e.g.for storing geometry settings)
69     QDockWidget::setObjectName("qsamplerMessages");
70    
71 capela 1739 // Intialize stdout capture stuff.
72 capela 3555 m_pStdoutNotifier = nullptr;
73 capela 1739 m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
74     m_fdStdout[QSAMPLER_MESSAGES_FDWRITE] = QSAMPLER_MESSAGES_FDNIL;
75 capela 94
76 capela 1465 // Create local text view widget.
77 capela 1738 m_pMessagesTextView = new QTextEdit(this);
78     // QFont font(m_pMessagesTextView->font());
79 capela 94 // font.setFamily("Fixed");
80 capela 1738 // m_pMessagesTextView->setFont(font);
81     m_pMessagesTextView->setLineWrapMode(QTextEdit::NoWrap);
82     m_pMessagesTextView->setReadOnly(true);
83     m_pMessagesTextView->setUndoRedoEnabled(false);
84     // m_pMessagesTextView->setTextFormat(Qt::LogText);
85 capela 94
86 capela 1465 // Initialize default message limit.
87     m_iMessagesLines = 0;
88     setMessagesLimit(QSAMPLER_MESSAGES_MAXLINES);
89    
90 capela 3555 m_pMessagesLog = nullptr;
91 capela 1738
92 capela 1465 // Prepare the dockable window stuff.
93 capela 1738 QDockWidget::setWidget(m_pMessagesTextView);
94 capela 1465 QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
95     QDockWidget::setAllowedAreas(
96     Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
97 capela 772 // Some specialties to this kind of dock window...
98 capela 1465 QDockWidget::setMinimumHeight(120);
99 capela 94
100 capela 1465 // Finally set the default caption and tooltip.
101     const QString& sCaption = tr("Messages");
102     QDockWidget::setWindowTitle(sCaption);
103     // QDockWidget::setWindowIcon(QIcon(":/icons/qsamplerMessages.png"));
104     QDockWidget::setToolTip(sCaption);
105 capela 94 }
106    
107    
108     // Destructor.
109 capela 1558 Messages::~Messages (void)
110 capela 94 {
111 capela 1739 // Turn off and close logging.
112 capela 1738 setLogging(false);
113    
114 capela 1739 // No more notifications.
115     if (m_pStdoutNotifier)
116     delete m_pStdoutNotifier;
117 capela 94
118 capela 1739 // No need to delete child widgets, Qt does it all for us.
119 capela 94 }
120    
121    
122 capela 2848 // Set stdout/stderr blocking mode.
123     bool Messages::stdoutBlock ( int fd, bool bBlock ) const
124     {
125 capela 3358 #if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
126 capela 2848 const int iFlags = ::fcntl(fd, F_GETFL, 0);
127     const bool bNonBlock = bool(iFlags & O_NONBLOCK);
128     if (bBlock && bNonBlock)
129     bBlock = (::fcntl(fd, F_SETFL, iFlags & ~O_NONBLOCK) == 0);
130     else
131     if (!bBlock && !bNonBlock)
132     bBlock = (::fcntl(fd, F_SETFL, iFlags | O_NONBLOCK) != 0);
133     #endif
134     return bBlock;
135     }
136    
137    
138 capela 94 // Own stdout/stderr socket notifier slot.
139 capela 1558 void Messages::stdoutNotify ( int fd )
140 capela 94 {
141 capela 3358 #if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
142 capela 2669 // Set non-blocking reads, if not already...
143 capela 2848 const bool bBlock = stdoutBlock(fd, false);
144 capela 2669 // Read as much as is available...
145     QString sTemp;
146 capela 1739 char achBuffer[1024];
147 capela 2669 const int cchBuffer = sizeof(achBuffer) - 1;
148     int cchRead = ::read(fd, achBuffer, cchBuffer);
149     while (cchRead > 0) {
150     achBuffer[cchRead] = (char) 0;
151     sTemp.append(achBuffer);
152 capela 2848 cchRead = (bBlock ? 0 : ::read(fd, achBuffer, cchBuffer));
153 capela 1739 }
154 capela 2669 // Needs to be non-empty...
155     if (!sTemp.isEmpty())
156     appendStdoutBuffer(sTemp);
157 capela 94 #endif
158     }
159    
160    
161     // Stdout buffer handler -- now splitted by complete new-lines...
162 capela 1558 void Messages::appendStdoutBuffer ( const QString& s )
163 capela 94 {
164 capela 1465 m_sStdoutBuffer.append(s);
165 capela 94
166 capela 2582 const int iLength = m_sStdoutBuffer.lastIndexOf('\n');
167 capela 1465 if (iLength > 0) {
168 capela 2582 const QString& sTemp = m_sStdoutBuffer.left(iLength);
169 schoenebeck 1474 m_sStdoutBuffer.remove(0, iLength + 1);
170 capela 1465 QStringList list = sTemp.split('\n');
171     QStringListIterator iter(list);
172     while (iter.hasNext())
173     appendMessagesText(iter.next());
174     }
175 capela 94 }
176    
177    
178     // Stdout flusher -- show up any unfinished line...
179 capela 1558 void Messages::flushStdoutBuffer (void)
180 capela 94 {
181 capela 1739 if (!m_sStdoutBuffer.isEmpty()) {
182     appendMessagesText(m_sStdoutBuffer);
183 capela 2669 m_sStdoutBuffer.clear();
184 capela 1739 }
185 capela 94 }
186    
187    
188     // Stdout capture accessors.
189 capela 1558 bool Messages::isCaptureEnabled (void)
190 capela 94 {
191 capela 3555 return (m_pStdoutNotifier != nullptr);
192 capela 94 }
193    
194 capela 1558 void Messages::setCaptureEnabled ( bool bCapture )
195 capela 94 {
196 capela 1739 // Flush current buffer.
197     flushStdoutBuffer();
198 capela 94
199 capela 3358 #if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
200 capela 1465 // Destroy if already enabled.
201     if (!bCapture && m_pStdoutNotifier) {
202     delete m_pStdoutNotifier;
203 capela 3555 m_pStdoutNotifier = nullptr;
204 capela 1465 // Close the notification pipes.
205     if (m_fdStdout[QSAMPLER_MESSAGES_FDREAD] != QSAMPLER_MESSAGES_FDNIL) {
206     ::close(m_fdStdout[QSAMPLER_MESSAGES_FDREAD]);
207     m_fdStdout[QSAMPLER_MESSAGES_FDREAD] = QSAMPLER_MESSAGES_FDNIL;
208     }
209     }
210     // Are we going to make up the capture?
211 capela 3555 if (bCapture && m_pStdoutNotifier == nullptr && ::pipe(m_fdStdout) == 0) {
212 capela 1465 ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDOUT_FILENO);
213     ::dup2(m_fdStdout[QSAMPLER_MESSAGES_FDWRITE], STDERR_FILENO);
214     m_pStdoutNotifier = new QSocketNotifier(
215     m_fdStdout[QSAMPLER_MESSAGES_FDREAD], QSocketNotifier::Read, this);
216     QObject::connect(m_pStdoutNotifier,
217     SIGNAL(activated(int)),
218     SLOT(stdoutNotify(int)));
219     }
220 capela 94 #endif
221     }
222    
223    
224     // Message font accessors.
225 capela 1558 QFont Messages::messagesFont (void)
226 capela 94 {
227 capela 1739 return m_pMessagesTextView->font();
228 capela 94 }
229    
230 capela 1738 void Messages::setMessagesFont ( const QFont& font )
231 capela 94 {
232 capela 1739 m_pMessagesTextView->setFont(font);
233 capela 94 }
234    
235    
236     // Maximum number of message lines accessors.
237 capela 1558 int Messages::messagesLimit (void)
238 capela 94 {
239 capela 1739 return m_iMessagesLimit;
240 capela 94 }
241    
242 capela 1558 void Messages::setMessagesLimit ( int iMessagesLimit )
243 capela 94 {
244 capela 1739 m_iMessagesLimit = iMessagesLimit;
245     m_iMessagesHigh = iMessagesLimit + (iMessagesLimit / 3);
246 capela 94 }
247    
248 capela 1738 // Messages logging stuff.
249     bool Messages::isLogging (void) const
250     {
251 capela 3555 return (m_pMessagesLog != nullptr);
252 capela 1738 }
253 capela 94
254 capela 1738 void Messages::setLogging ( bool bEnabled, const QString& sFilename )
255 capela 94 {
256 capela 1738 if (m_pMessagesLog) {
257     appendMessages(tr("Logging stopped --- %1 ---")
258     .arg(QDateTime::currentDateTime().toString()));
259     m_pMessagesLog->close();
260     delete m_pMessagesLog;
261 capela 3555 m_pMessagesLog = nullptr;
262 capela 1738 }
263    
264     if (bEnabled) {
265     m_pMessagesLog = new QFile(sFilename);
266     if (m_pMessagesLog->open(QIODevice::Text | QIODevice::Append)) {
267     appendMessages(tr("Logging started --- %1 ---")
268     .arg(QDateTime::currentDateTime().toString()));
269     } else {
270     delete m_pMessagesLog;
271 capela 3555 m_pMessagesLog = nullptr;
272 capela 1738 }
273     }
274 capela 94 }
275    
276 capela 1738
277     // Messages log output method.
278     void Messages::appendMessagesLog ( const QString& s )
279 capela 94 {
280 capela 1738 if (m_pMessagesLog) {
281 capela 3759 QTextStream(m_pMessagesLog) << s << endl;
282 capela 1738 m_pMessagesLog->flush();
283     }
284 capela 94 }
285    
286 capela 1738 // Messages widget output method.
287     void Messages::appendMessagesLine ( const QString& s )
288 capela 94 {
289 capela 1738 // Check for message line limit...
290     if (m_iMessagesLines > m_iMessagesHigh) {
291     m_pMessagesTextView->setUpdatesEnabled(false);
292     QTextCursor textCursor(m_pMessagesTextView->document()->begin());
293 capela 1465 while (m_iMessagesLines > m_iMessagesLimit) {
294     // Move cursor extending selection
295     // from start to next line-block...
296     textCursor.movePosition(
297     QTextCursor::NextBlock, QTextCursor::KeepAnchor);
298     m_iMessagesLines--;
299     }
300     // Remove the excessive line-blocks...
301     textCursor.removeSelectedText();
302 capela 1738 m_pMessagesTextView->setUpdatesEnabled(true);
303     }
304 capela 1465
305 capela 1738 m_pMessagesTextView->append(s);
306 capela 1465 m_iMessagesLines++;
307 capela 94 }
308    
309    
310 capela 1738 // The main utility methods.
311     void Messages::appendMessages ( const QString& s )
312     {
313 capela 1739 appendMessagesColor(s, "#999999");
314 capela 1738 }
315    
316     void Messages::appendMessagesColor ( const QString& s, const QString &c )
317     {
318 capela 2583 const QString& sText
319     = QTime::currentTime().toString("hh:mm:ss.zzz") + ' ' + s;
320 capela 1738 appendMessagesLine("<font color=\"" + c + "\">" + sText + "</font>");
321     appendMessagesLog(sText);
322     }
323    
324     void Messages::appendMessagesText ( const QString& s )
325     {
326     appendMessagesLine(s);
327     appendMessagesLog(s);
328     }
329    
330    
331 capela 1465 // History reset.
332 capela 1558 void Messages::clear (void)
333 capela 94 {
334 capela 1465 m_iMessagesLines = 0;
335 capela 1738 m_pMessagesTextView->clear();
336 capela 94 }
337    
338 capela 1558 } // namespace QSampler
339 capela 94
340 capela 1558
341 capela 94 // end of qsamplerMessages.cpp

  ViewVC Help
Powered by ViewVC