package Padre::Wx::Dialog::Diff;
use 5.008;
use strict;
use warnings;
use Padre::Constant ();
use Padre::Wx ();
our $VERSION = '0.96';
our @ISA = (
'Padre::Wx::Role::Main',
'Wx::PopupWindow',
);
sub new {
my $class = shift;
my $self = $class->SUPER::new(@_);
my $panel = Wx::Panel->new($self);
$self->{prev_diff_button} = Wx::BitmapButton->new(
$panel,
-1,
Padre::Wx::Icon::find("actions/go-up"),
);
$self->{prev_diff_button}->SetToolTip( Wx::gettext('Previous difference') );
$self->{next_diff_button} = Wx::BitmapButton->new(
$panel,
-1,
Padre::Wx::Icon::find("actions/go-down"),
);
$self->{next_diff_button}->SetToolTip( Wx::gettext('Next difference') );
$self->{revert_button} = Wx::BitmapButton->new(
$panel,
-1,
Padre::Wx::Icon::find("actions/edit-undo"),
);
$self->{revert_button}->SetToolTip( Wx::gettext('Revert this change') );
$self->{close_button} = Wx::BitmapButton->new(
$panel,
-1,
Padre::Wx::Icon::find("actions/window-close"),
);
$self->{close_button}->SetToolTip( Wx::gettext('Close this window') );
$self->{status_label} = Wx::TextCtrl->new(
$panel,
-1,
'',
Wx::DefaultPosition,
[ 130, -1 ],
Wx::TE_READONLY,
);
$self->{text_ctrl} = Wx::TextCtrl->new(
$panel,
-1,
'',
Wx::DefaultPosition,
# (pbp line = 78 chrs) *2/3=52
# (9/16) 52 chrs plus a half; (52*9)+4 = 472
# 4 lines plus a half: (4*16)+8= 72
[ 472, 72 ],
Wx::TE_READONLY | Wx::TE_MULTILINE | Wx::TE_DONTWRAP,
);
my $button_sizer = Wx::BoxSizer->new(Wx::HORIZONTAL);
$button_sizer->Add( $self->{prev_diff_button}, 0, 0, 0 );
$button_sizer->Add( $self->{next_diff_button}, 0, 0, 0 );
$button_sizer->Add( $self->{revert_button}, 0, 0, 0 );
$button_sizer->AddSpacer(10);
$button_sizer->Add( $self->{status_label}, 0, Wx::ALL, 0 );
$button_sizer->AddStretchSpacer;
$button_sizer->Add( $self->{close_button}, 0, 0, 0 );
my $vsizer = Wx::BoxSizer->new(Wx::VERTICAL);
$vsizer->AddSpacer(1);
$vsizer->Add( $button_sizer, 0, Wx::ALL | Wx::EXPAND, 1 );
$vsizer->Add( $self->{text_ctrl}, 0, Wx::ALL | Wx::EXPAND, 1 );
# Previous difference button
Wx::Event::EVT_BUTTON(
$self,
$self->{prev_diff_button},
\&on_prev_diff_button,
);
# Next difference button
Wx::Event::EVT_BUTTON(
$self,
$self->{next_diff_button},
\&on_next_diff_button,
);
# Revert button
Wx::Event::EVT_BUTTON(
$self,
$self->{revert_button},
\&on_revert_button,
);
# Close button
Wx::Event::EVT_BUTTON(
$self,
$self->{close_button},
sub {
$_[0]->Hide;
}
);
$panel->SetSizer($vsizer);
$panel->Fit;
$self->Fit;
return $self;
}
sub on_prev_diff_button {
$_[0]->main->diff->select_previous_difference;
}
sub on_next_diff_button {
$_[0]->main->diff->select_next_difference;
}
sub on_revert_button {
my $self = shift;
my $editor = $self->{editor};
my $line = $self->{line};
my $diff = $self->{diff};
my $old_text = $diff->{old_text};
my $new_text = $diff->{new_text};
my $start = $editor->PositionFromLine($line);
my $end = $editor->GetLineEndPosition( $line + $diff->{lines_added} ) + 1;
$editor->SetTargetStart($start);
$editor->SetTargetEnd( $start + length($new_text) );
$editor->ReplaceTarget( $old_text ? $old_text : '' );
$self->Hide;
}
sub show {
my $self = shift;
my $editor = shift;
my $line = shift;
my $diff = shift;
my $pt = shift;
my $type = $diff->{type} or return;
# Store editor reference so we can access it in revert
$self->{editor} = $editor;
$self->{line} = $line;
$self->{diff} = $diff;
# Inherit font from current editor
my $font = $editor->GetFont;
$self->{status_label}->SetFont($font);
$self->{text_ctrl}->SetFont($font);
# Hack to workaround Wx::PopupWindow relative positioning bug
if (Padre::Constant::WIN32) {
$self->Move( $self->main->ScreenToClient( $editor->ClientToScreen($pt) ) );
} else {
$self->Move( $editor->ClientToScreen($pt) );
}
my $color;
if ( $type eq 'A' ) {
$color = Padre::Wx::Editor::DARK_GREEN();
} elsif ( $type eq 'D' ) {
$color = Padre::Wx::Editor::LIGHT_RED();
} elsif ( $type eq 'C' ) {
$color = Padre::Wx::Editor::LIGHT_BLUE();
} else {
$color = Wx::Colour->new("black");
}
$self->{text_ctrl}->SetBackgroundColour($color);
$self->{status_label}->SetValue( $diff->{message} );
if ( $diff->{old_text} ) {
$self->{text_ctrl}->SetValue( $diff->{old_text} );
$self->{text_ctrl}->Show(1);
} else {
$self->{text_ctrl}->Show(0);
}
# Hide when the editor loses focus
my $popup = $self;
Wx::Event::EVT_KILL_FOCUS(
$editor,
sub {
$popup->Hide;
}
);
Wx::Event::EVT_KEY_UP(
$editor,
sub {
my ( $self, $event ) = @_;
if ( $event->GetKeyCode == Wx::WXK_ESCAPE ) {
# Escape hides the diff box
$popup->Hide;
}
$event->Skip;
}
);
my $panel = $self->{text_ctrl}->GetParent;
$panel->Layout;
$panel->Fit;
$self->Fit;
$self->Show(1);
}
1;
# Copyright 2008-2012 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.