Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 08-08-2007
Avatar de martinzcr
martinzcr martinzcr is offline
Miembro
 
Registrado: jun 2006
Ubicación: San Jose, Costa Rica
Posts: 53
Poder: 18
martinzcr Va por buen camino
Lightbulb TreeView para manejar perfiles de usuario

Hola Foro!

Tengo un sistema dividido en varios módulos. El sistema tiene control de acceso y cada usuario tiene un perfil que le permite o no ingresar a ciertos módulos y ejecutar ciertas tareas.

Tengo una tabla de usuarios y una de perfiles. Cada usuario esta relacionado con un perfil.

La cuestión es que necesito armar en un TreeView que me muestre cada módulo con sus opciones para chequear o deschequear segun sea el caso.

Un ejemplo de como sería la estructura del arbol es el siguiente

> Modulo de Inventario
>>> Agregar
>>> Modificar
>>> Eliminar
>>> Módulo de Rubros
>>>>>> Agregar
>>>>>> Modificar
>>>>>> Eliminar
> Modulo de Clientes
>>> Agregar
>>> Modificar
>>> Eliminar

Todas las opciones del árbol deben poderse marcar o desmarcar. En caso de desmarcar un nodo, se tienen que desmarcar los hijos también.

Trate de probar con una tabla intermedia que tenga la estructura del arbol, para saber de alguna forma que módulo depende de cual... pero no pude avanzar mucho porque no supe como obtener los valores del árbol para guardar en la base de datos.

Si alguien tiene una idea que me pueda aportar para resolver este asunto, le agradezco de antemano.

Saludos!
__________________
Martin Zalazar
Responder Con Cita
  #2  
Antiguo 08-08-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Hola martinzcr,

Tal vez esto pueda darte una idea, si bien no lo que tu buscas. El problema se resume en como "explorar" cada nodo y su subnodo.

Como comentario:
hace tiempo vi un mensaje de los foros acerca de un sistema de ventas hecho en Delphi que se encuentra disponible en sourceforge.net, (Buscalo por ventas). Me asombró como maneja el tema de los perfiles y las opciones a habilitar/deshabilitar en los menus.
Al comienzo cuesta entenderle la mano a la "fórmula".
Si estas interesado... puedes darle una ojeada, puede que te sirva o te otra perspectiva.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #3  
Antiguo 08-08-2007
Avatar de martinzcr
martinzcr martinzcr is offline
Miembro
 
Registrado: jun 2006
Ubicación: San Jose, Costa Rica
Posts: 53
Poder: 18
martinzcr Va por buen camino
Delphius, gracias por responder. Voy a bajar el programa para ver como trabaja. Cuelquier comentario vuelvo a escribir.
__________________
Martin Zalazar
Responder Con Cita
  #4  
Antiguo 08-08-2007
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
Me parece bien que te tomes el tiempo para "estudiar" lo que te pasé.
Recuerda que se ha dicho mucho sobre el TreeView en los foros. Te aconsejo que primero busques y si hay algo en donde no entiendes o te falla avisas.

Saludos,
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #5  
Antiguo 08-08-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Poder: 22
ArdiIIa Va por buen camino
Hola martinzcr

Yo tengo implementado un sistema consistente en lo siguiente:

Una tabla:
Código:
NOMBRE VAR_CHAR_15 NOT NULL ---->CODIFICADO
PASSWD VAR_CHAR_15 NOT NULL ---->CODIFICADO
PRIVILEGIOS BLOB
Los dos primeros campos, están codificados para que ningún listo toque nada de nada. El tercero no, pero se podría también....
El campo privilegios, viene a ser un INI con todas las opciones del programa, mas o menos así:

Código:
Cuentas Bancarias=S
Máquinas=S
Materiales=S
OT Fijas=S
Libreta de Contactos=S
Buscar Contactos=S
Pedidos de Clientes=S
Ofertas a Clientes=S
OT=S
Partes Diarios=S
Horas Trabajo Operarios=S
Pedidos a Proveedores=S
Petición de Presupuesto=S
Albaranes=S
Facturas=S
Notas de Entrega=S
Configuración=S
Ejercicios=N
Gestor de Correo=S
Usuarios=S
Donde cada elemento, se corresponde con un item del menú del programa. En mi caso, utilizo ActionManager, por lo que sería mas correcto decir, que cada elemento se corresponde con un TAction.


En el Form donde se encuentra el TreeView, el procedimiento que asisna los elementos, viene a ser algo así....



Código Delphi [-]
// ESTE PROCEDIMIENTO INICIALIZA el treevie de LOS OBJETOS DE SEGURIDAD
// PARA TENER PRIVILEGIOS DE ACCESO A LAS DIFERENTES SECCIONES DEL PROGRAMA
Procedure TFormUsuarios.MakeSecurity( TreeView : TTreeView);

Function Delsigno(Item : String) : String;
Begin
Delete( Item , Pos('&' , Item) ,1) ;
Result := Item;
End;

function FindAction (Caption : string) : TAction;
var
  i : Integer;
begin
  Result := nil;
  with FormMain.ActionManager1 do
   begin
    for I := 0 to ActionCount - 1 do    { Iterate }
     begin
      if TAction(Actions[i]).Caption = Caption then
      begin
        Result := TAction(Actions[i]);
        Break;
      end;
    end;    { for }
  end;  { with }
end;


Var
TreeNode, SubTreeNode : TTreeNode;
I,X : Integer;
cTemp : String;
Action : TAction;
Begin

LockWindowUpdate(Treeview.Handle);
TreeView.Items.Clear;

For I := 0 To FormMain.ActionManager1.ActionBars.ActionBars[0].Items.Count -4 DO

Begin
cTemp := DelSigno(FormMain.ActionManager1.ActionBars.ActionBars[0].Items[i].Caption);
TreeNode := TreeView.Items.Add(nil,cTemp);
TreeNode.ImageIndex := -1;
TreeNode.SelectedIndex := -1;

    For X := 0 to FormMain.ActionManager1.ActionBars.ActionBars[0].Items[i].Items.Count -1 DO
    Begin
    cTemp := DelSigno(FormMain.ActionManager1.ActionBars.ActionBars[0].Items[i].Items[x].Caption);
    if cTemp = '-' then continue;
    Action := FindAction(cTemp);
    if Action <> NIL then
    Begin

    SubTreeNode := TreeView.Items.AddChild(TreeNode,cTemp);
    SubTreeNode.ImageIndex := Action.ImageIndex;
    SubTreeNode.SelectedIndex := Action.ImageIndex;

    if Seguridad.FindItem(Action.Caption) <> NIL then
    SubTreeNode.Data := Seguridad.FindItem(Action.Caption)
    End;
    End;

End;
Treeview.FullExpand;
Treeview.Selected := Treeview.Items[0];
LockWindowUpdate(0);
End;

Dos procedimientos de carga y grabación de datos, necesarios para la gestión:



Código Delphi [-]

//Graba Los valores a la base de datos
procedure TFormUsuarios.Button1Click(Sender: TObject);
Var
Stream : TMemoryStream;
begin
Stream := NIL;
Try

    Stream:= TMemoryStream.Create;
    Seguridad.SaveToStream(Stream);
    Datamodule1.IBTableUsuarios.Edit;
    TMemoField(Datamodule1.IBTableUsuarios.FieldByName('Privilegios')).LoadFromStream(Stream);
    Datamodule1.IBTableUsuarios.FieldByName('Nombre').AsString := FormMain.Encrypt(Edit1.Text ,55423);
    Datamodule1.IBTableUsuarios.FieldByName('PassWd').AsString := FormMain.Encrypt(Edit2.Text ,55423);
    Datamodule1.IBTableUsuarios.Post;
finally
    Stream.Free
End
end;

//Carga Seguridad con los valores de la base de datos
procedure TFormUsuarios.DataSourceUsuariosDataChange(Sender: TObject;  Field: TField);
Var
Stream : TMemoryStream;
begin
Stream := NIL;
IF Datamodule1.IBTableUsuarios.State IN dsEditModes then exit;
Try
Stream:= TMemoryStream.Create;
TMemoField(Datamodule1.IBTableUsuarios.FieldByName('Privilegios')).SaveToStream(Stream);
Seguridad.LoadFromStream(Stream);
MakeSecurity(TreeView1);
Edit1.Text := FormMain.Decrypt(Datamodule1.IBTableUsuarios.FieldByName('Nombre').AsString,55423);
Edit2.Text := FormMain.Decrypt(Datamodule1.IBTableUsuarios.FieldByName('PassWd').AsString,55423);
Finally
Stream.Free;
End;
end;


Y finalmente, verás que se cita por ahí un objeto llamado seguridad, que no es otra cosa que un objeto derivado de la clase TCollection, que contiene una lista (TStrings) de todos los objetos TAction del programa y que los activa o desactiva en base a las selecciones hechas por el usuario.
El código de seguridad, es este:

Código Delphi [-]
unit Unit_Objetos_Seguridad;

interface
uses Classes,SysUtils,ActnList;


type


TFormSectionItem = class(TCollectionItem)
  public
    Action : TAction;
    Accesible : Boolean;
  end;



  TFormSectionItems = class(TCollection)
  private
    FStream : TStrings;
    function GetItem(Index: Integer): TFormSectionItem;
    procedure SetItem(Index: Integer; Value: TFormSectionItem);
    Procedure Initial;
  protected
    procedure Update(Item: TCollectionItem); override;
  public
    constructor Create;
    destructor Destroy ; override;
    function Add: TFormSectionItem;
    Procedure SaveToStream( Stream : TMemoryStream);
    procedure LoadFromStream( Stream : TMemoryStream);
    Function FindItem(Caption : String) : TFormSectionItem;
    procedure SetActionValues;
    property Items[Index: Integer]: TFormSectionItem read GetItem write SetItem; default;
  end;



(*
TFormSecurityItem = class(TCollectionItem)
  public
    FormName : String;
    Accesible : Boolean;
    Secciones : TFormSectionItems;
  end;


TFormSecurityItems = class(TCollection)
  private
    function GetItem(Index: Integer): TFormSecurityItem;
    procedure SetItem(Index: Integer; Value: TFormSecurityItem);
  protected
    procedure Update(Item: TCollectionItem); override;
  public
    constructor Create;
    function Add: TFormSecurityItem;
    property Items[Index: Integer]: TFormSecurityItem read GetItem write SetItem; default;
  end;

  *)



implementation

uses UnitMain;


//******************//
constructor TFormSectionItems.Create;
begin
  inherited Create(TFormSectionItem);
  FStream := TStringList.Create;
  Initial;
end;


destructor TFormSectionItems.Destroy;
begin
   FStream.Free;
  inherited Destroy;
end;


Function TFormSectionItems.FindItem(Caption : String) : TFormSectionItem;
Var I : Integer;
Begin
Result := NIL;
For I := 0 to Count -1 DO
if Items[i].Action.Caption = Caption then
Begin
Result := Items[i];
Break;
End;

End;



Procedure TFormSectionItems.Initial;

Function Delsigno(Item : String) : String;
Begin
System.Delete( Item , Pos('&' , Item) ,1) ;
Result := Item;
End;

Function FindAction (Caption : string) : TAction;
var
  i : Integer;
begin
  Result := nil;
  with FormMain.ActionManager1 do
   begin
    for I := 0 to ActionCount - 1 do    { Iterate }
     begin
      if TAction(Actions[i]).Caption = Caption then
      begin
        Result := TAction(Actions[i]);
        Break;
      end;
    end;    { for }
  end;  { with }
end;


Var
Item : TFormSectionItem;
I,X : Integer;
cTemp : String;
Action : TAction;
Begin

For I := 0 To FormMain.ActionManager1.ActionBars.ActionBars[0].Items.Count -4 DO
Begin
    For X := 0 to FormMain.ActionManager1.ActionBars.ActionBars[0].Items[i].Items.Count -1 DO
    Begin
    cTemp := DelSigno(FormMain.ActionManager1.ActionBars.ActionBars[0].Items[i].Items[x].Caption);
    if cTemp = '-' then continue;
    Action := FindAction(cTemp);
    if Action <> NIL then
    Begin
    Item := Add;
    Item.Action := Action;
    Item.Accesible := Action.Enabled;
    End;
    End;
End;

End;



procedure TFormSectionItems.SaveToStream( Stream : TMemoryStream);
Var
I : Integer;
cTemp : String;
begin
FStream.Clear;
For I := 0 To Count -1 DO
    Begin
    if Items[i].Accesible then
    cTemp := '=S'
    else
    cTemp := '=N';
    FStream.Add( Items[i].Action.Caption + cTemp)
    End;
   //FStream.Text := FormMain.Encrypt(FStream.Text,761);
   FStream.SaveToStream(Stream);
   Stream.Position := 0;
end;


procedure TFormSectionItems.LoadFromStream(Stream : TMemoryStream);
Var
I,Z : Integer;
begin
Stream.Position := 0;
FStream.LOadFromStream(Stream);
//FStream.Text := FormMain.Decrypt(FStream.Text,761);
For I := 0 To Count -1 DO
    Begin
    Z := FStream.IndexOfName( Items[i].Action.Caption );
    if Z <> -1 then
       Begin
       Items[i].Accesible := (FStream.ValueFromIndex[Z] = 'S');
       //Items[i].Action.Enabled := Items[i].Accesible;
       End;
     End;

End;




procedure TFormSectionItems.SetActionValues;
Var
I : Integer;
begin
For I := 0 To Count -1 DO
    Items[i].Action.Enabled := Items[i].Accesible;
end;




procedure TFormSectionItems.Update(Item: TCollectionItem);
begin
  inherited;
end;

function TFormSectionItems.GetItem(Index: Integer): TFormSectionItem;
begin
  Result := TFormSectionItem(inherited GetItem(Index));
end;

procedure TFormSectionItems.SetItem(Index: Integer; Value: TFormSectionItem);
begin
  inherited SetItem(Index, Value);
end;

function TFormSectionItems.Add: TFormSectionItem;
begin
  Result := TFormSectionItem(inherited Add);
end;


A la hora de ejecutar el programa y establecer la parametrización de cada usuario, sería algo tal como esto...

Código Delphi [-]
    Seguridad := TFormSectionItems.Create;


    TMemoField(Datamodule1.IBTableUsuarios.FieldByName('Privilegios')).SaveToStream(Stream);
    Seguridad.LoadFromStream(Stream);
    // Pone todas las TAction del Menú
    // Conforme a los valores del usuario que hizo login
    Seguridad.SetActionValues;

Verás que la table IBTableUsuarios, ya estaría posionada sobre el usuario en cuestión, por que previamente se habría identificado.... (otra cuestión aparte)



Básicamente, eso es todo. Lo único comentarte que en mi sistema, utilizo un TreeView normal y corriente, por lo que para que comentas y la forma en la que lo planteas:

Cita:
Todas las opciones del árbol deben poderse marcar o desmarcar. En caso de desmarcar un nodo, se tienen que desmarcar los hijos también.
Creo que lo ideal sería que utilizaras un VirtualTreeView, que si te lo permitiría. (es que en aquellas fecha, yo no conocía ese excelente componente...).

Espero que te sirva de orientación.

NOTA: El código está adaptado a un programa específico y no garantizo que su uso tal cual está, vaya a funcionar en cualquier otro programa.

Saludos.
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO

Última edición por ArdiIIa fecha: 08-08-2007 a las 11:36:46.
Responder Con Cita
  #6  
Antiguo 08-08-2007
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por martinzcr Ver Mensaje
Todas las opciones del árbol deben poderse marcar o desmarcar. En caso de desmarcar un nodo, se tienen que desmarcar los hijos también.
Para esta parte, podría valerte mi TCheckTreeView

// Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Para manejar Paradox abasoleno_69 Conexión con bases de datos 5 19-09-2006 17:02:39
Componentes para manejar BD corrupta zam Conexión con bases de datos 0 31-05-2005 16:57:38
¿Cómo obtener y manejar datos del usuario activo? JaviP Firebird e Interbase 3 13-05-2005 23:28:04
Ayuda, para manejar fechas, en sql Ariatna SQL 4 27-08-2004 22:11:53
componente para manejar un movil gsm coletaum Varios 1 17-09-2003 11:49:28


La franja horaria es GMT +2. Ahora son las 12:31:31.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi