Adding cache directories open and save.
This commit is contained in:
parent
b92d4a34c2
commit
e91251b33a
1
Build.PL
1
Build.PL
@ -15,6 +15,7 @@ my $build = Module::Build->new(
|
|||||||
'DBD::SQLite' => 0,
|
'DBD::SQLite' => 0,
|
||||||
'DBI' => 0,
|
'DBI' => 0,
|
||||||
'File::HomeDir' => 0,
|
'File::HomeDir' => 0,
|
||||||
|
'Moo' => 0,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
$build->create_build_script;
|
$build->create_build_script;
|
||||||
|
22
lib/GEmeTool/Config.pm
Normal file
22
lib/GEmeTool/Config.pm
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package GEmeTool::Config;
|
||||||
|
|
||||||
|
use v5.16.3;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Moo;
|
||||||
|
use File::HomeDir;
|
||||||
|
use Path::Tiny;
|
||||||
|
|
||||||
|
my $dist = 'GEmeTool';
|
||||||
|
|
||||||
|
sub config_dir {
|
||||||
|
my $class = shift;
|
||||||
|
return path(File::HomeDir->my_dist_config($dist, { create => 1 }));
|
||||||
|
}
|
||||||
|
sub data_dir {
|
||||||
|
my $class = shift;
|
||||||
|
return path(File::HomeDir->my_dist_data($dist, { create => 1 }));
|
||||||
|
}
|
||||||
|
1;
|
96
lib/GEmeTool/DB.pm
Normal file
96
lib/GEmeTool/DB.pm
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
package GEmeTool::DB;
|
||||||
|
|
||||||
|
use v5.16.3;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use DBI;
|
||||||
|
use DBD::SQLite;
|
||||||
|
use DBD::SQLite::Constants qw/:all/;
|
||||||
|
|
||||||
|
use GEmeTool::DB::Migrations;
|
||||||
|
use GEmeTool::Config;
|
||||||
|
|
||||||
|
my $dbh;
|
||||||
|
|
||||||
|
sub connect {
|
||||||
|
if ( defined $dbh ) {
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
my $class = shift;
|
||||||
|
my $app = shift;
|
||||||
|
my $data_dir = GEmeTool::Config->new->data_dir;
|
||||||
|
say $data_dir;
|
||||||
|
$dbh = DBI->connect(
|
||||||
|
"dbi:SQLite:dbname=@{[$data_dir->child('gemetool.sqlite')]}",
|
||||||
|
undef, undef,
|
||||||
|
{
|
||||||
|
RaiseError => 1,
|
||||||
|
sqlite_string_mode => DBD_SQLITE_STRING_MODE_UNICODE_STRICT,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
$class->_migrate($dbh);
|
||||||
|
return $dbh;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _migrate {
|
||||||
|
my $class = shift;
|
||||||
|
my $dbh = shift;
|
||||||
|
local $dbh->{RaiseError} = 0;
|
||||||
|
local $dbh->{PrintError} = 0;
|
||||||
|
my @migrations = GEmeTool::DB::Migrations::MIGRATIONS();
|
||||||
|
if ( $class->get_current_migration($dbh) > @migrations ) {
|
||||||
|
warn "Something happened there, wrong migration number.";
|
||||||
|
}
|
||||||
|
if ( $class->get_current_migration($dbh) >= @migrations ) {
|
||||||
|
say STDERR "Migrations already applied.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$class->_apply_migrations( $dbh, \@migrations );
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _apply_migrations {
|
||||||
|
my $class = shift;
|
||||||
|
my $dbh = shift;
|
||||||
|
my $migrations = shift;
|
||||||
|
for (
|
||||||
|
my $i = $class->get_current_migration($dbh) ;
|
||||||
|
$i < @$migrations ;
|
||||||
|
$i++
|
||||||
|
)
|
||||||
|
{
|
||||||
|
local $dbh->{RaiseError} = 1;
|
||||||
|
my $current_migration = $migrations->[$i];
|
||||||
|
my $migration_number = $i + 1;
|
||||||
|
$class->_apply_migration( $dbh, $current_migration, $migration_number );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _apply_migration {
|
||||||
|
my $class = shift;
|
||||||
|
my $dbh = shift;
|
||||||
|
my $current_migration = shift;
|
||||||
|
my $migration_number = shift;
|
||||||
|
{
|
||||||
|
if (ref $current_migration eq 'CODE') {
|
||||||
|
$current_migration->($dbh);
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
$dbh->do($current_migration);
|
||||||
|
}
|
||||||
|
$dbh->do( <<'EOF', undef, 'current_migration', $migration_number );
|
||||||
|
INSERT OR REPLACE INTO options
|
||||||
|
VALUES ($1, $2);
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_current_migration {
|
||||||
|
my $class = shift;
|
||||||
|
my $dbh = shift;
|
||||||
|
my $result = $dbh->selectrow_hashref( <<'EOF', undef, 'current_migration' );
|
||||||
|
select value from options where name = ?;
|
||||||
|
EOF
|
||||||
|
return int( $result->{value} // 0 );
|
||||||
|
}
|
||||||
|
1;
|
19
lib/GEmeTool/DB/Migrations.pm
Normal file
19
lib/GEmeTool/DB/Migrations.pm
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package GEmeTool::DB::Migrations;
|
||||||
|
|
||||||
|
use v5.16.3;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
use utf8;
|
||||||
|
|
||||||
|
use feature 'signatures';
|
||||||
|
|
||||||
|
sub MIGRATIONS {
|
||||||
|
return (
|
||||||
|
'CREATE TABLE options (
|
||||||
|
name TEXT PRIMARY KEY,
|
||||||
|
value TEXT
|
||||||
|
)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
1;
|
65
lib/GEmeTool/Options.pm
Normal file
65
lib/GEmeTool/Options.pm
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package GEmeTool::Options;
|
||||||
|
|
||||||
|
use v5.16.3;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Moo;
|
||||||
|
use GEmeTool::DB;
|
||||||
|
|
||||||
|
my $db = GEmeTool::DB->connect;
|
||||||
|
|
||||||
|
my $query_get_option = <<'EOF';
|
||||||
|
SELECT value
|
||||||
|
FROM options
|
||||||
|
WHERE name = ?;
|
||||||
|
EOF
|
||||||
|
|
||||||
|
my $query_replace_option = <<'EOF';
|
||||||
|
INSERT OR REPLACE
|
||||||
|
INTO options (name, value)
|
||||||
|
VALUES (?, ?);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sub _get_option_value {
|
||||||
|
my $self = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $result = $db->selectrow_hashref($query_get_option, {}, $name);
|
||||||
|
if (!defined $result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return $result->{value};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _set_option_value {
|
||||||
|
my $self = shift;
|
||||||
|
my $name = shift;
|
||||||
|
my $value = shift;
|
||||||
|
return $db->do($query_replace_option, {}, $name, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_last_dir_open {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->_get_option_value('last_dir_open');
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_last_dir_open {
|
||||||
|
my $self = shift;
|
||||||
|
my $value = shift;
|
||||||
|
die '$value must be defined' if !defined $value;
|
||||||
|
return $self->_set_option_value('last_dir_open', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub get_last_dir_save {
|
||||||
|
my $self = shift;
|
||||||
|
return $self->_get_option_value('last_dir_save') // $self->get_last_dir_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub set_last_dir_save {
|
||||||
|
my $self = shift;
|
||||||
|
my $value = shift;
|
||||||
|
die '$value must be defined' if !defined $value;
|
||||||
|
return $self->_set_option_value('last_dir_save', $value);
|
||||||
|
}
|
||||||
|
1;
|
@ -10,6 +10,7 @@ use Glib::IO;
|
|||||||
use Glib::Object::Introspection;
|
use Glib::Object::Introspection;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
use Path::Tiny;
|
use Path::Tiny;
|
||||||
|
use GEmeTool::Options;
|
||||||
use utf8;
|
use utf8;
|
||||||
|
|
||||||
use Rsaves
|
use Rsaves
|
||||||
@ -34,6 +35,7 @@ Glib::Object::Introspection->setup(
|
|||||||
my %rematches = @Rsaves::Constants::Emerald::Rematches::REMATCHES;
|
my %rematches = @Rsaves::Constants::Emerald::Rematches::REMATCHES;
|
||||||
|
|
||||||
my $app = Gtk4::Application->new( 'tech.owlcode.GEmeTool', 'default-flags' );
|
my $app = Gtk4::Application->new( 'tech.owlcode.GEmeTool', 'default-flags' );
|
||||||
|
my $options = GEmeTool::Options->new;
|
||||||
$app->signal_connect( activate => \&activate );
|
$app->signal_connect( activate => \&activate );
|
||||||
$app->run;
|
$app->run;
|
||||||
|
|
||||||
@ -98,12 +100,12 @@ sub activate_open {
|
|||||||
my $extra = shift;
|
my $extra = shift;
|
||||||
my $save_as = shift;
|
my $save_as = shift;
|
||||||
my $cancellable = Glib::IO::Cancellable->new;
|
my $cancellable = Glib::IO::Cancellable->new;
|
||||||
$cancellable->signal_connect(cancelled => sub {
|
|
||||||
say 'cancelled';
|
|
||||||
});
|
|
||||||
my $dialog = Gtk4::FileDialog->new;
|
my $dialog = Gtk4::FileDialog->new;
|
||||||
my $curdir = Glib::IO::File::new_for_path('.');
|
my $last_dir = $options->get_last_dir_open;
|
||||||
$dialog->set_initial_folder($curdir);
|
if (defined $last_dir && -d $last_dir) {
|
||||||
|
my $curdir = Glib::IO::File::new_for_path($last_dir);
|
||||||
|
$dialog->set_initial_folder($curdir);
|
||||||
|
}
|
||||||
$dialog->open(
|
$dialog->open(
|
||||||
$win, $cancellable,
|
$win, $cancellable,
|
||||||
sub {
|
sub {
|
||||||
@ -114,6 +116,7 @@ sub activate_open {
|
|||||||
my $file = $dialog->open_finish($res);
|
my $file = $dialog->open_finish($res);
|
||||||
return if !defined $file;
|
return if !defined $file;
|
||||||
$file = path( $file->get_path );
|
$file = path( $file->get_path );
|
||||||
|
$options->set_last_dir_open($file->parent.'');
|
||||||
start_editing_file( $win, $file, $saves, $extra, $save_as );
|
start_editing_file( $win, $file, $saves, $extra, $save_as );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -124,18 +127,22 @@ sub activate_save {
|
|||||||
my $saves = shift;
|
my $saves = shift;
|
||||||
my $extra = shift;
|
my $extra = shift;
|
||||||
my $dialog = Gtk4::FileDialog->new;
|
my $dialog = Gtk4::FileDialog->new;
|
||||||
my $curdir = Glib::IO::File::new_for_path('.');
|
my $last_dir = $options->get_last_dir_save;
|
||||||
$dialog->set_initial_folder($curdir);
|
if (defined $last_dir && -d $last_dir) {
|
||||||
$dialog->open(
|
my $curdir = Glib::IO::File::new_for_path($last_dir);
|
||||||
|
$dialog->set_initial_folder($curdir);
|
||||||
|
}
|
||||||
|
$dialog->save(
|
||||||
$win, undef,
|
$win, undef,
|
||||||
sub {
|
sub {
|
||||||
my ( $self, $res ) = @_;
|
my ( $self, $res ) = @_;
|
||||||
if ($res->had_error) {
|
if ($res->had_error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
my $file = $dialog->open_finish($res);
|
my $file = $dialog->save_finish($res);
|
||||||
return if !defined $file;
|
return if !defined $file;
|
||||||
$file = path( $file->get_path );
|
$file = path( $file->get_path );
|
||||||
|
$options->set_last_dir_save($file->parent.'');
|
||||||
save( $file, $saves, $extra );
|
save( $file, $saves, $extra );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user