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 )