19#include "moc_qgsmessagelogviewer.cpp" 
   26#include <QTableWidget> 
   30#include <QPlainTextEdit> 
   33#include <QDesktopServices> 
   36  : QDialog( parent, fl )
 
   42  connect( tabWidget, &QTabWidget::tabCloseRequested, 
this, &QgsMessageLogViewer::closeTab );
 
   44  connect( tabWidget, &QTabWidget::currentChanged, 
this, [
this]( 
int index ) {
 
   45    tabWidget->setTabIcon( index, QIcon() );
 
   48  mTabBarContextMenu = 
new QMenu( 
this );
 
   49  tabWidget->tabBar()->setContextMenuPolicy( Qt::CustomContextMenu );
 
   50  connect( tabWidget->tabBar(), &QWidget::customContextMenuRequested, 
this, &QgsMessageLogViewer::showContextMenuForTabBar );
 
 
   53void QgsMessageLogViewer::showContextMenuForTabBar( QPoint point )
 
   60  mTabBarContextMenu->clear();
 
   62  const int tabIndex = tabWidget->tabBar()->tabAt( point );
 
   64  QAction *actionCloseTab = 
new QAction( tr( 
"Close Tab" ), mTabBarContextMenu );
 
   65  connect( actionCloseTab, &QAction::triggered, 
this, [
this, tabIndex] {
 
   68  mTabBarContextMenu->addAction( actionCloseTab );
 
   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] {
 
   74    for ( i = tabWidget->tabBar()->count() - 1; i >= 0; i-- )
 
   82  mTabBarContextMenu->addAction( actionCloseOtherTabs );
 
   84  QAction *actionCloseAllTabs = 
new QAction( tr( 
"Close All Tabs" ), mTabBarContextMenu );
 
   85  actionCloseAllTabs->setEnabled( tabWidget->tabBar()->count() > 0 );
 
   86  connect( actionCloseAllTabs, &QAction::triggered, 
this, [
this] {
 
   88    for ( i = tabWidget->tabBar()->count() - 1; i >= 0; i-- )
 
   93  mTabBarContextMenu->addAction( actionCloseAllTabs );
 
   95  mTabBarContextMenu->exec( tabWidget->tabBar()->mapToGlobal( point ) );
 
  109  constexpr int MESSAGE_COUNT_LIMIT = 10000;
 
  111  if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
 
  113  ++mMessageLoggedCount;
 
  115  QString cleanedTag = tag;
 
  116  if ( cleanedTag.isNull() )
 
  117    cleanedTag = tr( 
"General" );
 
  120  for ( i = 0; i < tabWidget->count() && tabWidget->tabText( i ).remove( QChar( 
'&' ) ) != cleanedTag; i++ )
 
  123  QPlainTextEdit *w = 
nullptr;
 
  124  if ( i < tabWidget->count() )
 
  126    w = qobject_cast<QPlainTextEdit *>( tabWidget->widget( i ) );
 
  127    if ( i != tabWidget->currentIndex() )
 
  134    w = 
new QPlainTextEdit( 
this );
 
  135    w->setReadOnly( 
true );
 
  136    w->viewport()->installEventFilter( 
this );
 
  142  const QPalette 
pal = qApp->palette();
 
  143  const QString defaultColorName = 
pal.color( QPalette::WindowText ).name();
 
  148      levelString = QStringLiteral( 
"INFO" );
 
  149      colorName = settings.
value( QStringLiteral( 
"colors/info" ), QString() ).toString();
 
  152      levelString = QStringLiteral( 
"WARNING" );
 
  153      colorName = settings.
value( QStringLiteral( 
"colors/warning" ), QString() ).toString();
 
  156      levelString = QStringLiteral( 
"CRITICAL" );
 
  157      colorName = settings.
value( QStringLiteral( 
"colors/critical" ), QString() ).toString();
 
  160      levelString = QStringLiteral( 
"SUCCESS" );
 
  161      colorName = settings.
value( QStringLiteral( 
"colors/success" ), QString() ).toString();
 
  164      levelString = QStringLiteral( 
"NONE" );
 
  165      colorName = settings.
value( QStringLiteral( 
"colors/default" ), QString() ).toString();
 
  168  const QColor color = QColor( !colorName.isEmpty() ? colorName : defaultColorName );
 
  170  const QString prefix = QStringLiteral( 
"<font color=\"%1\">%2     %3    </font>" )
 
  171                           .arg( color.name(), QDateTime::currentDateTime().toString( Qt::ISODate ), levelString );
 
  172  QString cleanedMessage = message.toHtmlEscaped();
 
  173  if ( mMessageLoggedCount == MESSAGE_COUNT_LIMIT )
 
  174    cleanedMessage = tr( 
"Message log truncated" );
 
  176  cleanedMessage = cleanedMessage.prepend( prefix ).replace( 
'\n', QLatin1String( 
"<br>             " ) );
 
  177  w->appendHtml( cleanedMessage );
 
  178  w->verticalScrollBar()->setValue( w->verticalScrollBar()->maximum() );
 
 
  185  for ( 
int i = 0; i < tabWidget->count(); i++ )
 
  187    if ( tabWidget->tabText( i ).remove( QChar( 
'&' ) ) == tag )
 
  189      tabWidget->setCurrentIndex( i );
 
 
  195void QgsMessageLogViewer::closeTab( 
int index )
 
  197  tabWidget->removeTab( index );
 
  198  if ( tabWidget->count() == 0 )
 
  207  switch ( event->type() )
 
  209    case QEvent::MouseButtonPress:
 
  211      if ( QPlainTextEdit *te = qobject_cast<QPlainTextEdit *>( object->parent() ) )
 
  213        QMouseEvent *me = 
static_cast<QMouseEvent *
>( event );
 
  214        mClickedAnchor = ( me->button() & Qt::LeftButton ) ? te->anchorAt( me->pos() ) : QString();
 
  215        if ( !mClickedAnchor.isEmpty() )
 
  221    case QEvent::MouseButtonRelease:
 
  223      if ( QPlainTextEdit *te = qobject_cast<QPlainTextEdit *>( object->parent() ) )
 
  225        QMouseEvent *me = 
static_cast<QMouseEvent *
>( event );
 
  226        const QString clickedAnchor = ( me->button() & Qt::LeftButton ) ? te->anchorAt( me->pos() ) : QString();
 
  227        if ( !clickedAnchor.isEmpty() && clickedAnchor == mClickedAnchor )
 
  229          QDesktopServices::openUrl( mClickedAnchor );
 
  240  return QDialog::eventFilter( 
object, event );
 
 
MessageLevel
Level for messages This will be used both for message log and message bar in application.
 
@ Warning
Warning message.
 
@ Critical
Critical/error message.
 
@ Info
Information message.
 
@ Success
Used for reporting a successful operation.
 
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
 
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
 
void showTab(const QString &tag)
Activates the tab whose title matches the given tag, if any.
 
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.
 
Stores settings for use within QGIS.
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.