Padre
view release on metacpan or search on metacpan
lib/Padre/Wx/Editor.pm view on Meta::CPAN
);
$self->SetMarginMask(
Padre::Constant::MARGIN_FOLD,
Wx::Scintilla::SC_MASK_FOLDERS,
);
}
# Set up all of the default markers
$self->MarkerDefine(
Padre::Constant::MARKER_ERROR,
Wx::Scintilla::SC_MARK_SMALLRECT,
RED,
RED,
);
$self->MarkerDefine(
Padre::Constant::MARKER_WARN,
Wx::Scintilla::SC_MARK_SMALLRECT,
ORANGE,
ORANGE,
);
$self->MarkerDefine(
Padre::Constant::MARKER_LOCATION,
Wx::Scintilla::SC_MARK_SMALLRECT,
GREEN,
GREEN,
);
$self->MarkerDefine(
Padre::Constant::MARKER_BREAKPOINT,
# Wx::Scintilla::MARK_SMALLRECT,
Wx::Scintilla::SC_MARK_DOTDOTDOT,
BLUE,
BLUE,
);
$self->MarkerDefine(
Padre::Constant::MARKER_NOT_BREAKABLE,
Wx::Scintilla::SC_MARK_DOTDOTDOT,
GRAY,
GRAY,
);
$self->MarkerDefine(
Padre::Constant::MARKER_ADDED,
Wx::Scintilla::SC_MARK_PLUS,
DARK_GREEN,
DARK_GREEN,
);
$self->MarkerDefine(
Padre::Constant::MARKER_CHANGED,
Wx::Scintilla::SC_MARK_ARROW,
LIGHT_BLUE,
LIGHT_BLUE,
);
$self->MarkerDefine(
Padre::Constant::MARKER_DELETED,
Wx::Scintilla::SC_MARK_MINUS,
LIGHT_RED,
LIGHT_RED,
);
# CTRL-L or line cut should only work when there is no empty line
# This prevents the accidental destruction of the clipboard
$self->CmdKeyClear( ord('L'), Wx::Scintilla::SCMOD_CTRL );
# Disable CTRL keypad -/+. These seem to emit wrong scan codes
# on some laptop keyboards. (e.g. CTRL-Caps lock is the same as CTRL -)
# Please see bug #790
$self->CmdKeyClear( Wx::Scintilla::SCK_SUBTRACT, Wx::Scintilla::SCMOD_CTRL );
$self->CmdKeyClear( Wx::Scintilla::SCK_ADD, Wx::Scintilla::SCMOD_CTRL );
# Setup the editor indicators which we will use in smart, warning and error highlighting
# Indicator #0: Green round box indicator for smart highlighting
$self->IndicatorSetStyle(
Padre::Constant::INDICATOR_SMART_HIGHLIGHT,
Wx::Scintilla::INDIC_ROUNDBOX,
);
# Indicator #1, Orange squiggle for warning highlighting
$self->IndicatorSetForeground(
Padre::Constant::INDICATOR_WARNING,
ORANGE,
);
$self->IndicatorSetStyle(
Padre::Constant::INDICATOR_WARNING,
Wx::Scintilla::INDIC_SQUIGGLE,
);
# Indicator #2, Red squiggle for error highlighting
$self->IndicatorSetForeground(
Padre::Constant::INDICATOR_ERROR,
RED,
);
$self->IndicatorSetStyle(
Padre::Constant::INDICATOR_ERROR,
Wx::Scintilla::INDIC_SQUIGGLE,
);
# Indicator #3, underline for mouse-clickable tokens
$self->IndicatorSetForeground(
Padre::Constant::INDICATOR_UNDERLINE,
BLUE,
);
$self->IndicatorSetStyle(
Padre::Constant::INDICATOR_UNDERLINE,
Wx::Scintilla::INDIC_PLAIN,
);
# Basic event bindings
Wx::Event::EVT_SET_FOCUS(
$self,
sub {
shift->on_set_focus(@_);
},
);
Wx::Event::EVT_KILL_FOCUS(
$self,
sub {
shift->on_kill_focus(@_);
},
);
Wx::Event::EVT_KEY_UP(
$self,
lib/Padre/Wx/Editor.pm view on Meta::CPAN
# Called while the mouse is moving
sub on_mouse_moving {
my $self = shift;
my $event = shift;
if ( $event->Moving ) {
my $doc = $self->document or return;
if ( $doc->can('event_mouse_moving') ) {
$doc->event_mouse_moving( $self, $event );
}
}
# Keep processing
$event->Skip(1);
}
# Convert the Ctrl-Scroll behaviour of changing the font size
# to the non-Ctrl behaviour of scrolling.
sub on_mousewheel {
my $self = shift;
my $event = shift;
# Ignore this handler if it's a normal wheel movement
unless ( $event->ControlDown ) {
$event->Skip(1);
return;
}
if (Padre::Feature::FONTSIZE) {
# The default handler zooms in the wrong direction
$self->SetZoom( $self->GetZoom + int( $event->GetWheelRotation / $event->GetWheelDelta ) );
} else {
# Behave as if Ctrl wasn't down
$self->ScrollLines( $event->GetLinesPerAction * int( $event->GetWheelRotation / $event->GetWheelDelta * -1 ) );
}
return;
}
sub on_left_down {
my $self = shift;
my $event = shift;
$self->smart_highlight_hide;
# Keep processing
$event->Skip(1);
}
sub on_left_up {
my $self = shift;
my $event = shift;
my $config = $self->config;
my $text = $self->GetSelectedText;
if ( Wx::GTK and defined $text and $text ne '' ) {
# Only on X11 based platforms
# if ( $config->mid_button_paste ) {
# $self->put_text_to_clipboard( $text, 1 );
# } else {
# $self->put_text_to_clipboard($text);
# }
}
my $doc = $self->document;
if ( $doc and $doc->can('event_on_left_up') ) {
$doc->event_on_left_up( $self, $event );
}
# Keep processing
$event->Skip(1);
}
sub on_left_double {
my $self = shift;
my $event = shift;
$self->smart_highlight_show;
# Keep processing
$event->Skip(1);
}
sub on_middle_up {
my $self = shift;
my $event = shift;
my $config = $self->config;
# TO DO: Sometimes there are unexpected effects when using the middle button.
# It seems that another event is doing something but not within this module.
# Please look at ticket #390 for details!
if ( $config->mid_button_paste ) {
Wx::TheClipboard->UsePrimarySelection(1);
}
if ( Padre::Constant::WIN32 or not $config->mid_button_paste ) {
$self->Paste;
}
my $doc = $self->document;
if ( $doc->can('event_on_middle_up') ) {
$doc->event_on_middle_up( $self, $event );
}
if ( $config->mid_button_paste ) {
Wx::TheClipboard->UsePrimarySelection(0);
$event->Skip(1);
} else {
$event->Skip(0);
}
}
sub on_context_menu {
my $self = shift;
my $event = shift;
my $main = $self->main;
require Padre::Wx::Editor::Menu;
my $menu = Padre::Wx::Editor::Menu->new( $self, $event );
# Try to determine where to show the context menu
if ( $event->isa('Wx::MouseEvent') ) {
lib/Padre/Wx/Editor.pm view on Meta::CPAN
# find the start of paragraph by searching backwards till we find a
# line with only whitespace in it.
my $para1 = $lineno;
while ( $para1 > 0 ) {
my $line = $editor->GetLine($para1);
last if $line =~ /^\s*$/;
$para1--;
}
# now, find the end of paragraph by searching forwards until we find
# only white space
my $lastline = $editor->GetLineCount;
my $para2 = $lineno;
while ( $para2 < $lastline ) {
$para2++;
my $line = $editor->GetLine($para2);
last if $line =~ /^\s*$/;
}
# return the position
my $begin = $editor->PositionFromLine( $para1 + 1 );
my $end = $editor->PositionFromLine($para2);
return ( $begin, $end );
}
# TO DO: include the changing of file type in the undo/redo actions
# or better yet somehow fetch it from the document when it is needed.
sub convert_eols {
my $self = shift;
my $newline = shift;
my $mode = $WXEOL{$newline};
# Apply the change to the underlying document
my $document = $self->document or return;
$document->set_newline_type($newline);
# Convert and Set the EOL mode in the editor
$self->ConvertEOLs($mode);
$self->SetEOLMode($mode);
return 1;
}
# hack for cut n paste - start
sub Cut {
my $self = shift;
$self->{internal_copy} = $self->GetSelectedText;
return $self->SUPER::Cut(@_);
}
sub Copy {
my $self = shift;
$self->{internal_copy} = $self->GetSelectedText;
return $self->SUPER::Copy(@_);
}
sub CanPaste {
my $self = shift;
return 1 if $self->{internal_copy};
return 0 unless $self->SUPER::CanPaste;
return 0 unless $self->clipboard_length;
return 1;
}
sub Paste {
my $self = shift;
# Workaround for Copy/Paste bug ticket #390
my $text = $self->get_text_from_clipboard;
if ($text) {
# Conversion of pasted text is really needed since it usually comes
# with the platform's line endings
#
# Please see ticket:589, "Pasting in a UNIX document in win32
# corrupts it to MIXEd"
$self->ReplaceSelection( $self->_convert_paste_eols($text) );
} else {
$self->ReplaceSelection( $self->_convert_paste_eols( $self->{internal_copy} ) );
}
return 1;
}
# hack for cut n past - end
#
# This method converts line ending based on current document EOL mode
# and the newline type for the current text
#
sub _convert_paste_eols {
my ( $self, $paste ) = @_;
my $newline_type = Padre::Util::newline_type($paste);
my $eol_mode = $self->GetEOLMode;
# Handle the 'None' one-liner case
if ( $newline_type eq 'None' ) {
$newline_type = $self->config->default_line_ending;
}
#line endings
my $CR = "\015";
my $LF = "\012";
my $CRLF = "$CR$LF";
my ( $from, $to );
# From what to convert from?
if ( $newline_type eq 'WIN' ) {
$from = $CRLF;
} elsif ( $newline_type eq 'UNIX' ) {
$from = $LF;
} elsif ( $newline_type eq 'MAC' ) {
$from = $CR;
}
# To what to convert to?
if ( $eol_mode eq Wx::Scintilla::SC_EOL_CRLF ) {
$to = $CRLF;
} elsif ( $eol_mode eq Wx::Scintilla::SC_EOL_LF ) {
$to = $LF;
} else {
#must be Wx::Scintilla::EOL_CR
$to = $CR;
}
# Convert only when it is needed
if ( $from ne $to ) {
lib/Padre/Wx/Editor.pm view on Meta::CPAN
my $c = $self->GetTextRange( $start, $start + 1 );
unless ( defined $c and $c =~ /^[^\s\w]$/ ) {
$self->error( Wx::gettext("First character of selection must be a non-word character to align") );
}
# Locate the position of the align character,
# and the position of the earliest whitespace before it.
my $qc = quotemeta $c;
my @position = ();
foreach (@text) {
if (/^(.+?)(\s*)$qc/) {
push @position, [ length("$1"), length("$2") ];
} else {
# This line is not a member of the align set
push @position, undef;
}
}
# Find the latest position of the starting whitespace.
my $longest = List::Util::max map { $_->[0] } grep {$_} @position;
# Generate the target list to line them all up
my @targets = ();
foreach ( 0 .. $#line ) {
next unless $position[$_];
my $spaces = $longest - $position[$_]->[0] - $position[$_]->[1] + 1;
if ( $_ == 0 ) {
$start = $start + $spaces;
}
my $insert = $self->PositionFromLine( $line[$_] ) + $position[$_]->[0] + 1;
if ( $spaces > 0 ) {
push @targets, [ $insert, $insert, ' ' x $spaces ];
} elsif ( $spaces < 0 ) {
push @targets, [ $insert, $insert - $spaces, '' ];
}
}
# Apply the changes via a delta object
require Padre::Delta;
my $delta = Padre::Delta->new( position => reverse @targets );
$delta->to_editor($self);
}
sub needs_manual_colorize {
if ( defined $_[1] ) {
$_[0]->{needs_manual_colorize} = $_[1];
}
return $_[0]->{needs_manual_colorize};
}
######################################################################
# Clipboard Methods
# This is not necesarily the right place for these, since things other
# than editors might want to make use of the clipboard.
# But it will do for now as a starting point.
=pod
=head2 clipboard_length
my $chars = Padre::Wx::Editor->clipboard_length;
The C<clipboard_length> method returns the number of characters of text
currently in the clipboard, if any.
Returns an integer number of characters, or zero if the clipboard is empty
or contains non-text data.
=cut
sub clipboard_length {
my $class = shift;
my $chars = 0;
Wx::TheClipboard->Open;
if ( Wx::TheClipboard->IsSupported(Wx::DF_TEXT) ) {
my $data = Wx::TextDataObject->new;
if ( Wx::TheClipboard->GetData($data) ) {
$chars = $data->GetTextLength if defined $data;
}
}
Wx::TheClipboard->Close;
return $chars;
}
# TODO Change this to clipboard_set
sub put_text_to_clipboard {
my ( $self, $text, $clipboard ) = @_;
@_ = (); # Feeble attempt to kill Scalars Leaked
return if $text eq '';
my $config = $self->config;
$clipboard ||= 0;
# Backup last clipboard value:
$self->{Clipboard_Old} = $self->get_text_from_clipboard;
# if $self->{Clipboard_Old} ne $self->get_text_from_clipboard;
Wx::TheClipboard->Open;
# Wx::TheClipboard->UsePrimarySelection($clipboard)
# if $config->mid_button_paste;
Wx::TheClipboard->SetData( Wx::TextDataObject->new($text) );
Wx::TheClipboard->Close;
return;
}
# TODO Change this to clipboard_text
sub get_text_from_clipboard {
my $self = shift;
my $text = '';
Wx::TheClipboard->Open;
if ( Wx::TheClipboard->IsSupported(Wx::DF_TEXT) ) {
my $data = Wx::TextDataObject->new;
if ( Wx::TheClipboard->GetData($data) ) {
$text = $data->GetText if defined $data;
}
}
if ( $text eq $self->GetSelectedText ) {
$text = $self->{Clipboard_Old};
}
Wx::TheClipboard->Close;
return $text;
}
######################################################################
# Highlighting
# The main purpose of these manual highlighting methods is to prevent
# the document classes from having to use Wx code directly.
sub manual_highlight_show {
my $self = shift;
my $position = shift;
my $characters = shift;
$self->SetIndicatorCurrent(Padre::Constant::INDICATOR_UNDERLINE);
$self->IndicatorFillRange( $position, $characters );
return 1;
}
sub manual_highlight_hide {
my $self = shift;
my $position = shift;
my $characters = shift;
$self->SetIndicatorCurrent(Padre::Constant::INDICATOR_UNDERLINE);
$self->IndicatorClearRange( $position, $characters );
}
sub smart_highlight_show {
my $self = shift;
my $selection = $self->GetSelectedText;
my $selection_length = length $selection;
# Zero length selection should be ignored
return if $selection_length == 0;
# Whitespace should be ignored
return if $selection =~ /^\s+$/;
my $selection_re = quotemeta $selection;
my $line_count = $self->GetLineCount;
my $line_num = $self->GetCurrentLine;
# Limits search to C+N..C-N from current line respecting limits ofcourse
( run in 1.164 second using v1.01-cache-2.11-cpan-81fc1098f69 )