Page 1 of 1

Menues Configurables

Posted: Tue Dec 05, 2006 11:32 am
by jose_murugosa
Hola a todos!!!!

Como siempre me han ayudado mucho, me tomo el atrevimiento de tirar este tema para saber sus sugerencias y como lo han hecho.

Tengo aplicaciones en las que cada usuario tiene sus menúes y barras de botones personalizadas, pero (Rústico yo) :shock: , las he armado con varias secuencias de:
IF tal usuario
tal menu
ELSEIF tal usuario
tal menu
....

Ya sé, es muy elemental :lol: , por eso me gustaría saber como lo han resuelto Uds. en sus aplicaciones, para darme algunas ideas.

si hay porciones de código con la explicación mucho mejor. :wink:

Gracias desde ya por sus invalorables aportes a mi rustiquez :D :D

Saludos JOSE

Posted: Thu Dec 14, 2006 12:49 pm
by sildata
JOSE: yo creo que la solucion estaria en poder generar a travez de una matriz la cual seria primeramente muy facil de corregir, modificar y editar
lamentablemente yo solo hice una parte pero no se hacer lo demas, si consigues la solucion por favor avisame.
Saludos y feliz navidad
Rodolfo Silva
sildata@cantv.net

Posted: Thu Dec 14, 2006 12:52 pm
by jose_murugosa
Gracias por tu respuesta Rodolfo :D ,

Estoy viendo varias ideas......, veré que resulta de esto y si recibo más feedback de los colegas del foro. :wink:

Te tendré al tanto...

Posted: Thu Dec 14, 2006 2:26 pm
by Raymundo Islas M.
Hola Jose

Por el moment lo estoy manejando de esta manera :

Tengo un modulo donde "muestro" todas las opciones mas importantes que quiero o no asignar a X usuario.


Image

Image

Dichas selecciones, las guardo en un archivo y las aplico al usuario que se haya "logeado".

Creo que la unica diferencia mayor entre lo que quieres hacer y lo que hago, es que en tu caso, quieres crear las opciones personalizadas segun el usuario y sus privilegios, en mi caso, el menu y los botones siguen igual solo que algunas estan desactivados.


Espero te sirva


SALUDOS

Posted: Thu Dec 14, 2006 3:56 pm
by Silvio
Dear jose_murugosa,
do you see the fsdi2006 ?
I have a small function to create an acces to usuarios for all the program molules

it run ok and it is easy...
you can create level user...


OR

you can go to samples of fivewin
there is an sample to put button on button bar (configurable drop and drag ) it save on ini files
here you can create many ini files for each usuarios ... this is an good idea...

Posted: Thu Dec 14, 2006 6:35 pm
by jose_murugosa
Raymundo:

Que bella solución :D , solo una pregunta: ¿Que función cumple el botón "act. todo"?

Silvio:

Muy interesante, me gustaría ver algo de ese código o de la idea sobre la que lo has basado :roll: .
respondiendo a la pregunta de fsdi2006. acabo de llegar de entregar un sistema que me tenía los tiempos apretados, así que lo veré hoy o mañana seguramente.

Te tendré al tanto.... :wink:

Posted: Thu Dec 14, 2006 8:17 pm
by ramirezosvaldo
Hola Jose

En mi caso, yo tengo una tabla donde guardo los usuarios que accesan al sistema. y en un campo de esa tabla guardo un archivo texto donde tengo la definicion de los menus.

Como tu dices es algo rustico pero me funciona por cada usuario.

Saludos
Osvaldo Ramirez

P.S. Si necesitas el codigo dime, pues aun lo tengo desde Clip53 hasta Xbase++ 1.9

Posted: Thu Dec 14, 2006 8:41 pm
by Patricio Avalos Aguirre
Hola Jose

Mira yo lo hago de la siguiente manera, envio el menu y de ahi hago los acceso, te adjunto los fuentes

http://hyperupload.com/download/0274c3f ... o.zip.html

Dentro de la carpeta dbf\ esta el ejecutable

usuario=admin
clave=admin

usuario=prueba
clave=1

Espero que te sirva

Saludos
Patricio

Posted: Thu Dec 14, 2006 8:44 pm
by jose_murugosa
Gracias Patricio y Osvaldo por compartir sus soluciones!!!!!!! :D

Les agradezco su bondad al compartir sus ideas conmigo y los demás del foro. :D

Posted: Tue Dec 19, 2006 11:49 am
by cmsoft
Estimado Jose:
Yo desarrolle una solucion, poniendo los items del menu en una tabla, con el siguiente formato:
USUARIO: Clave del usuario
MODULO: Modulo que debe ejecutar
DETALLE: Item que va a salir como item del menu
SUBMENU: Esto indica: N no es submenu. S: Es un submenu. - Es separador.
ORDEN1: El orden dentro del menu, en forma similar a una cuenta contable de orden gerarquico. Ejemplo:
USUARIO MODULO DETALLE SUBMENU ORDEN1
CESAR Archivos S 100000
CESAR ABMCLIE Clientes N 110000
CESAR ABMPROV Proveedores N 120000
CESAR --------------- - 130000
CESAR Listados S 140000
CESAR REPCLIE Listar clientes N 141000
CESAR REPPROV Listar provee. N 142000
CESAR Procesos S 200000
CESAR FACTURA Facturacion N 210000
JUAN Archivos S 100000
JUAN ABMCLIE Clientes N 110000

Obviamente, esta tabla es autogestionable por el usuario, puede cargar nuevos usuarios y asignarle los permisos. Como se ve en el ejemplo, CESAR tiene acceso a todo y JUAN solo a cargar clientes.
Luego, el modulo que genera el menu segun el usuario que accede es el siguiente:

// --------------------------------------------------------------------//
// ------------- Funcion men£ de la pantalla principal ----------------//
// --------------------------------------------------------------------//
STATIC FUNCTION HazMenu(musuario,nItems)
LOCAL i, oMenu, j, oMenuItem, nivel, nivel1, ult
MEMVAR oWPpal
IF !abrirar("menues",1,"menu1") && Abrir menues con alias MENU1
RETURN oMenu
ELSE
SET INDEX TO menues
ENDIF
menu1->(DBSEEK(musuario))
MENU oMenu
j := 0
aproce :={}
nItems := 1
nivel := 1
ult := "N"
DO WHILE menu1->usuario = musuario
IF menu1->submenu = "S" && Si es submenu
MENUITEM ALLTRIM(menu1->detalle)
ult := "S"
MENU
ELSE
ult := "N"
IF menu1->submenu = "-" && Si un separador
SEPARATOR
ELSE && Si un proceso
j++
AADD(aproce,menu1->modulo) && Cargo la tabla de procesos
MENUITEM oMenuItem PROMPT ALLTRIM(menu1->detalle);
ACTION ejecfunc(oMenuItem:nHelpid) HELPID j
ENDIF
ENDIF
IF nivel = 1 && Si es un titulo
nItems++ && Cuento los items del menu principal
ENDIF
nivel1 := AT("0",menu1->orden1) - 1
menu1->(DBSKIP(1))
nivel := AT("0",menu1->orden1) - 1
IF nivel < nivel1 .and. menu1->usuario = musuario && Si retrocedo
FOR i := nivel TO (nivel1 - 1) && en nivel pongo
ENDMENU && los ENDMENU
NEXT i
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ELSE
IF ult = "S" .and. nivel = 1 && Si es titulo
ENDMENU && solo tambien
ENDIF
ENDIF
ENDDO
ENDMENU
** Esta parte del menu siempre va
MENUITEM "&Salir"
MENU
MENUITEM "&Salir" ACTION (oWPpal:end)
SEPARATOR
MENUITEM "&Acerca" ACTION MsgInfo("Sistema de Gestion " +CHR(10)+;
"Esta licencia pertenece a"+CHR(10)+memvar->xnomb_emp+CHR(10)+;
"Direccion de sistemas"+CHR(10)+;
"Municipalidad de Mercedes"+CHR(10)+;
"Todos los derechos reservados","Acerca de Gestion Plus")
SEPARATOR
MENUITEM "&Cascada" ACTION oWppal:oWndClient:Cascade() ;
WHEN(LEN(MEMVAR->aVentanas)>0)
MENUITEM "&Mosaico" ACTION oWppal:oWndClient:Tile() ;
WHEN(LEN(MEMVAR->aVentanas)>0)
MENUITEM "&Minimizar Todas" ACTION oWppal:oWndClient:IconizeAll() ;
WHEN(LEN(MEMVAR->aVentanas)>0)
ENDMENU
ENDMENU
CLOSE ALL
RETURN oMenu
// --------------------------------------------------------------------//
// ------------- Funcion que ejecuta las funciones del menu -----------//
// --------------------------------------------------------------------//
FUNCTION ejecfunc(mifunc)
DO &(aproce[mifunc])
RETURN NIL

Como se ve en el modulo, el arreglo aProce guarda las funciones que deben ejecutarse segun el item del menu y luego son llamadas en la funcion EjecFunc

Espero que se entienda y te pueda servir. Cualquier cosa me avisas
Atte.
Cesar

Posted: Tue Mar 27, 2007 11:06 pm
by Jairo Centeno
Hola José,

Yo lo hago "semi-rústico" asi:


/* 23/Marzo/2005 - Construye el Menú desde una base de datos - Jcenteno */
FUNCTION BldMenu()
*----------------------------------------------------------------*
LOCAL oMainMenu, oMnuItem
LOCAL cMnuAlias, i:= 1, nRec, fAction, cFileBmp, cResName
LOCAL lRight

IF Len( cMnuAlias := OpenDbf( aSysVar( cSysMenus ), 2, .T., .F., .F.,,"ADS",.T. ) ) = 0
MsgStop( "Ha ocurrido un error en el sistema y deberá cerrarse" )
oWnd:End()
ENDIF

nRec := ( cMnuAlias )->( LastRec() ) //RecCount()
( cMnuAlias )->( OrdSetFocus(1) )

MENU oMainMenu

FOR i := 1 To nRec

IF ( cMnuAlias )->FldSeparat = TRUE
SEPARATOR
ENDIF

IF ( cMnuAlias )->FldVirtKey = 0
MENUITEM oMnuItem PROMPT ALLTRIM(( cMnuAlias )->fldTxtOpt) ;
MESSAGE ALLTRIM(( cMnuAlias )->fldMessage)
ELSE
MENUITEM oMnuItem PROMPT ALLTRIM(( cMnuAlias )->fldTxtOpt) ;
MESSAGE ALLTRIM(( cMnuAlias )->fldMessage) ;
ACCELERATOR ( cMnuAlias )->FldnState, ( cMnuAlias )->FldVirtKey
ENDIF

oMnuItem:lChecked := ( cMnuAlias )->fldCheck

lRight:= Eval( {|| &( ALLTRIM( ( cMnuAlias )->fldCondi ) ) } )
oMnuItem:lActive := lRight

IF ! EMPTY( fAction := ALLTRIM( ( cMnuAlias )->fldAction ) )
oMnuItem:bAction := &( fAction )
// ??? fAction // Debug
ENDIF
IF FILE( cFileBmp := aGraphs(cMnuImgPath) + ALLTRIM( ( cMnuAlias )->FldFileBmp ) )
oMnuItem:hBitmap:= ReadBitmap( 0, cFileBmp )
ENDIF
IF ! EMPTY( cResName := ALLTRIM( ( cMnuAlias )->FldResBmp ) )
oMnuItem:hBitmap:= LoadBitmap( GetResources(), cResName )
ENDIF

DO CASE
CASE ( cMnuAlias )->cNext == "M0"
MENU
CASE ( cMnuAlias )->cNext == "M1"
MENU
CASE ( cMnuAlias )->cNext == "E1"
ENDMENU
CASE ( cMnuAlias )->cNext == "E2"
ENDMENU
ENDMENU
CASE ( cMnuAlias )->cNext == "E3"
ENDMENU
ENDMENU
ENDMENU
CASE ( cMnuAlias )->cNext == "E4"
ENDMENU
ENDMENU
ENDMENU
ENDMENU
CASE ( cMnuAlias )->cNext == "E5"
ENDMENU
ENDMENU
ENDMENU
ENDMENU
ENDMENU
CASE ( cMnuAlias )->cNext == "E6"
ENDMENU
ENDMENU
ENDMENU
ENDMENU
ENDMENU
ENDMENU
ENDCASE
( cMnuAlias )->(dbSkip())
NEXT i

( cMnuAlias )->(dbCloseArea())

RETURN oMainMenu

Espero te sirva.

Saludos,

Posted: Tue Mar 27, 2007 11:27 pm
by jose_murugosa
Gracias Jairo,

Por supuesto que sirve, todo aporte mejora y enriquece.

Gracias por compartirlo :D

Posted: Wed Mar 28, 2007 4:35 pm
by jacgsoft
Hola Jose

Yo lo hago asi:

1. En una tabla tengo las opciones de todos los sistemas (opciones.dbf)
2. En otra tabla tengo a los usuarios (usuarios.dbf)
3. En otra tabla tengo la Relacion de Usuarios+Opciones (Accesos.dbf)

Asi se ve el mantenimiento de los accesos

Image




Luego para desplegar los menus lo hago asi:



Static _Amnp,_Asmn

***********************************************************
Function Main
If Check_clav()
Get_opc_men()

Define Brush oBru Style Bricks
Define Font oFon Name 'Arial' Weight -8

Define Window oWind Title 'Sistema De Planillas' ;
Brush oBru Menu Menu1(oWind)
Set Message Of oWind To 'Medicina Externa S.A.' Clock Date
Activate Window oWind Maximized

Endif

Return(Nil)
*********************************************************

Function Menu1(oWind)
Local oMenu,I,J

Menu oMenu
For I=1 To Len(_Amnp)
MenuItem Alltrim(Left(_Amnp,30))
Menu
For J=1 To Len(_Asmn)
If Subs(_Amnp,31,2)=Subs(_Asmn[J],31,2)
MenuItem Alltrim(Left(_Asmn[J],30))
Endif
Next I
EndMenu
Next I
EndMenu

Return oMenu

************************************************************

Function Get_opc_men()
_Amnp:={}
_Asmn:={}

Select A
Net_use('Men_opci',.F.,3)
Set Index To ('Men_opci')

Seek Vsystem
Do While !Eof() .And. A->Men_sist=Vsystem
If A->Status#' ' //.Or. Len(Alltrim(A->Men_nive))>2
Skip
Loop
Endif

If Len(Alltrim(A->Men_nive))=2
Aadd(_Amnp,Left(Alltrim(A->Men_dscr)+Space(30),30)+A->en_nive)
Endif

If Len(Alltrim(A->Men_nive))=4
Aadd(_Asmn,Left(Alltrim(A->Men_dscr)+Space(30),30)+A->Men_nive)
Endif

Skip
Enddo
Close DataBases

Return(Nil)
***********************************************************


y asi queda

Image

Posted: Sat Dec 29, 2007 11:02 am
by MOISES
Sería muy bueno que Antonio implementara un control de acceso en la clase TMenu ;).

Un saludo,

Moisés

Posted: Sat Dec 29, 2007 12:03 pm
by Antonio Linares
Moisés,

Cada programador suele tener sus propias preferencias y es dificil construir un modelo que a todos satisfaga. Es por esto que FiveWin ofrece mucha libertad para que el programador lo construya como desee.