Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  complete_preferences.cpp   Sprache: C

 

/*****************************************************************************
 * complete_preferences.cpp : "Normal preferences"
 ****************************************************************************
 * Copyright (C) 2006-2011 the VideoLAN team
 *
 * Authors: Clément Stenac <zorglub@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 <QApplication>
#include <QLabel>
#include <QTreeWidget>
#include <QString>
#include <QFont>
#include <QGroupBox>
#include <QScrollArea>
#include <QVBoxLayout>
#include <QGridLayout>

#include "dialogs/preferences/complete_preferences.hpp"
#include "dialogs/preferences/preferences_widgets.hpp"

#include <vlc_modules.h>
#include <cassert>

#define ITEM_HEIGHT 25

/*********************************************************************
 * The Tree
 *********************************************************************/

PrefsTree::PrefsTree( qt_intf_t *_p_intf, QWidget *_parent,
                      module_t **p_list, size_t count ) :
                            QTreeWidget( _parent ), p_intf( _p_intf )
{
    b_show_only_loaded = false;
    /* General Qt options */
    setAlternatingRowColors( true );
    setHeaderHidden( true );

    setIconSize( QSize( ITEM_HEIGHT, ITEM_HEIGHT ) );
    setTextElideMode( Qt::ElideNone );

    setUniformRowHeights( true );
    connect( this, &PrefsTree::itemExpanded, this, &PrefsTree::resizeColumns );

    main_module = module_get_main();
    assert( main_module );

    enum vlc_config_cat cat = CAT_UNKNOWN;
    enum vlc_config_subcat subcat = SUBCAT_UNKNOWN;
    QTreeWidgetItem *cat_item = nullptr;

    /* Create base cat/subcat tree from core config set */
    unsigned confsize;
    module_t *p_module = main_module;
    module_config_t *const p_config = module_config_get (p_module, &confsize);
    for( size_t i = 0; i < confsize; i++ )
    {
        module_config_t *p_item = p_config + i;

        if( p_item->i_type != CONFIG_SUBCATEGORY )
            continue;

        subcat = (enum vlc_config_subcat) p_item->value.i;
        cat = vlc_config_cat_FromSubcat(subcat);

        if( cat == CAT_UNKNOWN || cat == CAT_HIDDEN )
            continue;

        /* Create parent cat node? */
        if( findCatItem(cat) == nullptr )
            cat_item = createCatNode( cat );

        // Create subcat node
        // Note that this is done conditionally, primarily because we must take
        // no action here for 'general' subcats (which are merged into the
        // parent category node), but also just out of caution should a mistake
        // result in more than one instance of a subcat to be present within the
        // core option set.
        if( findSubcatItem( subcat ) == nullptr )
            createSubcatNode( cat_item, subcat );
    }
    module_config_free( p_config );

    /* Add nodes for plugins */
    /* A plugin gets one node for its entire set, located based on the first used subcat */
    for( size_t i = 0; i < count; i++ )
    {
        p_module = p_list[i];

        /* Main module is already covered above */
        if( module_is_main( p_module) )
            continue;

        unsigned confsize;
        module_config_t *const p_config = module_config_get (p_module, &confsize);

        /* Get the first (used) subcat */
        cat = CAT_UNKNOWN;
        subcat = SUBCAT_UNKNOWN;
        bool has_options = false;
        for (size_t i = 0; i < confsize; i++)
        {
            const module_config_t *p_item = p_config + i;

            if( p_item->i_type == CONFIG_SUBCATEGORY )
            {
                subcat = (enum vlc_config_subcat) p_item->value.i;
                cat = vlc_config_cat_FromSubcat( subcat );
                continue;
            }

            if( CONFIG_ITEM(p_item->i_type) )
            {
                has_options = true;
                /* If cat lookup worked, we can stop now, else keep looking */
                if( cat != CAT_UNKNOWN )
                    break;
            }
        }
        module_config_free (p_config);

        /* No options, or definitely no place to place it in the tree - ignore */
        if( !has_options || cat == CAT_UNKNOWN || cat == CAT_HIDDEN )
            continue;

        /* Locate the category item */
        /* If not found (very unlikely), we will create it */
        cat_item = findCatItem( cat );
        if ( !cat_item )
            cat_item = createCatNode( cat );

        /* Locate the subcategory item */
        /* If not found (was not used in the core option set - quite possible), we will create it */
        QTreeWidgetItem *subcat_item = findSubcatItem( subcat );
        if( !subcat_item )
            subcat_item = createSubcatNode( cat_item, subcat );

        createPluginNode( subcat_item, p_module );
    }

    // We got everything, just sort a bit.
    // We allow the subcat and plugin nodes to be alphabetical, but we force
    // the top-level cat nodes into a preferred order.
    sortItems( 0, Qt::AscendingOrder );
    unsigned index = 0;
    for (unsigned i = 0; i < vlc_config_cat_Count(); i++)
    {
        const config_category_t *cat = vlc_config_cat_GetAt(i);
        cat_item = findCatItem(cat->id);
        if ( cat_item == NULL )
            continue;
        unsigned cur_index = (unsigned)indexOfTopLevelItem( cat_item );
        if (cur_index != index)
        {
            insertTopLevelItem( index, takeTopLevelItem( cur_index ) );
            expandItem( cat_item );
        }
        ++index;
    }

    resizeColumnToContents( 0 );
}

QTreeWidgetItem *PrefsTree::createCatNode( enum vlc_config_cat cat )
{
    enum vlc_config_subcat general_subcat = vlc_config_cat_GetGeneralSubcat( cat );
    assert(general_subcat != SUBCAT_UNKNOWN && general_subcat != SUBCAT_HIDDEN);

    PrefsTreeItem *item = new PrefsTreeItem( PrefsTreeItem::CATEGORY_NODE );

    item->cat_id = cat;
    item->subcat_id = general_subcat;
    item->p_module = this->main_module;
    item->name = qfu( vlc_config_subcat_GetName( general_subcat ) );
    item->help = qfu( vlc_config_subcat_GetHelp( general_subcat ) );

    QIcon icon;
    switch( cat )
    {
#define CI(a,b) case a: icon = QIcon( b );break
        CI( CAT_AUDIO,     ":/prefsmenu/advprefs_audio.svg"    );
        CI( CAT_VIDEO,     ":/prefsmenu/advprefs_video.svg"    );
        CI( CAT_INPUT,     ":/prefsmenu/advprefs_codec.svg"    );
        CI( CAT_SOUT,      ":/prefsmenu/advprefs_sout.svg"     );
        CI( CAT_ADVANCED,  ":/prefsmenu/advprefs_extended.svg" );
        CI( CAT_PLAYLIST,  ":/prefsmenu/advprefs_playlist.svg" );
        CI( CAT_INTERFACE, ":/prefsmenu/advprefs_intf.svg"     );
#undef CI
        default: break;
    }

    item->setText( 0, qfu( vlc_config_cat_GetName( cat ) ) );
    item->setIcon( 0, icon );
    //current_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );

    this->catMap[cat] = item;
    this->subcatMap[general_subcat] = item;

    addTopLevelItem( item );
    expandItem( item );

    return item;
}

QTreeWidgetItem *PrefsTree::createSubcatNode( QTreeWidgetItem * cat, enum vlc_config_subcat subcat )
{
    assert( cat );

    PrefsTreeItem *item = new PrefsTreeItem( PrefsTreeItem::SUBCATEGORY_NODE );

    item->cat_id = CAT_UNKNOWN;
    item->subcat_id = subcat;
    item->p_module = this->main_module;
    item->name = qfu( vlc_config_subcat_GetName( subcat ) );
    item->help = qfu( vlc_config_subcat_GetHelp( subcat ) );

    item->setText( 0, item->name );
    //item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );

    this->subcatMap[subcat] = item;

    cat->addChild( item );

    return item;
}

void PrefsTree::createPluginNode( QTreeWidgetItem * parent, module_t *mod )
{
    assert( parent );

    PrefsTreeItem *item = new PrefsTreeItem( PrefsTreeItem::PLUGIN_NODE );

    item->cat_id = CAT_UNKNOWN;
    item->subcat_id = SUBCAT_UNKNOWN;
    item->p_module = mod;
    item->module_name = strdup( module_get_object( mod ) );
    item->name = qfut( module_get_name( mod, false ) );
    const char *help = module_get_help( mod );
    if( help )
        item->help = qfut( help );
    const char *help_html = module_get_help_html( mod );
    if( help_html )
        item->help_html = qfut( help_html );

    item->setText( 0, item->name );
    //item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );

    parent->addChild( item );
}

QTreeWidgetItem *PrefsTree::findCatItem( enum vlc_config_cat cat )
{
    auto it = this->catMap.find(cat);
    if (it == std::end(this->catMap))
        return NULL;
    return it->second;
}

QTreeWidgetItem *PrefsTree::findSubcatItem( enum vlc_config_subcat subcat )
{
    auto it = this->subcatMap.find(subcat);
    if (it == std::end(this->subcatMap))
        return NULL;
    return it->second;
}

void PrefsTree::applyAll()
{
    for( int i_cat_index = 0 ; i_cat_index < topLevelItemCount();
             i_cat_index++ )
    {
        PrefsTreeItem *cat_item = topLevelItem( i_cat_index );
        for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
                 i_sc_index++ )
        {
            PrefsTreeItem *subcat_item = cat_item->child( i_sc_index );
            for( int i_module = 0 ; i_module < subcat_item->childCount();
                     i_module++ )
            {
                PrefsTreeItem *mod_item = subcat_item->child( i_module );
                if( mod_item->panel )
                    mod_item->panel->apply();
            }
            if( subcat_item->panel )
                subcat_item->panel->apply();
        }
        if( cat_item->panel )
            cat_item->panel->apply();
    }
}

/* apply filter on tree item and recursively on its sub items
 * returns whether the item was filtered */

bool PrefsTree::filterItems( PrefsTreeItem *item, const QString &text,
                           Qt::CaseSensitivity cs )
{
    bool sub_filtered = true;

    for( int i = 0; i < item->childCount(); i++ )
    {
        PrefsTreeItem *sub_item = item->child( i );
        if ( !filterItems( sub_item, text, cs ) )
        {
            /* not all the sub items were filtered */
            sub_filtered = false;
        }
    }

    bool filtered = sub_filtered && !item->contains( text, cs );
    if ( b_show_only_loaded && sub_filtered && !item->module_is_loaded )
        filtered = true;
    item->setHidden( filtered );

    return filtered;
}

void PrefsTree::unfilterItems( PrefsTreeItem *item )
{
    item->setHidden( false );
    for( int i = 0; i < item->childCount(); i++ )
        unfilterItems( item->child( i ) );
}

static void populateLoadedSet( QSet<QString> *loaded, vlc_object_t *p_node )
{
    Q_ASSERT( loaded );
    char *name = vlc_object_get_name( p_node );
    if ( !EMPTY_STR( name ) ) loaded->insert( QString( name ) );
    free( name );

    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_node, tab, size);
    }
    while (size < count);

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

    delete[] tab;
}

/* Updates the plugin node 'loaded' status to reflect currently
 * running modules */

void PrefsTree::updateLoadedStatus( PrefsTreeItem *item = NULL,
                                    QSet<QString> *loaded = NULL )
{
    bool b_release = false;

    if( loaded == NULL )
    {
        vlc_object_t *p_root = VLC_OBJECT( vlc_object_instance(p_intf) );
        loaded = new QSet<QString>();
        populateLoadedSet( loaded, p_root );
        b_release = true;
    }

    if ( item == NULL )
    {
        for( int i = 0 ; i < topLevelItemCount(); i++ )
            updateLoadedStatus( topLevelItem( i ), loaded );
    }
    else
    {
        if( item->node_type == PrefsTreeItem::PLUGIN_NODE )
            item->module_is_loaded = loaded->contains( QString( item->module_name ) );

        for( int i = 0; i < item->childCount(); i++ )
            updateLoadedStatus( item->child( i ), loaded );
    }

    if ( b_release )
        delete loaded;
}

/* apply filter on tree */
void PrefsTree::filter( const QString &text )
{
    bool clear_filter = text.isEmpty() && ! b_show_only_loaded;

    updateLoadedStatus();

    for( int i = 0 ; i < topLevelItemCount(); i++ )
    {
        PrefsTreeItem *cat_item = topLevelItem( i );
        if ( clear_filter )
            unfilterItems( cat_item );
        else
            filterItems( cat_item, text, Qt::CaseInsensitive );
    }
}

void PrefsTree::setLoadedOnly( bool b_only )
{
    b_show_only_loaded = b_only;
    filter( "" );
}

void PrefsTree::resizeColumns()
{
    resizeColumnToContents( 0 );
}

PrefsTreeItem::PrefsTreeItem( PrefsTreeItemType ty ) : QTreeWidgetItem(ty)
{
    node_type = ty;
    panel = nullptr;
    cat_id = CAT_UNKNOWN;
    subcat_id = SUBCAT_UNKNOWN;
    p_module = nullptr;
    module_name = nullptr;
    module_is_loaded = false;
}

/* go over the config items and search text in psz_text
 * also search the node name and head */

bool PrefsTreeItem::contains( const QString &text, Qt::CaseSensitivity cs )
{
    bool is_core = this->node_type != PrefsTreeItem::PLUGIN_NODE;
    enum vlc_config_subcat id = this->subcat_id;
    module_t *p_module = this->p_module;

    /* check the node itself (its name/longname/helptext) */

    QString head;
    if( !is_core )
        head = QString( qfut( module_GetLongName( p_module ) ) );

    if ( name.contains( text, cs )
         || (!is_core && head.contains( text, cs ))
         || (!help_html.isEmpty() ? help_html.contains( text, cs ) : help.contains( text, cs ))
       )
    {
        return true;
    }

    /* check options belonging to this core subcat or plugin */

    unsigned confsize;
    module_config_t *const p_config = module_config_get (p_module, &confsize),
                    *p_item = p_config,
                    *p_end = p_config + confsize;

    if( !p_config )
        return false;

    bool ret = false;

    if( is_core )
    {
        /* find start of relevant option block */
        while ( p_item < p_end )
        {
            if( p_item->i_type == CONFIG_SUBCATEGORY &&
                p_item->value.i == id
              )
                break;
            p_item++;
        }
        if( ++p_item >= p_end )
        {
            ret = false;
            goto end;
        }
    }

    do
    {
        if ( p_item->i_type == CONFIG_SUBCATEGORY )
        {
            /* for core, if we hit a subcat, stop */
            if ( is_core )
                break;
            /* a plugin's options are grouped under one node; we can/should
               ignore all other subcat entries. */

            continue;
        }

        /* cat-hint items are not relevant, they are an alternate set of headings for help output */
        if( p_item->i_type == CONFIG_HINT_CATEGORY ) continue;

        if ( p_item->psz_text && qfut( p_item->psz_text ).contains( text, cs ) )
        {
            ret = true;
            goto end;
        }
    }
    while ( ++p_item < p_end );

end:
    module_config_free( p_config );
    return ret;
}

/*********************************************************************
 * The Panel
 *********************************************************************/


AdvPrefsPanel::AdvPrefsPanel( qt_intf_t *_p_intf, QWidget *_parent,
                        PrefsTreeItem * node ) :
                        QWidget( _parent ), p_intf( _p_intf )
{
    module_t *p_module = node->p_module;

    unsigned confsize;
    p_config = module_config_get( p_module, &confsize );
    module_config_t *p_item = p_config,
                    *p_end = p_config + confsize;

    QString heading;

    if( node->node_type != PrefsTreeItem::PLUGIN_NODE  )
    {
        heading = QString( node->name );
        /* Skip to the relevant part of the core config */
        while (p_item < p_end)
        {
            if(  p_item->i_type == CONFIG_SUBCATEGORY &&
                 p_item->value.i == node->subcat_id )
                break;
            p_item++;
        }
        p_item++; // Skip past the subcat entry itself
    }
    else
    {
        heading = QString( qfut( module_GetLongName( p_module ) ) );
    }

    /* Widgets now */
    global_layout = new QVBoxLayout();
    global_layout->setContentsMargins(2, 2, 2, 2);

    QLabel *titleLabel = new QLabel( heading );
    QFont titleFont = QApplication::font();
    titleFont.setPointSize( titleFont.pointSize() + 6 );
    titleLabel->setFont( titleFont );

    // Title <hr>
    QFrame *title_line = new QFrame;
    title_line->setFrameShape(QFrame::HLine);
    title_line->setFrameShadow(QFrame::Sunken);

    QLabel *helpLabel = new QLabel( this );
    helpLabel->setWordWrap( true );
    if( node->help_html.isEmpty() )
    {
        helpLabel->setText( node->help );
        helpLabel->setTextFormat( Qt::PlainText );
    }
    else
    {
        helpLabel->setText( node->help_html );
        helpLabel->setTextFormat( Qt::RichText );
        helpLabel->setOpenExternalLinks( true );
    }

    global_layout->addWidget( titleLabel );
    global_layout->addWidget( title_line );
    global_layout->addWidget( helpLabel );

    QGroupBox *box = NULL;
    QGridLayout *boxlayout = NULL;

    QScrollArea *scroller= new QScrollArea;
    scroller->setFrameStyle( QFrame::NoFrame );
    QWidget *scrolled_area = new QWidget;

    QGridLayout *layout = new QGridLayout();
    int i_line = 0, i_boxline = 0;
    bool has_hotkey = false;

    if( p_item ) for ( ; p_item < p_end; ++p_item)
    {
        if( p_item->i_type == CONFIG_SUBCATEGORY )
        {
            if( node->node_type == PrefsTreeItem::PLUGIN_NODE )
                continue;
            else
                break;
        }

        if( p_item->i_type == CONFIG_SECTION )
        {
            if( box && i_boxline > 0 )
            {
                box->setLayout( boxlayout );
                box->show();
                layout->addWidget( box, i_line, 0, 1, -1 );
                i_line++;
            }
            i_boxline = 0;
            box = new QGroupBox( qfut( p_item->psz_text ), this );
            box->hide();
            boxlayout = new QGridLayout();
        }

        /* Only one hotkey control */
        if( p_item->i_type == CONFIG_ITEM_KEY )
        {
            if( has_hotkey )
                continue;
            has_hotkey = true;
        }

        ConfigControl *control;
        if( ! box )
            control = ConfigControl::createControl( p_item, this,
                                                    layout, i_line );
        else
            control = ConfigControl::createControl( p_item, this,
                                                    boxlayout, i_boxline );
        if( !control )
            continue;

        if( box ) i_boxline++;
        else i_line++;
        controls.append( control );
    }

    if( box && i_boxline > 0 )
    {
        box->setLayout( boxlayout );
        box->show();
        layout->addWidget( box, i_line, 0, 1, -1 );
    }

    scrolled_area->setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed );
    scrolled_area->setLayout( layout );
    scroller->setWidget( scrolled_area );
    scroller->setWidgetResizable( true );
    global_layout->addWidget( scroller );
    setLayout( global_layout );
}

void AdvPrefsPanel::apply()
{
    foreach ( ConfigControl *cfg, controls )
        cfg->doApply();
}

void AdvPrefsPanel::clean()
{}

AdvPrefsPanel::~AdvPrefsPanel()
{
    qDeleteAll( controls );
    controls.clear();
    module_config_free( p_config );
}

Messung
CHZG
83979993

¤ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet am  2026-11-04) ¤

*© 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1104857
#Domains=418424