Select printer feature added.
This commit is contained in:
parent
4bd58e1763
commit
abed9853f9
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
Loading…
Reference in New Issue