Source

Kephra / lib / Kephra / File.pm

use strict;
use warnings;
use File::Spec;
use Kephra::API;

package Kephra::File;

Kephra::API::Command::register({
 'file-new'        =>{sub=> 'new',          label=> 'New',        keys=> 'ctrl+n'},
 'file-open'       =>{sub=> 'open',         label=> 'Open ...',   keys=> 'ctrl+o'},
 'file-reopen'     =>{sub=> 'reopen_active',label=> 'Reopen',     keys=> 'ctrl+shift+o'},
 'file-save'       =>{sub=> 'save_active',  label=> 'Save',       keys=> 'ctrl+s'},
 'file-save-as'    =>{sub=> 'save_as',      label=> 'Save As ...',keys=> 'ctrl+shift+s'},
 'file-rename'     =>{sub=> 'rename',       label=> 'Rename ...', keys=> 'ctrl+alt+shift+s'},
 'file-close'      =>{sub=> 'close_active', label=> 'Close',      keys=> 'ctrl+q'},
 'file-close-other'=>{sub=> 'close_other',  label=> 'Close Other',keys=> 'ctrl+shift+q'},
 'file-close-all'  =>{sub=> 'close_all',    label=> 'Close All',  keys=> 'ctrl+alt+q'},
});

sub normalize_name {
	my $file = shift;
	return unless defined $file and $file;

	$file = File::Spec->canonpath($file);
	local $/ = "\r\n";
	chomp($file);
	return $file;
}


sub new  { Kephra::App::Part::Editor::create_document() }
sub open {
	# open dialog if no file was given
	$_[0] = Kephra::App::Dialog::get_file_open() unless @_;

	# new doc for each file name
	for my $file (@_){
		$file = normalize_name( $file );
		next unless $file and -e $file;

		# raise tab if doc is alread open
		Kephra::App::Part::Editor::raise_document($file), next
		  if Kephra::API::Docs::file_loaded($file);

		my $doc = Kephra::App::Part::Editor::create_document($file);
		next unless ref $doc eq 'Kephra::Document';
		my $file_content = _read_file( $doc, $file );
		$doc->editor->EmptyUndoBuffer;
	}
}
sub reopen {
	for my $doc (@_){
		next unless ref $doc eq 'Kephra::Document';
		Kephra::Log::warning("can't reopen nonexising file"), next
			unless $doc->file_path and -e $doc->file_path;
		_read_file( $doc );
	}
}
sub reopen_active { reopen( Kephra::API::document() ) }
sub reopen_all    { reopen( Kephra::API::all_documents()   ) }

sub _read_file {
	my $doc = shift;
	my $file = normalize_name( shift ) || $doc->file_path;
	return Kephra::Log::warning("can't load nonexising file") unless $file and -e $file;
	return Kephra::Log::warning("can't read $file") unless -r $file;
	my $ed = $doc->editor;
	CORE::open my $FH, '<', $file;
	binmode($FH);
	my $content = do { local $/; <$FH> };
	if ($content) {
		$ed->SetText( $content );
		$ed->SetSavePoint;
	}
}
sub _write_file {
	my $doc = shift;
	my $file = normalize_name( shift ) || $doc->file_path;
	return Kephra::Log::warning("need a file path") unless $file;
	return Kephra::Log::warning("can't overwrite $file") if -e $file and not -w $file;
	$doc->assign_file_path($file) unless $doc->file_path eq $file;
	my $ed = $doc->editor;
	CORE::open my $FH, '>', $file;
	print $FH $ed->GetText;
	$ed->SetSavePoint;
}

sub save {
	$_[0] = Kephra::API::document() unless @_;
	for my $doc (@_){
		next unless ref $doc eq 'Kephra::Document';
		next unless $doc->editor->GetModify;
		if ($doc->file_path){
			_write_file($doc);
		} else {
			$doc->raise;
			save_as($doc);
		}
	}
}
sub save_active { save( Kephra::API::document() ) }
sub save_all    { save( Kephra::API::all_documents() ) }
sub save_as {
	my $doc = shift || Kephra::API::document();
	my $file = normalize_name( Kephra::App::Dialog::get_file_save() );
	return unless $file;
	_write_file($doc, $file);
	$doc->assign_file_path($file);
	Kephra::API::docbar()->set_page_title( $doc->file_name);
	Kephra::API::main_window()->refresh_title();
}
sub rename {
	my $doc = shift || Kephra::API::document();
	my $old_file = $doc->file_name;
	save_as( $doc );
	unlink $old_file;
}


sub close {
	$_[0] = Kephra::API::document() unless @_;
	for my $doc (@_) {
		next unless ref $doc eq 'Kephra::Document';
		if ($doc->editor->GetModify) {
			my $save_answer = Kephra::App::Dialog::yes_no_cancel(
				'do you want to save it before?', 'close unsaved file'
			);
			next if $save_answer == &Wx::wxCANCEL;
			save($doc) if $save_answer == &Wx::wxYES;
		}
		Kephra::App::Part::Editor::remove_document( $doc );
	}
}
sub close_active { Kephra::File::close( Kephra::API::document() )}
sub close_all    { Kephra::File::close( Kephra::API::all_documents() ) }
sub close_other  {
	my $doc = Kephra::API::document();
	for (Kephra::API::all_documents()) { Kephra::File::close($_) unless $_ eq $doc }
}


1;
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.