Changeset 12389


Ignore:
Timestamp:
08/29/10 08:59:48 (18 months ago)
Author:
zenogantner
Message:

initial working version of the keyboard shortcut editor; fix translation issues w/ debugger menu entries

Location:
trunk/Padre
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Padre/Changes

    r12386 r12389  
    1414    - Added keyboard shortcuts to refactoring features "rename variable" 
    1515      and "extract subroutine" (ZENOG) 
     16    - Fixed small translation problem in ActionLibrary (ZENOG) 
     17    - Initial working version of the keyboard shortcut editor (ZENOG) 
    1618 
    17190.69 2010.08.17 
  • trunk/Padre/lib/Padre/Wx/Action.pm

    r12381 r12389  
    44use strict; 
    55use warnings; 
     6use Padre::Config   (); 
    67use Padre::Constant (); 
    78use Padre::Wx       (); 
     
    1516        name          => 'name', 
    1617        icon          => 'icon', 
    17         shortcut      => 'shortcut', 
    1818        menu_event    => 'menu_event', 
    1919        menu_method   => 'menu_method', 
    2020        toolbar_event => 'toolbar_event', 
    2121        toolbar_icon  => 'toolbar', 
    22     } 
     22    }, 
     23    accessors => { 
     24        shortcut => 'shortcut', 
     25    }, 
    2326}; 
    2427 
     
    9295    $self->{queue_event} ||= $self->{menu_event}; 
    9396 
     97    # Create shortcut setting for the action 
     98    my $config  = Padre->ide->config; 
     99    my $setting = "keyboard_shortcut_$name"; 
     100    $setting =~ s/\W/_/g; # setting names must be valid subroutine names 
     101    if ( not $config->can($setting) ) { 
     102        $config->setting( 
     103            name    => $setting, 
     104            type    => Padre::Constant::ASCII, 
     105            store   => Padre::Constant::HUMAN, 
     106            default => '', 
     107        ); 
     108    } 
     109 
     110    my $config_shortcut = eval '$config->' . $setting; 
     111    warn "$@\n" if $@; 
     112    if ($config_shortcut) { 
     113        $shortcut = $config_shortcut; 
     114        $self->shortcut($shortcut); 
     115    } 
     116 
    94117    # Validate the shortcut 
    95118    if ($shortcut) { 
     
    102125        } 
    103126 
     127        $ide->{shortcuts} = {} if not exists $ide->{shortcuts}; 
    104128        my $shortcuts = $ide->{shortcuts}; 
    105         if ( defined( $shortcuts->{$shortcut} ) ) { 
     129        if ( exists $shortcuts->{$shortcut} ) { 
    106130            warn "Found a duplicate shortcut '$shortcut' with " . $shortcuts->{$shortcut}->name . " for '$name'\n"; 
    107131        } else { 
     
    145169    my $self  = shift; 
    146170    my $label = $self->label; 
    147     if ( $self->shortcut 
    148         and ( ( $self->shortcut eq 'F12' ) or ( $self->id == -1 or Padre::Constant::WIN32() ) ) ) 
     171 
     172    my $shortcut = $self->shortcut; 
     173 
     174    if ( $shortcut 
     175        and ( ( $shortcut eq 'F12' ) or ( $self->id == -1 or Padre::Constant::WIN32() ) ) ) 
    149176    { 
    150         $label .= "\t" . $self->shortcut; 
     177        $label .= "\t" . $shortcut; 
    151178    } 
    152179    return $label; 
  • trunk/Padre/lib/Padre/Wx/ActionLibrary.pm

    r12386 r12389  
    17521752        label       => _T('Rename Variable...'), 
    17531753        comment     => _T('Prompt for a replacement variable name and replace all occurrences of this variable'), 
    1754         shortcut     => 'Shift-Alt-R', 
     1754        shortcut    => 'Shift-Alt-R', 
    17551755        menu_event  => sub { 
    17561756            my $document = $_[0]->current->document or return; 
     
    17681768                . 'A call to this sub is added in the place where the selection was.' 
    17691769        ), 
    1770         shortcut     => 'Shift-Alt-M', 
     1770        shortcut   => 'Shift-Alt-M', 
    17711771        menu_event => sub { 
    17721772            my $document = $_[0]->current->document or return; 
     
    19391939        need_file    => 1, 
    19401940        toolbar      => 'stock/code/stock_macro-stop-after-command', 
    1941         label        => _T('Step In') . ' (&s) ', 
     1941        label        => _T('Step In (&s)'), 
    19421942        comment      => _T( 
    19431943            'Execute the next statement, enter subroutine if needed. (Start debugger if it is not yet running)'), 
     
    19561956        need_file    => 1, 
    19571957        toolbar      => 'stock/code/stock_macro-stop-after-procedure', 
    1958         label        => _T('Step Over') . ' (&n) ', 
     1958        label        => _T('Step Over (&n)'), 
    19591959        comment      => _T( 
    19601960            'Execute the next statement. If it is a subroutine call, stop only after it returned. (Start debugger if it is not yet running)' 
     
    19751975        need_file    => 1, 
    19761976        toolbar      => 'stock/code/stock_macro-jump-back', 
    1977         label        => _T('Step Out') . ' (&r) ', 
     1977        label        => _T('Step Out (&r)'), 
    19781978        comment      => _T('If within a subroutine, run till return is called and then stop.'), 
    19791979 
     
    19911991        need_file    => 1, 
    19921992        toolbar      => 'stock/code/stock_tools-macro', 
    1993         label        => _T('Run till Breakpoint') . ' (&c) ', 
     1993        label        => _T('Run till Breakpoint (&c)'), 
    19941994        comment      => _T('Start running and/or continue running till next breakpoint or watch'), 
    19951995 
     
    20222022        need_file    => 1, 
    20232023        toolbar      => 'stock/code/stock_macro-insert-breakpoint', 
    2024         label        => _T('Set Breakpoint') . ' (&b) ', 
     2024        label        => _T('Set Breakpoint (&b)'), 
    20252025        comment      => _T('Set a breakpoint to the current location of the cursor with a condition'), 
    20262026 
  • trunk/Padre/lib/Padre/Wx/Dialog/KeyBindings.pm

    r12251 r12389  
    1515}; 
    1616 
    17 =pod 
    18  
    19 =head1 NAME 
    20  
    21 Padre::Wx::Dialog::KeyBindings - a dialog to show and configure key bindings 
    22  
    23 =head1 DESCRIPTION 
    24  
    25 This dialog lets the user search for a key binding and then configure a new 
    26 shortcut if needed 
    27  
    28 =head1 PUBLIC API 
    29  
    30 =head2 C<new> 
    31  
    32   my $advanced = Padre::Wx::Dialog::KeyBindings->new($main); 
    33  
    34 Returns a new C<Padre::Wx::Dialog::KeyBindings> instance 
    35  
    36 =cut 
    3717 
    3818sub new { 
     
    4424        $main, 
    4525        -1, 
    46         Wx::gettext('Key Bindings') . ' (Work in progress... Not finished)', 
     26        Wx::gettext('Key Bindings'), 
    4727        Wx::wxDefaultPosition, 
    4828        Wx::wxDefaultSize, 
     
    5131 
    5232    # Minimum dialog size 
    53     $self->SetMinSize( [ 517, 550 ] ); 
     33    $self->SetMinSize( [ 717, 550 ] ); 
    5434 
    5535    # Create sizer that will host all controls 
     
    8868        Wx::wxLC_REPORT | Wx::wxLC_SINGLE_SEL, 
    8969    ); 
    90     $self->{list}->InsertColumn( 0, Wx::gettext('Key binding name') ); 
    91     $self->{list}->InsertColumn( 1, Wx::gettext('Shortcut') ); 
    92     $self->{list}->InsertColumn( 2, Wx::gettext('Action') ); 
     70    $self->{list}->InsertColumn( 0, Wx::gettext('Action') ); 
     71    $self->{list}->InsertColumn( 1, Wx::gettext('Description') ); 
     72    $self->{list}->InsertColumn( 2, Wx::gettext('Shortcut') ); 
     73 
     74    # TODO add tooltip with the comments 
    9375 
    9476    # Shortcut label 
     
    9678 
    9779    # modifier radio button fields 
    98     $self->{ctrl}  = Wx::CheckBox->new( $self, -1, 'CTRL' ); 
    99     $self->{alt}   = Wx::CheckBox->new( $self, -1, 'ALT' ); 
    100     $self->{shift} = Wx::CheckBox->new( $self, -1, 'Shift' ); 
     80    $self->{ctrl}  = Wx::CheckBox->new( $self, -1, Wx::gettext('Ctrl') ); 
     81    $self->{alt}   = Wx::CheckBox->new( $self, -1, Wx::gettext('Alt') ); 
     82    $self->{shift} = Wx::CheckBox->new( $self, -1, Wx::gettext('Shift') ); 
    10183 
    10284    # + labels 
     
    10587 
    10688    # key choice list 
    107     my %keymap = ( 
    108         '00None'      => -1, 
    109         '01Backspace' => Wx::WXK_BACK, 
    110         '02Tab'       => Wx::WXK_TAB, 
    111         '03Space'     => Wx::WXK_SPACE, 
    112         '04Up'        => Wx::WXK_UP, 
    113         '05Down'      => Wx::WXK_DOWN, 
    114         '06Left'      => Wx::WXK_LEFT, 
    115         '07Right'     => Wx::WXK_RIGHT, 
    116         '08Insert'    => Wx::WXK_INSERT, 
    117         '09Delete'    => Wx::WXK_DELETE, 
    118         '10Home'      => Wx::WXK_HOME, 
    119         '11End'       => Wx::WXK_END, 
    120         '12Page up'   => Wx::WXK_PAGEUP, 
    121         '13Page down' => Wx::WXK_PAGEDOWN, 
    122         '14Enter'     => Wx::WXK_RETURN, 
    123         '15Escape'    => Wx::WXK_ESCAPE, 
    124         '21Numpad 0'  => Wx::WXK_NUMPAD0, 
    125         '22Numpad 1'  => Wx::WXK_NUMPAD1, 
    126         '23Numpad 2'  => Wx::WXK_NUMPAD2, 
    127         '24Numpad 3'  => Wx::WXK_NUMPAD3, 
    128         '25Numpad 4'  => Wx::WXK_NUMPAD4, 
    129         '26Numpad 5'  => Wx::WXK_NUMPAD5, 
    130         '27Numpad 6'  => Wx::WXK_NUMPAD6, 
    131         '28Numpad 7'  => Wx::WXK_NUMPAD7, 
    132         '29Numpad 8'  => Wx::WXK_NUMPAD8, 
    133         '30Numpad 9'  => Wx::WXK_NUMPAD9, 
    134         '31Numpad *'  => Wx::WXK_MULTIPLY, 
    135         '32Numpad +'  => Wx::WXK_ADD, 
    136         '33Numpad -'  => Wx::WXK_SUBTRACT, 
    137         '34Numpad .'  => Wx::WXK_DECIMAL, 
    138         '35Numpad /'  => Wx::WXK_DIVIDE, 
    139         '36F1'        => Wx::WXK_F1, 
    140         '37F2'        => Wx::WXK_F2, 
    141         '38F3'        => Wx::WXK_F3, 
    142         '39F4'        => Wx::WXK_F4, 
    143         '40F5'        => Wx::WXK_F5, 
    144         '41F6'        => Wx::WXK_F6, 
    145         '42F7'        => Wx::WXK_F7, 
    146         '43F8'        => Wx::WXK_F8, 
    147         '44F9'        => Wx::WXK_F9, 
    148         '45F10'       => Wx::WXK_F10, 
    149         '46F11'       => Wx::WXK_F11, 
    150         '47F12'       => Wx::WXK_F12, 
    151     ); 
    152  
    153     # Add alphanumerics 
    154     for my $alphanum ( 'A' .. 'Z', '0' .. '9' ) { 
    155         $keymap{ '20' . $alphanum } = ord($alphanum); 
    156     } 
    157  
    158     # Add symbols 
    159     for my $symbol ( '~', '-', '=', '[', ']', ';', '\'', ',', '.', '/' ) { 
    160         $keymap{ '50' . $symbol } = ord($symbol); 
    161     } 
    162  
    163     my @keys = sort keys %keymap; 
    164     for my $key (@keys) { 
    165         $key =~ s/^\d{2}//; 
    166     } 
    167  
    168     # Store it for later usage 
    169     $self->{keys} = \@keys; 
     89    $self->{keys} = [ 
     90        qw(None Backspace Tab Space Up Down Left Right Insert Delete Home 
     91            End PageUp PageDown Enter Escape F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 
     92            ), 'A' .. 'Z', '0' .. '9', '~', '-', '=', '[', ']', ';', '\'', ',', '.', '/' 
     93    ]; 
    17094 
    17195    $self->{key} = Wx::Choice->new( 
     
    17397        Wx::wxDefaultPosition, 
    17498        Wx::wxDefaultSize, 
    175         \@keys, 
     99        $self->{keys}, # TODO translate 
    176100    ); 
    177101    $self->{key}->SetSelection(0); 
     
    179103    # Set key binding button 
    180104    $self->{button_set} = Wx::Button->new( 
    181         $self, -1, Wx::gettext("&Set"), 
    182     ); 
    183     $self->{button_set}->Enable(0); 
     105        $self, -1, Wx::gettext('&Set'), 
     106    ); 
     107    $self->{button_set}->Enable(1); 
    184108 
    185109    # Reset to default key binding button 
    186110    $self->{button_reset} = Wx::Button->new( 
    187         $self, -1, Wx::gettext("&Reset"), 
     111        $self, -1, Wx::gettext('&Reset'), 
    188112    ); 
    189113    $self->{button_reset}->Enable(0); 
    190114 
    191     # Save button 
    192     $self->{button_save} = Wx::Button->new( 
    193         $self, Wx::wxID_OK, Wx::gettext("S&ave"), 
    194     ); 
    195     $self->{button_save}->SetDefault; 
    196  
    197     # Cancel button 
    198     $self->{button_cancel} = Wx::Button->new( 
    199         $self, Wx::wxID_CANCEL, Wx::gettext("&Cancel"), 
     115    # Close button 
     116    $self->{button_close} = Wx::Button->new( 
     117        $self, Wx::wxID_CANCEL, Wx::gettext('&Close'), 
    200118    ); 
    201119 
     
    209127    $filter_sizer->Add( $self->{filter}, 1, Wx::wxALIGN_CENTER_VERTICAL, 5 ); 
    210128 
    211     # CTRL/ALT Modifier sizer 
     129    # Ctrl/Alt Modifier sizer 
    212130    my $modifier_sizer = Wx::BoxSizer->new(Wx::wxVERTICAL); 
    213131    $modifier_sizer->Add( $self->{ctrl}, 1, Wx::wxALIGN_CENTER_VERTICAL, 5 ); 
     
    234152    # Button sizer 
    235153    my $button_sizer = Wx::BoxSizer->new(Wx::wxHORIZONTAL); 
    236     $button_sizer->Add( $self->{button_save},   1, 0,          0 ); 
    237     $button_sizer->Add( $self->{button_cancel}, 1, Wx::wxLEFT, 5 ); 
     154    $button_sizer->Add( $self->{button_close}, 1, Wx::wxLEFT, 5 ); 
    238155    $button_sizer->AddSpacer(5); 
    239156 
     
    308225    ); 
    309226 
    310     # Save button 
     227    # Close button 
    311228    Wx::Event::EVT_BUTTON( 
    312229        $self, 
    313         $self->{button_save}, 
     230        $self->{button_close}, 
    314231        sub { 
    315             shift->_on_save_button; 
    316         } 
    317     ); 
    318  
    319     # Cancel button 
    320     Wx::Event::EVT_BUTTON( 
    321         $self, 
    322         $self->{button_cancel}, 
    323         sub { 
    324             shift->EndModal(Wx::wxID_CANCEL); 
     232            shift->_on_close_button; 
    325233        } 
    326234    ); 
     
    349257    my $self  = shift; 
    350258    my $event = shift; 
    351     my $list  = $self->{list}; 
    352  
    353     # Fetch action name 
    354     my $name = $list->GetItem( $list->GetFirstSelected, 2 )->GetText; 
    355     my $binding = $self->{bindings}->{$name}; 
    356  
    357     # And get it shortcut 
    358     my $shortcut = lc( $binding->{shortcut} ); 
     259 
     260    my $list        = $self->{list}; 
     261    my $index       = $list->GetFirstSelected; 
     262    my $action_name = $list->GetItemText($index); 
     263 
     264    my $shortcut = Padre->ide->actions->{$action_name}->shortcut; 
     265    $shortcut = '' if not defined $shortcut; 
    359266 
    360267    # Get the regular (i.e. non-modifier) key in the shortcut 
    361268    my @parts = split /-/, $shortcut; 
    362     my $regular = @parts ? $parts[-1] : ''; 
     269    my $regular_key = @parts ? $parts[-1] : ''; 
    363270 
    364271    # Find the regular key index in the choice box 
    365272    my $regular_index = 0; 
    366273    my @keys          = @{ $self->{keys} }; 
    367     my $index         = 0; 
    368     foreach my $key (@keys) { 
    369         if ( $regular eq lc($key) ) { 
    370             $regular_index = $index; 
     274    for ( my $i = 0; $i < scalar @keys; $i++ ) { 
     275        if ( $regular_key eq $keys[$i] ) { 
     276            $regular_index = $i; 
    371277            last; 
    372278        } 
    373         $index++; 
    374279    } 
    375280 
    376281    # and update the UI 
    377282    $self->{key}->SetSelection($regular_index); 
    378     $self->{ctrl}->SetValue( $shortcut =~ /ctrl/ ? 1 : 0 ); 
    379     $self->{alt}->SetValue( $shortcut  =~ /alt/  ? 1 : 0 ); 
    380     $self->{shift}->SetValue( ( $shortcut =~ /shift/ ) ? 1 : 0 ); 
     283    $self->{ctrl}->SetValue( $shortcut =~ /Ctrl/ ? 1 : 0 ); 
     284    $self->{alt}->SetValue( $shortcut  =~ /Alt/  ? 1 : 0 ); 
     285    $self->{shift}->SetValue( ( $shortcut =~ /Shift/ ) ? 1 : 0 ); 
    381286 
    382287    # Make sure the value and info sizer are not hidden 
     
    402307    my $self = shift; 
    403308 
     309    my $list  = $self->{list}; 
     310    my $index = $list->GetFirstSelected; 
     311    my $name  = $list->GetItemText($index); 
     312 
     313    my @key_list = (); 
     314    for my $regular_key ( 'Shift', 'Ctrl', 'Alt' ) { 
     315        push @key_list, $regular_key if $self->{ lc $regular_key }->GetValue; 
     316    } 
     317    my $regular_key = $self->{keys}->[ $self->{key}->GetSelection ]; 
     318    push @key_list, $regular_key if not $regular_key eq 'None'; 
     319    my $shortcut = join '-', @key_list; 
     320 
     321    return if $shortcut eq ''; 
     322 
     323    my $shortcuts = Padre->ide->{shortcuts}; 
     324    if ( exists $shortcuts->{$shortcut} ) { 
     325        warn "Found a duplicate shortcut '$shortcut' with " . $shortcuts->{$shortcut}->name . " for '$name'\n"; 
     326 
     327        # TODO instead of a warning, offer to overwrite the old shortcut. 
     328    } else { 
     329        $shortcuts->{$shortcut} = Padre->ide->actions->{$name}; 
     330        $self->{bindings}->{$name}->{shortcut} = $shortcut; 
     331        warn "Set shortcut '$shortcut' for action '$name'\n"; 
     332 
     333        Padre->ide->actions->{$name}->shortcut($shortcut); 
     334 
     335        my $setting = "keyboard_shortcut_$name"; 
     336        $setting =~ s/\W/_/g; # setting names must be valid subroutine names 
     337        $self->config->set( $setting, $shortcut ); 
     338        $self->config->write; 
     339 
     340        $self->_update_list; 
     341    } 
     342 
     343    return; 
     344} 
     345 
     346# Private method to handle the pressing of the reset to default button 
     347sub _on_reset_button { 
     348    my $self = shift; 
     349 
    404350    # Prepare the key binding 
    405351    my $list  = $self->{list}; 
     
    407353    my $name  = $list->GetItemText($index); 
    408354 
    409     return; 
    410 } 
    411  
    412 # Private method to handle the pressing of the reset to default button 
    413 sub _on_reset_button { 
    414     my $self = shift; 
    415  
    416     # Prepare the key binding 
    417     my $list  = $self->{list}; 
    418     my $index = $list->GetFirstSelected; 
    419     my $name  = $list->GetItemText($index); 
    420  
    421     return; 
    422 } 
    423  
    424 # Private method to handle the save action 
    425 sub _on_save_button { 
    426     my $self = shift; 
    427  
    428     #TODO Implement saving of *Changed* key bindings 
    429  
    430     # Bye bye dialog 
    431     $self->EndModal(Wx::wxID_OK); 
    432  
     355    my $action = Padre->ide->actions->{$name}; 
     356 
     357    ## TODO 
     358    # restore default or previous value? 
     359    # ensure that list contains right value ... 
     360 
     361    return; 
     362} 
     363 
     364# Private method to handle the close action 
     365sub _on_close_button { 
     366    my $self = shift; 
     367    my $main = $self->GetParent; 
     368 
     369    delete $main->{menu}; 
     370    $main->{menu} = Padre::Wx::Menubar->new($main); 
     371    $main->SetMenuBar( $main->menu->wx ); 
     372    $main->refresh; 
     373 
     374    $self->EndModal(Wx::wxID_CLOSE); 
    433375    return; 
    434376} 
     
    446388    my $bindings            = $self->{bindings}; 
    447389    my $alternateColor      = Wx::Colour->new( 0xED, 0xF5, 0xFF ); 
    448     my @sorted_binding_keys = sort { $bindings->{$a}->{label} cmp $bindings->{$b}->{label} } keys %$bindings; 
     390    my @sorted_binding_keys = sort { $a cmp $b } keys %$bindings; 
    449391    foreach my $name (@sorted_binding_keys) { 
    450392 
     
    457399 
    458400        # Add the key binding to the list control 
    459         $list->InsertStringItem( ++$index, $binding->{label} ); 
    460         $list->SetItem( $index, 1, $binding->{shortcut} ); 
    461         $list->SetItem( $index, 2, $name ); 
     401        $list->InsertStringItem( ++$index, $name ); 
     402        $list->SetItem( $index, 1, $binding->{label} ); 
     403        $list->SetItem( $index, 2, $binding->{shortcut} ); 
    462404 
    463405        # Alternating table colors 
     
    487429    my $self = shift; 
    488430 
    489  
    490     my $bindings = (); 
     431    my $bindings = {}; 
    491432    my %actions  = %{ Padre::ide->actions }; 
    492433    foreach my $name ( keys %actions ) { 
    493434        my $action = $actions{$name}; 
    494435        my $shortcut = $action->shortcut ? $action->shortcut : ''; 
     436        warn "Duplicate action name: '" . $action->label_text . "'\n" if exists $bindings->{ $action->label_text }; 
    495437        $bindings->{$name} = { 
    496438            label    => $action->label_text, 
     
    516458} 
    517459 
    518 =pod 
    519  
    520 =head2 C<show> 
    521  
    522   $advanced->show($main); 
    523  
    524 Shows the dialog. Returns C<undef>. 
    525  
    526 =cut 
    527460 
    528461sub show { 
     
    5494821; 
    550483 
     484 
     485__END__ 
     486 
    551487=pod 
     488 
     489=head1 NAME 
     490 
     491Padre::Wx::Dialog::KeyBindings - a dialog to show and configure key bindings 
     492 
     493=head1 DESCRIPTION 
     494 
     495This dialog lets the user search for an action and then configure a new 
     496shortcut if needed 
     497 
     498=head1 PUBLIC API 
     499 
     500=head2 C<new> 
     501 
     502  my $advanced = Padre::Wx::Dialog::KeyBindings->new($main); 
     503 
     504Returns a new C<Padre::Wx::Dialog::KeyBindings> instance 
     505 
     506=head2 C<show> 
     507 
     508  $advanced->show($main); 
     509 
     510Shows the dialog. Returns C<undef>. 
    552511 
    553512=head1 COPYRIGHT & LICENSE 
     
    562521 
    563522=cut 
    564  
    565 # Copyright 2008-2010 The Padre development team as listed in Padre.pm. 
    566 # LICENSE 
    567 # This program is free software; you can redistribute it and/or 
    568 # modify it under the same terms as Perl 5 itself. 
Note: See TracChangeset for help on using the changeset viewer.