Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/VLC/modules/gui/qt/dialogs/messages/   (VLC Media Plyer ©)  Datei vom 23.9.2026 mit Größe 14 kB image not shown  

Quelle  messages.cpp   Sprache: C

 

/*****************************************************************************
 * messages.cpp : Information about an item
 ****************************************************************************
 * Copyright (C) 2006-2011 the VideoLAN team
 *
 * Authors: Jean-Baptiste Kempf <jb (at) videolan.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <QPlainTextEdit>
#include <QTextCursor>
#include <QTextBlock>
#include <QFileDialog>
#include <QTextStream>
#include <QMessageBox>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QScrollBar>
#include <QMutex>
#include <QMutexLocker>

#include <cassert>

#include <vlc_common.h>
#include <vlc_playlist.h>
#include <vlc_interface.h>
#include <vlc_input_item.h>


#include "dialogs/messages/messages.hpp"
#include "dialogs/dialogs/dialogmodel.hpp"

enum {
    MsgEvent_Type = QEvent::User + MsgEventTypeOffset + 1,
};

class MsgEvent : public QEvent
{
public:
    MsgEvent( int, const vlc_log_t *, const char * );

    int priority;
    uintptr_t object_id;
    QString object_type;
    QString header;
    QString module;
    QString text;
};

MsgEvent::MsgEvent( int type, const vlc_log_t *msg, const char *text )
    : QEvent( (QEvent::Type)MsgEvent_Type ),
      priority( type ),
      object_id( msg->i_object_id ),
      object_type( qfu(msg->psz_object_type) ),
      header( qfu(msg->psz_header) ),
      module( qfu(msg->psz_module) ),
      text( qfu(text) )
{
}

MessagesDialog::MessagesDialog( qt_intf_t *_p_intf)
               : QVLCFrame( _p_intf )
{
    setWindowTitle( qtr( "Messages" ) );
    setWindowRole( "vlc-messages" );
    /* Build Ui */
    ui.setupUi( this );
    ui.bottomButtonsBox->addButton( new QPushButton( qtr("&Close"), this ),
                                         QDialogButtonBox::RejectRole );

    /* Error messages */
    DialogErrorModel *errors = DialogErrorModel::getInstance<false>();
    connect( errors, &DialogErrorModel::countChanged, this, &MessagesDialog::errorsCountChanged );
    for(int i=0; i<errors->count(); i++)
        addError(i);

    /* Modules tree */
    ui.modulesTree->setHeaderHidden( true );

    /* Buttons and general layout */
    ui.saveLogButton->setToolTip( qtr( "Saves all the displayed logs to a file" ) );

    int i_verbosity = var_InheritInteger( p_intf, "verbose" );
    changeVerbosity( i_verbosity );
    ui.verbosityBox->setValue( qMin( i_verbosity, 2 ) );

    ui.filterEdit->setText( getSettings()->value( "Messages/messages-filter" ).toString() );

    updateButton = new QToolButton;
    updateButton->setIcon( QIcon(":/menu/update.svg") );
    updateButton->setAutoRaise( true );
    ui.mainTab->setCornerWidget( updateButton );

#ifndef NDEBUG
    QWidget *pldebugTab = new QWidget();
    QVBoxLayout *pldebugTabLayout = new QVBoxLayout();
    pldebugTab->setLayout( pldebugTabLayout );
    ui.mainTab->addTab( pldebugTab, "Playlist Tree" );
    pldebugTree = new QTreeWidget();
    pldebugTree->headerItem()->setText( 0, "Name" );
    pldebugTree->headerItem()->setText( 1, "PL id" );
    pldebugTree->headerItem()->setText( 2, "Item id" );
    pldebugTree->headerItem()->setText( 3, "PL flags" );
    pldebugTree->headerItem()->setText( 4, "Item flags" );
    pldebugTree->setColumnCount( 5 );
    pldebugTabLayout->addWidget( pldebugTree );
#endif

    tabChanged(0);

    BUTTONACT( updateButton, &MessagesDialog::updateOrClear );
    BUTTONACT( ui.saveLogButton, &MessagesDialog::save );
    connect( ui.filterEdit, &QLineEdit::editingFinished, this, &MessagesDialog::updateConfig );
    connect( ui.filterEdit, &QLineEdit::textChanged, this, &MessagesDialog::filterMessages );
    connect( ui.bottomButtonsBox, &QDialogButtonBox::rejected, this, &MessagesDialog::hide );
    connect( ui.verbosityBox, QOverload<int>::of(&QVLCDebugLevelSpinBox::valueChanged),
             this, &MessagesDialog::changeVerbosity );

    connect( ui.mainTab, &QTabWidget::currentChanged, this, &MessagesDialog::tabChanged );

    /* General action */
    restoreWidgetPosition( "Messages", QSize( 600, 450 ) );

    /* Hook up to LibVLC messaging */
    static const struct vlc_logger_operations log_ops =
    {
        MessagesDialog::MsgCallback,
        NULL
    };
    libvlc_int_t *vlc = vlc_object_instance(p_intf);

    vlc_LogSet( vlc, &log_ops, this );

    buildTree( NULL, VLC_OBJECT(vlc) );
}

MessagesDialog::~MessagesDialog()
{
    saveWidgetPosition( "Messages" );
    vlc_LogSet( vlc_object_instance(p_intf), NULL, NULL );
};

void MessagesDialog::changeVerbosity( int i_verbosity )
{
    verbosity = i_verbosity;
}

void MessagesDialog::updateConfig()
{
    getSettings()->setValue( "Messages/messages-filter", ui.filterEdit->text() );
}

void MessagesDialog::addError(int row){
    DialogErrorModel *errors = DialogErrorModel::getInstance<false>();

    QPlainTextEdit * errorsList = ui.errors;

    bool b_autoscroll = ( errorsList->verticalScrollBar()->value()
                          + errorsList->verticalScrollBar()->pageStep()
                          >= errorsList->verticalScrollBar()->maximum() );

    /* Copy selected text to the clipboard */
    if( errorsList->textCursor().hasSelection() )
        errorsList->copy();

    /* Fix selected text bug */
    if( !errorsList->textCursor().atEnd() ||
         errorsList->textCursor().anchor() != errorsList->textCursor().position() )
         errorsList->moveCursor( QTextCursor::End );

    /* Start a new logic block */
    if( !errorsList->document()->isEmpty() )
        errorsList->textCursor().insertBlock();

    QTextCharFormat format;

    format.setProperty( QTextFormat::FontItalic, true );
    format.setForeground( Qt::darkRed );
    errorsList->textCursor().insertText( errors->data(errors->index(row, 0), DialogErrorModel::DIALOG_TITLE).toString()+": ", format );

    format.setProperty( QTextFormat::FontItalic, false );
    format.setForeground( errorsList->palette().windowText() );
    errorsList->textCursor().insertText( errors->data(errors->index(row, 0), DialogErrorModel::DIALOG_TEXT).toString(), format );

    if ( b_autoscroll ) errorsList->ensureCursorVisible();
}

void MessagesDialog::errorsCountChanged(){
    DialogErrorModel *errors = DialogErrorModel::getInstance(p_intf);
    addError(errors->count() - 1);
}

void MessagesDialog::filterMessages()
{
    QMutexLocker locker( &messageLocker );
    QPlainTextEdit *messages = ui.messages;
    QTextBlock block = messages->document()->firstBlock();

    while( block.isValid() )
    {
        block.setVisible( matchFilter( block.text().toLower() ) );
        block = block.next();
    }

    /* Consider the whole QTextDocument as dirty now */
    messages->document()->markContentsDirty( 0, messages->document()->characterCount() );

    /* FIXME This solves a bug (Qt?) with the viewport not resizing the
       vertical scroll bar when one or more QTextBlock are hidden */

    QSize vsize = messages->viewport()->size();
    messages->viewport()->resize( vsize + QSize( 1, 1 ) );
    messages->viewport()->resize( vsize );
}

bool MessagesDialog::matchFilter( const QString& text )
{
    const QString& filter = ui.filterEdit->text();

    if( filter.isEmpty() || text.contains( filter.toLower() ) )
        return true;
    return false;
}

void MessagesDialog::sinkMessage( const MsgEvent *msg )
{
    QMutexLocker locker( &messageLocker );

    QPlainTextEdit *messages = ui.messages;
    /* Only scroll if the viewport is at the end.
       Don't bug user by auto-changing/losing viewport on insert(). */

    bool b_autoscroll = ( messages->verticalScrollBar()->value()
                          + messages->verticalScrollBar()->pageStep()
                          >= messages->verticalScrollBar()->maximum() );

    /* Copy selected text to the clipboard */
    if( messages->textCursor().hasSelection() )
        messages->copy();

    /* Fix selected text bug */
    if( !messages->textCursor().atEnd() ||
         messages->textCursor().anchor() != messages->textCursor().position() )
         messages->moveCursor( QTextCursor::End );

    /* Start a new logic block */
    if( !messages->document()->isEmpty() )
        messages->textCursor().insertBlock();

    /* Insert the prefix */
    QTextCharFormat format;
    format.setProperty( QTextFormat::FontItalic, true );
    format.setForeground( Qt::darkBlue );

    messages->textCursor().insertText( msg->module, format );

    switch ( msg->priority )
    {
        case VLC_MSG_INFO:
            format.setForeground( Qt::darkBlue );
            messages->textCursor().insertText( " info: ", format );
            break;
        case VLC_MSG_ERR:
            format.setForeground( Qt::darkRed );
            messages->textCursor().insertText( " error: ", format );
            break;
        case VLC_MSG_WARN:
            format.setForeground( Qt::darkGreen );
            messages->textCursor().insertText( " warning: ", format );
            break;
        case VLC_MSG_DBG:
        default:
            format.setForeground( Qt::darkGray );
            messages->textCursor().insertText( " debug: ", format );
            break;
    }

    /* Insert the message */
    format.setProperty( QTextFormat::FontItalic, false );
    format.setForeground( messages->palette().windowText() );
    messages->textCursor().insertText( msg->text, format );

    /* Pass the new message thru the filter */
    QTextBlock b = messages->document()->lastBlock();
    b.setVisible( matchFilter( b.text() ) );

    if ( b_autoscroll ) messages->ensureCursorVisible();
}

void MessagesDialog::customEvent( QEvent *event )
{
    MsgEvent *msge = static_cast<MsgEvent *>(event);

    assert( msge );
    sinkMessage( msge );
}

bool MessagesDialog::save()
{
    QString saveLogFileName = QFileDialog::getSaveFileName(
            this, qtr( "Save log file as..." ),
            QVLCUserDir( VLC_DOCUMENTS_DIR ),
            qtr( "Texts/Logs (*.log *.txt);; All (*.*)") );

    if( !saveLogFileName.isNull() )
    {
        QFile file( saveLogFileName );
        if ( !file.open( QFile::WriteOnly | QFile::Text ) ) {
            QMessageBox::warning( this, qtr( "Application" ),
                    qtr( "Cannot write to file %1:\n%2." )
                    .arg( saveLogFileName )
                    .arg( file.errorString() ) );
            return false;
        }

        QTextStream out( &file );

        QTextBlock block = ui.messages->document()->firstBlock();
        while( block.isValid() )
        {
            if( block.isVisible() )
                out << block.text() << "\n";

            block = block.next();
        }
        return true;
    }
    return false;
}

void MessagesDialog::buildTree( QTreeWidgetItem *parentItem,
                                vlc_object_t *p_obj )
{
    QTreeWidgetItem *item;

    if( parentItem )
        item = new QTreeWidgetItem( parentItem );
    else
        item = new QTreeWidgetItem( ui.modulesTree );

    char *name = vlc_object_get_name( p_obj );
    item->setText( 0, QString("%1%2 (0x%3)")
                   .arg( qfu( vlc_object_typename(p_obj) ) )
                   .arg( ( name != NULL )
                         ? QString( " \"%1\"" ).arg( qfu( name ) )
                             : "" )
                   .arg( (uintptr_t)p_obj, 0, 16 )
                 );
    free( name );
    item->setExpanded( true );

    size_t count = 0, size;
    vlc_object_t **tab = NULL;

    do
    {
        delete[] tab;
        size = count;
        tab = new vlc_object_t *[size];
        count = vlc_list_children(p_obj, tab, size);
    }
    while (size < count);

    for (size_t i = 0; i < count ; i++)
    {
        buildTree( item, tab[i] );
        vlc_object_release(tab[i]);
    }

    delete[] tab;
}

void MessagesDialog::updateOrClear()
{
    if( ui.mainTab->currentIndex() == 2)
    {
        ui.modulesTree->clear();
        buildTree( NULL, VLC_OBJECT( vlc_object_instance(p_intf) ) );
    }
    else if( ui.mainTab->currentIndex() == 0 )
        ui.messages->clear();
    else if( ui.mainTab->currentIndex() == 1 )
        ui.errors->clear();
#ifndef NDEBUG
    else
        updatePLTree();
#endif
}

void MessagesDialog::tabChanged( int i )
{
    updateButton->setIcon( i > 1 ? QIcon(":/menu/update.svg") : QIcon(":/menu/clear.svg") );
    updateButton->setToolTip( i > 1 ? qtr("Update the tree")
                                     : i == 0 ? qtr("Clear the messages")
                                              : qtr("Clear the errors"));
}

void MessagesDialog::showTab( int i )
{
    ui.mainTab->setCurrentIndex(i);
    show();
    raise();
}

void MessagesDialog::MsgCallback( void *self, int type, const vlc_log_t *item,
                                  const char *format, va_list ap )
{
    MessagesDialog *dialog = (MessagesDialog *)self;
    char *str;
    int verbosity = dialog->verbosity.load();

    if( verbosity < 0 || verbosity < (type - VLC_MSG_ERR)
     || unlikely(vasprintf( &str, format, ap ) == -1) )
        return;

    int canc = vlc_savecancel();
    QApplication::postEvent( dialog, new MsgEvent( type, item, str ) );
    vlc_restorecancel( canc );
    free( str );
}

#ifndef NDEBUG

void MessagesDialog::updatePLTree()
{
    pldebugTree->clear();
    {
        vlc_playlist_t* playlist = p_intf->p_playlist;
        vlc_playlist_Lock(playlist);
        size_t count = vlc_playlist_Count( playlist );
        for (size_t i = 0; i < count; i++)
        {
            QTreeWidgetItem *current = new QTreeWidgetItem();
            vlc_playlist_item_t* item = vlc_playlist_Get( playlist, i );
            input_item_t* media = vlc_playlist_item_GetMedia( item );
            current->setText( 0, qfu( media->psz_name ) );
            current->setToolTip( 0, qfu( media->psz_uri ) );
            current->setText( 1, QString("%1").arg( i ) );
            current->setText( 2, QString("%1").arg( (uintptr_t)media ) );
            //current->setText( 3, QString("0x%1").arg( p_node->i_flags, 0, 16 ) );
            current->setText( 3, QString("0x%1").arg( media->i_type, 0, 16 ) );
            pldebugTree->addTopLevelItem( current );
        }
        vlc_playlist_Unlock(playlist);
    }

    pldebugTree->expandAll();
    for ( int i=0; i< 4; i++ )
        pldebugTree->resizeColumnToContents( i );
}
#endif

Messung
CHZG
839710093

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover


Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.