Example #1
0
File: help.c Project: IAPark/vlc
static void Usage (vlc_object_t *p_this, char const *psz_search)
{
    bool b_has_advanced = false;
    bool found = false;
    unsigned i_only_advanced = 0; /* Number of modules ignored because they
                               * only have advanced options */
    bool strict = false;
    if (psz_search != NULL && psz_search[0] == '=')
    {
        strict = true;
        psz_search++;
    }

    bool color = false;
#ifndef _WIN32
    if (isatty(STDOUT_FILENO))
        color = var_InheritBool(p_this, "color");
#endif

    const bool desc = var_InheritBool(p_this, "help-verbose");
    const bool advanced = var_InheritBool(p_this, "advanced");

    /* Enumerate the config for each module */
    for (const vlc_plugin_t *p = vlc_plugins; p != NULL; p = p->next)
    {
        const module_t *m = p->module;
        const module_config_t *section = NULL;
        const char *objname = module_get_object(m);

        if (p->conf.count == 0)
            continue; /* Ignore modules without config options */
        if (!module_match(m, psz_search, strict))
            continue;
        found = true;

        if (!plugin_show(p, advanced))
        {   /* Ignore plugins with only advanced config options if requested */
            i_only_advanced++;
            continue;
        }

        /* Print name of module */
        printf(color ? "\n " GREEN "%s" GRAY " (%s)\n" : "\n %s (%s)\n",
               module_gettext(m, m->psz_longname), objname);
        if (m->psz_help != NULL)
            printf(color ? CYAN" %s\n"GRAY : " %s\n",
                   module_gettext(m, m->psz_help));

        /* Print module options */
        for (size_t j = 0; j < p->conf.size; j++)
        {
            const module_config_t *item = p->conf.items + j;

            if (item->b_removed)
                continue; /* Skip removed options */
            if (item->b_advanced && !advanced)
            {   /* Skip advanced options unless requested */
                b_has_advanced = true;
                continue;
            }
            print_item(m, item, &section, color, desc);
        }
    }

    if( b_has_advanced )
        printf(color ? "\n" WHITE "%s" GRAY " %s\n"
                     : "\n%s %s\n", _( "Note:" ), _( "add --advanced to your "
                                     "command line to see advanced options."));
    if( i_only_advanced > 0 )
    {
        printf(color ? "\n" WHITE "%s" GRAY " " : "\n%s ", _( "Note:" ) );
        printf(vlc_ngettext("%u module was not displayed because it only has "
               "advanced options.\n", "%u modules were not displayed because "
               "they only have advanced options.\n", i_only_advanced),
               i_only_advanced);
    }
    else if (!found)
        printf(color ? "\n" WHITE "%s" GRAY "\n" : "\n%s\n",
               _("No matching module found. Use --list or "
                 "--list-verbose to list available modules."));
}
Example #2
0
/*********************************************************************
 * The Tree
 *********************************************************************/
PrefsTree::PrefsTree( intf_thread_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, itemExpanded(QTreeWidgetItem*), this, resizeColumns() );

    /* Nice icons */
#define BI( a,b) QIcon a##_icon = QIcon( b )
    BI( audio, ":/prefsmenu/advanced/audio" );
    BI( video, ":/prefsmenu/advanced/video" );
    BI( input, ":/prefsmenu/advanced/codec" );
    BI( sout, ":/prefsmenu/advanced/sout" );
    BI( advanced, ":/prefsmenu/advanced/extended" );
    BI( playlist, ":/prefsmenu/advanced/playlist" );
    BI( interface, ":/prefsmenu/advanced/intf" );
#undef BI

    /* Build the tree for the main module */
    module_t *p_module = module_get_main();

    /* Initialisation and get the confsize */
    PrefsItemData *data = NULL;
    PrefsItemData *data_sub = NULL;
    QTreeWidgetItem *current_item = NULL;
    unsigned confsize;
    module_config_t *const p_config = module_config_get (p_module, &confsize);

    /* Go through the list of conf */
    for( size_t i = 0; i < confsize; i++ )
    {
        const char *psz_help;
        QIcon icon;

        /* Work on a new item */
        module_config_t *p_item = p_config + i;

        switch( p_item->i_type )
        {
        /* This is a category */
        case CONFIG_CATEGORY:
            if( p_item->value.i == -1 ) break;

            /* PrefsItemData Init */
            data = new PrefsItemData( this );
            data->name = qtr( config_CategoryNameGet( p_item->value.i ) );
            psz_help = config_CategoryHelpGet( p_item->value.i );
            if( psz_help )
                data->help = qtr( psz_help );
            else
                data->help.clear();
            data->i_type = PrefsItemData::TYPE_CATEGORY;
            data->i_object_id = p_item->value.i;

            /* This is a category, put a nice icon */
            switch( p_item->value.i )
            {
#define CI(a,b) case a: icon = b##_icon;break
            CI( CAT_AUDIO, audio );
            CI( CAT_VIDEO, video );
            CI( CAT_INPUT, input );
            CI( CAT_SOUT, sout );
            CI( CAT_ADVANCED, advanced );
            CI( CAT_PLAYLIST, playlist );
            CI( CAT_INTERFACE, interface );
            }
#undef CI

            /* Create a new QTreeItem to display it in the tree at top level */
            current_item = new QTreeWidgetItem();
            current_item->setText( 0, data->name );
            current_item->setIcon( 0 , icon );
            //current_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
            current_item->setData( 0, Qt::UserRole,
                                   qVariantFromValue( data ) );
            addTopLevelItem( current_item );
            expandItem( current_item );
            break;

        /* This is a subcategory */
        case CONFIG_SUBCATEGORY:
            if( p_item->value.i == -1 ) break;

            /* Special cases: move the main subcategories to the parent cat*/
            if( data &&
                ( p_item->value.i == SUBCAT_VIDEO_GENERAL ||
                  p_item->value.i == SUBCAT_ADVANCED_MISC ||
                  p_item->value.i == SUBCAT_INPUT_GENERAL ||
                  p_item->value.i == SUBCAT_INTERFACE_GENERAL ||
                  p_item->value.i == SUBCAT_SOUT_GENERAL||
                  p_item->value.i == SUBCAT_PLAYLIST_GENERAL||
                  p_item->value.i == SUBCAT_AUDIO_GENERAL ) )
            {
                /* Data still contains the correct thing */
                data->i_type = PrefsItemData::TYPE_CATSUBCAT;
                data->i_subcat_id = p_item->value.i;
                data->name = qtr( config_CategoryNameGet( p_item->value.i ) );
                psz_help = config_CategoryHelpGet( p_item->value.i );
                if( psz_help )
                    data->help = qtr( psz_help );
                else
                    data->help.clear();
                current_item->setData( 0, Qt::UserRole,
                                       QVariant::fromValue( data ) );
                continue;
            }

            /* Normal Subcategories */

            /* Process the Data */
            data_sub = new PrefsItemData( this );
            data_sub->name = qtr( config_CategoryNameGet( p_item->value.i) );
            psz_help = config_CategoryHelpGet( p_item->value.i );
            if( psz_help )
                data_sub->help = qtr( psz_help );
            else
                data_sub->help.clear();
            data_sub->i_type = PrefsItemData::TYPE_SUBCATEGORY;
            data_sub->i_object_id = p_item->value.i;

            /* Create a new TreeWidget */
            QTreeWidgetItem *subcat_item = new QTreeWidgetItem();
            subcat_item->setText( 0, data_sub->name );
            subcat_item->setData( 0, Qt::UserRole,
                                  qVariantFromValue( data_sub ) );
            //subcat_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );

            /* Add it to the parent */
            assert( current_item );
            current_item->addChild( subcat_item );
            break;

        /* Other items don't need yet a place on the tree */
        }
    }
    module_config_free( p_config );

    /* Build the tree of plugins */
    for( size_t i = 0; i < count; i++ )
    {
        p_module = p_list[i];
        // Main module excluded
        if( module_is_main( p_module) ) continue;

        unsigned  confsize;
        int i_subcategory = 0, i_category = 0;

        bool b_options = false;
        module_config_t *const p_config = module_config_get (p_module, &confsize);

        /* Loop through the configurations items */
        for (size_t i = 0; i < confsize; i++)
        {
            const module_config_t *p_item = p_config + i;

            if( p_item->i_type == CONFIG_CATEGORY )
                i_category = p_item->value.i;
            else if( p_item->i_type == CONFIG_SUBCATEGORY )
                i_subcategory = p_item->value.i;

            if( CONFIG_ITEM(p_item->i_type) )
                b_options = true;

            if( b_options && i_category && i_subcategory )
                break;
        }
        module_config_free (p_config);

        /* Dummy item, please proceed */
        if( !b_options || i_category == 0 || i_subcategory == 0 ) continue;


        // Locate the category item;
        QTreeWidgetItem *subcat_item = NULL;
        bool b_found = false;

        for( int i_cat_index = 0 ; i_cat_index < topLevelItemCount();
                                   i_cat_index++ )
        {
            /* Get the treeWidgetItem that correspond to the category */
            QTreeWidgetItem *cat_item = topLevelItem( i_cat_index );
            PrefsItemData *data = cat_item->data( 0, Qt::UserRole ).
                                             value<PrefsItemData *>();

            /* If we match the good category */
            if( data->i_object_id == i_category )
            {
                for( int i_sc_index = 0; i_sc_index < cat_item->childCount();
                         i_sc_index++ )
                {
                    subcat_item = cat_item->child( i_sc_index );
                    PrefsItemData *sc_data = subcat_item->data(0, Qt::UserRole).
                                                value<PrefsItemData *>();
                    if( sc_data && sc_data->i_object_id == i_subcategory )
                    {
                        b_found = true;
                        break;
                    }
                }
                if( !b_found )
                {
                    subcat_item = cat_item;
                    b_found = true;
                }
                break;
            }
        }
        if( !b_found ) continue;

        PrefsItemData *module_data = new PrefsItemData( this );
        module_data->i_type = PrefsItemData::TYPE_MODULE;
        module_data->psz_shortcut = strdup( module_get_object( p_module ) );
        module_data->name = qtr( module_get_name( p_module, false ) );
        module_data->help.clear();
        module_data->p_module = p_module;
        const char *psz_help = module_get_help( p_module );
        if ( psz_help )
            module_data->help = qtr( psz_help );

        QTreeWidgetItem *module_item = new QTreeWidgetItem();
        module_item->setText( 0, module_data->name );
        module_item->setData( 0, Qt::UserRole,
                              QVariant::fromValue( module_data) );
        //module_item->setSizeHint( 0, QSize( -1, ITEM_HEIGHT ) );
        subcat_item->addChild( module_item );
    }

    /* We got everything, just sort a bit */
    sortItems( 0, Qt::AscendingOrder );

    resizeColumnToContents( 0 );
}
Example #3
0
File: file.c Project: 0xheart0/vlc
/**
 * Saves the in-memory configuration into a file.
 * @return 0 on success, -1 on error.
 */
int config_SaveConfigFile (vlc_object_t *p_this)
{

    if( config_PrepareDir( p_this ) )
    {
        msg_Err( p_this, "no configuration directory" );
        return -1;
    }

    /*
     * Save module config in file
     */
    char *temporary;
    char *permanent = config_GetConfigFile (p_this);
    if (permanent == NULL)
        return -1;
    if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1)
    {
        free (permanent);
        return -1;
    }
    else
    {
        struct stat st;

        /* Some users make vlcrc read-only to prevent changes.
         * The atomic replacement scheme breaks this "feature",
         * so we check for read-only by hand. */
        if (stat (permanent, &st) == 0 && !(st.st_mode & S_IWUSR))
        {
            msg_Err (p_this, "configuration file is read-only");
            goto error;
        }
    }

    /* Configuration lock must be taken before vlcrc serializer below. */
    vlc_rwlock_rdlock (&config_lock);

    /* The temporary configuration file is per-PID. Therefore this function
     * should be serialized against itself within a given process. */
    static vlc_mutex_t lock = VLC_STATIC_MUTEX;
    vlc_mutex_lock (&lock);

    int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
    if (fd == -1)
    {
        vlc_rwlock_unlock (&config_lock);
        vlc_mutex_unlock (&lock);
        goto error;
    }
    FILE *file = fdopen (fd, "wt");
    if (file == NULL)
    {
        msg_Err (p_this, "cannot create configuration file: %s",
                 vlc_strerror_c(errno));
        vlc_rwlock_unlock (&config_lock);
        vlc_close (fd);
        vlc_mutex_unlock (&lock);
        goto error;
    }

    fprintf( file,
        "\xEF\xBB\xBF###\n"
        "###  "PACKAGE_NAME" "PACKAGE_VERSION"\n"
        "###\n"
        "\n"
        "###\n"
        "### lines beginning with a '#' character are comments\n"
        "###\n"
        "\n" );

    /* Ensure consistent number formatting... */
    locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
    locale_t baseloc = uselocale (loc);

    /* We would take the config lock here. But this would cause a lock
     * inversion with the serializer above and config_AutoSaveConfigFile().
    vlc_rwlock_rdlock (&config_lock);*/

    /* Look for the selected module, if NULL then save everything */
    size_t count;
    module_t **list = module_list_get (&count);
    for (size_t i = 0; i < count; i++)
    {
        module_t *p_parser = list[i];
        module_config_t *p_item, *p_end;

        if( !p_parser->i_config_items )
            continue;

        fprintf( file, "[%s]", module_get_object (p_parser) );
        if( p_parser->psz_longname )
            fprintf( file, " # %s\n\n", p_parser->psz_longname );
        else
            fprintf( file, "\n\n" );

        for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize;
             p_item < p_end;
             p_item++ )
        {
            if (!CONFIG_ITEM(p_item->i_type)   /* ignore hint */
             || p_item->b_removed              /* ignore deprecated option */
             || p_item->b_unsaveable)          /* ignore volatile option */
                continue;

            if (IsConfigIntegerType (p_item->i_type))
            {
                int64_t val = p_item->value.i;
                config_Write (file, p_item->psz_text,
                             (CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL)
                                  ? N_("boolean") : N_("integer"),
                              val == p_item->orig.i,
                              p_item->psz_name, "%"PRId64, val);
            }
            else
            if (IsConfigFloatType (p_item->i_type))
            {
                float val = p_item->value.f;
                config_Write (file, p_item->psz_text, N_("float"),
                              val == p_item->orig.f,
                              p_item->psz_name, "%f", val);
            }
            else
            {
                const char *psz_value = p_item->value.psz;
                bool modified;

                assert (IsConfigStringType (p_item->i_type));

                modified = !!strcmp (psz_value ? psz_value : "",
                                     p_item->orig.psz ? p_item->orig.psz : "");
                config_Write (file, p_item->psz_text, N_("string"),
                              !modified, p_item->psz_name, "%s",
                              psz_value ? psz_value : "");
            }
        }
    }
    vlc_rwlock_unlock (&config_lock);

    module_list_free (list);
    if (loc != (locale_t)0)
    {
        uselocale (baseloc);
        freelocale (loc);
    }

    /*
     * Flush to disk and replace atomically
     */
    fflush (file); /* Flush from run-time */
    if (ferror (file))
    {
        vlc_unlink (temporary);
        vlc_mutex_unlock (&lock);
        msg_Err (p_this, "cannot write configuration file");
        fclose (file);
        goto error;
    }
#if defined(__APPLE__) || defined(__ANDROID__)
    fsync (fd); /* Flush from OS */
#else
    fdatasync (fd); /* Flush from OS */
#endif
#if defined (_WIN32) || defined (__OS2__)
    /* Windows cannot (re)move open files nor overwrite existing ones */
    fclose (file);
    vlc_unlink (permanent);
#endif
    /* Atomically replace the file... */
    if (vlc_rename (temporary, permanent))
        vlc_unlink (temporary);
    /* (...then synchronize the directory, err, TODO...) */
    /* ...and finally close the file */
    vlc_mutex_unlock (&lock);
#if !defined (_WIN32) && !defined (__OS2__)
    fclose (file);
#endif

    free (temporary);
    free (permanent);
    return 0;

error:
    free (temporary);
    free (permanent);
    return -1;
}