#!/opt/bin/perl use Gtk2 -init; use Gtk2::Gdk::Keysyms; use Gtk2::CV::ImageWindow; use Gtk2::CV::Schnauzer; use Gtk2::CV; Gtk2::Rc->parse (Gtk2::CV::find_rcfile "gtkrc"); use File::Spec; my $mainwin; my $viewer; my $schnauzer; my $info; my $help; my $schnauzer_idx = 0; sub new_schnauzer { my $s = new Gtk2::CV::Schnauzer; $s->signal_connect_after (key_press_event => \&std_keys); $s->signal_connect (activate => sub { my $label = sprintf "%s (%d)", (File::Spec->splitpath ($_[1]))[2], -s $_[1]; $info->set_label ($label); $viewer->load_image ($_[1]); }); $s; } sub std_keys { my $key = $_[1]->keyval; my $state = $_[1]->state; my $ctrl = $state * "control-mask"; if ($key == $Gtk2::Gdk::Keysyms{q}) { main_quit Gtk2; } elsif ($ctrl && $key == $Gtk2::Gdk::Keysyms{v}) { my $w = new Gtk2::Window; $w->set_title ("CV: Schnauzer"); $w->add (my $s = new_schnauzer); $s->set_dir (File::Spec->curdir); $s->set_geometry_hints; $w->show_all; } elsif ($ctrl && $key == $Gtk2::Gdk::Keysyms{h}) { unless ($help) { require Gtk2::PodViewer; $help = new Gtk2::Window; $help->set_title ("CV: Help"); $help->set_default_size (500, 300); $help->signal_connect (delete_event => sub { $help->hide; 1 }); $help->add (my $sw = new Gtk2::ScrolledWindow); $sw->add (my $h = new Gtk2::PodViewer); #binmode DATA, ":utf8"; $h->load_string (do { local $/; }); } $help->show_all; } else { #$mainwin->show_all; $schnauzer->handle_key ($key, $state); } 1; } { $viewer = new Gtk2::CV::ImageWindow; $viewer->set_title ("CV: Image"); $viewer->signal_connect (key_press_event => \&std_keys); $viewer->signal_connect (delete_event => sub { main_quit Gtk2 }); $viewer->signal_connect (button3_press_event => sub { $mainwin->visible ? $mainwin->hide : $mainwin->show_all; 1; }); $schnauzer = new_schnauzer; $mainwin = new Gtk2::Window; $mainwin->set_title ("CV"); $mainwin->add (my $vbox = new Gtk2::VBox); $mainwin->signal_connect (delete_event => sub { $mainwin->hide; 1; }); $vbox->add ($schnauzer); $vbox->pack_end (my $frame = new Gtk2::Frame, 0, 0, 0); $frame->add (my $hbox = new Gtk2::HBox 0, 0); $hbox->pack_start ((new Gtk2::Label "Info"), 0, 0, 0); $hbox->pack_start (($info = new Gtk2::Label), 1, 1, 0); $schnauzer->set_geometry_hints; } if (@ARGV) { $schnauzer->set_paths (\@ARGV); $schnauzer->handle_key ($Gtk2::Gdk::Keysyms{space}, []); } else { $schnauzer->set_dir (File::Spec->curdir); $mainwin->show_all; } $viewer->show_all; main Gtk2; __DATA__ =head1 NAME cv - a fast gtk+ image viewer modeled after xv =head1 SYNOPSIS cv [file...] =head1 DESCRIPTION None yet. =head2 THE IMAGE WINDOW You can use the following keys in the image window: q quit the program < half the image size > double the image size , shrink the image by 10% . enlarge the image by 10% n reset to normal size m maximize to screensize M maxime to screensize, respecting image aspect ctrl-m toggle maxpect-always mode u uncrop r set scaling mode to 'nearest' (fastest) s set scaling mode to 'bilinear' (default) S set scaling mode to 'hyper' (slowest) t rotate clockwise 90° T rotate counterclockwise° ctrl-v open a new visual schnauzer window for the current dir The following keys are redirected to the default visual schnauzer window: space next image backspace last image =head2 THE VISUAL SCHNAUZER You can use the following keys in the schnauzer window: space move to and display next image backspace move to and display previous image return display selected picture cursor keys move selection page-up move one page up page-down move one page down home move to first file end move to last file ctrl-d delete selected files WITHOUT ASKING AGAIN ctrl-g generate icons for the selected files ctrl-u update selected (or all) icons if neccessary =head1 ENVIRONMENT =over 4 =item CV_PRINT_DESTINATION The default (perl-style) destination to use in the print dialog. =back =head1 SECURITY CONSIDERATIONS CV uses Pixbuf to load images. Pixbuf is not considered safe for this purpose, though (from the gtk-2.2 release notes): "While efforts have been made to make gdk-pixbuf robust against invalid images, using gdk-pixbuf to load untrusted data is not recommended, due to the likelyhood that there are additional problems where an invalid image could cause gdk-pixbuf to crash or worse." =head1 BUGS/TODO Pixbuf doesn't honor G_BROKEN_FILENAMES, so accessing files with names incompatible with utf-8 fails. rotate on disk print lots of ui issues save(?) preferences ctrl-u in schnauzer shift-cursor in schnauzer =head1 AUTHOR Marc Lehmann . =cut