Text-Editor-Easy

 view release on metacpan or  search on metacpan

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

    FONT_HEIGHT => 9,

    #HEIGHT => 7,
    #------------------------------------
    # $self->[?]
    #------------------------------------
    INSER     => 0,
    SCREEN    => 1,
    SEGMENT   => 2,
    #ID    => 3,    # Text::Editor::Easy unique identifier
    GRAPHIC   => 4,
    REGEXP    => 5,
    CALC_LINE => 6,
    CURSOR    => 7,
    FILE      => 8,
    RETURN    => 10,    # Test de redirection
    SUB_REF   => 11,
    INIT_TAB  => 12,
    PARENT    => 13,
    ASSIST    => 14,
    KEY => 15,
    H_FONT => 16,
    SELECTION => 17,
    AT_END => 18,
    EVENTS => 19,
    SEQUENCES => 20,
};

use Text::Editor::Easy::Key;
my %key = (
    'Insert' => \&Text::Editor::Easy::Key::inser,
    'Prior'  => [ \&Text::Editor::Easy::Abstract::Key::page_up, 'Abstract' ],
    'Next'   => [ \&Text::Editor::Easy::Abstract::Key::page_down, 'Abstract' ],

    'Down'  => [ \&Text::Editor::Easy::Abstract::Key::down, 'Abstract' ],
    'Up'    => [ \&Text::Editor::Easy::Abstract::Key::up, 'Abstract' ],
    'Home'  => [ \&Text::Editor::Easy::Abstract::Key::home, 'Abstract' ],
    'End'   => [ \&Text::Editor::Easy::Abstract::Key::end, 'Abstract' ],
    'Left'  => [ \&Text::Editor::Easy::Abstract::Key::left, 'Abstract' ],
    'Right' => [ \&Text::Editor::Easy::Abstract::Key::right, 'Abstract' ],
    'Return'   => [ \&Text::Editor::Easy::Abstract::Key::enter, 'Abstract' ],
    'KP_Enter' => [ \&Text::Editor::Easy::Abstract::Key::enter, 'Abstract' ],
    'Delete'   => [ \&Text::Editor::Easy::Abstract::Key::delete, 'Abstract' ],
    'BackSpace'  => [ \&Text::Editor::Easy::Abstract::Key::backspace, 'Abstract' ],

    'ctrl_End'   => [ \&Text::Editor::Easy::Abstract::Key::end_file, 'Abstract' ],
    'ctrl_Home'  => \&Text::Editor::Easy::Key::top_file,
    'ctrl_Right' => \&Text::Editor::Easy::Key::jump_right,
    'ctrl_Left'  => \&Text::Editor::Easy::Key::jump_left,

    'F3' => \&Text::Editor::Easy::next_search,

    'ctrl_c' => [ \&Text::Editor::Easy::Abstract::Key::copy, 'Abstract' ],
    'ctrl_C' => [ \&Text::Editor::Easy::Abstract::Key::copy, 'Abstract' ],
    'ctrl_f'    => \&Text::Editor::Easy::Key::search,
    'ctrl_F'    => \&Text::Editor::Easy::Key::search,

    'ctrl_i'    => [ \&Text::Editor::Easy::Abstract::test_new_insert, 'Abstract' ],
    'ctrl_I'    => [ \&Text::Editor::Easy::Abstract::test_new_insert, 'Abstract' ],
    
    'ctrl_j'    => \&Text::Editor::Easy::Abstract::print_clipboard,
    'ctrl_J'    => \&Text::Editor::Easy::Abstract::print_clipboard,

    'ctrl_l' => \&Text::Editor::Easy::Key::close,
    'ctrl_L' => \&Text::Editor::Easy::Key::close,
    'ctrl_m'    => \&decrease_line_space,
    'ctrl_M'    => \&decrease_line_space,
    'ctrl_p'    => \&increase_line_space,
    'ctrl_P'    => \&increase_line_space,

    'ctrl_q'     => \&Text::Editor::Easy::Key::query_segments,
    'ctrl_Q'     => \&Text::Editor::Easy::Key::query_segments,

    'ctrl_r' => \&revert,
    'ctrl_R' => \&revert,
    'ctrl_s'     => \&Text::Editor::Easy::Key::save,
    'ctrl_S'     => \&Text::Editor::Easy::Key::save,

    'ctrl_v' => [ \&Text::Editor::Easy::Abstract::Key::paste, 'Abstract' ],
    'ctrl_V' => [ \&Text::Editor::Easy::Abstract::Key::paste, 'Abstract' ],
    #'ctrl_v' => \&paste,
    #'ctrl_V' => \&paste,

    'ctrl_w' => \&Text::Editor::Easy::Key::wrap,
    'ctrl_W' => \&Text::Editor::Easy::Key::wrap,

    'ctrl_x'    => [ \&Text::Editor::Easy::Abstract::Key::cut, 'Abstract' ],
    'ctrl_X'    => [ \&Text::Editor::Easy::Abstract::Key::cut, 'Abstract' ],
    'F3'    => \&Text::Editor::Easy::Key::f3_search,
    
    'ctrl_Up'   => \&Text::Editor::Easy::Key::jump_up,
    'ctrl_Down' => \&Text::Editor::Easy::Key::jump_down,
    'alt_Up'    => \&Text::Editor::Easy::Key::move_up,
    'alt_Down'  => \&Text::Editor::Easy::Key::move_down,

    'ctrl_plus' => \&increase_font,

    'ctrl_shift_n' => \&Text::Editor::Easy::Key::print_screen_number,
    'ctrl_shift_N' => \&Text::Editor::Easy::Key::print_screen_number,
    'ctrl_shift_l' => \&Text::Editor::Easy::Key::display_cursor_display,
    'ctrl_shift_L' => \&Text::Editor::Easy::Key::display_cursor_display,
    'ctrl_shift_p' => \&Text::Editor::Easy::Key::list_display_positions,
    'ctrl_shift_P' => \&Text::Editor::Easy::Key::list_display_positions,

    'alt_ampersand' => \&Text::Editor::Easy::Key::sel_first,
    'alt_eacute'    => \&Text::Editor::Easy::Key::sel_second,
    
    # Selection
    'shift_Down'  => [\&Text::Editor::Easy::Abstract::Key::shift_down, 'Abstract' ],
    'shift_Up'    => [ \&Text::Editor::Easy::Abstract::Key::shift_up, 'Abstract' ],
    'shift_Left'  => [ \&Text::Editor::Easy::Abstract::Key::shift_left, 'Abstract' ],
    'shift_Right' => [ \&Text::Editor::Easy::Abstract::Key::shift_right, 'Abstract' ],
    'shift_Home'  => [ \&Text::Editor::Easy::Abstract::Key::shift_home, 'Abstract' ],
    'shift_End'   => [ \&Text::Editor::Easy::Abstract::Key::shift_end, 'Abstract' ],
    'shift_Prior'  => [ \&Text::Editor::Easy::Abstract::Key::shift_page_up, 'Abstract' ],
    'shift_Next'   => [ \&Text::Editor::Easy::Abstract::Key::shift_page_down, 'Abstract' ],

    'alt_F4' => \&Text::Editor::Easy::Abstract::exit,
);

Text::Editor::Easy::Comm::manage_debug_file( __PACKAGE__, *DBG );

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

my %ref_sub;

sub examine_external_request {

    #while ( anything_for_me ) { # Ne marche pas bien sous Linux (?)
    if ( anything_for_me() ) {
        my ( $what, $call_id, @param ) = get_task_to_do();
        $origin     = $call_id;
        if ( defined $sub_origin ) {
            # Il y a eu un évènement graphique
            $last_graphic_event = $sub_origin;
        }    
        $sub_origin = $what;
        # Inter-thread call, not to be shown in trace
        execute_this_task( $what, $call_id, @param );
        #print "Retour de execute task $sub_origin, $param[2]\n";
    }
    $origin     = "graphic";
    $sub_origin = undef;
}

sub test {
    my ( $self, @param ) = @_;

    # Génération d'un dead lock
    print "Début test : ", cursor_position_in_display($self), "\n";

    if (wantarray) {
        print "Dans test : Contexte de liste\n";
        $self->[PARENT]->append("Dans test : Contexte de liste");
        return ( $param[4]->{cursor_pos_in_line}, $param[3] );
    }
    elsif ( defined(wantarray) ) {
        print "Dans test : Contexte scalaire\n";
        if ( $param[1] eq 'test undef' ) {
            return;
        }
        else {
            return $param[2];
        }
    }
    else {
        print "Dans TEST : Contexte vide\n";
    }
}

# On donne la main au gestionnaire d'évènement : le thread principal n'exécutera plus que examine_external_request périodiquement
sub manage_event {
    my $compteur = 0;
    for ( keys %abstract ) {
        $compteur += 1;
        $abstract{$_}->[GRAPHIC]->manage_event();
        last;
    }
    if ( !$compteur ) {
        print STDERR
"Can't call manage_event loop when no Text::Editor::Easy object is created\n";
    }
}

sub clipboard_set {
    my ( $self, $string ) = @_;

    print "Dans clipboard_set de abstract : |$string|\n";
    for ( keys %abstract ) {
        return $abstract{$_}->[GRAPHIC]->clipboard_set( $string );
    }
    print STDERR
"Can't call clipboard_set when no Text::Editor::Easy object is created\n";
    return;
}

sub clipboard_get {
    for ( keys %abstract ) {
        return $abstract{$_}->[GRAPHIC]->clipboard_get();
    }
    print STDERR
"Can't call clipboard_get when no Text::Editor::Easy object is created\n";
    return;
}

sub print_clipboard {
    my $clipboard = clipboard_get();
    
    my @lines = split( /\n/, $clipboard );
    for my $line ( @lines ) {
        print "$line|\n\t";
        for my $indice ( 0..length($line) - 1 ) {
            my $char = substr( $line, $indice, 1 );
            print ord($char), ":";
        }
        print "\n";
    }
}

#-------------------------------------------------
# "From file to memory" functions
#-------------------------------------------------

sub read_next_line {
    my ( $edit_ref, $prev_line_ref ) = @_;

    my $ref;
    if ($prev_line_ref) {
        $ref = $prev_line_ref->[REF];
    }
    my ( $last, $text ) = $edit_ref->[PARENT]->next_line($ref);

    if ( !$last ) {
        return;
    }
    my $line_ref;
    $line_ref->[REF] = $last;

    chomp $text;

# Suppression des \r éventuels : lecture d'un fichier Windows sous UNIX
# voir aussi l'instruction "read PRG" qui utilise le binmode dans write_file() lors de la sauvegarde du fichier édité
    $text =~ s/\r//g;

    # Suppression des tabulations ...
    $text =~ s/\t/    /g;

    $line_ref->[TEXT] = $text;

    if ($prev_line_ref) {
        $line_ref->[PREVIOUS]  = $prev_line_ref;
        $prev_line_ref->[NEXT] = $line_ref;
    }

    create_text_in_line( $edit_ref, $line_ref );

    return $line_ref;
}

sub create_line_ref_from_ref {    # Création d'une ligne isolée pour affichage
    my ( $edit_ref, $ref, $text ) = @_;

    if ( !defined($text) ) {
        $text = $edit_ref->[PARENT]->line_text($ref);
    }

    return if ( !defined $text );

    my $line_ref;

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

sub get_line_number {
    my ( $edit_ref, $line_ref ) = @_;

    return $edit_ref->[PARENT]->get_line_number_from_ref( $line_ref->[REF] );
}

sub get_displayed_editor {
    my ($edit_ref) = @_;

    #print "Dans Abstract : $edit_ref\n";
    return $edit_ref->[GRAPHIC]->get_displayed_editor();
}

sub get_screen_size {
    my ($edit_ref) = @_;

    return ( $edit_ref->[SCREEN][WIDTH], $edit_ref->[SCREEN][HEIGHT] );
}

sub change_reference {
    my ($edit_ref) = @_;

    $edit_ref->[GRAPHIC]->change_reference( $edit_ref, $edit_ref->[FILE] );
}

sub increase_font {
    my ($edit_ref) = @_;

    print "Taille de la fonte actuelle : $edit_ref->[SCREEN][FONT_HEIGHT]\n";
    $edit_ref->[SCREEN][FONT_HEIGHT] += 1;
    my %distinct_fonts;
    for my $font ( values %{$edit_ref->[H_FONT]} ) {
        $distinct_fonts{$font} = $font;
    }
    for my $font ( keys %distinct_fonts ) {
        $edit_ref->[GRAPHIC]->set_font_size( $distinct_fonts{$font},
            $edit_ref->[SCREEN][FONT_HEIGHT] );
    }
    $edit_ref->[SCREEN][LINE_HEIGHT] =
      17 * $edit_ref->[SCREEN][FONT_HEIGHT] / 13;
}

#sub get_positions {
#    return {
#        "first_line_number"  => $top_true_line_number,
#        "first_line_pos"     => $top_screen_line_number,
#        "cursor_line_number" => $cursor_true_line_number,
#        "cursor_pos_in_line" => $edit_ref->[CURSOR][POSITION_IN_DISPLAY]
#    };
#}

######################################################################
#
#  INTERFACE
#
######################################################################

sub test_new_insert {
    my ( $edit_ref ) = @_;

    my $text = $edit_ref->[GRAPHIC]->clipboard_get;
    my $options_ref = do 'options_ref.txt';
    # Test gros bloc
    #$text = "";
    #my $texte = " : ligne n° : ";
    #my $indice = 0;
    #while ( $indice++ < 100000 ) {
    #    $text .= "\n" . $indice . $texte . $indice;
    #}
    #
    #print "start time ", scalar(localtime), "\n";
    new_insert( $edit_ref, $text, $options_ref );
    #print "stop time ", scalar(localtime), "\n";
}

sub position_bottom_tag_from {
    my ( $edit_ref, $line_ref ) = @_;
    
    $edit_ref->[GRAPHIC]->delete_tag('bottom');
    
    while ( $line_ref ) {
        #print "Adding bottom tag to ", $line_ref->[TEXT], "\n";
        my $text_ref = $line_ref->[FIRST];
        while ( $text_ref ) {
            $edit_ref->[GRAPHIC]->add_tag( 'bottom', $text_ref->[ID] );
            $text_ref = $text_ref->[NEXT];
        }
        $line_ref = $line_ref->[NEXT];
    }
}

sub insert {
    my ( $edit_ref, $text, $options_ref ) = @_;

    if ( ! defined( $text ) or $text eq q{} ) {
        #print STDERR "No text to insert, no insert execution...\n";
        return;
    }
    
    $options_ref = {} if ( ! defined $options_ref );
    
    #print "Dans new insert : options_ref = ", dump( $options_ref ), "\n";
    #print "Text = |$text|\n";
    $text =~ s/\t/    /g;    # Suppression des tabulations

    my $display_should_be_done = 0;
    my $display_options = $options_ref->{'display'};
    my $search_ref = {};

    my @lines = split( /\n/, $text, -1 );
    my $size_line = scalar(@lines);

    if ( defined $display_options ) {
        if ( ref $display_options eq 'ARRAY' ) {
            $display_should_be_done = 1;
            my $line = $display_options->[0];
            if ( $line =~ /^line_(\d+)/ ) {
                $search_ref->{$1} = 0;
            }
            elsif ( $line eq 'line_end' ) {
                my $number = $size_line - 1;

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

    #sleep 2;

}

sub clean {
    my ($self) = @_;

    my $to_delete_ref = $self->[SCREEN][FIRST];
    $self->[SCREEN][FIRST] = 0;
    while ($to_delete_ref) {
        my $next_ref = $to_delete_ref->[NEXT];
        $to_delete_ref->[NEXT]     = 0;
        $to_delete_ref->[PREVIOUS] = 0;
        $to_delete_ref             = $next_ref;
    }
    $self->[SCREEN][LAST] = 0;
}

sub abstract_eval {
    my ( $self, $program ) = @_;

    print "\n\n$program\n", threads->tid, "$origin, $sub_origin\n";
    eval "$program";
    print $@ if ($@);
}

sub abstract_size {
    my $total;
    for my $self ( sort keys %abstract ) {
        my $size = total_size( $abstract{$self} );
        print "Taille $self : $size\n";
        $total += $size;
    }
    print "=> Taille totale : $total\n";
}

sub abstract_number {
    my @total = keys %abstract;
    return scalar @total;
}

sub increase_line_space {
    my ($self) = values %abstract;

    print "In increase_line_offset\n";
    $self->[GRAPHIC]->increase_line_offset;
    resize_all();
}

sub decrease_line_space {
    my ($self) = values %abstract;

    print "In increase_line_offset\n";
    $self->[GRAPHIC]->decrease_line_offset;
    resize_all();
}

sub paste {
        my ( $edit_ref ) = @_;
                 
        my $string = $edit_ref->[GRAPHIC]->clipboard_get;
        insert($edit_ref, $string, { 'bloc' => 1 } );
}        

sub resize_all {

#my @zones = Text::Editor::Easy::Zone->list;
#ZONE: for my $zone ( @zones ) {
#print "Zone $zone\n";
#my $graphic = Text::Editor::Easy::Graphic->get_graphic_focused_in_zone ( $zone );
    for my $abstract_ref ( values %abstract ) {

        #if ( $graphic == $abstract_ref->[GRAPHIC] ) {
        print "Text::Editor::Easy $abstract_ref->[ID]\n";
        $abstract_ref->deselect;
        resize(
            $abstract_ref,
            $abstract_ref->[SCREEN][WIDTH],
            $abstract_ref->[SCREEN][HEIGHT]
        );
    }
}

sub reference_zone_events {
    my ( $self, $name, $events ) = @_;

    $zone_events{$name} = {};

    print "Dans reference_zone_events : name = $name, event_ref = $events\n";
    my $hash_returned = Text::Editor::Easy::Events::reference_events( 'Text::Editor::Easy', $events );
    print "Valeur de retour de hash_returned : $hash_returned\n";
    return if ( ! ref $hash_returned );
    $zone_events{$name} = $hash_returned;
}

sub abstract_join {
    my ( $self, $tid ) = @_;

    print "Dans abstract_join tid = $tid\n";
    my $thread = threads->object($tid);
    $thread->join;
    return $tid;
}

sub exit {
    my ($rc) = @_;

    Text::Editor::Easy::Comm::untie_print();
    print "Dans exit |$rc|\n";
    exit 0 if ( !$rc or $rc =~ /\D/ );
    exit $rc;
}

sub on_focus_lost {
    my ( $edit_ref, $sync ) = @_;
    
    # Il faut : la première ligne à l'écran, sa position (ord et abs car décalage possible)
    # Il faut la position du curseur (ligne + position dans la ligne)
    # Il faut le mode wrap
    # La taille de la zone et la zone elle-même sont connues pas ailleurs
    my $screen_ref = $edit_ref->[SCREEN];

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

}

sub visual_slurp {    
    my ( $edit_ref, $sequence ) = @_;
    
    #print DBG "Dans méthode visual_slurp, séquence $sequence\n";
    
    my $slurp;
    my $line_ref = $edit_ref->[SCREEN][FIRST];
    my $indice = 1;
    
    while ( $line_ref ) {
        print DBG "\t$indice (", $line_ref->[REF], ") - ", $line_ref->[TEXT], "\n";
        $slurp .= $line_ref->[TEXT] . "\n";
        $line_ref = $line_ref->[NEXT];
    }
    chomp $slurp;
    return $slurp;
}

1;



=head1 FUNCTIONS

=head2 abstract_eval

=head2 abstract_join

=head2 abstract_size

=head2 add_tag

=head2 add_tag_complete

=head2 assist_on_inserted_text

=head2 bind_key

Affectation of code to a specific key for a specific instance (initial instance call "bind_key")

=head2 bind_key_global

Affectation of code to a specific key for all instances (initial class call "bind_key")

=head2 calc_line_position_from_display_position

=head2 change_reference

=head2 change_title

=head2 check_cursor

=head2 clean

=head2 clear_screen

=head2 clic

=head2 clipboard_get

Retrieve the content of the clipboard (for paste operation)

=head2 clipboard_set

Set the content of the clipboard (for copy operation)

=head2 concat

=head2 create_line_ref_from_ref

=head2 create_text_in_line

=head2 cursor_abs

=head2 cursor_display

=head2 cursor_get

=head2 cursor_set_shape

Test for future use of motion event according to position (borders of Text::Editor::Easy::Zone to resize them, for instance).

=head2 cursor_line

=head2 cursor_make_visible

=head2 cursor_position_in_display

=head2 cursor_position_in_text

=head2 cursor_set

=head2 cursor_virtual_abs

=head2 debug_display_lines

What is on the screen according to Abstract... ?

=head2 decrease_line_space

=head2 delete_return

=head2 delete_text_in_line

=head2 deselect

=head2 display

=head2 display_abs

=head2 display_bottom_of_the_screen

=head2 display_height

=head2 display_line_from_bottom

=head2 display_line_from_top

=head2 display_middle_ord

Return the middle ordinate of a displayed line.

=head2 display_next

=head2 display_next_is_same

lib/Text/Editor/Easy/Abstract.pm  view on Meta::CPAN

=head2 if

=head2 increase_font

=head2 increase_line_space

=head2 indent_on_return

=head2 init

=head2 inser

=head2 insert

=head2 key

=head2 line_deselect

Deselection of a single line.

=head2 line_displayed

=head2 line_ref_abs

=head2 line_select

=head2 line_set

Set the content of a line.

=head2 load_search

=head2 manage_event

=head2 motion

=head2 wheel

=head2 move_bottom

=head2 new

=head2 on_editor_destroy

A zone event called when an editor has been closed : useful to change the tab state.

=head2 on_focus_lost

Event used to update Text::Editor::Easy configuration.

=head2 at_top

=head2 on_top_ref_editor

Returns the reference of the Text::Editor::Easy instance that is above the other.

=head2 parent

=head2 paste

Copy the clipboard content to the cursor position.

=head2 position_cursor_in_display

=head2 position_cursor_in_line

=head2 read_next_line

=head2 read_previous_line

=head2 reference_zone_event

=head2 resize

=head2 resize_all

=head2 complete_line

=head2 revert

=head2 save_search

=head2 screen_check_borders

Prevent space to appear at the bottom (after the last line) or at the top (before the first line).

=head2 screen_first

=head2 screen_font_height

=head2 screen_height

=head2 screen_last

=head2 screen_line_height

=head2 screen_margin

=head2 screen_move

=head2 screen_number

=head2 screen_set_height

=head1 COPYRIGHT & LICENSE

Copyright 2008 - 2009 Sebastien Grommier, all rights reserved.

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1;



( run in 0.756 second using v1.01-cache-2.11-cpan-84e82930d8c )