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 )