Commits

Anonymous committed f180e03

Initial Commit

Comments (0)

Files changed (5)

+package Padre::Plugin::HG;
+
+use 5.008;
+use warnings;
+use strict;
+
+use Padre::Config ();
+use Padre::Wx     ();
+use Padre::Plugin ();
+use Padre::Util   ();
+
+use Capture::Tiny  qw(capture_merged);
+use File::Basename ();
+use File::Spec;
+use lib ("/home/mm/.padre/plugins");
+use Padre::Plugin::HG::StatusTree;
+use Padre::Plugin::HG::ProjectCommit;
+use Padre::Plugin::HG::ProjectClone;
+my %projects;
+our $VERSION = '0.01';
+our @ISA     = 'Padre::Plugin';
+
+my $VCS = "Mercurial";
+
+my %VCSCommand = ( commit => 'hg commit -A -m"$message" $path ',
+		add => 'hg add $path',
+		status =>'hg status --all $path',
+		root => 'hg root', 
+		diff => 'hg diff $path',
+		clone=> 'hg clone $path',
+		pull =>'hg pull --update --noninteractive  ',
+		push =>'hg push');
+		
+my %HGStatus = ( M => 'File Modified', 
+A => 'File Added not Committed',
+R => 'File Removed',
+C => 'Up to Date',
+'!' => 'Deleted But Still Tracked!',
+'?' => 'Not Tracked',
+I => 'ignored'
+);
+
+# TODO
+# diff of file/dir/project
+# commit of file/dir/project
+
+=head1 NAME
+
+Padre::Plugin::Git - Simple Git interface for Padre
+
+=head1 SYNOPSIS
+
+cpan install Padre::Plugin::Git
+
+Acces it via Plugin/Git
+
+
+=head1 AUTHOR
+
+Kaare Rasmussen, C<< <kaare at cpan.org> >>
+
+=head1 BUGS
+
+Please report any bugs or feature requests to L<http://padre.perlide.org/>
+
+
+=head1 COPYRIGHT & LICENSE
+
+Copyright 2008-2009 The Padre development team as listed in Padre.pm.
+all rights reserved.
+
+This program is free software; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+
+=cut
+
+
+#####################################################################
+# Padre::Plugin Methods
+
+sub padre_interfaces {
+	'Padre::Plugin' => 0.24
+}
+
+sub plugin_name {
+	'HG';
+}
+
+sub menu_plugins_simple {
+	my $self = shift;
+	return $self->plugin_name => [
+		'About'             => sub { $self->show_about },
+		'View Project'	    => sub {$self->show_statusTree},
+		'Add'		    => sub {$self->vcs_add},
+		'Clone'		    => sub {$self->show_project_clone},
+		'Commit...' => [
+			'File'     => sub { $self->vcs_commit_file },
+			'Project'  => sub { $self->show_commit_list},
+		],
+		'Status...' => [
+			'File'    => sub { $self->vcs_status_of_file },
+			'Dir'     => sub { $self->status_of_dir },
+			'Project' => sub { $self->vcs_status_of_project },
+		],
+		'Diff...' => [
+			'File'    => sub { $self->diff_of_file },
+			'Dir'     => sub { $self->diff_of_dir },
+			'Project' => sub { $self->diff_of_project },
+		],
+	];
+}
+
+
+
+#####################################################################
+# Custom Methods
+
+sub show_about {
+	my $self = shift;
+
+	# Generate the About dialog
+	my $about = Wx::AboutDialogInfo->new;
+	$about->SetName("Padre::Plugin::HG");
+	$about->SetDescription( <<"END_MESSAGE" );
+Initial HG support for Padre
+END_MESSAGE
+	$about->SetVersion( $VERSION );
+
+	# Show the About dialog
+	Wx::AboutBox( $about );
+
+	return;
+}
+
+
+sub vcs_commit {
+	my ($self, $path, $dir ) = @_;
+	my $main = Padre->ide->wx->main;
+	
+	if (!$self->_project_root($path))
+	{
+		$main->error("File not in a $VCS Project", "Padre $VCS" );
+		return;
+	}
+
+	my $message = $main->prompt("$VCS Commit of $path", "Please type in your message", "MY_".$VCS."_COMMIT");
+	if ($message) {
+		
+		my $command = eval "qq\0$VCSCommand{commit} $path\0";
+		my $result = $self->vcs_execute($command, $dir);
+		$main->message( $result, "$VCS Commiting $path" );
+	}
+
+	return;	
+}
+
+
+
+sub vcs_add {
+	my ($self, $path, $dir) = @_;
+	my $main = Padre->ide->wx->main;
+
+	#$main->message( "$VCS adding $path", 'Adding to Repository' );
+	my $command = eval "qq\0$VCSCommand{add} $path\0";
+	my $result = $self->vcs_execute($command,$dir);
+	$main->message( $result, "$VCS Adding to Repository" );
+	return;	
+}
+
+sub vcs_diff {
+	my ($self, $path, $dir) = @_;
+	
+	my $main = Padre->ide->wx->main;
+	my $command = eval "qq\0$VCSCommand{diff} $path\0";
+	return $main->error('File not in a $VCS Project', "Padre $VCS" ) if not $self->_project_root($path);
+	my $result = $self->vcs_execute($command, $dir);
+	use Padre::Wx::Dialog::Text;
+	Padre::Wx::Dialog::Text->show($main, "$VCS Diff of $path", $result);
+	return;
+}
+
+sub clone_project
+{
+	my ($self, $path, $dir) = @_;
+	my $main = Padre->ide->wx->main;
+	my $command = eval "qq\0$VCSCommand{clone}\0";
+	my $result = $self->vcs_execute($command, $dir);
+	$main->message( $result, "$VCS Cloning $path" );
+	return;
+}
+
+sub pull_update_project
+{
+	my ($self, $path, $dir) = @_;
+	my $main = Padre->ide->wx->main;
+	return $main->error('File not in a $VCS Project', "Padre $VCS" ) if not $self->_project_root($path);
+	my $command = eval "qq\0$VCSCommand{pull}\0";
+	my $result = $self->vcs_execute($command, $dir);
+	$main->message( $result, "$VCS Cloning $path" );
+	return;
+}
+
+sub push_project
+{
+	my ($self, $path, $dir) = @_;
+	my $main = Padre->ide->wx->main;
+	return $main->error('File not in a $VCS Project', "Padre $VCS" ) if not $self->_project_root($path);
+	my $command = eval "qq\0$VCSCommand{push}\0";
+	my $result = $self->vcs_execute($command, $dir);
+	$main->message( $result, "$VCS Pushing $path" );
+	return;
+}
+
+sub vcs_execute
+{
+	my ($self, $command, $dir) = @_;
+	print "\n\nvcs_execute $command $dir\n\n";
+	my $result = capture_merged(sub{chdir($dir);system($command)});
+	print "\n\nresult = $result \n\n";
+	return $result;
+}
+# displays the status of the Hg project in the side bar. 
+#
+sub show_statusTree
+{	
+	my ($self) = @_;
+	my $main = Padre->ide->wx->main;
+	my $project_root = $self->_project_root(current_filename());
+
+	return $main->error("Not a $VCS Project") if !$project_root;
+	# we only want to add a tree for projects that don't already have one. 
+	if (!exists($projects{$project_root}) )
+	{
+		$projects{$project_root} = Padre::Plugin::HG::StatusTree->new($self,$project_root);	
+	}
+}
+
+# displays the status of the Hg project in the side bar. 
+#
+sub show_commit_list
+{	
+	my ($self) = @_;
+	my $main = Padre->ide->wx->main;
+	 $self->{project_path} = $self->_project_root(current_filename());
+
+	return $main->error("Not a $VCS Project") if ! $self->{project_path} ;
+ 
+	Padre::Plugin::HG::ProjectCommit->showList($self);	
+
+}
+
+sub show_project_clone
+{	
+	my ($self) = @_;
+	my $main = Padre->ide->wx->main;
+	Padre::Plugin::HG::ProjectClone->new($self);	
+
+}
+
+
+
+
+sub _project_root
+{
+	my ($self, $filename) = @_;
+	my $dir = File::Basename::dirname($filename);
+	my $project_root = $self->vcs_execute($VCSCommand{root}, $dir);
+	#file in not in a HG project.
+	if ($project_root =~ m/^abort:/)
+	{
+			$project_root = 0;
+	}
+	chomp ($project_root);
+	return $project_root;
+}
+
+
+sub _get_hg_files
+{
+	my ($self, @hg_status) = @_;
+	my @files;
+	foreach my $line (@hg_status)
+	{
+		my ($filestatus, $path) = split(/\s/,$line);
+		push (@files, ([$filestatus,$path]));
+	}
+	return @files;
+}
+
+
+
+sub current_filename {
+
+	my $main = Padre->ide->wx->main;
+	my $doc = $main->current->document;
+	
+	my $filename = $doc->filename;
+	return $main->error("No document found") if not $filename;
+        return ($filename); 
+}
+
+1;
+
+# Copyright 2008-2009 The Padre development team as listed in Padre.pm.
+# LICENSE
+# This program is free software; you can redistribute it and/or
+# modify it under the same terms as Perl 5 itself.
+

HG/ProjectClone.pm

+package Padre::Plugin::HG::ProjectClone;
+
+
+
+
+
+
+=pod
+
+=head1 NAME
+
+Module::Name - My author was too lazy to write an abstract
+
+=head1 SYNOPSIS
+
+  my $object = Module::Name->new(
+      foo  => 'bar',
+      flag => 1,
+  );
+  
+  $object->dummy;
+
+=head1 DESCRIPTION
+
+The author was too lazy to write a description.
+
+=head1 METHODS
+
+=cut
+
+use 5.006;
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+use Wx qw[:everything];
+use base 'Wx::Panel';
+
+=pod
+
+=head2 new
+
+  my $object = Module::Name->new(
+      foo => 'bar',
+  );
+
+The C<new> constructor lets you create a new B<Module::Install> object.
+
+So no big surprises there...
+
+Returns a new B<Module::Install> or dies on error.
+
+=cut
+
+sub new
+{
+    my ($class, $hg) = @_; 
+    my $self       = $class->SUPER::new( Padre::Current->main);
+    $self->{hg} = $hg;
+    $self->enter_repository();
+    if ($self->{project_url})
+    {
+        $self->choose_destination();
+        $self->clone();
+    }
+    
+    
+    return $self;
+}
+
+sub clone
+{
+    my ($self) = @_;
+   if ($self->{project_url}  and $self->{selected_dir})
+   {
+         $self->{hg}->clone_project($self->{project_url},$self->{destination_dir}); 
+   }
+        
+    
+}
+
+sub enter_repository
+{
+ my ($self) = @_;
+ my $main = Padre->ide->wx->main;
+ my $message = $main->prompt("Clone Project", "Enter the Project URL to clone", 'http://');    
+ $self->{project_url} = $message ; 
+    
+}
+
+sub choose_destination
+{
+    my ($self) = @_;
+    my $dialog = Wx::DirDialog->new($self, 'Choose a Destination Directory');
+    $dialog->ShowModal();
+    $self->{destination_dir} = $dialog->GetPath();
+}
+=pod
+
+=head2 dummy
+
+This method does something... apparently.
+
+=cut
+
+
+
+1;
+
+=pod
+
+=head1 SUPPORT
+
+No support is available
+
+=head1 AUTHOR
+
+Copyright 2008 Anonymous.
+
+=cut

HG/ProjectCommit.pm

+package Padre::Plugin::HG::ProjectCommit;
+use strict;
+use Wx qw[:everything];
+use Wx::Event qw( EVT_BUTTON );
+use base 'Wx::Panel';
+
+
+my $images = Wx::ImageList->new( 16, 16 );
+        my $file_types = {
+                M => $images->Add(
+	                        Wx::ArtProvider::GetBitmap( 'wxART_TIP', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                dir => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_FOLDER', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                C => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_TICK_MARK', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                '?' => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_MISSING_IMAGE', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+          };
+
+
+sub showList
+{
+	my ($class, $hg) = @_;
+	
+	my $self       = $class->SUPER::new( Padre::Current->main);
+	$self->{hg} = $hg;
+	my $frame = Wx::Frame->new( undef, -1, 'Padre Mecurial Commit');
+	my $sizer = Wx::BoxSizer->new(wxVERTICAL);
+	my $sizer2 = Wx::BoxSizer->new(wxHORIZONTAL);
+	my   $listbox1 = Wx::ListCtrl->new($frame, -1, wxDefaultPosition,
+	wxDefaultSize,wxLC_LIST, wxDefaultValidator, 'listbox_1');
+        $listbox1->AssignImageList($images,1);
+        #insert the HG data
+        chdir ($self->{hg}->{project_path});
+        my @hgdata = `hg status`;
+        my @filestatus =  $self->{hg}->_get_hg_files(@hgdata);
+        $self->{file_listbox} = $listbox1;
+	$self->_populate_list( \@filestatus );
+   
+
+	
+
+
+	my $ok_button = Wx::Button->new($frame, 
+						1,                  # id
+						"OK", # label
+						[50,50]             # position
+                                       );
+	my $cancel_button = Wx::Button->new($frame,             # parent
+                                        2,                  # id
+                                        "Cancel", # label
+                                        [50,50]             # position
+                                       );
+
+	#Handle the Button Clicks
+	
+	EVT_BUTTON( $ok_button, 
+             1,         
+             sub{$self->_get_selected_items} 
+             );
+             
+	EVT_BUTTON( $cancel_button, 
+             2,
+              sub{$frame->Destroy(); return} 
+             );
+
+    $sizer->Add($listbox1, 1, wxEXPAND, 10);
+    $sizer2->Add($ok_button, 0, wxALL, 10);
+    $sizer2->Add($cancel_button, 0, wxALL, 10);
+    $sizer->Add($sizer2, 0, wxEXPAND, 10);
+    $frame->SetSizerAndFit($sizer);
+    $frame->Show( 1 ); 
+}
+
+
+sub _get_selected_items
+{
+	my( $self, $event ) = @_; 
+
+	# Change the contents of $self->{txt}
+	print "print the button was clicked\n";
+	my $file_list;
+	#$self->{txt}->SetLabel("The button was clicked!"); 
+	my $item = -1;
+	 while ( 1 ==1 )
+	{
+        $item = $self->{file_listbox}->GetNextItem($item,
+                                     wxLIST_NEXT_ALL,
+                                     wxLIST_STATE_SELECTED);
+        if ( $item == -1 )
+        {
+            last;
+	}
+        # this item is selected - do whatever is needed with it
+        my $itemObj = $self->{file_listbox}->GetItem($item);
+        $file_list .= '"'.$itemObj->GetText().'" ';
+       
+    }
+    
+    $self->{hg}->vcs_commit($file_list, $self->{hg}->{project_path});
+}
+
+sub _populate_list
+{
+ my ($self, $filestatus) = @_;
+ 
+ if (!$filestatus) {return}
+ foreach my $file (@$filestatus)
+ {
+	my ($status, $path) = @$file;
+	$self->{file_listbox}->InsertImageStringItem(1, $path, $file_types->{$status});
+ }	
+	
+}
+
+
+package Padre::Plugin::HG::StatusTree;
+
+use strict;
+use warnings;
+
+our $VERSION = '0.01';
+
+use Padre::Wx;
+use lib ("/home/mm/.padre/plugins");
+use Padre::Util qw/_T/;
+use Wx qw/WXK_UP WXK_DOWN wxTR_HAS_BUTTONS  wxTR_HIDE_ROOT  /;
+use base 'Wx::Panel';
+use Padre::Plugin::My;
+use Padre::Plugin::HG;
+use File::Spec;
+use File::Basename;
+my $HG;
+my %dirTree;
+my $project_name;
+my %WxTree;
+my $ThisTree;
+
+ my $images = Wx::ImageList->new( 16, 16 );
+        my $file_types = {
+                M => $images->Add(
+	                        Wx::ArtProvider::GetBitmap( 'wxART_TIP', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                dir => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_FOLDER', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                C => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_TICK_MARK', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+                '?' => $images->Add(
+                        Wx::ArtProvider::GetBitmap( 'wxART_MISSING_IMAGE', 'wxART_OTHER_C', [ 16, 16 ] ),
+                ),
+          };
+
+
+my @root = qw (root root);
+
+
+
+
+
+sub new
+{
+  my ($class, $hg, $root) = @_;
+  $project_name = $root;
+  $HG = $hg;
+  my $self       = $class->SUPER::new( Padre::Current->main->left );
+  my $box        = Wx::BoxSizer->new(Wx::wxVERTICAL);
+  my $treectrl = Wx::TreeCtrl->new( $self, -1 );
+  $treectrl->AssignImageList($images);
+
+  $self->drawTree($treectrl);
+  Wx::Event::EVT_TREE_ITEM_MENU(
+         $treectrl, $treectrl,
+         \&_on_tree_item_menu,
+  );
+  
+  #Double Click
+  Wx::Event::EVT_TREE_ITEM_ACTIVATED(
+            $treectrl, $treectrl,
+             \&_on_tree_item_activated
+  );
+  
+  $box->Add( $treectrl, 1, Wx::wxGROW );
+
+  $self->SetSizer($box);  
+  Padre::Current->main->left->show($self);
+  $ThisTree = $self;
+  return $self;
+   
+}
+
+sub process_key {
+        my ( $input, $event ) = @_;
+        my $code = $event->GetKeyCode;
+
+        if ( $code == WXK_UP ) {
+                Padre::Plugin::REPL::History::go_previous();
+        } elsif ( $code == WXK_DOWN ) {
+                Padre::Plugin::REPL::History::go_next();
+        }
+        $event->Skip();
+}
+
+sub gettext_label {
+        
+         my @dirs = File::Spec->splitdir( $project_name );
+         my $name = File::Spec->catdir(('..',$dirs[-2], $dirs[-1]));
+         chomp $name;
+        return "(HG) ".$name;
+}
+
+
+ 
+#$dirTree{root} = 'root';# = treectrl->AppendRoot('.');
+
+
+sub getWxNode
+{
+    my ($treectrl,$node,$path) = @_;
+    
+    my $name = $node->[0];
+    my $parent = $node->[1];
+    my $type = $node->[2];
+    chomp $path;
+    chomp $name;
+    if (exists($WxTree{$path}))
+    {
+      return $WxTree{$path};
+      # $WxTree{$path} = $treectrl->AppendItem( $WxTree{$parent}, $name);
+      
+    }else
+    {
+        $WxTree{$path} = $treectrl->AppendItem( 
+                  getWxNode($treectrl, $dirTree{$parent}, $parent), 
+                            $name, 
+                            $file_types->{$type},
+                             -1,
+                             Wx::TreeItemData->new(
+                                            {   name => $name,
+                                                path  => $path,
+	                                        type => $type,
+	                                }));
+    }
+  
+  
+}
+
+sub parseHgStatus
+{
+      my (@hgstatus) = @_;
+      
+      foreach my $line (@hgstatus)
+      {
+        my ($filestatus, $path) = split(/\s/,$line);
+        chomp $path;
+        my @dir =  split(/\//,$path);
+        createBranch(\@dir,$filestatus);
+               
+      }
+  
+  
+  
+}
+
+sub createBranch
+{
+  
+  my ($dirRef, $status) = @_;
+  my @dir = @$dirRef;
+  my $count = 0;
+  my %parentChild;
+  foreach my $item (@dir)
+  {
+    my $type;
+    my $parent = '';
+    if ($count == 0 ) 
+    { 
+      $parent = $dirTree{root}->[0]; 
+    }
+    else
+    {
+      $parent= join('/',@dir[0..$count -1 ]);
+    }
+    my $node = join('/',@dir[0..$count]);
+    if (!exists($dirTree{$node}))
+    {
+
+	     if ($count < (scalar(@dir) -1))
+	     {
+	       $type = 'dir';
+	     }
+	     else
+	     {
+	       $type = $status;
+	     }
+	     $dirTree{$node} = [$item, $parent, $type];
+    }
+    
+     $count ++;
+  }
+  #return %dirTree;
+}
+
+sub drawTree {
+  my ($self,$treectrl) = @_;
+  
+  %WxTree = ();
+  $WxTree{root} = $treectrl->AddRoot( 
+                        $project_name, 
+                        $file_types->{dir},
+                        -1,
+                        Wx::TreeItemData->new(
+                                            {   name => 'root',
+                                                path  => '',
+	                                        type => 'root',
+	                                })  ); 
+    
+  #$treectrl->DeleteAllItems;
+  %dirTree = ();
+  $dirTree{root} = ['root', 'root', 'dir'];
+  chdir ($project_name);
+  my @hgStatus = `hg status --all`;
+  chomp (@hgStatus);
+  parseHgStatus(@hgStatus);
+  foreach my $file  (keys(%dirTree))
+  {
+       my $path = File::Spec->catdir($project_name,$file);
+       my $dir = File::Basename::dirname($path);
+       print $path."\n";
+       getWxNode($treectrl, $dirTree{$file}, $file);      
+  }
+
+
+}
+
+sub _on_tree_item_activated
+{
+	
+	my ( $self, $event,$me ) = @_;
+	my $node      = $event->GetItem;
+        my $node_data = $self->GetPlData($node);
+	my $selected_path  = $node_data->{path};
+        my $selected_file = $node_data->{name};
+        my $selected_type = $node_data->{type};
+        my $full_path = File::Spec->catdir(($project_name,$selected_path));
+
+        if ($selected_type ne 'dir' and $selected_type ne 'root')
+        {
+                open_file($full_path);
+        }
+        
+
+}
+sub _on_tree_item_menu {
+        my ( $self, $event,$me ) = @_;
+        my $node      = $event->GetItem;
+        my $node_data = $self->GetPlData($node);
+        my $menu          = Wx::Menu->new;
+        # Default action - same when the item is activated
+        my $selected_path  = $node_data->{path};
+        my $selected_file = $node_data->{name};
+        my $selected_type = $node_data->{type};
+        my $full_path = File::Spec->catdir(($project_name,$selected_path));
+        print "selected Path = $selected_path\n";
+        my $parent_dir = File::Basename::dirname($full_path);
+        #Commit
+        if ($selected_type eq 'root')
+        {
+               print "ParentDir". $parent_dir ."\n";
+                my $default = $menu->Append(
+                        -1,
+                       Wx::gettext( 'Refresh' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $default,
+                       sub { $ThisTree->refresh($self) }
+               );   
+               my $pull = $menu->Append(
+                        -1,
+                       Wx::gettext( 'Pull & Update' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $pull,
+                        sub {  $HG->pull_update_project($selected_file, $project_name) }
+               );    
+               my $push = $menu->Append(
+                        -1,
+                       Wx::gettext( 'Push' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $push,
+                       sub {  $HG->push_project($selected_file, $project_name) }
+               );   
+        }
+        
+        elsif ($selected_type ne 'dir' and $selected_type ne 'root')
+        {
+                my $default = $menu->Append(
+                        -1,
+                       Wx::gettext( 'Commit' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $default,
+                       sub { $HG->vcs_commit($selected_file, $parent_dir ); $ThisTree->refresh($self)}
+               );
+               
+               #Add
+               my $add = $menu->Append(
+                         -1,
+                       Wx::gettext( 'Add' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $add,
+                       sub { $HG->vcs_add($selected_file, $parent_dir);$ThisTree->refresh($self)}
+               );   
+               
+               #diff (just diffs current file to Tip) 
+               my $diff = $menu->Append(
+                         -1,
+                       Wx::gettext( 'Diff to Tip' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $diff,
+                       sub { $HG->vcs_diff($selected_file, $parent_dir);}
+               );  
+               
+               #open 
+               my $open = $menu->Append(
+                         -1,
+                       Wx::gettext( 'Open' ));
+                    
+                Wx::Event::EVT_MENU(
+                       $self, $open,
+                       sub{open_file($full_path)}
+               ); 
+               
+                 
+       }
+       
+       
+        my $x = $event->GetPoint->x;
+        my $y = $event->GetPoint->y;
+        $self->PopupMenu( $menu, $x, $y );
+        
+
+}
+
+sub open_file
+{ 
+     	 my ($path) = @_;
+     	        my $main = Padre->ide->wx->main;
+	        if ( my $id = $main->find_editor_of_file($path) ) {
+	                my $page = $main->notebook->GetPage($id);
+	                $page->SetFocus;
+	        } else {
+	                $main->setup_editors($path);
+	        }
+}
+
+sub refresh {
+    my ($self, $treeCtrl) = @_;
+        $treeCtrl->DeleteAllItems;
+        $self->drawTree($treeCtrl); 
+    return ();
+}
+1;
+#!/usr/bin/perl
+
+use 5.006;
+use strict;
+use warnings;
+use Test::More tests => 3;
+use FindBin qw ($Bin);
+use lib ("$Bin/../../../../");
+use Padre::Plugin::HG;
+my @hgstatus = ( 'M dir1/test.txt',
+	'? CVS',
+	'? dir2/text1.txt',
+	'? dir2/text2.txt',
+	'? parseStatus.pm',
+	'? status.txt',
+	'? t/padreUtil.t',
+	'? t/parseStatus.t',
+	'? test1.txt');
+
+my @files;
+ok( @files = Padre::Plugin::HG::_get_hg_files(@hgstatus), "Get files from  hg status");
+is ($files[0], 'dir1/test.txt', 'first file');
+is ($files[8], 'test1.txt', 'last file');
+
+print Padre::Plugin::HG::_project_root('','/home/mm/hg/test.pl');
+