Ticket #1271: Plack.pm.patch
| File Plack.pm.patch, 29.8 KB (added by bowtie, 21 months ago) |
|---|
-
usr/src/Padre/Padre-Plugin-Plack/lib/Padre/Plugin/Plack.pm
7 7 8 8 use utf8; 9 9 10 use Padre::Util ('_T'); 10 use Padre::Plugin (); 11 use Padre::Util ('_T'); 11 12 use Padre::Logger; 12 13 13 14 our $VERSION = "0.01"; … … 19 20 20 21 =cut 21 22 23 ####### 24 # Define Padre Interfaces required 25 ####### 22 26 sub padre_interfaces { 23 'Padre::Plugin' => 0.43, 24 'Padre::Document' => 0.82; 27 return ( 28 'Padre::Plugin' => '0.90', 29 'Padre::Document' => '0.90', 30 'Padre::Wx' => '0.90', 31 'Padre::Wx::Main' => '0.90', 32 'Padre::Wx::Role::Main' => '0.90', 33 'Padre::Logger' => '0.90', 34 ); 25 35 } 26 36 27 37 38 28 39 sub plugin_name { 29 'Plack';40 return Wx::gettext('Plack'); 30 41 } 42 31 43 =method registered_documents 32 44 33 45 Declare ourselves as the handler for .psgi files … … 35 47 =cut 36 48 37 49 sub registered_documents { 38 'application/x-psgi' => 'Padre::Document::PSGI';50 'application/x-psgi' => 'Padre::Document::PSGI'; 39 51 } 40 52 41 53 # Static cache for the dot-psgi examples (read off disk) … … 48 60 =cut 49 61 50 62 sub menu_plugins { 51 my $self = shift;52 my $main = shift;63 my $self = shift; 64 my $main = shift; 53 65 54 my $menu = Wx::Menu->new;66 my $menu = Wx::Menu->new; 55 67 56 my $app_menu = Wx::Menu->new;57 $menu->Append( -1, _T('New PSGI App'), $app_menu );68 my $app_menu = Wx::Menu->new; 69 $menu->Append( -1, _T('New PSGI App'), $app_menu ); 58 70 59 for my $basename ( sort keys %PSGI_EXAMPLES ) {60 Wx::Event::EVT_MENU(61 $main,62 $app_menu->Append( -1, $basename ),63 sub {64 $self->on_app_load( $PSGI_EXAMPLES{$basename} );65 return;66 },67 );68 }71 for my $basename ( sort keys %PSGI_EXAMPLES ) { 72 Wx::Event::EVT_MENU( 73 $main, 74 $app_menu->Append( -1, $basename ), 75 sub { 76 $self->on_app_load( $PSGI_EXAMPLES{$basename} ); 77 return; 78 }, 79 ); 80 } 69 81 70 my $docs_menu = Wx::Menu->new;71 $menu->Append( -1, _T('Online References'), $docs_menu );82 my $docs_menu = Wx::Menu->new; 83 $menu->Append( -1, _T('Online References'), $docs_menu ); 72 84 73 Wx::Event::EVT_MENU(74 $main,75 $docs_menu->Append( -1, 'plackperl.org' ),76 sub {77 Padre::Wx::launch_browser('http://plackperl.org');78 }79 );85 Wx::Event::EVT_MENU( 86 $main, 87 $docs_menu->Append( -1, 'plackperl.org' ), 88 sub { 89 Padre::Wx::launch_browser('http://plackperl.org'); 90 } 91 ); 80 92 81 Wx::Event::EVT_MENU(82 $main,83 $docs_menu->Append( -1, _T('Plack Advent Calendar') ),84 sub {85 Padre::Wx::launch_browser('http://advent.plackperl.org');86 },87 );93 Wx::Event::EVT_MENU( 94 $main, 95 $docs_menu->Append( -1, _T('Plack Advent Calendar') ), 96 sub { 97 Padre::Wx::launch_browser('http://advent.plackperl.org'); 98 }, 99 ); 88 100 89 Wx::Event::EVT_MENU( $main, $menu->Append( -1, _T('About') ), sub { $self->on_about_load }, );101 Wx::Event::EVT_MENU( $main, $menu->Append( -1, _T('About') ), sub { $self->on_about_load }, ); 90 102 91 # Return it and the label for our plug-in92 return ( $self->plugin_name => $menu );103 # Return it and the label for our plug-in 104 return ( $self->plugin_name => $menu ); 93 105 } 94 106 95 107 =method on_app_load … … 99 111 =cut 100 112 101 113 sub on_app_load { 102 my $self = shift;103 my $file = shift;114 my $self = shift; 115 my $file = shift; 104 116 105 my $main = $self->main;117 my $main = $self->main; 106 118 107 # Slurp in the new app content from the template file108 my $template = Padre::Util::slurp($file);109 unless ($template) {119 # Slurp in the new app content from the template file 120 my $template = Padre::Util::slurp($file); 121 unless ($template) { 110 122 111 # Rare failure, no need to translate112 $self->main->error( sprintf( _T('Failed to open template file %s'), $file ) );113 return;114 }123 # Rare failure, no need to translate 124 $self->main->error( sprintf( _T('Failed to open template file %s'), $file ) ); 125 return; 126 } 115 127 116 # Create new document editor tab117 $main->new_document_from_string( $$template, 'application/x-psgi' );118 my $editor = $main->current->editor;119 my $doc = $editor->{Document};128 # Create new document editor tab 129 $main->new_document_from_string( $$template, 'application/x-psgi' ); 130 my $editor = $main->current->editor; 131 my $doc = $editor->{Document}; 120 132 121 # N.B. It used to be necessary to deliberately use application/x-perl mime type and then rebless as122 # a hack to make syntax highlighting work off the bat, but it seems to work now123 # $doc->set_mimetype('application/x-psgi');124 # $doc->rebless;125 $self->on_doc_load($doc);133 # N.B. It used to be necessary to deliberately use application/x-perl mime type and then rebless as 134 # a hack to make syntax highlighting work off the bat, but it seems to work now 135 # $doc->set_mimetype('application/x-psgi'); 136 # $doc->rebless; 137 $self->on_doc_load($doc); 126 138 127 # The tab exists, so trigger set_tab_icon128 $doc->set_tab_icon;139 # The tab exists, so trigger set_tab_icon 140 $doc->set_tab_icon; 129 141 } 130 142 131 143 =method is_psgi_doc … … 133 145 =cut 134 146 135 147 sub is_psgi_doc { 136 my $self = shift;137 my $doc = shift;148 my $self = shift; 149 my $doc = shift; 138 150 139 return $doc->isa('Padre::Document::PSGI') && $doc->can('mimetype') && $doc->mimetype eq 'application/x-psgi';151 return $doc->isa('Padre::Document::PSGI') && $doc->can('mimetype') && $doc->mimetype eq 'application/x-psgi'; 140 152 } 141 153 142 154 =method editor_enable … … 144 156 =cut 145 157 146 158 sub editor_enable { 147 my $self = shift;148 my $editor = shift;149 my $doc = shift;159 my $self = shift; 160 my $editor = shift; 161 my $doc = shift; 150 162 151 # Only respond to event on psgi docs152 return unless $self->is_psgi_doc($doc);163 # Only respond to event on psgi docs 164 return unless $self->is_psgi_doc($doc); 153 165 154 TRACE('->editor_enable') if DEBUG;166 TRACE('->editor_enable') if DEBUG; 155 167 156 $self->on_doc_load($doc);168 $self->on_doc_load($doc); 157 169 158 # Deliberately don't trigger Padre::Document::PSGI::set_tab_icon here because the tab doesn't exist yet159 # (it gets triggered by our tomfoolery in Padre::Document::PSGI::restore_cursor_position)170 # Deliberately don't trigger Padre::Document::PSGI::set_tab_icon here because the tab doesn't exist yet 171 # (it gets triggered by our tomfoolery in Padre::Document::PSGI::restore_cursor_position) 160 172 } 161 173 162 174 =method editor_changed … … 164 176 =cut 165 177 166 178 sub editor_changed { 167 my $self = shift;179 my $self = shift; 168 180 169 my $main = $self->main or return;170 my $editor = $main->current->editor or return;171 my $doc = $editor->{Document} or return;181 my $main = $self->main or return; 182 my $editor = $main->current->editor or return; 183 my $doc = $editor->{Document} or return; 172 184 173 # Only respond to event on psgi docs174 return unless $self->is_psgi_doc($doc);185 # Only respond to event on psgi docs 186 return unless $self->is_psgi_doc($doc); 175 187 176 TRACE('->editor_changed') if DEBUG;188 TRACE('->editor_changed') if DEBUG; 177 189 178 ## TODO: add check that doc is now selected (for safety)..179 $self->on_panel_load($doc);190 ## TODO: add check that doc is now selected (for safety).. 191 $self->on_panel_load($doc); 180 192 } 181 193 182 194 =method on_panel_load … … 184 196 =cut 185 197 186 198 sub on_panel_load { 187 my $self = shift;188 my $doc = shift;199 my $self = shift; 200 my $doc = shift; 189 201 190 if ( !$doc->panel ) {191 TRACE('->on_panel_load creating panel') if DEBUG;192 require Padre::Plugin::Plack::Panel;193 $doc->panel( Padre::Plugin::Plack::Panel->new($doc) );194 }202 if ( !$doc->panel ) { 203 TRACE('->on_panel_load creating panel') if DEBUG; 204 require Padre::Plugin::Plack::Panel; 205 $doc->panel( Padre::Plugin::Plack::Panel->new($doc) ); 206 } 195 207 196 # Show the panel, and pass an onclose callback197 Padre::Current->main->bottom->show(198 $doc->panel,199 sub {208 # Show the panel, and pass an onclose callback 209 Padre::Current->main->bottom->show( 210 $doc->panel, 211 sub { 200 212 201 # Closing the panel causes bad things to happen202 $self->main->error(203 _T(q{'Sorry Dave, I can't do that - you need to close the corresponding file tab to close this panel})204 );213 # Closing the panel causes bad things to happen 214 $self->main->error( 215 _T(q{'Sorry Dave, I can't do that - you need to close the corresponding file tab to close this panel}) 216 ); 205 217 206 # We can't actually cancel the close, so re-create it207 $self->plackdown($doc);208 $doc->panel(undef);209 $self->on_panel_load($doc);210 }211 );212 Padre::Current->main->refresh;218 # We can't actually cancel the close, so re-create it 219 $self->plackdown($doc); 220 $doc->panel(undef); 221 $self->on_panel_load($doc); 222 } 223 ); 224 Padre::Current->main->refresh; 213 225 } 214 226 215 227 =method on_panel_close … … 217 229 =cut 218 230 219 231 sub on_panel_close { 220 my $self = shift;221 my $doc = shift;232 my $self = shift; 233 my $doc = shift; 222 234 223 return unless $doc && $doc->panel;235 return unless $doc && $doc->panel; 224 236 225 if ( my $panel = $doc->panel ) {226 $self->plackdown($doc);227 $self->main->bottom->hide($panel);228 $doc->panel(undef);229 }237 if ( my $panel = $doc->panel ) { 238 $self->plackdown($doc); 239 $self->main->bottom->hide($panel); 240 $doc->panel(undef); 241 } 230 242 } 231 243 232 244 =method on_doc_load … … 238 250 =cut 239 251 240 252 sub on_doc_load { 241 my $self = shift;242 my $doc = shift;253 my $self = shift; 254 my $doc = shift; 243 255 244 TRACE('->on_doc_load') if DEBUG;256 TRACE('->on_doc_load') if DEBUG; 245 257 246 if ( !$doc->isa('Padre::Document::PSGI') ) {247 $self->error( sprintf( _T('Expected a PSGI document, but instead got: %s'), ref $doc ) );248 return;249 }258 if ( !$doc->isa('Padre::Document::PSGI') ) { 259 $self->error( sprintf( _T('Expected a PSGI document, but instead got: %s'), ref $doc ) ); 260 return; 261 } 250 262 251 # Set the icon path, but don't actually trigger set_icon_tab() just yet252 $doc->icon_path( $self->plugin_directory_share . "/icons/16x16/logo.png" );253 $doc->plugin($self);263 # Set the icon path, but don't actually trigger set_icon_tab() just yet 264 $doc->icon_path( $self->plugin_directory_share . "/icons/16x16/logo.png" ); 265 $doc->plugin($self); 254 266 255 # Trigger the Document's general setup event256 $doc->on_load;267 # Trigger the Document's general setup event 268 $doc->on_load; 257 269 258 # Show the panel259 $self->on_panel_load($doc);270 # Show the panel 271 $self->on_panel_load($doc); 260 272 } 261 273 262 274 =method on_doc_close … … 264 276 =cut 265 277 266 278 sub on_doc_close { 267 my $self = shift;268 my $doc = shift;279 my $self = shift; 280 my $doc = shift; 269 281 270 TRACE('->on_doc_close') if DEBUG;282 TRACE('->on_doc_close') if DEBUG; 271 283 272 if ( !$doc->isa('Padre::Document::PSGI') ) {273 $self->error( sprintf( _T('Expected a PSGI document, but instead got: %s'), ref $doc ) );274 return;275 }284 if ( !$doc->isa('Padre::Document::PSGI') ) { 285 $self->error( sprintf( _T('Expected a PSGI document, but instead got: %s'), ref $doc ) ); 286 return; 287 } 276 288 277 $self->on_panel_close($doc);289 $self->on_panel_close($doc); 278 290 } 279 291 280 292 =method on_about_load … … 282 294 =cut 283 295 284 296 sub on_about_load { 285 require Plack;286 require Class::Unload;287 my $about = Wx::AboutDialogInfo->new;288 $about->SetName("Padre::Plugin::Plack");289 $about->SetDescription( _T('PSGI/Plack support for Padre') . "\n"290 . _T('by') . "\n"291 . 'Patrick Donelan (pat@patspam.com)' . "\n\n"292 . _T('This system is running Plack version')293 . " $Plack::VERSION\n"294 . 'http://plackperl.org' );295 $about->SetVersion($Padre::Plugin::Plack::VERSION);296 Class::Unload->unload('Plack');297 require Plack; 298 require Class::Unload; 299 my $about = Wx::AboutDialogInfo->new; 300 $about->SetName("Padre::Plugin::Plack"); 301 $about->SetDescription( _T('PSGI/Plack support for Padre') . "\n" 302 . _T('by') . "\n" 303 . 'Patrick Donelan (pat@patspam.com)' . "\n\n" 304 . _T('This system is running Plack version') 305 . " $Plack::VERSION\n" 306 . 'http://plackperl.org' ); 307 $about->SetVersion($Padre::Plugin::Plack::VERSION); 308 Class::Unload->unload('Plack'); 297 309 298 Wx::AboutBox($about);299 return;310 Wx::AboutBox($about); 311 return; 300 312 } 301 313 302 314 =method load_dot_psgi_examples … … 304 316 =cut 305 317 306 318 sub load_dot_psgi_examples { 307 my $self = shift;319 my $self = shift; 308 320 309 require File::Find::Rule;310 %PSGI_EXAMPLES =311 map { File::Basename::basename($_) => $_ }312 File::Find::Rule->file()->name('*.psgi')->in( $self->plugin_directory_share . '/dot-psgi' );321 require File::Find::Rule; 322 %PSGI_EXAMPLES = 323 map { File::Basename::basename($_) => $_ } 324 File::Find::Rule->file()->name('*.psgi')->in( $self->plugin_directory_share . '/dot-psgi' ); 313 325 } 314 326 315 327 =method plugin_enable … … 319 331 320 332 321 333 sub plugin_enable { 322 my $self = shift;334 my $self = shift; 323 335 324 $self->load_dot_psgi_examples;336 $self->load_dot_psgi_examples; 325 337 } 326 338 327 339 =method plugin_enable … … 329 341 =cut 330 342 331 343 sub plugin_disable { 332 my $self = shift;344 my $self = shift; 333 345 334 # TODO: Loop over all docs and turn off their psgi goodies: panel, stop server, etc..346 # TODO: Loop over all docs and turn off their psgi goodies: panel, stop server, etc.. 335 347 336 # cleanup loaded classes 337 require Class::Unload; 338 Class::Unload->unload('Padre::Document::PSGI'); 339 Class::Unload->unload('Padre::Plugin::Plack::Panel'); 348 # Unload all our child classes 349 $self->unload( 350 qw{ 351 Padre::Document::PSGI 352 Padre::Plugin::Plack::Panel 353 } 354 ); 355 356 $self->SUPER::plugin_disable(@_); 357 358 return; 340 359 } 341 360 342 361 =method plackup … … 344 363 =cut 345 364 346 365 sub plackup { 347 my $self = shift;348 my $doc = shift;366 my $self = shift; 367 my $doc = shift; 349 368 350 return unless $doc;351 TRACE('->plackup') if DEBUG;369 return unless $doc; 370 TRACE('->plackup') if DEBUG; 352 371 353 my $main = $self->main;354 my $filename = $doc->filename;372 my $main = $self->main; 373 my $filename = $doc->filename; 355 374 356 if ( !$filename ) {357 $main->on_save;358 $filename = $doc->filename;359 return unless $filename;360 }375 if ( !$filename ) { 376 $main->on_save; 377 $filename = $doc->filename; 378 return unless $filename; 379 } 361 380 362 my $pwd = Cwd::cwd();363 chdir $doc->dirname;381 my $pwd = Cwd::cwd(); 382 chdir $doc->dirname; 364 383 365 # Server ("Let plackup guess" means leave as unspecified)366 my $server = $doc->panel->{server}->GetValue;367 $server = $server eq _T('Let plackup guess') ? '' : "-s $server";384 # Server ("Let plackup guess" means leave as unspecified) 385 my $server = $doc->panel->{server}->GetValue; 386 $server = $server eq _T('Let plackup guess') ? '' : "-s $server"; 368 387 369 # Port (required for browser url)370 my $port = $doc->panel->{port}->GetValue || 5000;371 $port = "-p $port";388 # Port (required for browser url) 389 my $port = $doc->panel->{port}->GetValue || 5000; 390 $port = "-p $port"; 372 391 373 my $restart = $doc->panel->{restart}->GetValue ? '-r' : '';374 my $plackup_options = $doc->panel->{plackup_options}->GetValue;392 my $restart = $doc->panel->{restart}->GetValue ? '-r' : ''; 393 my $plackup_options = $doc->panel->{plackup_options}->GetValue; 375 394 376 require File::Which;377 my $plackup = File::Which::which('plackup');378 if ( !$plackup ) {379 $main->error( _T('plackup command not found, please check your Plack installation and $PATH') );380 return;381 }395 require File::Which; 396 my $plackup = File::Which::which('plackup'); 397 if ( !$plackup ) { 398 $main->error( _T('plackup command not found, please check your Plack installation and $PATH') ); 399 return; 400 } 382 401 383 my $cmd = qq{$plackup $port $restart $server $plackup_options "$filename"};384 TRACE("->plackup $cmd") if DEBUG;385 $self->run_command( $doc, $cmd );402 my $cmd = qq{$plackup $port $restart $server $plackup_options "$filename"}; 403 TRACE("->plackup $cmd") if DEBUG; 404 $self->run_command( $doc, $cmd ); 386 405 387 # restore previous dir388 chdir $pwd;406 # restore previous dir 407 chdir $pwd; 389 408 } 390 409 391 410 =method plackdown … … 393 412 =cut 394 413 395 414 sub plackdown { 396 my $self = shift;397 my $doc = shift;415 my $self = shift; 416 my $doc = shift; 398 417 399 return unless $doc;418 return unless $doc; 400 419 401 TRACE('->plackdown') if DEBUG;420 TRACE('->plackdown') if DEBUG; 402 421 403 my $process = $doc->process;404 return unless $process;422 my $process = $doc->process; 423 return unless $process; 405 424 406 # sanity check407 if ( !$process->IsAlive ) {408 TRACE('->plackdown process was dead but not undef, strange') if DEBUG;409 $doc->process(undef);410 }425 # sanity check 426 if ( !$process->IsAlive ) { 427 TRACE('->plackdown process was dead but not undef, strange') if DEBUG; 428 $doc->process(undef); 429 } 411 430 412 my $processid = $process->GetProcessId();413 my $panel = $doc->panel;431 my $processid = $process->GetProcessId(); 432 my $panel = $doc->panel; 414 433 415 require Proc::Killfam;416 my @signals = qw(INT TERM QUIT KILL STOP);417 for my $sig (@signals) {418 TRACE("Sending $sig to PID: $processid") if DEBUG;419 my $signalled = Proc::Killfam::killfam( $sig, $processid );434 require Proc::Killfam; 435 my @signals = qw(INT TERM QUIT KILL STOP); 436 for my $sig (@signals) { 437 TRACE("Sending $sig to PID: $processid") if DEBUG; 438 my $signalled = Proc::Killfam::killfam( $sig, $processid ); 420 439 421 if ( $panel->{restart}->GetValue ) {440 if ( $panel->{restart}->GetValue ) { 422 441 423 # with auto-restart, we expect 3 processes 424 return if $signalled > 1; 425 } 426 else { 442 # with auto-restart, we expect 3 processes 443 return if $signalled > 1; 444 } else { 427 445 428 # otherwise, just one429 return if $signalled > 0;430 }431 }446 # otherwise, just one 447 return if $signalled > 0; 448 } 449 } 432 450 433 $panel->output->AppendText( "\n" . "Process PID $processid did not respond, you may need to kill it manually\n" );451 $panel->output->AppendText( "\n" . "Process PID $processid did not respond, you may need to kill it manually\n" ); 434 452 } 435 453 436 454 =method run_command … … 438 456 =cut 439 457 440 458 sub run_command { 441 my ( $self, $doc, $command ) = (@_);459 my ( $self, $doc, $command ) = (@_); 442 460 443 my $panel = $doc->panel;461 my $panel = $doc->panel; 444 462 445 # clear the panel446 $panel->output->Remove( 0, $panel->output->GetLastPosition );463 # clear the panel 464 $panel->output->Remove( 0, $panel->output->GetLastPosition ); 447 465 448 # If this is the first time a command has been run, set up the ProcessStream bindings.449 unless ( $panel->{bound} ) {450 TRACE(' setting up ProcessStream bindings') if DEBUG;466 # If this is the first time a command has been run, set up the ProcessStream bindings. 467 unless ( $panel->{bound} ) { 468 TRACE(' setting up ProcessStream bindings') if DEBUG; 451 469 452 require Wx::Perl::ProcessStream; 453 if ( $Wx::Perl::ProcessStream::VERSION < .20 ) { 454 $self->main->error( 455 sprintf( 456 _T( 457 'Wx::Perl::ProcessStream is version %s' 458 . ' which is known to cause problems. Get at least 0.20 by typing' 459 . "\ncpan Wx::Perl::ProcessStream" 460 ), 461 $Wx::Perl::ProcessStream::VERSION 462 ) 463 ); 464 return 1; 465 } 470 require Wx::Perl::ProcessStream; 471 if ( $Wx::Perl::ProcessStream::VERSION < .20 ) { 472 $self->main->error( 473 sprintf( 474 _T( 'Wx::Perl::ProcessStream is version %s' 475 . ' which is known to cause problems. Get at least 0.20 by typing' 476 . "\ncpan Wx::Perl::ProcessStream" 477 ), 478 $Wx::Perl::ProcessStream::VERSION 479 ) 480 ); 481 return 1; 482 } 466 483 467 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_STDOUT(468 $panel->output,469 sub {470 $_[1]->Skip(1);471 my $outpanel = $_[0];472 $outpanel->style_good;473 $outpanel->AppendText( $_[1]->GetLine . "\n" );474 return;475 },476 );477 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_STDERR(478 $panel->output,479 sub {480 $_[1]->Skip(1);481 my $outpanel = $_[0];482 $outpanel->style_neutral;483 $outpanel->AppendText( $_[1]->GetLine . "\n" );484 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_STDOUT( 485 $panel->output, 486 sub { 487 $_[1]->Skip(1); 488 my $outpanel = $_[0]; 489 $outpanel->style_good; 490 $outpanel->AppendText( $_[1]->GetLine . "\n" ); 491 return; 492 }, 493 ); 494 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_STDERR( 495 $panel->output, 496 sub { 497 $_[1]->Skip(1); 498 my $outpanel = $_[0]; 499 $outpanel->style_neutral; 500 $outpanel->AppendText( $_[1]->GetLine . "\n" ); 484 501 485 return;486 },487 );488 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_EXIT(489 $panel->output,490 sub {491 $_[1]->Skip(1);492 $_[1]->GetProcess->Destroy;502 return; 503 }, 504 ); 505 Wx::Perl::ProcessStream::EVT_WXP_PROCESS_STREAM_EXIT( 506 $panel->output, 507 sub { 508 $_[1]->Skip(1); 509 $_[1]->GetProcess->Destroy; 493 510 494 TRACE(' PROCESS_STREAM_EXIT') if DEBUG;511 TRACE(' PROCESS_STREAM_EXIT') if DEBUG; 495 512 496 my $outpanel = $_[0];497 $outpanel->style_neutral;498 $outpanel->AppendText("\nProcess terminated\n");499 $panel->set_as_stopped;513 my $outpanel = $_[0]; 514 $outpanel->style_neutral; 515 $outpanel->AppendText("\nProcess terminated\n"); 516 $panel->set_as_stopped; 500 517 501 $doc->process(undef);502 },503 );504 $panel->{bound} = 1;505 }518 $doc->process(undef); 519 }, 520 ); 521 $panel->{bound} = 1; 522 } 506 523 507 # Start the command508 my $process = Wx::Perl::ProcessStream::Process->new( $command, "Run $command", $panel->output );509 $doc->process( $process->Run );524 # Start the command 525 my $process = Wx::Perl::ProcessStream::Process->new( $command, "Run $command", $panel->output ); 526 $doc->process( $process->Run ); 510 527 511 # Check if we started the process or not512 if ( $doc->process ) {513 $panel->set_as_started;528 # Check if we started the process or not 529 if ( $doc->process ) { 530 $panel->set_as_started; 514 531 515 } 516 else { 532 } else { 517 533 518 # Failed to start the command. Clean up.519 $panel->set_as_stopped;# should already be stopped, but just in case520 Wx::MessageBox( sprintf( _T("Failed to start server via '%s'"), $command ), _T("Error"), Wx::wxOK, $self );521 }534 # Failed to start the command. Clean up. 535 $panel->set_as_stopped; # should already be stopped, but just in case 536 Wx::MessageBox( sprintf( _T("Failed to start server via '%s'"), $command ), _T("Error"), Wx::wxOK, $self ); 537 } 522 538 523 return;539 return; 524 540 } 525 541 526 542 =method build_panel … … 531 547 =cut 532 548 533 549 sub build_panel { 534 my $self = shift;535 my $doc = shift;536 my $panel = shift;550 my $self = shift; 551 my $doc = shift; 552 my $panel = shift; 537 553 538 require Scalar::Util;539 $panel->{doc} = $doc;540 Scalar::Util::weaken( $panel->{doc} );554 require Scalar::Util; 555 $panel->{doc} = $doc; 556 Scalar::Util::weaken( $panel->{doc} ); 541 557 542 # main container543 my $box = Wx::BoxSizer->new(Wx::wxVERTICAL);558 # main container 559 my $box = Wx::BoxSizer->new(Wx::wxVERTICAL); 544 560 545 # top box, holding buttons, icons and checkboxes546 my $top_box = Wx::BoxSizer->new(Wx::wxHORIZONTAL);561 # top box, holding buttons, icons and checkboxes 562 my $top_box = Wx::BoxSizer->new(Wx::wxHORIZONTAL); 547 563 548 # LED showing process status549 $panel->{led} = Wx::StaticBitmap->new( $panel, -1, Wx::wxNullBitmap );550 $top_box->Add( $panel->{led}, 0, Wx::wxALIGN_CENTER_VERTICAL );564 # LED showing process status 565 $panel->{led} = Wx::StaticBitmap->new( $panel, -1, Wx::wxNullBitmap ); 566 $top_box->Add( $panel->{led}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 551 567 552 # Servers 553 my @servers = sort qw( 554 Standalone 555 Apache1 556 Apache2 557 Apache2::RegistryAnyEvent 558 AnyEvent::HTTPD 559 AnyEvent::ReverseHTTP 560 AnyEvent::SCGI 561 AnyEvent::Server::Starter 562 CGI 563 Corona 564 FCGI 565 FCGI::Engine 566 HTTP::Server::PSGI 567 HTTP::Server::Simple 568 Server::Simple 569 SCGI 570 Starman 571 Starlet 572 Twiggy 573 POE 574 ReverseHTTP 575 ); 576 unshift @servers, _T('Let plackup guess'); 577 $top_box->AddSpacer(5); 578 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Server') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL ); 579 $panel->{server} = 580 Wx::ComboBox->new( $panel, -1, 'Standalone', Wx::wxDefaultPosition, Wx::wxDefaultSize, [@servers], 581 Wx::wxCB_DROPDOWN ); 582 $top_box->Add( $panel->{server}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 568 # Servers 569 my @servers = sort qw( 570 Standalone 571 Apache1 572 Apache2 573 Apache2::RegistryAnyEvent 574 AnyEvent::HTTPD 575 AnyEvent::ReverseHTTP 576 AnyEvent::SCGI 577 AnyEvent::Server::Starter 578 CGI 579 Corona 580 FCGI 581 FCGI::Engine 582 HTTP::Server::PSGI 583 HTTP::Server::Simple 584 Server::Simple 585 SCGI 586 Starman 587 Starlet 588 Twiggy 589 POE 590 ReverseHTTP 591 ); 592 unshift @servers, _T('Let plackup guess'); 593 $top_box->AddSpacer(5); 594 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Server') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL ); 595 $panel->{server} = Wx::ComboBox->new( 596 $panel, -1, 'Standalone', Wx::wxDefaultPosition, Wx::wxDefaultSize, [@servers], 597 Wx::wxCB_DROPDOWN 598 ); 599 $top_box->Add( $panel->{server}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 583 600 584 # Port585 $top_box->AddSpacer(5);586 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Port') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL );587 $panel->{port} = Wx::TextCtrl->new( $panel, -1, '5000' );588 $top_box->Add( $panel->{port}, 0, Wx::wxALIGN_CENTER_VERTICAL );601 # Port 602 $top_box->AddSpacer(5); 603 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Port') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL ); 604 $panel->{port} = Wx::TextCtrl->new( $panel, -1, '5000' ); 605 $top_box->Add( $panel->{port}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 589 606 590 # Plackup Options591 $top_box->AddSpacer(5);592 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Options') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL );593 $panel->{plackup_options} = Wx::TextCtrl->new( $panel, -1, '' );594 $top_box->Add( $panel->{plackup_options}, 0, Wx::wxALIGN_CENTER_VERTICAL );607 # Plackup Options 608 $top_box->AddSpacer(5); 609 $top_box->Add( Wx::StaticText->new( $panel, -1, _T('Options') . ':' ), 0, Wx::wxALIGN_CENTER_VERTICAL ); 610 $panel->{plackup_options} = Wx::TextCtrl->new( $panel, -1, '' ); 611 $top_box->Add( $panel->{plackup_options}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 595 612 596 # Restart597 $top_box->AddSpacer(5);598 $panel->{restart} = Wx::CheckBox->new( $panel, -1, _T('Auto-Restart') );599 $panel->{restart}->SetValue(1);600 $top_box->Add( $panel->{restart}, 0, Wx::wxALIGN_CENTER_VERTICAL );613 # Restart 614 $top_box->AddSpacer(5); 615 $panel->{restart} = Wx::CheckBox->new( $panel, -1, _T('Auto-Restart') ); 616 $panel->{restart}->SetValue(1); 617 $top_box->Add( $panel->{restart}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 601 618 602 # Start/stop button603 $top_box->AddSpacer(5);604 $panel->{start_stop} = Wx::Button->new( $panel, -1, '' );605 Wx::Event::EVT_BUTTON(606 $panel,607 $panel->{start_stop},608 sub {609 my $panel = shift;619 # Start/stop button 620 $top_box->AddSpacer(5); 621 $panel->{start_stop} = Wx::Button->new( $panel, -1, '' ); 622 Wx::Event::EVT_BUTTON( 623 $panel, 624 $panel->{start_stop}, 625 sub { 626 my $panel = shift; 610 627 611 # Trigger plackup/down 612 if ( $panel->{start_stop}->GetLabel eq _T('Start') ) { 613 $doc->plugin->plackup($doc); 614 } 615 else { 616 $doc->plugin->plackdown($doc); 617 } 618 }, 619 ); 620 $top_box->Add( $panel->{start_stop}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 628 # Trigger plackup/down 629 if ( $panel->{start_stop}->GetLabel eq _T('Start') ) { 630 $doc->plugin->plackup($doc); 631 } else { 632 $doc->plugin->plackdown($doc); 633 } 634 }, 635 ); 636 $top_box->Add( $panel->{start_stop}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 621 637 622 # Browser623 $top_box->AddSpacer(5);624 $panel->{browse} = Wx::Button->new( $panel, -1, _T('View in Browser') );625 Wx::Event::EVT_BUTTON(626 $panel,627 $panel->{browse},628 sub {629 my $panel = shift;630 my $port = $panel->{port}->GetValue || 5000;631 Padre::Wx::launch_browser("http://0:$port");632 },633 );634 $top_box->Add( $panel->{browse}, 0, Wx::wxALIGN_CENTER_VERTICAL );638 # Browser 639 $top_box->AddSpacer(5); 640 $panel->{browse} = Wx::Button->new( $panel, -1, _T('View in Browser') ); 641 Wx::Event::EVT_BUTTON( 642 $panel, 643 $panel->{browse}, 644 sub { 645 my $panel = shift; 646 my $port = $panel->{port}->GetValue || 5000; 647 Padre::Wx::launch_browser("http://0:$port"); 648 }, 649 ); 650 $top_box->Add( $panel->{browse}, 0, Wx::wxALIGN_CENTER_VERTICAL ); 635 651 636 # finishing up the top_box637 $box->Add( $top_box, 0, Wx::wxALIGN_LEFT | Wx::wxALIGN_CENTER_VERTICAL );652 # finishing up the top_box 653 $box->Add( $top_box, 0, Wx::wxALIGN_LEFT | Wx::wxALIGN_CENTER_VERTICAL ); 638 654 639 # output panel for server640 require Padre::Wx::Output;641 my $output = Padre::Wx::Output->new( $self->main, $panel );655 # output panel for server 656 require Padre::Wx::Output; 657 my $output = Padre::Wx::Output->new( $self->main, $panel ); 642 658 643 $box->Add( $output, 1, Wx::wxGROW );659 $box->Add( $output, 1, Wx::wxGROW ); 644 660 645 # wrapping it up646 $panel->SetSizer($box);661 # wrapping it up 662 $panel->SetSizer($box); 647 663 648 # holding on to some objects we'll need to manipulate later on649 $panel->{output} = $output;664 # holding on to some objects we'll need to manipulate later on 665 $panel->{output} = $output; 650 666 651 $panel->set_as_stopped;667 $panel->set_as_stopped; 652 668 } 653 669 654 670 =method TRACE
