package Padre::Plugin::Catalyst::Helper;
use 5.008;
use strict;
use warnings;
use Cwd ();
use File::Spec ();
use Padre::Wx ();
use Padre::Wx::Dialog ();
use Padre::Util ('_T');
use Padre::Perl;
our $VERSION = '0.09';
# TODO: these should've been passed as a parameter
# but I'm too tired to figure how to do it
# under a Wx::Dialog
my $helpers_for = {
'view' => [],
'model' => [],
'controller' => [],
};
sub dialog {
my $layout = shift;
my $ok_sub = shift;
my $main = Padre->ide->wx->main;
my $config = Padre->ide->config;
my $dialog = Padre::Wx::Dialog->new(
parent => $main,
title => _T('Create New Component'),
layout => $layout,
width => [ 100, 200 ],
bottom => 20,
);
$dialog->{_widgets_}->{_ok_}->SetDefault;
Wx::Event::EVT_BUTTON( $dialog, $dialog->{_widgets_}->{_ok_}, $ok_sub );
Wx::Event::EVT_BUTTON( $dialog, $dialog->{_widgets_}->{_cancel_}, \&cancel_clicked );
$dialog->{_widgets_}->{_name_}->SetFocus;
return $dialog;
}
sub get_model_layout {
my $available_models = $helpers_for->{'model'}; #shift; TODO: ungloball this
my @layout = (
[ [ 'Wx::StaticText', undef, _T('Model Name:') ],
[ 'Wx::TextCtrl', '_name_', 'DB' ],
],
[ [ 'Wx::StaticText', undef, _T('Type') ],
[ 'Wx::Choice', '_type_', $available_models ],
],
[ [ 'Wx::StaticText', undef, _T('Additional Parameters:') ],
[ 'Wx::TextCtrl', '_extra_params_', '' ],
],
[ [ 'Wx::CheckBox', '_force_', 'force', 0 ], #TODO add -mechanize parameter too
],
[ [ 'Wx::Button', '_ok_', Wx::wxID_OK ],
[ 'Wx::Button', '_cancel_', Wx::wxID_CANCEL ],
],
);
return \@layout;
}
sub get_view_layout {
my $available_views = $helpers_for->{'view'}; #shift; TODO: ungloball this
my @layout = (
[ [ 'Wx::StaticText', undef, _T('View Name:') ],
[ 'Wx::TextCtrl', '_name_', 'TT' ],
],
[ [ 'Wx::StaticText', undef, _T('Type') ],
[ 'Wx::Choice', '_type_', $available_views ],
],
[ [ 'Wx::CheckBox', '_force_', _T('force'), 0 ], #TODO add -mechanize parameter too
],
[ [ 'Wx::Button', '_ok_', Wx::wxID_OK ],
[ 'Wx::Button', '_cancel_', Wx::wxID_CANCEL ],
],
);
return \@layout;
}
sub get_controller_layout {
my $available_controllers = $helpers_for->{'controller'}; #shift; TODO: ungloball this
my @layout = (
[ [ 'Wx::StaticText', undef, _T('Controller Name:') ],
[ 'Wx::TextCtrl', '_name_', '' ],
],
[ [ 'Wx::StaticText', undef, _T('Type') ],
[ 'Wx::Choice', '_type_', $available_controllers ],
],
[ [ 'Wx::StaticText', undef, _T('Additional Parameters:') ],
[ 'Wx::TextCtrl', '_extra_params_', '' ],
],
[ [ 'Wx::CheckBox', '_force_', 'force', 0 ], #TODO add -mechanize parameter too
],
[ [ 'Wx::Button', '_ok_', Wx::wxID_OK ],
[ 'Wx::Button', '_cancel_', Wx::wxID_CANCEL ],
],
);
return \@layout;
}
sub find_helpers_for {
my $type = shift;
my $none_str = _T('[none]');
require Module::Pluggable::Object;
my @available_helpers = map {
s{Catalyst::Helper::$type\:\:}{}; $_
} Module::Pluggable::Object->new(
'search_path' => "Catalyst::Helper::$type",
)->plugins();
push @available_helpers, $none_str;
## Put preferred types first on the list. For example,
# as a view, TT is preferred.
# TODO: make this configurable under a Plugin Preferences window
my $favourite = find_favourites( $type, \@available_helpers );
$favourite ||= $none_str;
# puts favourite option always on top of the list
@available_helpers = (
$favourite,
grep { $_ ne $favourite } sort @available_helpers
);
return \@available_helpers;
}
sub find_favourites {
my $type = shift;
my $helpers = shift;
my $none_str = _T('[none]');
if ( $type eq 'View' ) {
foreach ( @{$helpers} ) {
return $_ if ( $_ eq 'TT' );
}
} elsif ( $type eq 'Model' ) {
foreach ( @{$helpers} ) {
return $_ if ( $_ eq 'DBIC::Schema' );
}
}
# no favorites found.
return;
}
sub on_create_view {
$helpers_for->{'view'} = find_helpers_for('View'); # TODO: unglobal this
my $layout = get_view_layout();
my $dialog = dialog( $layout, \&create_view );
$dialog->Show(1);
return;
}
sub on_create_controller {
$helpers_for->{'controller'} = find_helpers_for('Controller'); # TODO: unglobal this
my $layout = get_controller_layout();
my $dialog = dialog( $layout, \&create_controller );
$dialog->Show(1);
return;
}
sub on_create_model {
$helpers_for->{'model'} = find_helpers_for('Model'); # TODO: unglobal this
my $layout = get_model_layout();
my $dialog = dialog( $layout, \&create_model );
$dialog->Show(1);
return;
}
sub cancel_clicked {
my $dialog = shift;
$dialog->Destroy;
return;
}
sub create_view {
my $dialog = shift;
my $data = $dialog->get_data;
$dialog->Destroy;
create( 'View', $data );
}
sub create_model {
my $dialog = shift;
my $data = $dialog->get_data;
$dialog->Destroy;
create( 'Model', $data );
}
sub create_controller {
my $dialog = shift;
my $data = $dialog->get_data;
$dialog->Destroy;
create( 'Controller', $data );
}
sub create {
my $type = lc(shift);
my $data = shift;
my $main = Padre->ide->wx->main;
unless ( $data->{'_name_'} ) {
Wx::MessageBox(
sprintf( _T("You must provide a name for your %s module"), $type ),
_T('Module name required'), Wx::wxOK, $main
);
return;
}
require Padre::Plugin::Catalyst::Util;
my $project_dir = Padre::Plugin::Catalyst::Util::get_document_base_dir() || return;
my $helper_filename = Padre::Plugin::Catalyst::Util::get_catalyst_project_name($project_dir);
$helper_filename .= '_create.pl';
my $helper_full_path = File::Spec->catfile( $project_dir, 'script', $helper_filename );
if ( !-e $helper_full_path ) {
Wx::MessageBox(
sprintf(
_T( "Catalyst helper script not found at\n%s\n\nPlease make sure the active document is from your Catalyst project."
),
$helper_full_path
),
_T('Helper not found'),
Wx::wxOK, $main
);
return;
}
# Prepare the output window for the output
$main->show_output(1);
$main->output->Remove( 0, $main->output->GetLastPosition );
my $perl = Padre::Perl->perl;
push my @cmd, $perl, File::Spec->catfile( 'script', $helper_filename ), $type,;
my $helper = $helpers_for->{$type}; #TODO: unglobal this
push @cmd, $data->{'_name_'},
(
${$helper}[ $data->{'_type_'} ] eq '[none]' ? ''
: ${$helper}[ $data->{'_type_'} ]
),
(
defined $data->{'_extra_params_'} ? $data->{'_extra_params_'}
: ''
),
;
if ( $data->{'_force_'} ) {
push @cmd, '-force';
}
$main->output->AppendText( _T('running:') . "@cmd\n" );
# go to the selected directory
my $pwd = Cwd::cwd();
chdir $project_dir;
# FIXME: STDERR output is going to the console
my $output_text = qx{@cmd};
$main->output->AppendText($output_text);
chdir $pwd; # restore directory
$main->output->AppendText( "\n" . _T("Catalyst helper script ended.") . "\n" );
require Padre::Plugin::Catalyst::Util;
my $file = Padre::Plugin::Catalyst::Util::find_file_from_output(
$data->{'_name_'},
$output_text
);
if ($file) {
$file = Cwd::realpath($file); # avoid relative paths
my $ret = Wx::MessageBox(
sprintf( _T("%s apparently created. Do you want to open it now?"), $type ),
_T('Done'),
Wx::wxYES_NO | Wx::wxCENTRE,
$main,
);
if ( $ret == Wx::wxYES ) {
Padre::DB::History->create(
type => 'files',
name => $file,
);
$main->setup_editor($file);
$main->refresh;
}
} else {
Wx::MessageBox(
sprintf( _T("Error creating %s. Please check the error output and try again"), $type ),
_T('Error'),
Wx::wxOK | Wx::wxCENTRE,
$main,
);
}
return;
}
42;