Gtk2-CV

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

	- much improved resize/move handling (still not up to xv's level).
	- every schnauzer now has an associated label/info field.
	- better ^D performance.
	- can now play videos if mplayer is in the path (and probably is
	  identical to my versions and your config file is empty etc. etc.
	  the usual caveats about embedding mplayer...)
	  (http://itdp.fh-biergarten.de/mplayer-dev-eng/2004-12/txt00028.txt fixes
	   the resize problems).
	- remove gtk20-compatibility cruft.
	- added progress window for lengthy operations.
	- removed <parent> entry, use popup=>Up.
	- change of contact address.
	- updated icons for some file-extensions.
	- make cv's info label wrap as not to change horizontal window width
	  (doesn't work, but that's general gtk2 brokenness).
	- use set_absolute_size for the schnauzer font. doesn't result in an
	  absolute size, but at least results in the same height everywhere.
	- implemented a primitive plugin system (see Gtk2::CV::Plugin and
	  eg/plugin-skeleton).
	- removed bin/cvc's clusteriser.
	- added a new clusteriser algorithm, use Popup=>"Filename clustering..."

eg/plugin-skeleton  view on Meta::CPAN

      my $ctrl = grep $_ eq "control-mask", @{$_[1]->state};
      if ($ctrl && $key == $Gtk2::Gdk::Keysyms{c}) {
         warn "pressed ctrl-c\n";
      } else {
         return 0;
      }

      1
   });

   $schnauzer->signal_connect (popup => sub {
      my ($self, $menu, $cursor, $event) = @_;

      $menu->append (my $item = new Gtk2::MenuItem "select me");
      $item->signal_connect (activate => sub { warn "activated menu\n" });
   });
}

1

lib/Gtk2/CV/ImageWindow.pm  view on Meta::CPAN

   $self->push_composite_child;

   $self->double_buffered (0);

   $self->set_role ("image window");

   $self->signal_connect (destroy => sub { $self->kill_player });
   $self->signal_connect (realize => sub { $_[0]->do_realize; 0 });
   $self->signal_connect (map_event => sub { $_[0]->check_screen_size; $_[0]->auto_position (($_[0]->allocation->values)[2,3]) });
   $self->signal_connect (expose_event => sub {
      # in most cases, we get no expose events, except when our _own_ popups
      # obscure some part of the window. se we have to do lots of unneessary refreshes :(
      $self->{window}->clear_area ($_[1]->area->values);
      $self->draw_drag_rect ($_[1]->area);
      1
   });
   $self->signal_connect (configure_event => sub { $_[0]->do_configure ($_[1]); 0 });
   $self->signal_connect (key_press_event => sub { $_[0]->handle_key ($_[1]->keyval, $_[1]->state) });

   $self->{frame_extents_property}         = Gtk2::Gdk::Atom->intern ("_NET_FRAME_EXTENTS", 0);
   $self->{request_frame_extents_property} = Gtk2::Gdk::Atom->intern ("_NET_REQUEST_FRAME_EXTENTS", 0);

lib/Gtk2/CV/Plugin/MetaCluster.pm  view on Meta::CPAN

sub custom {#TODO
   $_[0] =~ $::CUSTOM_CLUSTERING
      ? $1 : "???"
}

sub new_schnauzer {
   my ($self, $schnauzer) = @_;

   my $metacluster;

   $schnauzer->signal_connect (popup => sub {
      my ($self, $menu, $cursor, $event) = @_;
      
      $menu->append (my $i_up = new Gtk2::MenuItem "Imagesize clustering...");
      $i_up->signal_connect (activate => sub {
         ($metacluster = Gtk2::CV::Plugin::MetaCluster->new)->start ($self, \&imgsize);
      });

      $menu->append (my $i_up = new Gtk2::MenuItem "Filetime clustering...");
      $i_up->signal_connect (activate => sub {
         ($metacluster = Gtk2::CV::Plugin::MetaCluster->new)->start ($self, \&mtime);

lib/Gtk2/CV/Plugin/NameCluster.pm  view on Meta::CPAN

   $self->analyse;

   $self->show_all;
}

sub new_schnauzer {
   my ($self, $schnauzer) = @_;

   my $namecluster;

   $schnauzer->signal_connect (popup => sub {
      my ($self, $menu, $cursor, $event) = @_;
      
      $menu->append (my $i_up = new Gtk2::MenuItem "Filename clustering...");
      $i_up->signal_connect (activate => sub {
         $namecluster = Gtk2::CV::Plugin::NameCluster->new;
         $namecluster->start ($self, 0);
      });

      $menu->append (my $i_up = new Gtk2::MenuItem "Subdir view...");
      $i_up->signal_connect (activate => sub {

lib/Gtk2/CV/Plugin/PatRenamer.pm  view on Meta::CPAN

      my $ctrl = grep $_ eq "control-mask", @{$_[1]->state};
      if ($ctrl && $key == $Gtk2::Gdk::Keysyms{r}) {
         new_renamer $schnauzer;
      } else {
         return 0;
      }

      1
   });

   $schnauzer->signal_connect (popup => sub {
      my ($self, $menu, $cursor, $event) = @_;

      2 <= scalar keys %{ $schnauzer->{sel} }
         or return;

      $menu->append (my $item = new Gtk2::MenuItem "Pattern Rename...");
      $item->signal_connect (activate => sub {
         new_renamer $schnauzer;
      });
   });

lib/Gtk2/CV/Plugin/RCluster.pm  view on Meta::CPAN

      $entry->[ $idx[$_] ] = $ent[ $sorted->[$_] ];
   }

   $schnauzer->entry_changed;
   $schnauzer->invalidate_all;
}

sub new_schnauzer {
   my ($self, $schnauzer) = @_;

   $schnauzer->signal_connect (popup => sub {
      my ($self, $menu, $cursor, $event) = @_;
      
      $menu->append (my $i_up = new Gtk2::MenuItem "Image clustering (GNU-R)...");
      $i_up->signal_connect (activate => sub {
         histsort_selected $schnauzer;
      });
   });
}

=head1 AUTHORS

lib/Gtk2/CV/Progress.pm  view on Meta::CPAN

=cut

package Gtk2::CV::Progress;

use common::sense;
use Gtk2;
use Gtk2::CV;

use Time::HiRes 'time';

sub INITIAL   (){ 0.15 } # initial popup delay
sub INTERVAL1 (){ 0.01 } # minimum update interval
sub INTERVAL2 (){ 0.10 } # minimum update interval

=item new Gtk2::CV::Progress ...

 title => the progress widget title (mandatory)
 work  => amount of work (default 1)

=cut

lib/Gtk2/CV/Schnauzer.pm  view on Meta::CPAN

use Gtk2;
use Gtk2::Pango;
use Gtk2::Gdk::Keysyms;

use Gtk2::CV;

use Glib::Object::Subclass
   Gtk2::VBox::,
   signals => {
      activate          => { flags => [qw/run-first/], return_type => undef, param_types => [Glib::Scalar::] },
      popup             => { flags => [qw/run-first/], return_type => undef, param_types => [Gtk2::Menu::, Glib::Scalar::, Gtk2::Gdk::Event::] },
      popup_selected    => { flags => [qw/run-first/], return_type => undef, param_types => [Gtk2::Menu::, Glib::Scalar::] },
      selection_changed => { flags => [qw/run-first/], return_type => undef, param_types => [Glib::Scalar::] },
      chpaths           => { flags => [qw/run-first/], return_type => undef, param_types => [] },
      chdir             => { flags => [qw/run-first/], return_type => undef, param_types => [Glib::Scalar::] },
   };

use List::Util qw(min max);

use File::Spec;
use File::Copy;
use File::Temp ();

lib/Gtk2/CV/Schnauzer.pm  view on Meta::CPAN

                  (($cursor - $self->{offs}) % $self->{cols},
                   ($cursor - $self->{offs}) / $self->{cols}) x 2
               );
            } else {
               ($self->{sel_x1}, $self->{sel_y1}) =
               ($self->{sel_x2}, $self->{sel_y2}) = ($x, $y);
               $self->{oldsel} = $self->{sel};
               $self->selrect;
            }
         } elsif ($_[1]->button == 3) {
            $self->emit_popup ($_[1],
                               $cursor < @{$self->{entry}} ? $cursor : undef);
         }
      } elsif ($_[1]->type eq "2button-press") { 
         $self->emit_activate ($cursor) if $cursor < @{$self->{entry}};
      }

      1
   });

   my $scroll_diff; # for drag & scroll

lib/Gtk2/CV/Schnauzer.pm  view on Meta::CPAN

                       (strftime "%Y-%m-%d %H:%M:%S", localtime +(stat _)[9]),
                       (filename_display_name $entry->[E_DIR]),
            );
         };
      }
   }

   $self->signal_emit (selection_changed => $self->{sel});
}

sub emit_popup {
   my ($self, $event, $cursor) = @_;

   my $idx   = $self->cursor_valid ? $self->{cursor} : $cursor;
   my $entry = $self->{entry}[$idx];

   my $menu = new Gtk2::Menu;

   if (exists $self->{dir}) {
      $menu->append (my $i_up = new Gtk2::MenuItem "Parent (^)");
      $i_up->signal_connect (activate => sub {

lib/Gtk2/CV/Schnauzer.pm  view on Meta::CPAN

      $item->set_submenu (my $rotate = new Gtk2::Menu);
      $rotate->append (my $item = new Gtk2::MenuItem "90 clockwise");
      $item->signal_connect (activate => sub { $self->rotate (90, @sel) });
      $rotate->append (my $item = new Gtk2::MenuItem "90 counter-clockwise");
      $item->signal_connect (activate => sub { $self->rotate (270, @sel) });
      $rotate->append (my $item = new Gtk2::MenuItem "180");
      $item->signal_connect (activate => sub { $self->rotate (180, @sel) });
      $rotate->append (my $item = new Gtk2::MenuItem "automatic (exif orientation tag)");
      $item->signal_connect (activate => sub { $self->rotate ("auto", @sel) });
		
      $self->signal_emit (popup_selected => $menu, \@sel);
   }

   {
      $menu->append (my $item = new Gtk2::MenuItem "Select");
      $item->set_submenu (my $sel = new Gtk2::Menu);

      $sel->append (my $item = new Gtk2::MenuItem "By Adjacent Name");
      $item->set_submenu (my $by_pfx = new Gtk2::Menu);

      my $name = $entry->[E_FILE];

lib/Gtk2/CV/Schnauzer.pm  view on Meta::CPAN

      $sel->append (my $item = new Gtk2::MenuItem "By Adjacent Dir (Alt-A)");
      $item->signal_connect (activate => sub { $self->selection_adjacent_dir });

      $sel->append (my $item = new Gtk2::MenuItem "Unselect Thumbnailed (Ctrl -)");
      $item->signal_connect (activate => sub { $self->selection_remove_thumbnailed });

      $sel->append (my $item = new Gtk2::MenuItem "Keep only Thumbnailed (Ctrl +)");
      $item->signal_connect (activate => sub { $self->selection_keep_only_thumbnailed });
   }

   $self->signal_emit (popup => $menu, $cursor, $event);
   $_->show_all for $menu->get_children;
   $menu->popup (undef, undef, undef, undef, $event->button, $event->time);
}

sub emit_activate {
   my ($self, $cursor) = @_;

   $self->prefetch_cancel;

   my $entry = $self->{entry}[$cursor];
   my $path = "$entry->[E_DIR]/$entry->[E_FILE]";



( run in 2.227 seconds using v1.01-cache-2.11-cpan-364913b4093 )