Select printer feature added.

This commit is contained in:
Sergiotarxz 2024-10-15 22:08:08 +02:00
parent 4bd58e1763
commit abed9853f9
4 changed files with 196 additions and 19 deletions

View File

@ -23,6 +23,10 @@ has port => (
required => 1,
);
has name => (
is => 'ro',
);
has _guts_device => ( is => 'rw' );
has _tempdir => ( is => 'rw', );
@ -95,6 +99,9 @@ sub serialize($self) {
my $hash = {};
$hash->{address} = $self->address;
$hash->{port} = $self->port;
if (defined $self->name) {
$hash->{name} = $self->name;
}
$hash->{type} = 'bluetooth';
return $hash;
}

View File

@ -28,15 +28,30 @@ sub _build__guts_device($self) {
}
sub image( $self, $image ) {
$self->_guts_device->printer->image($image);
eval {
$self->_guts_device->printer->image($image);
};
if ($@) {
die 'Unable to write to file does ' . $self->output_file . " exist?, error: $@.";
}
}
sub lf($self) {
$self->_guts_device->printer->lf;
eval {
$self->_guts_device->printer->lf;
};
if ($@) {
die 'Unable to write to file does ' . $self->output_file . " exist?, error: $@.";
}
}
sub print($self) {
$self->_guts_device->printer->print;
eval {
$self->_guts_device->printer->print;
};
if ($@) {
die 'Unable to write to file, does ' . $self->output_file . " exist?, error: $@.";
}
}
sub serialize($self) {

View File

@ -21,6 +21,7 @@ use Capture::Tiny qw/capture/;
use Exd::Printer;
use Exd::DeviceToBluetooth;
use Exd::DeviceToImage;
use Exd::Gui::PrinterConfigure;
use JSON;
@ -44,7 +45,7 @@ Glib::Object::Introspection->setup(
has _app => ( is => 'rw', );
has _win => ( is => 'rw', );
has window => ( is => 'rw', );
has _scroll_log_upper => ( is => 'rw', );
has _execute_log => ( is => 'rw', );
@ -59,6 +60,7 @@ has _read_from_script => ( is => 'rw' );
has _read_from_parent => ( is => 'rw' );
has _write_to_parent => ( is => 'rw' );
has _write_to_script => ( is => 'rw' );
has device => (is => 'rw');
sub _tempdir_previews($self) {
if ( !defined $self->_tempdir_previews_guts ) {
@ -106,10 +108,8 @@ sub _run_script( $self, $device = undef, $verbose = 1 ) {
my $end_iter = $buffer->get_end_iter;
my $script = $buffer->get_text( $begin_iter, $end_iter, 0 );
if ( !defined $device ) {
$device = Exd::DeviceToBluetooth->new(
address => '5A:4A:AE:8C:E9:D2',
port => 1
);
$self->add_to_log('You have to select a printer.');
return;
}
local $| = 1;
my $fh = $self->_write_to_script;
@ -146,7 +146,7 @@ sub _daemon_script_runner($self) {
my $data = JSON::from_json($line);
my ( $script, $device, $verbose ) =
$data->@{ 'script', 'device', 'verbose' };
$device = $self->_device_hash_to_object($device);
$device = $self->device_hash_to_object($device);
if ( $last_pid
&& $last_device->isa('Exd::DeviceToImage')
&& !$verbose )
@ -173,7 +173,7 @@ sub _daemon_script_runner($self) {
close $write_to_parent;
}
sub _device_hash_to_object( $self, $device_hash ) {
sub device_hash_to_object( $self, $device_hash ) {
my $type = delete $device_hash->{type};
my %dispatch_table = (
image => sub {
@ -225,13 +225,8 @@ sub _on_run_script( $self, $script, $device, $write_to_parent, $verbose = 1 ) {
sub _monitor_run($self) {
my @fhs = $self->_select->can_read(0);
for my $fh (@fhs) {
my $execute_log = $self->_execute_log;
my $buffer = $execute_log->get_buffer;
my $begin_iter = $buffer->get_iter_at_offset(0);
my $end_iter = $buffer->get_end_iter;
my $text = '';
$fh->blocking(0);
my $text = '';
while (my $line = <$fh>) {
if (!defined $line) {
next;
@ -239,10 +234,18 @@ sub _monitor_run($self) {
$text .= $line;
}
return if $text =~ /^\s*$/;
$buffer->insert( $end_iter, $text, -1 );
$self->add_to_log($text);
}
}
sub add_to_log($self, $text) {
my $execute_log = $self->_execute_log;
my $buffer = $execute_log->get_buffer;
my $end_iter = $buffer->get_end_iter;
$buffer->insert( $end_iter, $text, -1 );
}
sub _build__select($self) {
return IO::Select->new;
}
@ -333,11 +336,18 @@ sub _activate($self) {
);
my $app = $self->_app;
my $win = Gtk4::ApplicationWindow->new($app);
$self->_win($win);
$self->window($win);
my $box_vertical = Gtk4::Box->new( 'vertical', 10 );
my $execute_log = Gtk4::TextView->new;
my $run_button = Gtk4::Button->new_with_label('Run');
my $preview_button = Gtk4::Button->new_with_label('Preview');
my $select_printer = Gtk4::Button->new_with_label('Select Printer');
$select_printer->signal_connect(
'clicked',
sub {
Exd::Gui::PrinterConfigure->new(app => $self)->start;
}
);
$preview_button->signal_connect(
'clicked',
sub {
@ -348,7 +358,7 @@ sub _activate($self) {
$run_button->signal_connect(
clicked => sub {
$self->_run_script( undef, 1 );
$self->_run_script( $self->device, 1 );
}
);
@ -366,6 +376,7 @@ sub _activate($self) {
my $box_buttons = Gtk4::Box->new( 'horizontal', 10 );
$box_buttons->append($run_button);
$box_buttons->append($preview_button);
$box_buttons->append($select_printer);
$self->_populate_editor_and_preview($box_vertical);
$box_vertical->append($box_buttons);
my $execute_log_window = Gtk4::ScrolledWindow->new;

View File

@ -0,0 +1,144 @@
package Exd::Gui::PrinterConfigure;
use v5.40.0;
use strict;
use warnings;
use Moo;
use Glib;
use Glib::IO;
use Glib::Object::Introspection;
use JSON;
use Net::Bluetooth qw//;
has app => (is => 'ro', required => 1);
has _pid_daemon => (is => 'rw');
has _read_from_daemon => (is => 'rw');
has _write_to_app => (is => 'rw');
has _select => ( is => 'lazy', );
has _window => ( is => 'rw' );
has _bluetooth_printers => ( is => 'rw', default => sub { [] } );
has _usb_printers => ( is => 'rw', default => sub { [] });
my $cache;
sub _build__select($self) {
return IO::Select->new;
}
sub _read_bluetooth_printers($self) {
my @fhs = $self->_select->can_read(0);
if (scalar @fhs == 0) {
}
for my $fh (@fhs) {
$fh->blocking(0);
while (my $line = <$fh>) {
my @return = map {$self->app->device_hash_to_object($_)} @{JSON::from_json($line)};
$self->_bluetooth_printers(\@return);
}
}
}
sub _usb_printer_print_to_box($self, $device, $box) {
my $window = $self->_window;
my $button = Gtk4::Button->new_with_label($device->output_file);
$button->signal_connect('clicked', sub {
$self->app->device($device);
$window->close;
});
$box->append($button);
}
sub _bluetoth_printer_print_to_box($self, $device, $box) {
my $window = $self->_window;
my $button = Gtk4::Button->new_with_label($device->name.':'.$device->address);
$button->signal_connect('clicked', sub {
$self->app->device($device);
$window->close;
});
$box->append($button);
}
sub _read_usb_printers($self) {
my @printers = map { Exd::DeviceToRawFile->new(output_file => $_) } glob '/dev/usb/lp*';
$self->_usb_printers(\@printers);
}
sub start($self) {
$self->_start_daemon_bluetooth_search;
my $parent_window = $self->app->window;
my $window = Gtk4::Window->new;
$self->_window($window);
$window->set_default_size( 600, 600 );
$window->signal_connect('close-request', sub{
$self->_on_close;
return 0;
});
$window->set_title('Printer Selection');
$window->set_child(Gtk4::Label->new('Searching for printers...'));
$self->_select->add($self->_read_from_daemon);
Glib::Timeout->add(1000, sub {
eval {
$self->_read_usb_printers;
$self->_read_bluetooth_printers;
$self->_update_box;
};
return 1;
});
$window->present;
}
sub _update_box($self) {
my $window = $self->_window;
my $box = Gtk4::Box->new( 'vertical', 10 );
for my $device ($self->_bluetooth_printers->@*) {
$self->_bluetoth_printer_print_to_box($device, $box);
}
for my $device ($self->_usb_printers->@*) {
$self->_usb_printer_print_to_box($device, $box);
}
$window->set_child($box);
}
sub _start_daemon_bluetooth_search($self) {
my ($read, $write);
pipe $read, $write;
$self->_read_from_daemon($read);
$self->_write_to_app($write);
my $pid = fork;
if (!$pid) {
close $read;
while (1) {
$self->_daemon_bluetooth_search_iteration;
}
exit 0;
}
close $write;
$self->_pid_daemon($pid);
}
sub _daemon_bluetooth_search_iteration($self) {
say 'Listing bluetooth devices';
my $devices = Net::Bluetooth::get_remote_devices;
my @return;
for my $address (keys %$devices) {
say "Detected $devices->{$address}:$address, looking if it supports Serial Port...";
my $search = Net::Bluetooth::sdp_search($address, "1101", "");
if (defined $search && defined $search->{RFCOMM}) {
say "$devices->{$address}:$address supports Serial Port and may be a printer, the port is: $search->{RFCOMM}";
push @return, Exd::DeviceToBluetooth->new(name => $devices->{$address}, address => $address, port => $search->{RFCOMM});
}
}
@return = map { $_->serialize } sort { $a->name cmp $b->name } @return;
$self->_write_to_app->print(JSON::to_json(\@return));
$self->_write_to_app->flush;
}
sub _on_close($self) {
kill 'TERM', $self->_pid_daemon;
waitpid $self->_pid_daemon, 0;
say 'Finished printer select daemon';
}
1;