LicenseDialog/es

Todos los cambios añadidos a el codigo fuente original de OpenOfiice.org proporcionados en esta pagina, son:


 * '''Bajo licencia LGPL V3, (y puede redistribuirlo y/o modificarlo bajo los términos de la GNU Lesser General Public License publicada por la Free Software Foundation)
 * Copyright Eric Bachard 12 Agosto 2009
 * Copyright sobre la traducción Gildardo A. Maravilla Jacome 27 Marzo 2010

Estado de la implementacion

 * Mac OS X (Aqua
 * Escribir el .xcu
 * Crear el cuadro de dialogoCreate the dialog box
 * Descripcion de la calse ShowLicenseDialog
 * Conectar a vcl
 * Conectar a svx
 * Conectar a sfx2
 * Conectar al framework
 * Conectar unotools
 * Debug
 * Documentacion

Introducción
Abajo, encontraras una descripción técnica de la característica Licencia de menú de entrada. Es cuestión del código fuente de OpenOffice.org (principalmente C++ y Objective C), por ejemplo, la organización interna del código fuente en el framework de OpenOffice.org, la interacción con la parte gráfica alias VCL, .. y así sucesivamente. Por lo tanto, suponemos que el lector tiene las bases obligatorias para comprender el contenido de la propuesta.

Los pre-requisitos para leer este artículo aún no se han definido, pero si el lector no esta acostumbrado a algunas nociones, le invitamos a echar un vistazo en la wiki de OpenOffice.org para completar sus conocimientos, y leer este artículo en las mejores condiciones.

Especificaciones

 * Agregue una entrada en todos los menús de las aplicaciones, permitiendo comprobar la licencia OOo4Kids.




 * Comportamiento esperado:
 * Un clic en la entrada del menú abre una ventana modal, explicando la licencia OOo4Kids, y da un enlace para que lo lea.
 * Un click en OK Cierra la ventana.

Forma usada

 * Una nueva entrada sera añadida en algun menu

El menu enviara un evento, la aplicacion lo revibiria, y se convertira en un comando ( .uno:ShowLicense). El comando sera enviado, y la venana modal, mostrando el texto, se abrira. Ok la cerrara.

Otras maneras:


 * El GenericCommands.xcu tendra una entrada .uno:ShowLicense ( un comando sera enviado )

Entonces tanto una nueva entrada en el menu estara disponible en la lista, '''o un nuevo boton "Licencia ..." ''' puede añadirse a cualquier barra de herramientas, atraves de Opciones ->Personalizar el menu.

Como prueba, el menubar.xml de todas las aplicaciones tendran este comando disponible ( para propositos de prueba).

1) empezando desde vcl
La descripcion en esta parte es para Mac OS X version Aqua unicamente

En Mac OS X, version Aqua:

La cadena "License ..." (en-US) es creada en vcl/source/src/stdtext.src

String SV_STDTEXT_LICENSE {                                                                                                                                          Text [ en-US ] = "License ..."; Text [ es ] = "Licencia ..."; };

'''En tiempo de construccion, la cadena sera añadida en vcles.res (es) o vcl.res(en-US, default), y entregados, empacados .. y asi sucesivamente'''

Seleccionar el menu principal Aqua: " File -> Licencia... " Select the main Aqua menu : " File -> License... "

=> enviara un evento tipo "SHOW_DIALOG", conteniendo la cadena "LICENSE"

En el codigo: ver vcl/aqua/source/window/salmenu.cxx else if( nDialog == SHOWDIALOG_ID_LICENSE ) aDialog = String( RTL_CONSTASCII_USTRINGPARAM( "LICENSE" ) ); const ApplicationEvent* pAppEvent = new ApplicationEvent( String,                                                                                                                              ApplicationAddress,                                                                                                                   ByteString( "SHOWDIALOG" ),                                                                                                             aDialog ); AquaSalInstance::aAppEventList.push_back( pAppEvent );

2) ...en el framework
Siguiente paso : desde que este es un evento del sistema, la Apicacion (ver siguiente punto, en escritorio) no puede tomar este evento, y el ambiente iniciara un eventlisdtener en el framework, para tomar todos los eventos SHOWDIALOG codificados. Esto es exactamente recibido en framework/source/dispatch/windowcommanddispatch.cxx

Primero un listener es lanzado ( void WindowCommandDispatch::impl_startListening ) en el Ctor.

Segundo, creamos un OUString : const ::rtl::OUString WindowCommandDispatch::COMMAND_LICENSEBOX   = ::rtl::OUString::createFromAscii(".uno:ShowLicense"); Una ves que el evento es tomado, usamos un callback para enviarlo, usando : IMPL_LINK(WindowCommandDispatch, impl_notifyCommand, void*, pParam) Quien hace : switch (nCommand) {                                                                                                            ...                                    case SHOWDIALOG_ID_LICENSE : sCommand = WindowCommandDispatch::COMMAND_LICENSEBOX; and finishes with : impl_dispatchCommand(sCommand);

Siguiente paso -> el comando es tomado y eecutado en sfx2

Sugerencia : 

=> ver la descripcion completa en : framework/source/inc/dispatch/windowcommanddispatch.cxx /** @short internal helper to bind e.g. MAC-Menu events to our internal dispatch API. @descr On e.g. MAC platform system menus are merged together with some fix entries as                                    e.g. "Preferences" or "About". These menu entries trigger hard coded commands. Here we map these commands to the right URLs and dispatch them.

3) del escritorio a (unotools ?)
POR HACER : ¿Esta API esta disponible para usarla?i

4) officefg
Que pasa en officecfg ?


 * Una nueva entrada de menu es creada, con el nombre .uno:ShowLicense. Si coincide con un espacio id real, la entrada del menu se volvera activa, sino continuara estando gris.

Los cambios han sido hechos en GenericCommand.xcu, y respecto a la sintaxis .xml. Añadimos el "nodo" .uno:ShowLicense :   L~icense ... L~icence ...

En Herramientas -> Personalizacion, el usuario tendra la posibilidad de añadir tanto una nueva entrada de menu "Licencia ...", o un nuevo boton "Licencia ..." en cualquie barra de herramientas.

Como ejemplo, la imagen de abajo describe el caso de añadir una nueva entrada de menu "Licencia ..." :



5) que suceden en sfx2

 * Un espacio, visto como un nuevo comando, se volvera activo (sino la entrada de menu estara gris). El papel de sfx2, es enviar la entrada de menu cuando se clickea
 * Cualquier "evento" visto como SID_LICENSE sera enviado, y reenviado al framework, y sera tratado como comando .uno:ShowLicense command en appserv.cxx

Tener cuidado: lo que sigue, puede tener cambios errornos. Por favor contactenme (y expliquenme que esta mal, y debera ser modificado).

Por ejemplo : Yo he elegido aleatoreamente algunos valores ;-)

Definir nuevas constates
< '''¿Cuales son los mejores valores? '''

=> Parece no haber una regla exacta (solo tener cuidado de no encimarlos)


 * en sfx2/inc/sfx2/sfx.hrc:

Añadir :

// ressource ID used in appserv.cxx


 * 1) define RID_DEFAULTLICENSE                                     (RID_SFX_START+20)

// constants used to define the dialog box content
 * 1) define LICENSE_BTN_OK                       6
 * 1) define LICENSE_FTXT_VERSION                 6
 * 2) define LICENSE_FTXT_COPYRIGHT               7
 * 1) define LICENSE_STR_DEVELOPER_ARY            6
 * 2) define LICENSE_STR_FRENCH_COPYRIGHT         7
 * 3) define LICENSE_STR_ACCEL                    8


 * en sfx2/inc/sfx2/sfxsids.hrc:

// added SID_LICENSE constant

// default-ids for application
 * 1) define SID_QUITAPP                        (SID_SFX_START + 300)
 * 2) define SID_ABOUT                          (SID_SFX_START + 301)
 * 3) define SID_SETUPPRINTER                   (SID_SFX_START + 302)
 * 4) define SID_EXITANDRETURN                  (SID_SFX_START + 303)
 * 5) define SID_LICENSE                        (SID_SFX_START + 304)

Definir el nuevo espacio
Primero, añadir un nuevo elemento en sfx2/sdi/sfx.sdi:SfxVoidItem ShowLicense SID_LICENSE

Por favor observa la sintaxis : SfxVoidItem ShowLicense SID_LICENSE


 * Tipo es SfxVoidItem
 * EL nombre del metodo del espacio es ShowLicense
 * la constante asociada es SID_LICENSE

Nota : obviamente inspirado por SID_ABOUT

//--                                                           SfxVoidItem ShowLicense SID_LICENSE [                                                                                                                                              /* flags: */ AutoUpdate = FALSE, Cachable = Cachable, FastCall = FALSE, HasCoreId = FALSE, HasDialog = TRUE, ReadOnlyDoc = TRUE, Toggle = FALSE, Container = FALSE, RecordAbsolute = FALSE, RecordPerSet; Synchron; /* config: */ AccelConfig = TRUE, MenuConfig = TRUE, StatusBarConfig = FALSE, ToolBoxConfig = TRUE, GroupId = GID_APPLICATION; ]

Y ahora, definir la interface. Significa que en el appserv.cxx, la implementacion real usara el metodo MiscExec.

Si lees otras definiciones de interfaces en el mismo archivos, veras otras posibilidades.

Index: sfx2/sdi/appslots.sdi

=
======================================================                                               --- sfx2/sdi/appslots.sdi       (revision 274625) +++ sfx2/sdi/appslots.sdi      (working copy) @@ -52,6 +52,10 @@                                                                                                        [                                                                                                                          ExecMethod = MiscExec_Impl ; ]                                                                                                         +       SID_LICENSE // ole(no) api(final/play/rec) +      [                                                                                                          +               ExecMethod = MiscExec_Impl ; +      ]                                                                                                                  SID_SETOPTIONS [                                                                                                                         ExecMethod = MiscExec_Impl ;

Implemtentando el metodo
Ahora, estamos en sfx2/source/appl/appserv.cxx

Primero, incluimos el showlicence.hxx (nuevo archivo de cabecera, derivado de about.hxx)<

Entonces, como esperamos, en void SfxApplication::MiscExec_Impl( SfxRequest& rReq ), añadir el nuevo caso SID_LICENSE

+      case SID_LICENSE: +      {                                                                                                                 +                                                                                                                         +           String sBuildId( String::CreateFromAscii( "This text will explain the license OOo4Kids will use

Lo que sigue contrendra "Licencia ..."

+                                                                                                                        +           rtl::OUString aLicenseContent( DEFINE_CONST_OUSTRING( "SHOW_LICENSE" ) );

Retrieve the resource ID

+           // search for the resource of the license box +           ResId aDialogResId( RID_DEFAULTLICENSE, *pAppData_Impl->pLabelResMgr ); +           ResMgr* pResMgr = pAppData_Impl->pLabelResMgr; +           if( ! pResMgr->IsAvailable( aDialogResId.SetRT( RSC_MODALDIALOG ) ) ) +               pResMgr = GetOffResManager_Impl; +

... verificamos que esta bien.

+           aDialogResId.SetResMgr( pResMgr ); +           if ( !pResMgr->IsAvailable( aDialogResId ) ) +           {                                                                                                            +                DBG_ERRORFILE( "No RID_DEFAULTLICENSE in label-resource-dll" ); +           }                                                                                                            +

Una vez que todo esta bien, mostramos el cuadro de dialogo

+           // then show the license box +           ShowLicenseDialog* pDlg = new ShowLicenseDialog( 0, aDialogResId, sBuildId ); pDlg->Execute; delete pDlg; bDone = TRUE; +          break; +      }

6) EL cuadro modal "ShowLicense"
POR HACER : describir

7) Nota sobre lo que pasa en el escritorio
ARREGLARME : ¿porque nunca utilizamos eso?

En el escritorio, Desktop::HandleAppEvent deberia tomar el evento normalmente, en app.cxx:2830 (ver desktop/source/app/app.cxx ), y si se la cadena tomada no contiene "LICENSE". Pero por una razon que sigo ignorando, nunca usamos este metodo. Si alguna ves pudieramos llegar a ese lugar, lo que pasaria es como se describe abajo :

Primer, '''la cadena ".uno:ShowLicense", osea la etiquta del comando, sera creada :

En el codigo :

app.cxx:2837, en void Desktop::HandleAppEvent( const ApplicationEvent& rAppEvent ) :

else if( rAppEvent.GetData.EqualsAscii( "LICENSE" ) ) aCommand.Complete = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ShowLicense" ) );

Entonces, una vez completo, el comando sera enviado : if( aCommand.Complete.getLength ) {                                                                                                                                          xParser->parseStrict(aCommand); css::uno::Reference< css::frame::XDispatch > xDispatch = xDesktop->queryDispatch(aCommand, rtl::OUString, 0); if (xDispatch.is) xDispatch->dispatch(aCommand, css::uno::Sequence< css::beans::PropertyValue >); }

Parte Mac OS X (Aqua)


Combios en el codigo :

1) vcl :

--

Añadida la constante en vcl/inc/vcl/cmdevt.hxx
 * 1) HUNK1

+#if defined( OOo4Kids ) +#define SHOWDIALOG_ID_LICENCE         3 +#endif --


 * 1) HUNK 2

Añadida la nueva entrada de menu Cocoa, como la cadena, en vcl/source/src/stdtxt.src

String SV_STDTEXT_LICENSE {                                                                                                                          Text [ en-US ] = "License "; Text [ es ] = "Licencia "; };                                                                                                                     --


 * 1) HUNK 3

Añadida la nueva constante en vcl/inc/vcl/menu.hxx :

Index: vcl/inc/vcl/menu.hxx

=
======================================================                                                    --- vcl/inc/vcl/menu.hxx        (revision 274625) +++ vcl/inc/vcl/menu.hxx       (working copy) @@ -90,6 +90,7 @@                                                                                                       +#define MIB_SHOWLICENSE                                ((MenuItemBits)0x0016) // not in rsc/vclsrc.hxx because only a prelimitary solution --
 * 1) define MIB_AUTOCHECK                 ((MenuItemBits)0x0004)
 * 2) define MIB_ABOUT                             ((MenuItemBits)0x0008)
 * 3) define MIB_HELP                              ((MenuItemBits)0x0010)
 * 1) define MIB_POPUPSELECT               ((MenuItemBits)0x0020)
 * 1) define MIB_NOSELECT              ((MenuItemBits)0x0040)

Añadida la nueva constante en vcl/inc/vcl/svids.hrc : Index: vcl/inc/vcl/svids.hrc

=
======================================================                                                    --- vcl/inc/vcl/svids.hrc       (revision 274625) +++ vcl/inc/vcl/svids.hrc      (working copy) @@ -108,6 +108,7 @@                                                                                                     +#define SV_STDTEXT_LICENSE                 10207
 * 1) define SV_STDTEXT_ABOUT                   10204
 * 2) define SV_STDTEXT_PREFERENCES             10205
 * 3) define SV_MAC_SCREENNNAME                 10206
 * 1) define SV_STDTEXT_LAST                                       SV_MAC_SCREENNNAME
 * 1) define SV_ACCESSERROR_FIRST                          SV_ACCESSERROR_WRONG_VERSION

--

Añadida la nueva entrada en el menu Aqua ( vcl/aqua/source/window/salmenu.cxx ) @@ -146,11 +153,25 @@                                                                                                                           [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 3]; }                                                                                                 +                    // insert license entry +                   String aLicense( ResId( SV_STDTEXT_LICENSE, *pMgr ) ); +                   pString = CreateNSString( aLicense ); +                   pNewItem = [pAppMenu insertItemWithTitle: pString +                                        action: @selector(showLicense:) +                                        keyEquivalent: @"," +                                        atIndex: 4]; +                   if (pString) +                       [pString release]; +                   if( pNewItem ) +                   {                                                                                                  +                        [pNewItem setTarget: pMainMenuSelector]; +                       [pAppMenu insertItem: [NSMenuItem separatorItem] atIndex: 5]; +                   }

+ define the method to receive the events :

Interface :

-(void)showLicense: (id)sender;

Implementación : -(void)showLicense: (id) sender {                                                                                                                         [self showDialog: SHOWDIALOG_ID_LICENSE]; }

IMPORTANTE : no olvidar añadir +2 a todos los indices !! (sino otras entradas del menu seran encimadas :-) )

--

2) svx:

en svx/inc/globlmn_tmpl.hrc

--

-> Añadir el elemento .uno:ShowLicence

Por ejemplo :

Identifier = SID_ABOUT ; \ Command = ".uno:About" ; \ HelpID = SID_ABOUT ; \ Text [ en-US ] = "A~bout %PRODUCTNAME..." ; \
 * 1) define ITEM_HELP_ABOUT \

3) escritorio

desktop/source/app/app.cxx

--


 * 1) HUNK 1

361    struct AboutBoxVersion 362    	: public rtl::Static< String, AboutBoxVersion > {};

--


 * 1) HUNK 2

+ see ReplaceStringHookProc( UniString& rStr )

=>

void ReplaceStringHookProc( UniString& rStr ) 374 {   375     static int nAll = 0, nPro = 0; 376    377 	nAll++; 378    if ( rStr.SearchAscii( "%PRODUCT" ) != STRING_NOTFOUND ) 379    {    380         String &rBrandName = BrandName::get; 381        String &rVersion = Version::get; 382        String &rAboutBoxVersion = AboutBoxVersion::get;

--
 * 1) HUNK 3

+ see : void Desktop::HandleAppEvent(

5) unotools

unotools/inc/unotools/configmgr.hxx#ABOUTBOXPRODUCTVERSION

See line around 90 :    enum ConfigProperty

y :

//direct readonly access to some special configuration elements 108            static com::sun::star::uno::Any GetDirectConfigProperty(ConfigProperty eProp); 109    110             sal_Bool        IsLocalConfigProvider; 111            com::sun::star::uno::Reference< com::sun::star::container::XHierarchicalNameAccess> 112                GetHierarchyAccess(const rtl::OUString& rFullPath); 113            com::sun::star::uno::Any GetLocalProperty(const rtl::OUString& rProperty); 114            void PutLocalProperty(const rtl::OUString&, const com::sun::star::uno::Any& rValue); 115


 * El extremamente importante articulo de Mathias Bauer : Implementation of the Dispatch API in sfx2


 * La imagen de fondo
 * Poner una maqueta aqui.