/usr/local/CPAN/Padre/Padre/Wx/Directory/TreeCtrl.pm
package Padre::Wx::Directory::TreeCtrl;
use 5.008;
use strict;
use warnings;
use File::Path ();
use File::Spec ();
use Padre::Constant ();
use Padre::Wx::TreeCtrl ();
use Padre::Wx::Role::Main ();
use Padre::Wx::Directory::Path ();
our $VERSION = '0.86';
our @ISA = qw{
Padre::Wx::Role::Main
Padre::Wx::TreeCtrl
};
######################################################################
# Constructor
sub new {
my $class = shift;
my $panel = shift;
my $self = $class->SUPER::new(
$panel,
-1,
Wx::wxDefaultPosition,
Wx::wxDefaultSize,
Wx::wxTR_HIDE_ROOT | Wx::wxTR_SINGLE | Wx::wxTR_FULL_ROW_HIGHLIGHT | Wx::wxTR_HAS_BUTTONS
| Wx::wxTR_LINES_AT_ROOT | Wx::wxBORDER_NONE | Wx::wxCLIP_CHILDREN
);
# Create the image list
my $images = Wx::ImageList->new( 16, 16 );
$self->{images} = {
upper => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_GO_DIR_UP',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
folder => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_FOLDER',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
package => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_NORMAL_FILE',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
};
$self->AssignImageList($images);
# Set up the events
Wx::Event::EVT_TREE_ITEM_ACTIVATED(
$self, $self,
sub {
shift->on_tree_item_activated(@_);
}
);
Wx::Event::EVT_TREE_ITEM_MENU(
$self, $self,
sub {
shift->on_tree_item_menu(@_);
},
);
Wx::Event::EVT_KEY_UP( $self, \&key_up );
# Set up the root
$self->AddRoot( Wx::gettext('Directory'), -1, -1 );
# Ident to sub nodes
$self->SetIndent(10);
return $self;
}
######################################################################
# Event Handlers
# Action that must be executaded when a item is activated
# Called when the item is actived
sub on_tree_item_activated {
my $self = shift;
my $item = shift->GetItem;
my $data = $self->GetPlData($item);
my $parent = $self->GetParent;
# If a folder, toggle the expand/collanse state
if ( $data->type == 1 ) {
$self->Toggle($item);
return;
}
# Open the selected file
my $current = $self->current;
my $main = $current->main;
my $file = File::Spec->catfile( $parent->root, $data->path );
$main->setup_editor($file);
return;
}
sub key_up {
my $self = shift;
my $event = shift;
my $mod = $event->GetModifiers || 0;
my $code = $event->GetKeyCode;
# see Padre::Wx::Main::key_up
$mod = $mod & ( Wx::wxMOD_ALT() + Wx::wxMOD_CMD() + Wx::wxMOD_SHIFT() );
my $current = $self->current;
my $main = $current->main;
my $project = $current->project;
my $item_id = $self->GetSelection;
my $data = $self->GetPlData($item_id);
return if not $data;
my $file = File::Spec->catfile( $project->root, $data->path );
if ( $code == Wx::WXK_DELETE ) {
$self->_delete_file($file);
}
$event->Skip;
return;
}
sub _create_directory {
my $self = shift;
my $file = shift;
my $main = $self->main;
my $dir_name =
$main->prompt( 'Please type in the name of the new directory', 'Create Directory', 'CREATE_DIRECTORY' );
return if ( !defined($dir_name) || $dir_name =~ /^\s*$/ );
require File::Spec;
require File::Basename;
my $path = File::Basename::dirname($file);
if ( mkdir File::Spec->catdir( $path, $dir_name ) ) {
$self->GetParent->browse;
} else {
$main->error( sprintf( Wx::gettext(q(Could not create: '%s': %s)), $path, $! ) );
}
return;
}
sub _delete_file {
my $self = shift;
my $file = shift;
my $main = $self->main;
return if not $main->yes_no( sprintf( Wx::gettext('Really delete the file "%s"?'), $file ) );
my $error_ref;
File::Path::remove_tree( $file, { error => \$error_ref } );
if ( scalar @$error_ref == 0 ) {
$self->GetParent->browse;
} else {
$main->error( sprintf Wx::gettext(q(Could not delete: '%s': %s)), $file, ( join ' ', @$error_ref ) );
}
}
# Shows up a context menu above an item with its controls
# the file if don't.
# Called when a item context menu is requested.
sub on_tree_item_menu {
my $self = shift;
my $event = shift;
my $item = $event->GetItem;
my $data = $self->GetPlData($item);
# Only show the context menu for files (for now)
if ( $data->type == Padre::Wx::Directory::Path::DIRECTORY ) {
return;
}
# Generate the context menu for this file
my $menu = Wx::Menu->new;
my $file = File::Spec->catfile(
$self->GetParent->root,
$data->path,
);
# The default action is the same as when it is double-clicked
Wx::Event::EVT_MENU(
$self,
$menu->Append( -1, Wx::gettext('Open File') ),
sub {
shift->on_tree_item_activated($event);
}
);
Wx::Event::EVT_MENU(
$self,
$menu->Append( -1, Wx::gettext('Open in File Browser') ),
sub {
shift->main->on_open_in_file_browser($file);
}
);
Wx::Event::EVT_MENU(
$self,
$menu->Append( -1, Wx::gettext('Delete File') ),
sub {
my $self = shift;
$self->_delete_file($file);
}
);
$menu->AppendSeparator;
Wx::Event::EVT_MENU(
$self,
$menu->Append( -1, Wx::gettext('Create Directory') ),
sub {
my $self = shift;
$self->_create_directory($file);
}
);
$menu->AppendSeparator;
# Updates the directory listing
Wx::Event::EVT_MENU(
$self,
$menu->Append( -1, Wx::gettext('Refresh') ),
sub {
shift->GetParent->rebrowse;
}
);
# Pops up the context menu
$self->PopupMenu(
$menu,
$event->GetPoint->x,
$event->GetPoint->y,
);
return;
}
######################################################################
# General Methods
# Scan the tree to find all directory nodes which are expanded.
# Returns a reference to a HASH of ->unix path strings.
sub expanded {
my $self = shift;
my $items = $self->GetExpandedPlData;
my %hash = map { $_->unix => 1 } @$items;
return \%hash;
}
1;
# Copyright 2008-2011 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.