in reply to Tk drag and drop (DND) using TList
in thread Perl::Tk and Win32::Perms Startup help

F A N T A S T I C.

I will get back with my findings as soon as I have debugged and added few bits.
Thanks are not enogh...

Replies are listed 'Best First'.
Re: Re: Tk drag and drop (DND) using TList
by blackadder (Hermit) on Jul 24, 2002 at 17:16 UTC
    Hi .dave."Buddy"

    This is what I have done.

    1-I have amended the GetGroups subroutine so that the script will extract local group information, taking in account whether the drive or the path is a local or remote drive, this works fine. However the GetUsers sub doesn’t work, although it worked when I tested it on its own, what I have done there is; I obtained a list of permissions (groups and users generated from the ShowPathInfo sub where it says my $counter = $perms->Get (\@perms_list)) then I obtained a list of local groups the I compared the two list to obtain the items that do not exist in the groups list but they do exist in the @perms_list which means the item is a user so that it can be displayed in the users box in the form.

    2-The DirTree box always picks up the local c:\ drive no matter what I pass to @ARGV, the script will always pick the C drive. I am not sure on how to get the DirTree box to refresh when a new drive is entered in the entry box.

    3-The other thing that I am a bit confused about is that; in the permissions list (the first top box on the right) the access type is displayed with a user icon as well, also any groups displayed in there will be displayed with a user icon rather than group, and if a local group was detected and therefore displayed it the account will come up as unknown.

    I tried various methods to over come the above, unfortunately I was unsuccessful.

    I really appreciate your help in sorting these points.

    Finally, just to let you know that I have written another sub that will remove or add permission. And I would like to bind this script to the right button click of the mouse. So when I point at a user account I can have the option of dragging (this is done an it seems working fine) or removing for this I need the user name (where the mouse is pointing at) and the path to be fed to remove_add_perms.pl sub.

    I wil include this seperate sub on the next posting.

    Thanks very much for your help.

    use strict; use Tk 800.005; use Tk::TList; use Tk::DirTree; use Tk::Frame; use Tk::Scrollbar; use Tk::Adjuster; # These are required for drag-n-drop operations use Tk::DragDrop; use Tk::DropSite; use File::Find; use Win32::Perms; # these are required to obtain group, drive information use Win32::AdminMisc; use Win32::NetAdmin; use Win32::NetResource; # $tk{widget_refs}, $dr{data_refs}, $im{image_refs} use vars qw/%tk %dr %im @users @perms_list @groups $dnd_token $pdc/; $dr{Domain} = Win32::DomainName(); $dr{PATH} = shift @ARGV || "."; $dr{perms} = "Permissions: ".$dr{PATH}; $tk{mw} = MainWindow->new(-background => 'white'); $tk{mw}->geometry('500x400'); $tk{top_frame} = $tk{mw}->Frame; $tk{left_frame} = $tk{mw}->Frame; $tk{adjuster} = $tk{mw}->Adjuster(-widget=> $tk{left_frame}, -side= +>'left'); $tk{right_frame} = $tk{mw}->Frame; $tk{entry_box} = $tk{top_frame}->Entry(-textvariable=>\$dr{PATH}); $tk{dir_tree} = $tk{left_frame}->Scrolled('DirTree', -height=>'0', -width=>'0', -scrollbars=>'e', ); $tk{output_list} = $tk{right_frame}->Scrolled('TList', -height=>'1', -width=>'1', -scrollbars=>'osoe',); $tk{user_list} = $tk{right_frame}->Scrolled('TList', -height=>'1', -width=>'1', -scrollbars=>'osoe',); $tk{group_list} = $tk{right_frame}->Scrolled('TList', -height=>'1', -width=>'1', -scrollbars=>'osoe',); $tk{user_label} = $tk{right_frame}->Label(-text => "User List:"); $tk{group_label} = $tk{right_frame}->Label(-text => "Group List:"); $tk{output_label} = $tk{right_frame}->Label(-textvariable => \$dr{perm +s}); $im{ONE} = $tk{mw}->Photo(-file => 'one.gif'); $im{GROUP} = $tk{mw}->Photo(-file => 'group.gif'); $tk{dir_tree}->chdir( $dr{PATH} ); $tk{dir_tree}->bind('<ButtonRelease-1>',sub {get_perms();}); $tk{entry_box}->bind('<Key-Return>',sub {OnNewPath();}); $tk{top_frame}->pack(qw/-side top -fill x/); $tk{left_frame}->pack(qw/-side left -fill y/); $tk{adjuster}->pack(qw/-side left -fill y/); $tk{right_frame}->pack(qw/-side right -fill both -expand 1/); $tk{entry_box} ->pack(qw/-side top -fill both -expand 1/); $tk{dir_tree} ->pack(qw/-side left -fill both -expand 1/); $tk{output_label}->pack(qw/-side top -fill both/); $tk{output_list} ->pack(qw/-side top -fill both -expand 1/); $tk{user_label} ->pack(qw/-side top -fill both/); $tk{user_list} ->pack(qw/-side top -fill both -expand 1/); $tk{group_label} ->pack(qw/-side top -fill both/); $tk{group_list} ->pack(qw/-side top -fill both -expand 1/); # Define the source for drags. # Drags are started while pressing the left mouse button and moving th +e # mouse. Then the StartDrag callback is executed. # # The DragDrop method returns a "token", which is a Label widget for # the text or image displayed during the drag action. $dnd_token = $tk{user_list}->DragDrop (-event => '<B1-Motion>', -sitetypes => [qw/Local/], -startcommand => \&DragStart, ); # Define the target for drops. $tk{group_list}->DropSite (-droptypes => [qw/Local/], -dropcommand => [\&Drop, $tk{group_list}, $dnd_token ], ); # Add the users to the user list and the groups to the group list @users = GetUsers(); map { $tk{user_list}->insert('end', -itemtype=>'imagetext', -text=>"$_", -image=>$im{ONE}) } @users; @groups = GetGroups(); map { $tk{group_list}->insert('end', -itemtype=>'imagetext', -text=>"$_", -image=>$im{GROUP}) } @groups; MainLoop; exit 0; sub DragStart { my($token) = @_; my $w = $token->parent; # $w is the source listbox my $e = $w->XEvent; my $idx = $w->GetNearest($e->x, $e->y); # get the listbox entry un +der cursor if (defined $idx) { # Configure the dnd token to show the listbox entry $token->configure(-text => $w->entrycget($idx, '-text') ); # Show the token my($X, $Y) = ($e->X, $e->Y); $token->MoveToplevelWindow($X, $Y); $token->raise; $token->deiconify; $token->FindSite($X, $Y, $e); } } # Accept a drop and insert a new item in the destination sub Drop { my($lb, $dnd_source) = @_; my $user_item = $dnd_source->cget('-text'); # figure out where in the group listbox the drop occurred my $y = $lb->pointery - $lb->rooty; my $x = $lb->pointerx - $lb->rootx; my $nearest = $lb->nearest($x,$y); if (defined $nearest) { my $group_item = $lb->entrycget($nearest, '-text'); &AddUserToGroup($user_item, $group_item); $lb->see($nearest); } } sub get_perms { my $path = $tk{dir_tree}->selectionGet(); &ShowPathInfo($path); } # This method is bound to the 'enter' key so that we can update # the path information from the entry widget. sub OnNewPath { $tk{dir_tree}->chdir( $dr{PATH} ); &ShowPathInfo( $dr{PATH} ); } sub ShowPathInfo { my ($path) = @_; my $perms = new Win32::Perms($path) || die "\n$^E\n"; print "Path: " . $perms->Path(); my $counter = $perms->Get(\ @perms_list); $dr{perms} = "Permisssions: $path"; $tk{output_list}->delete('0.1','end'); $tk{output_list}->insert('end', -itemtype=> 'text', -text=> "$path"); foreach my $item (@perms_list) { while (@_ = each %$item) { next unless $_[0] =~ /account|access/i; $tk{output_list}->insert('end', -itemtype=> 'imagetext', -text=> $_[0].":". $_[1], -image=> $im{ONE}); # image ONE if user a +nd image Groupe if it group. } } } sub GetUsers { my %seen =(); # declare a record if an item has been spotted once +before, i.e. duplicate entry in the list my @found = (); # is an item was not found in the gorups list then + that item is a user # now comparing two list (groups and perms list)to obtain users foreach my $item (@perms_list) { $seen{$item} =1; #make a note of items available in both list } foreach my $item (@groups) { unless (! $seen{$item}) #if an item is not seen then it means +it is a user { push (@found, $item); } } return @found; # this will return empty list #[qw/One Two Three/]; } sub GetGroups { my ($srv); print "\nAnalysing $dr{PATH}\n"; # # Check $dr{PATH} before getting local group information, # if (Win32::NetResource::GetUNCName(my $unc, $dr{PATH})) { $unc =~ s/^\\\\(\w)+//; $srv = $&; print "\nPath is $dr{PATH} and server is: $srv\n"; } else { $srv = Win32::NodeName(); print "\nPath is $dr{PATH} and server is: $srv\n"; } if (Win32::AdminMisc::GetGroups("$srv", GROUP_TYPE_LOCAL, \ @group +s)) { print "\n\nThis is the list of groups\n"; foreach my $item (@groups) { print "$item\n"; } } return @groups; #[qw/RED BLUE GREEN/]; } sub AddUserToGroup { my ($user, $group) = @_; # # Do something with $user_item and with $group_item # $dr{perms} = "User $user added to $group"; }