1
package Padre::Wx::Diff;
8
use Padre::Constant ();
9
use Padre::Role::Task ();
12
use Padre::Wx::Dialog::Diff ();
15
our $VERSION = '0.92';
24
######################################################################
25
# Constructor and Accessors
31
my $self = bless {@_}, $class;
32
$self->{main} = $main;
43
######################################################################
44
# Padre::Role::Task Methods
47
TRACE( $_[1] ) if DEBUG;
50
my $chunks = Params::Util::_ARRAY0( $task->{data} ) or return;
51
my $main = $self->{main};
52
my $editor = $main->current->editor or return;
53
my $lock = $editor->lock_update;
55
# Clear any old content
60
for my $chunk ( @$chunks ) {
61
my $marker_line = undef;
62
my $lines_deleted = 0;
64
for my $diff ( @$chunk ) {
65
my ( $type, $line, $text ) = @$diff;
66
TRACE("$type, $line, $text") if DEBUG;
68
unless ($marker_line) {
69
$marker_line = $line + $delta;
71
$self->{diffs}->{$marker_line} = {
79
my $diff = $self->{diffs}->{$marker_line};
83
$diff->{old_text} .= $text;
86
$diff->{new_text} .= $text;
91
my $diff = $self->{diffs}->{$marker_line};
93
if ( $lines_deleted > 0 and $lines_added > 0 ) {
98
? sprintf( Wx::gettext('%d lines changed'), $lines_deleted )
99
: sprintf( Wx::gettext('%d line changed'), $lines_deleted );
100
$editor->MarkerDelete( $marker_line, $_ ) for ( Padre::Constant::MARKER_ADDED, Padre::Constant::MARKER_DELETED );
101
$editor->MarkerAdd( $marker_line, Padre::Constant::MARKER_CHANGED );
104
} elsif ( $lines_added > 0 ) {
109
? sprintf( Wx::gettext('%d lines added'), $lines_added )
110
: sprintf( Wx::gettext('%d line added'), $lines_added );
111
$editor->MarkerDelete( $marker_line, $_ ) for ( Padre::Constant::MARKER_CHANGED, Padre::Constant::MARKER_DELETED );
112
$editor->MarkerAdd( $marker_line, Padre::Constant::MARKER_ADDED );
114
} elsif ( $lines_deleted > 0 ) {
119
? sprintf( Wx::gettext('%d lines deleted'), $lines_deleted )
120
: sprintf( Wx::gettext('%d line deleted'), $lines_deleted );
121
$editor->MarkerDelete( $marker_line, $_ ) for ( Padre::Constant::MARKER_ADDED, Padre::Constant::MARKER_CHANGED );
122
$editor->MarkerAdd( $marker_line, Padre::Constant::MARKER_DELETED );
127
# TODO No change... what to do there... ignore? :)
128
$description = 'no change!';
132
# Record lines added/deleted
133
$diff->{lines_added} = $lines_added;
134
$diff->{lines_deleted} = $lines_deleted;
135
$diff->{type} = $type;
136
$diff->{message} = $description;
139
$delta = $delta + $lines_added - $lines_deleted;
141
TRACE("$description at line #$marker_line") if DEBUG;
144
$editor->SetMarginSensitive( 1, 1 );
146
Wx::Event::EVT_STC_MARGINCLICK(
152
if ( $event->GetMargin == 1 ) {
153
$myself->show_diff_box( $editor->LineFromPosition( $event->GetPosition ), $editor );
168
######################################################################
173
my $current = $self->{main}->current or return;
174
my $editor = $current->editor or return;
175
my $lock = $editor->lock_update;
177
$editor->MarkerDeleteAll(Padre::Constant::MARKER_ADDED);
178
$editor->MarkerDeleteAll(Padre::Constant::MARKER_CHANGED);
179
$editor->MarkerDeleteAll(Padre::Constant::MARKER_DELETED);
181
$self->{dialog}->Hide if $self->{dialog};
185
TRACE( $_[0] ) if DEBUG;
187
my $current = shift or return;
188
my $document = $current->document;
190
# Cancel any existing diff task
193
# Hide the widgets when no files are open
199
# Shortcut if there is nothing to search for
200
if ( $document->is_unused ) {
204
# Trigger the task to fetch the refresh data
206
task => 'Padre::Task::Diff',
207
document => $document,
211
# Generic method to select next or previous difference
212
sub _select_next_prev_difference {
214
my $select_next_diff = shift;
215
my $current = $self->{main}->current or return;
216
my $editor = $current->editor or return;
218
# Sort lines in ascending order
219
my @lines = sort { $a <=> $b } keys %{ $self->{diffs} };
221
# Lines in descending order if select previous diff is enabled
222
@lines = reverse @lines unless $select_next_diff;
224
my $current_line = $editor->LineFromPosition( $editor->GetCurrentPos );
225
my $line_to_select = undef;
226
for my $line (@lines) {
227
unless ( defined $line_to_select ) {
228
$line_to_select = $line;
230
if ($select_next_diff) {
233
if ( $line > $current_line ) {
234
$line_to_select = $line;
239
# Previous difference
240
if ( $line < $current_line ) {
241
$line_to_select = $line;
246
if ( defined $line_to_select ) {
248
# Select the line in the editor and show the diff box
249
Padre::Util::select_line_in_editor( $line_to_select, $editor );
250
$self->show_diff_box( $line_to_select, $editor );
252
$self->{main}->error( Wx::gettext('No changes found') );
256
# Selects the next difference in the editor
257
sub select_next_difference {
258
$_[0]->_select_next_prev_difference(1);
261
# Selects the previous difference in the editor
262
sub select_previous_difference {
263
$_[0]->_select_next_prev_difference(0);
266
# Shows the difference dialog box for the provided line in the editor provided
271
my $diff = $self->{diffs}->{$line} or return;
273
unless ( defined $self->{dialog} ) {
274
$self->{dialog} = Padre::Wx::Dialog::Diff->new( $self->{main} );
276
$self->{dialog}->show(
277
$editor, $line, $diff,
278
$editor->PointFromPosition( $editor->PositionFromLine( $line + 1 ) )
284
# Copyright 2008-2011 The Padre development team as listed in Padre.pm.
286
# This program is free software; you can redistribute it and/or
287
# modify it under the same terms as Perl 5 itself.