App-Chart
view release on metacpan or search on metacpan
lib/App/Chart/Gtk2/DownloadDialog.pm view on Meta::CPAN
# Copyright 2007, 2008, 2009, 2010, 2011 Kevin Ryde
# This file is part of Chart.
#
# Chart is free software; you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation; either version 3, or (at your option) any later version.
#
# Chart is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with Chart. If not, see <http://www.gnu.org/licenses/>.
package App::Chart::Gtk2::DownloadDialog;
use 5.010;
use strict;
use warnings;
use Glib::Ex::SignalIds;
use Gtk2 1.220;
use Gtk2::Ex::Units;
use Locale::TextDomain ('App-Chart');
use Regexp::Common 'whitespace';
use App::Chart::Glib::Ex::MoreUtils;
use App::Chart;
use App::Chart::Gtk2::GUI;
use App::Chart::Gtk2::Job;
use App::Chart::Gtk2::JobQueue;
use App::Chart::Gtk2::Subprocess;
# uncomment this to run the ### lines
#use Smart::Comments;
use base 'App::Chart::Gtk2::Ex::ToplevelSingleton';
use Glib::Object::Subclass
'Gtk2::Dialog',
signals => { destroy => \&_do_destroy };
use constant { RESPONSE_START => 0,
RESPONSE_STOP => 1,
RESPONSE_CLEAR => 2 };
use constant { WHEN_UPDATE => 0,
WHEN_BACKTO => 1 };
sub popup {
my ($class, $symbol, $parent) = @_;
require App::Chart::Gtk2::Ex::ToplevelBits;
my $dialog = App::Chart::Gtk2::Ex::ToplevelBits::popup
($class,
hide_on_delete => 1,
screen => $parent);
if (defined $symbol) {
$dialog->{'entry'}->set_text($symbol);
}
return $dialog;
}
sub popup_update {
my ($class, $symbol, $parent) = @_;
my $dialog = $class->popup ($symbol, $parent);
$dialog->start ($symbol, undef);
$dialog->{'hide_on_success'} = 1;
return $dialog;
}
sub INIT_INSTANCE {
my ($self) = @_;
$self->set_title (__('Chart: Download'));
$self->add_buttons (__('_Start') => RESPONSE_START,
__('_Stop') => RESPONSE_STOP,
'gtk-clear' => RESPONSE_CLEAR,
'gtk-close' => 'close',
'gtk-help' => 'help');
$self->signal_connect (response => \&_do_response);
my $vbox = $self->vbox;
my $renderer = Gtk2::CellRendererText->new;
$renderer->set (xalign => 0,
ypad => 0);
{ my $label = Gtk2::Label->new (__('Subprocesses'));
$label->set (xalign => 0);
$vbox->pack_start ($label, 0,0,0);
}
my $proc_scrolled = Gtk2::ScrolledWindow->new;
$proc_scrolled->set (hscrollbar_policy => 'automatic',
vscrollbar_policy => 'automatic');
$vbox->pack_start ($proc_scrolled, 1,1,0);
{
require App::Chart::Gtk2::Subprocess;
my $treeview = $self->{'proc_treeview'}
= Gtk2::TreeView->new_with_model ($App::Chart::Gtk2::Subprocess::store);
$treeview->set (headers_visible => 0,
reorderable => 1);
$proc_scrolled->add ($treeview);
$treeview->add_events ('button-press-mask');
$treeview->signal_connect
(button_press_event => \&_do_proc_treeview_button_press, $self);
{
my $column = Gtk2::TreeViewColumn->new;
$column->pack_start ($renderer, 1);
$column->set_cell_data_func ($renderer, \&_proc_cell_status);
$treeview->append_column ($column);
}
}
{ my $label = Gtk2::Label->new (__('Jobs'));
$label->set (xalign => 0);
$vbox->pack_start ($label, 0,0,0);
}
my $model = $self->{'model'} = App::Chart::Gtk2::JobQueue->instance;
$self->{'model_ids'} = Glib::Ex::SignalIds->new
($model,
$model->signal_connect (row_changed => \&_do_job_row_changed, $self));
lib/App/Chart/Gtk2/DownloadDialog.pm view on Meta::CPAN
$self->_do_start_button;
} elsif ($response eq RESPONSE_STOP) {
my $treeview = $self->{'jobs_treeview'};
my $selection = $treeview->get_selection;
my ($model, $iter) = $selection->get_selected;
my $job = $model->get_value ($iter, 0);
$job->stop;
} elsif ($response eq RESPONSE_CLEAR) {
my $textbuf = $self->{'textbuf'};
$textbuf->delete ($textbuf->get_start_iter, $textbuf->get_end_iter);
if (App::Chart::Gtk2::JobQueue->can('remove_done')) { # if loaded
App::Chart::Gtk2::JobQueue->remove_done;
}
if (App::Chart::Gtk2::Subprocess->can('remove_done')) { # if loaded
App::Chart::Gtk2::Subprocess->remove_done;
}
} elsif ($response eq 'close') {
# as per a keyboard close, defaults to raising 'delete-event', which in
# turn defaults to a destroy
$self->signal_emit ('close');
} elsif ($response eq 'help') {
require App::Chart::Manual;
App::Chart::Manual->open(__p('manual-node','Download'), $self);
}
}
sub _update_stop_sensitive {
my ($self) = @_;
my $treeview = $self->{'jobs_treeview'};
my $selection = $treeview->get_selection;
my ($model, $iter) = $selection->get_selected;
my $job = $iter && $model->get_value ($iter, 0);
my $sensitive = $job && $job->is_stoppable;
$self->set_response_sensitive (RESPONSE_STOP, $sensitive);
}
sub _update_clear_sensitive {
my ($self) = @_;
my $anything_to_clear = do {
my $textbuf = $self->{'textbuf'};
$textbuf->get_char_count != 0
} || do {
App::Chart::Gtk2::JobQueue->can('remove_done') # if loaded
&& List::Util::first {$_->get('done')} App::Chart::Gtk2::JobQueue->all_jobs;
} || do {
App::Chart::Gtk2::Subprocess->can('remove_done') # if loaded
&& List::Util::first {! $_->pid} App::Chart::Gtk2::Subprocess->all_subprocesses;
};
$self->set_response_sensitive (RESPONSE_CLEAR, $anything_to_clear);
}
# 'button-press-event' on the treeview
sub _do_proc_treeview_button_press {
my ($treeview, $event, $self) = @_;
if ($event->button == 3) {
require App::Chart::Gtk2::SubprocessStopMenu;
App::Chart::Gtk2::SubprocessStopMenu->popup_from_treeview ($event, $treeview);
}
return Gtk2::EVENT_PROPAGATE;
}
# 'changed' on the treeview selection
sub _do_selection_changed {
my ($selection, $self) = @_;
_update_stop_sensitive ($self);
}
# 'row-changed' on the JobQueue model
sub _do_job_row_changed {
my ($model, $path, $iter, $self) = @_;
_update_stop_sensitive ($self);
if (my $hide = $self->{'hide_on_success'}) {
my $job = $model->get_value ($iter, 0);
if ($job == $hide && $job->status eq __('Done')) {
$self->hide;
}
}
}
# 'set_cell_data_func' to display a cell in the job model row
sub _job_cell_status {
my ($treecolumn, $renderer, $model, $iter) = @_;
my $job = $model->get_value ($iter, 0);
my $str = join (' - ', $job->type // '', $job->status // ());
$renderer->set (text => $str);
}
# 'set_cell_data_func' to display a cell in the subprocess model row
sub _proc_cell_status {
my ($treecolumn, $renderer, $model, $iter) = @_;
my $proc = $model->get_value ($iter, 0);
my $str = $proc->status;
$renderer->set (text => $str);
}
# 'button-press-event' on the treeview
sub _do_jobs_treeview_button_press {
my ($treeview, $event) = @_;
if ($event->button == 3) {
require App::Chart::Gtk2::JobStopMenu;
my $self = $treeview->get_toplevel;
my $menu = ($self->{'job_menu'} ||= App::Chart::Gtk2::JobStopMenu->new);
$menu->popup_from_treeview ($event, $treeview);
}
return Gtk2::EVENT_PROPAGATE;
}
#------------------------------------------------------------------------------
# generic helpers
1;
__END__
=for stopwords popup
=head1 NAME
App::Chart::Gtk2::DownloadDialog -- download dialog widget
=head1 SYNOPSIS
use App::Chart::Gtk2::DownloadDialog;
App::Chart::Gtk2::DownloadDialog->popup;
=head1 WIDGET HIERARCHY
C<App::Chart::Gtk2::DownloadDialog> is a subclass of C<Gtk2::Dialog>.
Gtk2::Widget
Gtk2::Container
Gtk2::Bin
Gtk2::Window
Gtk2::Dialog
App::Chart::Gtk2::DownloadDialog
=head1 DESCRIPTION
...
=head1 FUNCTIONS
=over 4
=item C<< App::Chart::Gtk2::DownloadDialog->popup () >>
=item C<< App::Chart::Gtk2::DownloadDialog->popup ($symbol) >>
Popup a C<DownloadDialog> dialog, re-presenting any existing one or
otherwise creating a new one.
The optional C<$symbol> parameter is put into the symbol entry field, so the
user can have that already entered on choosing the "One Symbol" download.
=back
=head1 SEE ALSO
L<App::Chart>
=head1 HOME PAGE
L<http://user42.tuxfamily.org/chart/index.html>
=head1 LICENCE
Copyright 2007, 2008, 2009, 2010, 2011 Kevin Ryde
Chart is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
Chart is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
You should have received a copy of the GNU General Public License along with
Chart; see the file F<COPYING>. Failing that, see
L<http://www.gnu.org/licenses/>.
=cut
( run in 1.497 second using v1.01-cache-2.11-cpan-364913b4093 )