package Padre::Wx::ReplaceInFiles;
# Class for the output window at the bottom of Padre that is used to display
# results from Replace in Files searches.
use 5.008;
use strict;
use warnings;
use File::Spec ();
use Padre::Role::Task ();
use Padre::Wx::Role::Idle ();
use Padre::Wx::Role::View ();
use Padre::Wx::Role::Main ();
use Padre::Wx::Role::Context ();
use Padre::Wx::TreeCtrl ();
use Padre::Wx ();
use Padre::Logger;
our $VERSION = '1.00';
our @ISA = qw{
Padre::Role::Task
Padre::Wx::Role::Idle
Padre::Wx::Role::View
Padre::Wx::Role::Main
Padre::Wx::Role::Context
Padre::Wx::TreeCtrl
};
######################################################################
# Constructor
sub new {
my $class = shift;
my $main = shift;
my $panel = shift || $main->bottom;
# Create the underlying object
my $self = $class->SUPER::new(
$panel,
-1,
Wx::DefaultPosition,
Wx::DefaultSize,
Wx::TR_SINGLE | Wx::TR_FULL_ROW_HIGHLIGHT | Wx::TR_HAS_BUTTONS | Wx::CLIP_CHILDREN
);
# Create the image list
my $images = Wx::ImageList->new( 16, 16 );
$self->{images} = {
folder => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_FOLDER',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
file => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_NORMAL_FILE',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
result => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_GO_FORWARD',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
root => $images->Add(
Wx::ArtProvider::GetBitmap(
'wxART_HELP_FOLDER',
'wxART_OTHER_C',
[ 16, 16 ],
),
),
};
$self->AssignImageList($images);
Wx::Event::EVT_TREE_ITEM_ACTIVATED(
$self, $self,
sub {
$_[0]->idle_method(
item_clicked => $_[1]->GetItem,
);
},
);
# $self->context_bind;
# Inialise statistics
$self->{files} = 0;
$self->{matches} = 0;
return $self;
}
######################################################################
# Event Handlers
sub item_clicked {
my $self = shift;
my $item = shift;
my $data = $self->GetPlData($item) or return;
my $dir = $data->{dir} or return;
my $file = $data->{file} or return;
my $path = File::Spec->catfile( $dir, $file );
$self->main->setup_editor($path);
}
######################################################################
# Padre::Wx::Role::View Methods
sub view_panel {
return 'bottom';
}
sub view_label {
Wx::gettext('Replace in Files');
}
sub view_close {
$_[0]->task_reset;
$_[0]->main->show_replaceinfiles(0);
}
######################################################################
# Padre::Wx::Role::Context Methods
sub context_menu {
my $self = shift;
my $menu = shift;
$self->context_append_options( $menu => 'main_foundinfiles_panel' );
return;
}
######################################################################
# Search Methods
sub replace {
my $self = shift;
my %param = @_;
# If we are given a root and no project, and the root path
# is precisely the root of a project, switch so that the search
# will automatically pick up the manifest/skip rules for it.
if ( defined $param{root} and not exists $param{project} ) {
my $project = $self->ide->project_manager->project( $param{root} );
$param{project} = $project if $project;
}
# Kick off the replace task
$self->task_reset;
$self->task_request(
task => 'Padre::Task::ReplaceInFiles',
on_message => 'replace_message',
on_finish => 'replace_finish',
dryrun => 0,
%param,
);
$self->clear;
my $root = $self->AddRoot('Root');
$self->SetItemText(
$root,
sprintf( Wx::gettext(q{Replacing '%s' in '%s'...}), $param{search}->find_term, $param{root} )
);
$self->SetItemImage( $root, $self->{images}->{root} );
return 1;
}
sub replace_message {
TRACE( $_[0] ) if DEBUG;
my $self = shift;
my $task = shift;
my $path = shift;
my $root = $self->GetRootItem;
# Lock the tree to reduce flicker and prevent auto-scrolling
my $lock = $self->lock_scroll;
# Add the file node to the tree.
# Added to avoid crash in next line.
require Padre::Wx::Directory::Path;
my $name = $path->name;
my $dir = File::Spec->catfile( $task->root, $path->dirs );
my $full = File::Spec->catfile( $task->root, $path->path );
my $count = shift or next;
if ( $count > 0 ) {
my $label = sprintf( Wx::gettext('%s (%s changed)'), $full, $count );
my $file = $self->AppendItem( $root, $label, $self->{images}->{file} );
$self->SetPlData( $file, { dir => $dir, file => $name } );
# Update statistics
$self->{matches} += $count;
$self->{files} += 1;
} else {
my $label = sprintf( Wx::gettext('%s (crashed)'), $full );
my $file = $self->AppendItem( $root, $label, $self->{images}->{file} );
$self->SetItemTextColour( $file => Padre::Wx::color('990000') );
$self->SetItemBold( $file => 1 );
$self->SetPlData( $file => { dir => $dir, file => $name } );
}
# Ensure the root is expanded
$self->Expand($root);
return 1;
}
sub replace_finish {
TRACE( $_[0] ) if DEBUG;
my $self = shift;
my $task = shift;
my $term = $task->{search}->find_term;
my $dir = $task->{root};
# Display the summary
my $root = $self->GetRootItem;
if ( $self->{files} ) {
$self->SetItemText(
$root,
sprintf(
Wx::gettext(q{Replace complete, found '%s' %d time(s) in %d file(s) inside '%s'}),
$term,
$self->{matches},
$self->{files},
$dir,
)
);
} else {
$self->SetItemText(
$root,
sprintf(
Wx::gettext(q{No results found for '%s' inside '%s'}),
$term,
$dir,
)
);
}
return 1;
}
#####################################################################
# General Methods
sub select {
my $self = shift;
my $parent = $self->GetParent;
$parent->SetSelection( $parent->GetPageIndex($self) );
return;
}
sub clear {
my $self = shift;
$self->{files} = 0;
$self->{matches} = 0;
$self->DeleteAllItems;
return 1;
}
1;
# Copyright 2008-2013 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.