LicenseDialog/es
From Wiki.ooo4kids.org
License Dialog
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)</font>
- 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).
Como funcionan las cosas
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 :
<node oor:name=".uno:ShowLicense" oor:op="replace"> <prop oor:name="Label" oor:type="xs:string"> <value xml:lang="en-US">L~icense ...</value> <value xml:lang="fr">L~icence ...</value> </prop> </node>
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
#define RID_DEFAULTLICENSE (RID_SFX_START+20)
// constants used to define the dialog box content
#define LICENSE_BTN_OK 6
#define LICENSE_FTXT_VERSION 6
#define LICENSE_FTXT_COPYRIGHT 7
#define LICENSE_STR_DEVELOPER_ARY 6
#define LICENSE_STR_FRENCH_COPYRIGHT 7
#define LICENSE_STR_ACCEL 8
- en sfx2/inc/sfx2/sfxsids.hrc:
// added SID_LICENSE constant // default-ids for application #define SID_QUITAPP (SID_SFX_START + 300) #define SID_ABOUT (SID_SFX_START + 301) #define SID_SETUPPRINTER (SID_SFX_START + 302) #define SID_EXITANDRETURN (SID_SFX_START + 303) #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 :
- HUNK1
Añadida la constante en vcl/inc/vcl/cmdevt.hxx
+#if defined( OOo4Kids ) +#define SHOWDIALOG_ID_LICENCE 3 +#endif
- 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 ";
};
- 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_AUTOCHECK ((MenuItemBits)0x0004) #define MIB_ABOUT ((MenuItemBits)0x0008) #define MIB_HELP ((MenuItemBits)0x0010) +#define MIB_SHOWLICENSE ((MenuItemBits)0x0016) #define MIB_POPUPSELECT ((MenuItemBits)0x0020) // not in rsc/vclsrc.hxx because only a prelimitary solution #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_ABOUT 10204
#define SV_STDTEXT_PREFERENCES 10205
#define SV_MAC_SCREENNNAME 10206
+#define SV_STDTEXT_LICENSE 10207
#define SV_STDTEXT_LAST SV_MAC_SCREENNNAME
#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 :
- define ITEM_HELP_ABOUT \
Identifier = SID_ABOUT ; \
Command = ".uno:About" ; \
HelpID = SID_ABOUT ; \
Text [ en-US ] = "A~bout %PRODUCTNAME..." ; \
3) escritorio
desktop/source/app/app.cxx
- HUNK 1
361 struct AboutBoxVersion
362 : public rtl::Static< String, AboutBoxVersion > {};
- 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();
- 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
External links
- El extremamente importante articulo de Mathias Bauer : Implementation of the Dispatch API in sfx2
- La imagen de fondo
- Poner una maqueta aqui.


