ToolbarsAndUserLevel/fr

From Wiki.ooo4kids.org

Jump to: navigation, search

DRF Back alt.png [[Main_Page/{{{2}}}|OOo4Kids]]

Barres d'outils qui dépendent du niveau de l'utilisateur

À propos du code proposé dans cette page : tous les changements par rapport au code original d'OpenOffice.org ayant servi de base, et fournis dans cette page, sont :


Introduction

Ci-dessous, vous trouverez une description technique de l'implémentation de la fonctionnalité : Barres d'outils qui dépendent du niveau de l'utilisateur. Il est ainsi question de code source (C++), de la couche graphique, côté interface utilisateur, dite "layout", de l'implémentation UNO du gestionnaire de la couche graphique, de la gestion des barres d'outils dans sfx2 (workwin), et de quelques autres points techniques comme la notion de shell graphique, et la lecture du niveau de l'utilisateur à l'aide du gestionnaire de configuration (config manager) . Nous supposons que le lecteur possède les bases nécessaires pour lire et comprendre le contenu de ce qui est exposé.

Les pré-requis pour lire cet article sont encore à définir, mais si certaines notions ne vous sont pas familières, nous vous invitons à consulter le wiki d'OpenOffice.org pour compléter vos connaissances, afin de pouvoir lire cet article dans les meilleures conditions possibles.


Objectifs

Cette fonctionnalité est couplée à Choix du niveau de l'utilisateur dans les préférences, et vise d'avoir une barre principale d'outils par niveau , dans les applications :

Pour chaque application citée ci-dessus, le même nom de barre d'outils sera utilisé, avec l'idée d'avoir, comme barre visible, soit :

La règle : Parmi les barres d'outils précédentes, une seule doit être visible à la fois.


Specifications

Le besoin a été décrit à la page Idées et suggestions de ce wiki.

Comportement attendu : lorsque l'utilisateur modifie le niveau d'utilisateur en cliquant sur le bouton radio ( cliquer sur l'image pour agrandir), la barre d'outils principale change immédiatement.


Preferences niveau utilisateur.png


Writer (par exemple)

Comme proposé, l'idée est d'avoir une barre d'outil par niveau d'utilisateur.

La proposition concerne pour l'instant Writer seulement, mais la fonctionnalité peut immédiatement être étendue aux autres applications (en attente de participation des enseignants ... ).

Niveau débutant

Pour enfants, entre 8 et 9 ans :

Barre cycle2.png

Niveau moyen

Pour enfants entre 10 et 11 ans :

Barre cycle3.png


Niveau Expert

Enfants au delà de 11 ans :

Barre standard.png


Dans le Code

Traduction en cours

-> Les changements concernant OOo4Kids sont protégés par des #ifdef OOo4Kids ... #endif


Modules concernés

En fait, la fonctionnalité possède deux faces distinctes, présentées ci-dessous :

Enfin: vérifier la possibilité d'ajouter les barres d'outils (à confirmer).

Ce n'est PAS la solution définitive car : sc, sfx2, svx, svx utilisent le même code pour lire/écrire le niveau de l'utilisateur dans le fichier Common.xcu, et une factorisation, ainsi qu'un nettoyage de code seront nécessaires prochainement. Une meilleurs solution pourrait consister à créer une classe permettant de lire écrire dans Common.xcu dans l'un des modules comme tools ou configmgr, mais cela demande quelque attention et réflexion. Probablement après la 1.0



Module svx

Les parties suivantes doivent être modifiées dans le fichier optgdlg.cxx (placé dans svx/source/cui) :

static const OUString sULConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
static const OUString sULAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );
static const OUString sULaNode( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Misc" ) );
static const OUString sULPropertyName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserLevel" ) ) );

Autres chaînes utiles :

/* adapt the toolbars to the level */

static const OUString aLayoutManagerPropName( RTL_CONSTASCII_USTRINGPARAM( "LayoutManager" ) );

// The alignment bar
// static const OUString sAlignmentToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/alignmentbar" ) );
// The standard toolbar
static const OUString sStandardbarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/standardbar" ) );
// The beginner toolbar (every application has its own)
static const OUString sBeginnerbarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/beginner" ) );
// The average toolbar (every application has its own)
static const OUString sAveragebarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/average" ) );



static short setToolbarState( const OUString sSetAToolbarTypeName, bool isTrue )
{
    try
    {
        // avoids a crash if ever the user opens the prefs while the start center is the current view
        if ( ! (SfxViewFrame::Current()) )
            return -1;
        
        Reference< XPropertySet > xPropSet( SfxViewFrame::Current()->GetFrame()->GetFrameInterface(), UNO_QUERY );
        Reference< XLayoutManager > xLayoutManager;

        if ( xPropSet.is() )
        {
            Any aValue = xPropSet->getPropertyValue( aLayoutManagerPropName );
            aValue >>= xLayoutManager;
        }

        if ( !xLayoutManager.is() )
            return -1;
        else
        {
            xLayoutManager->lock();

            if ( isTrue )
                xLayoutManager->requestElement( sSetAToolbarTypeName );
            else
                xLayoutManager->destroyElement( sSetAToolbarTypeName );

            // should refresh, but does not when showElement() is used
            xLayoutManager->unlock();
        }
    }
    catch( Exception& )
    {
    }
    return 0;
}


Note: les barres d'outils sont initialisées en même temps que les boutons radio quand la fenêtre des préférences est instanciée.


    // initialize the Radio button (User Level)
    switch ( getUserLevel() )
    {
        case USER_LEVEL_BEGINNER:
        {
#ifdef DEBUG
	    fprintf(stdout, " %s : User level beginner \n", __func__);
#endif

            setToolbarState( sStandardbarToolbarTypeName, false);
            setToolbarState( sBeginnerbarToolbarTypeName, true );
            setToolbarState( sAveragebarToolbarTypeName, false);
            aUserLevelBeginnerRB.SetState( TRUE );
        }
            break;

        case USER_LEVEL_AVERAGE:
        {
#ifdef DEBUG
            fprintf(stdout, " %s : User level average \n", __func__);
#endif

            setToolbarState( sStandardbarToolbarTypeName, false);
            setToolbarState( sBeginnerbarToolbarTypeName, false );
            setToolbarState( sAveragebarToolbarTypeName, true);
            aUserLevelAverageRB.SetState( TRUE );
        }
            break;    

        case USER_LEVEL_EXPERT:
        {
#ifdef DEBUG
            fprintf(stdout, " %s : User level expert \n", __func__);
#endif
          aUserLevelExpertRB.SetState( TRUE );

            setToolbarState( sStandardbarToolbarTypeName, true );
            setToolbarState( sBeginnerbarToolbarTypeName, false );
            setToolbarState( sAveragebarToolbarTypeName, false);

        }
            break;
        default:
            break;
    }
#endif // OOo4Kids



Note: pour être certain qu'une seule barre est active, une seule est activée et les deux autres sont détruites, pour chaque niveau utilisateur.



#ifdef OOo4Kids
IMPL_LINK( OfaMiscTabPage, UserLevelCheckHdl_Impl, RadioButton*, pButton )
{
	(void) pButton;
    if ( aUserLevelExpertRB.IsChecked() )
    {
        setUserLevel( USER_LEVEL_EXPERT );

        setToolbarState( sStandardbarToolbarTypeName, true );
        setToolbarState( sBeginnerbarToolbarTypeName, false );
        setToolbarState( sAveragebarToolbarTypeName, false);
    }
    
    else if ( aUserLevelAverageRB.IsChecked() )
    {
        setUserLevel( USER_LEVEL_AVERAGE );

        setToolbarState( sStandardbarToolbarTypeName, false );
        setToolbarState( sBeginnerbarToolbarTypeName, false );
        setToolbarState( sAveragebarToolbarTypeName, true);
    }

    else
    {
        setUserLevel( USER_LEVEL_BEGINNER );

        setToolbarState( sStandardbarToolbarTypeName, false );
        setToolbarState( sBeginnerbarToolbarTypeName, true );
        setToolbarState( sAveragebarToolbarTypeName, false);
    }
    return 0;
}



Module sfx2

Tout a été implémenté dans sfx2/source/appl/workwin.cxx. le rôle de la SfxWorkWindow est extrêmement important, car pour chaque nouveau document, les barres d'outils seront dessinée là. Autre cas : lorsqu'on ferme la la boîte de dialogue des préférence (boîte de dialogue modale)


Ce qui a été fait :

// The standard toolbar
static const OUString sStandardbarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/standardbar" ) );
// The beginner toolbar (every application has its own)
static const OUString sBeginnerbarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/beginner" ) );
// The average toolbar (every application has its own)
static const OUString sAveragebarToolbarTypeName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/average" ) );
// Generic constants
static const OUString sULConfigSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
static const OUString sULAccessSrvc( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationUpdateAccess" ) );



static short getUserLevel()
{
    short dUserLevel = 1; // default is beginner 
    try
    {
	// get service provider
        Reference< XMultiServiceFactory > xSMgr( vcl::unohelper::GetMultiServiceFactory() );
        // create configuration hierachical access name
        if( xSMgr.is() )
        {
            try
            {
                Reference< XMultiServiceFactory > xConfigProvider(
                    Reference< XMultiServiceFactory >(
                        xSMgr->createInstance( sULConfigSrvc ),
                        UNO_QUERY )
                    );
                if( xConfigProvider.is() )
                {
                    Sequence< Any > aArgs(1);
                    PropertyValue aVal;
                    aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
                    aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Misc" ) );
                    aArgs.getArray()[0] <<= aVal;
                    Reference< XNameAccess > xConfigAccess(
                        Reference< XNameAccess >(
                            xConfigProvider->createInstanceWithArguments( sULAccessSrvc, aArgs ), UNO_QUERY )
                        );
                    if( xConfigAccess.is() )
                    {
                        try
                        {
                            short bValue = 1;
                            Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserLevel" ) ) );
                            if( aAny >>= bValue )
                                dUserLevel = bValue;
                        }
                        catch( NoSuchElementException& )
                        {
                        }
                        catch( WrappedTargetException& )
                        {
                        }
                    }
                }
            }
            catch( Exception& )
            {
            }
        }
    }
    catch( WrappedTargetException& )
    {
    }
    return dUserLevel;
}


Note: valeurs défiies "au pif" car rien trouvé sur le sujet dans le code.

static const ResIdToResName pToolBarResToName[] =
{
    { 558,      "fullscreenbar"        },
    { 560,      "standardbar",         },

...

#ifdef OOo4Kids
    { 20001,    "beginner"      },      //writer
    { 20002,    "average"       },      //writer
#endif

...

Note: déverouiller par "unlock" le LayoutManager, déclenche le rafraichissement, mais quand le niveau de l'utilisateur est modifié dans les préférences, le rafraichissement n'est effectif que lorsqu'on ferme la boîte de dialogue (basiquement une boîte de dialogue modale, qui garde le focus, et empêche le rafraichissement des autres fenêtres).


....

void SfxWorkWindow::UpdateObjectBars_Impl()
{

#ifdef OOo4Kids
        short int nUserLevel = getUserLevel();
        rtl::OUString aTbxId( m_aTbxTypeName );
        aTbxId += GetResourceURLFromResId( aObjBarList[n].nId );

        switch ( nUserLevel ) 
        {
            case USER_LEVEL_BEGINNER:
              {
#ifdef DEBUG
                fprintf(stdout, " %s : User level beginner \n", __func__);
                fprintf(stdout, "nId = %d \n", nId );
                fprintf(stdout, "aTbxId = %s \n", dbg_dump( aTbxId) );
#endif
                //xLayoutManager->showElement( sBeginnerbarToolbarTypeName );
                xLayoutManager->requestElement( sBeginnerbarToolbarTypeName );
                xLayoutManager->destroyElement( sAveragebarToolbarTypeName );
                xLayoutManager->destroyElement( sStandardbarToolbarTypeName );
              }
                break;

            case USER_LEVEL_AVERAGE:
              {
#ifdef DEBUG
                fprintf(stdout, " %s : User level average \n", __func__);
                fprintf(stdout, " nId = %d \n", nId );
#endif
                //xLayoutManager->showElement( sAveragebarToolbarTypeName );
                xLayoutManager->requestElement( sAveragebarToolbarTypeName );
                xLayoutManager->destroyElement( sBeginnerbarToolbarTypeName );
                xLayoutManager->destroyElement( sStandardbarToolbarTypeName );
              }
                break;

            case USER_LEVEL_EXPERT:
              {
#ifdef DEBUG
                fprintf(stdout, " %s : User level expert \n", __func__);
                fprintf(stdout, " nId = %d \n", nId );
#endif
                //xLayoutManager->showElement( sStandardbarToolbarTypeName );
                xLayoutManager->requestElement( sStandardbarToolbarTypeName );
                xLayoutManager->destroyElement( sBeginnerbarToolbarTypeName );
                xLayoutManager->destroyElement( sAveragebarToolbarTypeName );
              }
                break;

            default:
                break;        
        }
#endif // OOo4Kids

...

}
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox