Wrangler
view release on metacpan or search on metacpan
lib/Wrangler/Wx/FileBrowser.pm view on Meta::CPAN
## do the actual rename on storage
my $ok = $filebrowser->{wrangler}->{fs}->rename($oldpath, $newpath);
if($ok){
$filebrowser->RePopulate();
}else{
my $dialog = Wx::MessageDialog->new($filebrowser, "Error renaming (Rename, single) \"$oldpath\" to \"$newpath\": $!", "Renaming error", wxOK );
$dialog->ShowModal();
}
}
$dialog->Destroy();
}
}elsif($selCnt > 1){
# use a more sophisticated dialogue for multi-renames
require Wrangler::Wx::Dialog::MultiRename;
my $dialog = Wrangler::Wx::Dialog::MultiRename->new($filebrowser, $filebrowser->{our_stash}->{rename});
if($dialog->ShowModal() == wxID_OK){
if( $dialog->{pre}->IsModified || $dialog->{ins}->IsModified ){
Wrangler::debug("Prepend/append-rename was used ");
my $pre = $dialog->{pre}->GetValue();
my $ins = $dialog->{ins}->GetValue();
my @errors;
for(@{ $filebrowser->{our_stash}->{rename} }){
my $oldpath = $_->{richlist_item}->{'Filesystem::Path'};
my ($file, $dirs, $suffix) = $filebrowser->{wrangler}->{fs}->fileparse($oldpath, qr/\.[^.]*/);
my $newpath = $filebrowser->{wrangler}->{fs}->catfile( $filebrowser->{current_dir}, $pre.$file.$ins.$suffix);
Wrangler::debug("Rename: multi: $oldpath -> $newpath");
next if $oldpath eq $newpath;
## do the actual rename
my $ok = $filebrowser->{wrangler}->{fs}->rename($oldpath, $newpath);
push(@errors, "Error renaming (Rename, multiple) \"$oldpath\" to \"$newpath\": $!\n") unless $ok;
}
if(@errors){
my $dialog = Wx::MessageDialog->new($filebrowser, "@errors", "Renaming error", wxOK );
$dialog->ShowModal();
}else{
$filebrowser->RePopulate();
}
}elsif( $dialog->{pattern} && $dialog->{pattern}->IsModified ){
Wrangler::debug("Pattern-rename was used ");
my $multi = $dialog->{multi}->GetValue();
my $oldlen = $dialog->{length};
my $newlen = length($multi);
Wrangler::debug("MULTI: $multi OLDLEN: $oldlen NEWLEN:$newlen");
# todo
}
}else{
Wrangler::debug("Multiple rename CANCELd ");
}
# clear ourclipboard
undef($filebrowser->{our_stash});
}
}
sub ChangeProperty {
my $filebrowser = shift;
my $metakey = shift;
my $w = $filebrowser->{wrangler};
my $selections = $filebrowser->GetSelections_as_richlist_items();
my $selCnt = @$selections;
Wrangler::debug("FileBrowser: ChangeProperty: $selCnt items ");
return unless $selCnt;
my $dialog = Wx::TextEntryDialog->new($filebrowser, "New value for \"$metakey\":", "Change value of \"$metakey\"", $selections->[0]->{$metakey} );
return unless $dialog->ShowModal() == wxID_OK;
my $new_value = $dialog->GetValue();
$dialog->Destroy();
if($selCnt > 2){
my $text = "Are you sure you want to change the metadata value on $selCnt items?";
my $dialog = Wx::MessageDialog->new($filebrowser, "$text\nThis can't be undone!", $text, wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION );
unless($dialog->ShowModal() == wxID_YES){
Wrangler::debug("ChangeProperty canceled");
return;
}
}
my @errors;
for(@$selections){
Wrangler::debug("ChangeProperty: set_property($_->{'Filesystem::Path'}, $metakey, $new_value)");
my $ok = $filebrowser->{wrangler}->{fs}->set_property($_->{'Filesystem::Path'}, $metakey, $new_value);
push(@errors, "Error on set_property($_->{'Filesystem::Path'}, $metakey, $new_value)") unless $ok;
}
$filebrowser->RePopulate();
}
sub Delete {
my $filebrowser = shift;
my $really = shift || 0; # really means we don't move to Trash
my $w = $filebrowser->{wrangler};
my @selections = $filebrowser->GetSelections(); # docs: wxPerl note: In wxPerl this method takes no parameters and returns a list of Wx::TreeItemIds.
my $selCnt = @selections;
Wrangler::debug("FileBrowser: Delete(really=".$really."): $selCnt items ");
return if $selCnt == 0;
if($really && $filebrowser->{wrangler}->config()->{'ui.filebrowser.confirm.delete'}){
# confirm dialog
my $text = "Are you sure to permanently delete the selected $selCnt item(s)?"; # message grows/stretches the dialog horizontally, in caption/title it doesn't, so we use it twice
my $dialog = Wx::MessageDialog->new($filebrowser, "$text\nThis can't be undone!", $text, wxYES_NO | wxNO_DEFAULT | wxICON_EXCLAMATION );
unless($dialog->ShowModal() == wxID_YES){
Wrangler::debug("Delete canceled");
return;
}
lib/Wrangler/Wx/FileBrowser.pm view on Meta::CPAN
sub PasteSymlinks {
my $filebrowser = shift;
wxTheClipboard->Open();
my $fdo = Wx::FileDataObject->new();
my $ok = wxTheClipboard->GetData($fdo);
wxTheClipboard->Close();
Wrangler::debug("FileBrowser::PasteSymlinks: ok:$ok");
unless($ok){
my $dialog = Wx::MessageDialog->new($filebrowser, "The Clipboard doesn't hold files to paste as symlinks.", "Paste ...as symlinks", wxOK );
$dialog->ShowModal();
return;
}
for( $fdo->GetFilenames() ){
my $filepath = $_;
next if $filepath =~ /\.\.$/; # don't handle the up-dir!! todo: prevent that in UI
my ($name,$path) = $filebrowser->{wrangler}->{fs}->fileparse($filepath);
my $newpath = $filebrowser->{wrangler}->{fs}->catfile($filebrowser->{current_dir}, $name);
# figure out new name: append "_copy"
if( $filebrowser->{wrangler}->{fs}->test('e', $newpath) ){
for(1..10){
Wrangler::debug(" paste: copy/insert: newpath $newpath exists!");
$newpath .= '_copy';
last if ! $filebrowser->{wrangler}->{fs}->test('e', $newpath);
}
}
Wrangler::debug(" paste as symlink: $filepath -> $newpath");
my $ok = $filebrowser->{wrangler}->{fs}->symlink($filepath, $newpath);
Wrangler::debug("Error on paste as symlinks: $! ") unless $ok;
}
delete($filebrowser->{our_stash}->{cut}) if $filebrowser->{our_stash}->{cut};
$filebrowser->RePopulate();
}
sub PasteBitmap {
my $filebrowser = shift;
wxTheClipboard->Open();
my $bdo = Wx::BitmapDataObject->new();
my $ok = wxTheClipboard->GetData($bdo);
wxTheClipboard->Close();
Wrangler::debug("FileBrowser::PasteBitmap: ok:$ok");
unless($ok){
my $dialog = Wx::MessageDialog->new($filebrowser, "The Clipboard doesn't hold bitmap data to paste.", "Paste ...as image", wxOK );
$dialog->ShowModal();
return;
}
my $dialog = Wx::FileDialog->new($filebrowser, "Choose a filename and directory", $filebrowser->{current_dir}, 'clipboard.png', "*.*", wxFD_SAVE|wxFD_OVERWRITE_PROMPT );
return unless $dialog->ShowModal() == wxID_OK;
my $path = $dialog->GetPath();
my $type = $path =~ /\.jpg$/ ? wxBITMAP_TYPE_JPEG : wxBITMAP_TYPE_PNG;
$ok = $bdo->GetBitmap()->SaveFile($path, $type);
unless($ok){
my $error = "PasteBitmap: can't write clipboard's bitmap-data to file: $!";
Wrangler::debug($error);
my $dialog = Wx::MessageDialog->new($filebrowser, $error, "Error on Paste ...as image", wxOK );
$dialog->ShowModal();
return;
}
$filebrowser->RePopulate();
}
sub Todo {
my $filebrowser = shift;
my $dialog = Wx::MessageDialog->new($filebrowser, "Not yet implemented", "Not yet implemented", wxOK );
$dialog->ShowModal();
}
sub OnRightClick {
my $filebrowser = shift;
my $event = shift;
my $selections = $filebrowser->GetSelections_as_richlist_items();
my $menu = Wx::Menu->new();
my ($colId,$col_value_from) = $filebrowser->GetColumn($event);
if(@$selections){
## hardcoded file context menu entries
EVT_MENU( $filebrowser, $menu->Append(-1, "View\tENTER", 'Execute/view with viewer'), sub { $filebrowser->OnActivated } );
EVT_MENU( $filebrowser, $menu->Append(-1, "View/open with...", 'Select default viewer/application/command for this mime-type'), sub { Wrangler::PubSub::publish('show.settings', 1, 3); } );
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Cut\tCTRL+X", 'Cut' ), sub { $filebrowser->Cut(); } );
EVT_MENU( $filebrowser, $menu->Append(-1, "Copy\tCTRL+C", 'Copy' ), sub { $filebrowser->Copy(); } );
my $itemPaste = Wx::MenuItem->new($menu, -1, "Paste\tCTRL+V", 'Paste');
$menu->Append($itemPaste);
if(0){ # todo: check: we have something in the clipboard AND selection is 1 dir -> "integrate into folder"
$menu->Enable($itemPaste->GetId(),1);
EVT_MENU( $filebrowser, $itemPaste, sub { $filebrowser->Todo(); } );
}else{
$menu->Enable($itemPaste->GetId(),0);
}
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Rename\tF2", 'Rename file' ), sub { $filebrowser->Rename(); } );
unless($col_value_from eq 'Filesystem::Filename'){
my $itemChange = Wx::MenuItem->new($menu, -1, "Change '$col_value_from'", "Change '$col_value_from'");
$menu->Append($itemChange);
if( $filebrowser->{wrangler}->{fs}->can_mod($col_value_from) ){
$menu->Enable($itemChange->GetId(),1);
EVT_MENU( $filebrowser, $itemChange, sub { $filebrowser->ChangeProperty($col_value_from); } );
}else{
$menu->Enable($itemChange->GetId(),0);
}
}
EVT_MENU( $filebrowser, $menu->Append(-1, "Create directory", 'Create a directory' ), sub { $filebrowser->Mkdir(); } );
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Move to trash\tDEL", 'Move a file to trash' ), sub { $filebrowser->Delete(); } );
EVT_MENU( $filebrowser, $menu->Append(-1, "Delete\tCTRL+DEL", 'Really delete a file or directory' ), sub { $filebrowser->Delete(1); } ) if $filebrowser->{wrangler}->config()->{'ui.filebrowser.offer.delete'};
## plugin file context menu entries
if( my $plugins_ref = Wrangler::PluginManager::plugins('file_context_menu') ){
for my $plugin (@$plugins_ref){
if( my $plugin_menu_entries = $plugin->file_context_menu($menu,$selections) ){
$menu->AppendSeparator();
for my $entry ( @$plugin_menu_entries ){
next unless ref($entry) eq 'ARRAY' && ref(${$entry}[0]) eq 'Wx::MenuItem' && ref(${$entry}[1]) eq 'CODE';
EVT_MENU( $filebrowser, $menu->Append( ${$entry}[0] ), ${$entry}[1] );
&{ ${$entry}[2] } if ${$entry}[2];
}
}
}
}
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Properties", 'Show details about current selection' ), sub {
require Wrangler::Wx::Dialog::Properties;
my $selections = $filebrowser->GetSelections_as_richlist_items();
my $dialog = Wrangler::Wx::Dialog::Properties->new($filebrowser,$selections);
$dialog->ShowModal();
$dialog->Destroy();
});
}else{
## hardcoded folder context menu entries
EVT_MENU( $filebrowser, $menu->Append(-1, "New folder", 'Create a folder' ), sub { $filebrowser->Mkdir(); } );
EVT_MENU( $filebrowser, $menu->Append(-1, "New file", 'Create a file/node' ), sub { $filebrowser->Mknod(); } );
$menu->AppendSeparator();
my $itemPaste = Wx::MenuItem->new($menu, -1, "Paste\tCTRL+V", 'Paste');
my $itemPasteSymlinks = Wx::MenuItem->new($menu, -1, "Paste ...as symlink(s)", 'Paste files on the clipboard as symlinks');
my $itemPasteBitmap = Wx::MenuItem->new($menu, -1, "Paste ...as image", 'Paste clipboard contents as image file');
$menu->Append($itemPaste);
$menu->Append($itemPasteSymlinks);
$menu->Append($itemPasteBitmap);
if(1){ # as it seems, it's safe to assume there's always something in the clipboard
$menu->Enable($itemPaste->GetId(),1);
EVT_MENU( $filebrowser, $itemPaste, sub { $filebrowser->Paste(); } );
$menu->Enable($itemPasteSymlinks->GetId(),1);
EVT_MENU( $filebrowser, $itemPasteSymlinks, sub { $filebrowser->PasteSymlinks(); } );
$menu->Enable($itemPasteBitmap->GetId(),1);
EVT_MENU( $filebrowser, $itemPasteBitmap, sub { $filebrowser->PasteBitmap(); } );
}else{
$menu->Enable($itemPaste->GetId(),0);
}
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Zoom in\tCTRL++", 'Zoom in'), sub { Wrangler::PubSub::publish('zoom.in'); } );
EVT_MENU( $filebrowser, $menu->Append(-1, "Zoom standard\tCTRL+0", 'Zoom standard'), sub { Wrangler::PubSub::publish('zoom.standard'); } );
EVT_MENU( $filebrowser, $menu->Append(-1, "Zoom out\tCTRL+-", 'Zoom out'), sub { Wrangler::PubSub::publish('zoom.out'); } );
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Export listing as text", ''), sub {
require Wrangler::Wx::Dialog::ListingToText;
Wrangler::Wx::Dialog::ListingToText->new($filebrowser);
});
$menu->AppendSeparator();
EVT_MENU( $filebrowser, $menu->Append(-1, "Settings", 'Settings'), sub { Wrangler::PubSub::publish('show.settings', 1, 0); } );
}
$filebrowser->PopupMenu( $menu, wxDefaultPosition ); # alt: $event->GetPosition
}
sub OnChar {
my ($filebrowser, $event) = @_;
my $keycode = $event->GetKeyCode(); # speedup by less calls
Wrangler::debug("OnChar: $keycode");
# more or less ordered by probability
if($keycode == 22 && $event->ControlDown() ){
Wrangler::debug("CTRL+V: Paste/Insert");
$filebrowser->Paste();
}elsif($keycode == 24 && $event->ControlDown() ){
Wrangler::debug("CTRL+X: Cut");
$filebrowser->Cut();
}elsif($keycode == 3 && $event->ControlDown() ){
Wrangler::debug("CTRL+C: Copy");
$filebrowser->Copy();
}elsif($keycode == WXK_ESCAPE){
# if($filebrowser->{in_viewmode}){
# Wrangler::debug("ESC: Filebrowser is viewing: so close Viewer.");
# # $filebrowser->{viewer}->Close();
# # $filebrowser->Show(1);
# }else{
Wrangler::debug("ESC: Deselect all");
$filebrowser->DeselectAll();
# }
}elsif($keycode == WXK_F2){
Wrangler::debug("F2: Rename");
$filebrowser->Rename();
}elsif($keycode == WXK_DELETE){
Wrangler::debug("Delete");
$event->ControlDown() ? $filebrowser->Delete('really') : $filebrowser->Delete();
}elsif($keycode == 1 && $event->ControlDown() ){
( run in 0.341 second using v1.01-cache-2.11-cpan-81fc1098f69 )