package Padre::Util::FileBrowser;
=head1 NAME
Padre::Util::FileBrowser - Open in file browser action
=head1 DESCRIPTION
A collection of single-shot methods to open a file in the platform's file
manager or browser while trying to select it if possible.
=head1 METHODS
=cut
use 5.008;
use strict;
use warnings;
# package exports and version
our $VERSION = '1.00';
use Padre::Constant ();
# -- constructor
sub new {
my ($class) = @_;
return bless {}, $class;
}
=head2 C<open_in_file_browser>
Padre::Util::FileBrowser->open_in_file_browser($filename);
Single shot method to open the provided C<$filename> in the file browser
On win32, selects it in Windows Explorer
On UNIX, opens the containing folder for it using either KDE or GNOME
=cut
sub open_in_file_browser {
my ( $class, $filename ) = @_;
my $self = $class->new(@_);
my $main = Padre::Current->main;
unless ($filename) {
$main->error( Wx::gettext("No filename") );
return;
}
my $error;
if (Padre::Constant::WIN32) {
# In windows, simply execute: explorer.exe /select,"$filename"
$filename =~ s/\//\\/g;
$error = $self->_execute( 'explorer.exe', "/select,\"$filename\"" );
} elsif (Padre::Constant::UNIX) {
my $parent_folder = -d $filename ? $filename : File::Basename::dirname($filename);
$error = $self->_execute_unix($parent_folder);
} else {
# Unsupported
$error = sprintf( Wx::gettext("Unsupported OS: %s"), '$^O' );
}
if ($error) {
$main->error($error);
}
return;
}
=head2 C<open_with_default_system_editor>
Padre::Util::FileBrowser->open_in_file_browser($filename);
Single shot method to open the provided C<$filename> using the default system editor
=cut
sub open_with_default_system_editor {
my ( $class, $filename ) = @_;
my $self = $class->new(@_);
my $main = Padre::Current->main;
unless ($filename) {
$main->error( Wx::gettext("No filename") );
return;
}
my $error;
if (Padre::Constant::WIN32) {
# Win32
require Padre::Util::Win32;
Padre::Util::Win32::ExecuteProcessAndWait(
directory => $self->{cwd},
file => $filename,
parameters => '',
show => 1
);
} elsif (Padre::Constant::UNIX) {
# Unix
#TODO implement for UNIX
$error = $self->_execute_unix($filename);
} else {
# Unsupported
$error = sprintf( Wx::gettext("Unsupported OS: %s"), '$^O' );
}
if ($error) {
$main->error($error);
}
return;
}
=head2 C<open_in_command_line>
Padre::Util::FileBrowser->open_in_command_line($filename);
Single shot method to open a command line/shell using the working
directory of C<$filename>
=cut
sub open_in_command_line {
my ( $class, $filename ) = @_;
my $self = $class->new(@_);
my $main = Padre::Current->main;
unless ($filename) {
$main->error( Wx::gettext("No filename") );
return;
}
my $error;
if (Padre::Constant::WIN32) {
# Win32
my $parent_folder = File::Basename::dirname($filename);
system( 1, 'cmd', '/C', 'start', '/D', qq{"$parent_folder"} );
} elsif (Padre::Constant::UNIX) {
# Unix
#TODO implement for UNIX
} else {
# Unsupported
$error = sprintf( Wx::gettext("Unsupported OS: %s"), '$^O' );
}
if ($error) {
$main->error($error);
}
return;
}
#
# private method for executing a process without waiting
#
sub _execute {
my ( $self, $exe_name, @cmd_args ) = @_;
my $result = undef;
require File::Which;
my $cmd = File::Which::which($exe_name);
if ( -e $cmd ) {
# On Windows, if we don't have STDIN/STDOUT, avoid IPC::Open3
# because it crashes when launching a non-console app
if (Padre::Constant::WIN32) {
# There is no actual waiting since cmd.exe starts explorer.exe and quits
require Padre::Util::Win32;
Padre::Util::Win32::ExecuteProcessAndWait(
directory => $self->{project},
file => 'cmd.exe',
parameters => "/C $cmd @cmd_args",
);
} else {
require IPC::Open2;
my $ok = eval {
my $r = '';
my $w = '';
my $pid = IPC::Open2::open2( $r, $w, $cmd, @cmd_args );
1;
};
if ( !$ok ) {
$result = $@;
}
}
} else {
$result = Wx::gettext("Failed to execute process\n");
}
return $result;
}
#
# Private method to execute a file in KDE or GNOME
#
sub _execute_unix {
die "Only to be called in UNIX!" unless Padre::Constant::UNIX;
my ( $self, $filename ) = @_;
my $error;
if ( defined $ENV{KDE_FULL_SESSION} ) {
# In KDE, execute: kfmclient exec $filename
$error = $self->_execute( 'kfmclient', "exec", $filename );
} elsif ( defined $ENV{GNOME_DESKTOP_SESSION_ID} ) {
# In Gnome, execute: nautilus --nodesktop --browser $filename
$error = $self->_execute( 'nautilus', "--no-desktop", "--browser", $filename );
} else {
$error = Wx::gettext("Could not find KDE or GNOME");
}
return $error;
}
1;
__END__
=pod
=head1 COPYRIGHT & LICENSE
Copyright 2008-2013 The Padre development team as listed in Padre.pm.
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
=cut
# Copyright 2008-2013 The Padre development team as listed in Padre.pm.
# LICENSE
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl 5 itself.