QGIS API Documentation 3.41.0-Master (3440c17df1d)
Loading...
Searching...
No Matches
qgsmessagelogviewer.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsmessagelogviewer.cpp - description
3 -------------------
4 begin : October 2011
5 copyright : (C) 2011 by Juergen E. Fischer
6 email : jef at norbit dot de
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include "qgsmessagelogviewer.h"
19#include "moc_qgsmessagelogviewer.cpp"
20#include "qgsmessagelog.h"
21#include "qgssettings.h"
22#include "qgsapplication.h"
23#include "qgsdockwidget.h"
24
25#include <QFile>
26#include <QDateTime>
27#include <QTableWidget>
28#include <QToolButton>
29#include <QStatusBar>
30#include <QToolTip>
31#include <QPlainTextEdit>
32#include <QScrollBar>
33#include <QDebug>
34#include <QDesktopServices>
35
36QgsMessageLogViewer::QgsMessageLogViewer( QWidget *parent, Qt::WindowFlags fl )
37 : QDialog( parent, fl )
38{
39 setupUi( this );
40
41 connect( QgsApplication::messageLog(), static_cast<void ( QgsMessageLog::* )( const QString &, const QString &, Qgis::MessageLevel )>( &QgsMessageLog::messageReceived ),
42 this, static_cast<void ( QgsMessageLogViewer::* )( const QString &, const QString &, Qgis::MessageLevel )>( &QgsMessageLogViewer::logMessage ) );
43
44 connect( tabWidget, &QTabWidget::tabCloseRequested, this, &QgsMessageLogViewer::closeTab );
45
46 mTabBarContextMenu = new QMenu( this );
47 tabWidget->tabBar()->setContextMenuPolicy( Qt::CustomContextMenu );
48 connect( tabWidget->tabBar(), &QWidget::customContextMenuRequested, this, &QgsMessageLogViewer::showContextMenuForTabBar );
49}
50
51void QgsMessageLogViewer::showContextMenuForTabBar( QPoint point )
52{
53 if ( point.isNull() )
54 {
55 return;
56 }
57
58 mTabBarContextMenu->clear();
59
60 const int tabIndex = tabWidget->tabBar()->tabAt( point );
61
62 QAction *actionCloseTab = new QAction( tr( "Close Tab" ), mTabBarContextMenu );
63 connect( actionCloseTab, &QAction::triggered, this, [this, tabIndex]
64 {
65 closeTab( tabIndex );
66 }
67 );
68 mTabBarContextMenu->addAction( actionCloseTab );
69
70 QAction *actionCloseOtherTabs = new QAction( tr( "Close Other Tabs" ), mTabBarContextMenu );
71 actionCloseOtherTabs->setEnabled( tabWidget->tabBar()->count() > 1 );
72 connect( actionCloseOtherTabs, &QAction::triggered, this, [this, tabIndex]
73 {
74 int i;
75 for ( i = tabWidget->tabBar()->count() - 1; i >= 0; i-- )
76 {
77 if ( i != tabIndex )
78 {
79 closeTab( i );
80 }
81 }
82 }
83 );
84 mTabBarContextMenu->addAction( actionCloseOtherTabs );
85
86 QAction *actionCloseAllTabs = new QAction( tr( "Close All Tabs" ), mTabBarContextMenu );
87 actionCloseAllTabs->setEnabled( tabWidget->tabBar()->count() > 0 );
88 connect( actionCloseAllTabs, &QAction::triggered, this, [this]
89 {
90 int i;
91 for ( i = tabWidget->tabBar()->count() - 1; i >= 0; i-- )
92 {
93 closeTab( i );
94 }
95 }
96 );
97 mTabBarContextMenu->addAction( actionCloseAllTabs );
98
99 mTabBarContextMenu->exec( tabWidget->tabBar()->mapToGlobal( point ) );
100}
101
103{
104 e->ignore();
105}
106
110
111void QgsMessageLogViewer::logMessage( const QString &message, const QString &tag, Qgis::MessageLevel level )
112{
113 constexpr int MESSAGE_COUNT_LIMIT = 10000;
114 // Avoid logging too many messages, which might blow memory.
115 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
116 return;
117 ++mMessageLoggedCount;
118
119 QString cleanedTag = tag;
120 if ( cleanedTag.isNull() )
121 cleanedTag = tr( "General" );
122
123 int i;
124 for ( i = 0; i < tabWidget->count() && tabWidget->tabText( i ).remove( QChar( '&' ) ) != cleanedTag; i++ );
125
126 QPlainTextEdit *w = nullptr;
127 if ( i < tabWidget->count() )
128 {
129 w = qobject_cast<QPlainTextEdit *>( tabWidget->widget( i ) );
130 tabWidget->setCurrentIndex( i );
131 }
132 else
133 {
134 w = new QPlainTextEdit( this );
135 w->setReadOnly( true );
136 w->viewport()->installEventFilter( this );
137 tabWidget->addTab( w, cleanedTag );
138 tabWidget->setCurrentIndex( tabWidget->count() - 1 );
139 }
140
141 QString levelString;
142 const QgsSettings settings;
143 const QPalette pal = qApp->palette();
144 const QString defaultColorName = pal.color( QPalette::WindowText ).name();
145 QString colorName;
146 switch ( level )
147 {
149 levelString = QStringLiteral( "INFO" );
150 colorName = settings.value( QStringLiteral( "colors/info" ), QString() ).toString();
151 break;
153 levelString = QStringLiteral( "WARNING" );
154 colorName = settings.value( QStringLiteral( "colors/warning" ), QString() ).toString();
155 break;
157 levelString = QStringLiteral( "CRITICAL" );
158 colorName = settings.value( QStringLiteral( "colors/critical" ), QString() ).toString();
159 break;
161 levelString = QStringLiteral( "SUCCESS" );
162 colorName = settings.value( QStringLiteral( "colors/success" ), QString() ).toString();
163 break;
165 levelString = QStringLiteral( "NONE" );
166 colorName = settings.value( QStringLiteral( "colors/default" ), QString() ).toString();
167 break;
168 }
169 const QColor color = QColor( !colorName.isEmpty() ? colorName : defaultColorName );
170
171 const QString prefix = QStringLiteral( "<font color=\"%1\">%2 &nbsp;&nbsp;&nbsp; %3 &nbsp;&nbsp;&nbsp;</font>" )
172 .arg( color.name(), QDateTime::currentDateTime().toString( Qt::ISODate ), levelString );
173 QString cleanedMessage = message;
174 if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
175 cleanedMessage = tr( "Message log truncated" );
176
177 cleanedMessage = cleanedMessage.prepend( prefix ).replace( '\n', QLatin1String( "<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;" ) );
178 w->appendHtml( cleanedMessage );
179 w->verticalScrollBar()->setValue( w->verticalScrollBar()->maximum() );
180 tabWidget->show();
181 emptyLabel->hide();
182}
183
184void QgsMessageLogViewer::closeTab( int index )
185{
186 tabWidget->removeTab( index );
187 if ( tabWidget->count() == 0 )
188 {
189 tabWidget->hide();
190 emptyLabel->show();
191 }
192}
193
194bool QgsMessageLogViewer::eventFilter( QObject *object, QEvent *event )
195{
196 switch ( event->type() )
197 {
198 case QEvent::MouseButtonPress:
199 {
200 if ( QPlainTextEdit *te = qobject_cast<QPlainTextEdit *>( object->parent() ) )
201 {
202 QMouseEvent *me = static_cast< QMouseEvent *>( event );
203 mClickedAnchor = ( me->button() & Qt::LeftButton ) ? te->anchorAt( me->pos() ) :
204 QString();
205 if ( !mClickedAnchor.isEmpty() )
206 return true;
207 }
208 break;
209 }
210
211 case QEvent::MouseButtonRelease:
212 {
213 if ( QPlainTextEdit *te = qobject_cast<QPlainTextEdit *>( object->parent() ) )
214 {
215 QMouseEvent *me = static_cast< QMouseEvent *>( event );
216 const QString clickedAnchor = ( me->button() & Qt::LeftButton ) ? te->anchorAt( me->pos() ) :
217 QString();
218 if ( !clickedAnchor.isEmpty() && clickedAnchor == mClickedAnchor )
219 {
220 QDesktopServices::openUrl( mClickedAnchor );
221 return true;
222 }
223 }
224 break;
225 }
226
227 default:
228 break;
229 }
230
231 return QDialog::eventFilter( object, event );
232}
MessageLevel
Level for messages This will be used both for message log and message bar in application.
Definition qgis.h:154
@ NoLevel
No level.
Definition qgis.h:159
@ Warning
Warning message.
Definition qgis.h:156
@ Critical
Critical/error message.
Definition qgis.h:157
@ Info
Information message.
Definition qgis.h:155
@ Success
Used for reporting a successful operation.
Definition qgis.h:158
static QgsMessageLog * messageLog()
Returns the application's message log.
A generic dialog widget for displaying QGIS log messages.
void closeEvent(QCloseEvent *e) override
bool eventFilter(QObject *obj, QEvent *ev) override
QgsMessageLogViewer(QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags)
Create a new message log viewer.
void logMessage(const QString &message, const QString &tag, Qgis::MessageLevel level)
Logs a message to the viewer.
Interface for logging messages from QGIS in GUI independent way.
void messageReceived(const QString &message, const QString &tag, Qgis::MessageLevel level)
Emitted whenever the log receives a message.
This class is a composition of two QSettings instances:
Definition qgssettings.h:64
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.