App-Devel-MAT-Explorer-GTK

 view release on metacpan or  search on metacpan

bin/pmat-explore-gtk  view on Meta::CPAN

#!/usr/bin/perl

use strict;
use warnings;

use Carp;

use Glib qw( TRUE FALSE );
use Gtk2 -init;
use Gtk2::SimpleList;

use Devel::MAT;

use List::Util qw( pairs );
use List::UtilsBy qw( sort_by );

use App::Devel::MAT::Explorer::GTK::Resources qw( get_icon );
use App::Devel::MAT::Explorer::GTK::Shell;
use App::Devel::MAT::Explorer::GTK::SVDetail;
use App::Devel::MAT::Explorer::GTK::Utils qw( bytes2size );
use App::Devel::MAT::Explorer::GTK::Widgets qw( framed vscrollable );

my $pmat;
my $df;

my $win = Gtk2::Window->new( "toplevel" );
$win->signal_connect( destroy => sub { Gtk2->main_quit } );
$win->resize( 1000, 600 );
my $winbox = Gtk2::VBox->new( 0, 0 );
$win->add( $winbox );

my $menu = Gtk2::MenuBar->new;
$winbox->pack_start( $menu, FALSE, TRUE, 0 );

my $filemenu = add_submenu( $menu, "File" );
add_menuitem( $filemenu, "Quit" => sub { Gtk2->main_quit } );

my $navmenu = add_submenu( $menu, "Navigate" );

my $toolbar = Gtk2::Toolbar->new;
$toolbar->set_style( 'both' );
$winbox->pack_start( $toolbar, FALSE, TRUE, 0 );

my $backbtn = $toolbar->append_item( "Back", "Go back to the previous SV", "",
   Gtk2::Image->new_from_stock("gtk-go-back", "small-toolbar"), \&history_back );
my $forwardbtn = $toolbar->append_item( "Forward", "Go forward to the next SV", "",
   Gtk2::Image->new_from_stock("gtk-go-forward", "small-toolbar"), \&history_forward );

my $svs_loaded;

my $outrefs_mth = "outrefs";
my $inrefs_mth = "inrefs";
{
   my %mode_buttons;

   my %mode_tooltip = (
      All    => "Display and count every kind of inref and outref",
      Direct => "Display and count only direct inrefs and outrefs",
      Strong => "Display and count only strong direct inrefs and outrefs",
   );

   Devel::MAT::UI->provides_radiobutton_set(
      map {
         my $filter = $_ eq "All" ? "" : "_\L$_";

         Devel::MAT::UI->register_icon(
            name => "refs-$_",
            svg => "icons/refs-$_.svg"
         );

         {
            text    => $_,
            icon    => "refs-$_",
            tooltip => $mode_tooltip{$_},
            code    => sub {
               $outrefs_mth = "outrefs$filter";
               $inrefs_mth  = "inrefs$filter";

               reset_svlist_refs() if $svs_loaded;
               redisplay_sv();
            },
         }
      } qw( All Direct Strong )
   );

   Devel::MAT::UI->provides_sv_detail(
      order => 1E6,
      type => "widget",
      title => "Outrefs",
      render => sub {
         my ( $sv ) = @_;
         my $outrefs = Gtk2::SimpleList->new(

bin/pmat-explore-gtk  view on Meta::CPAN

         5 => scalar $sv->$outrefs_mth,
         6 => scalar $sv->$inrefs_mth,
      );

      $count++;
      progress( sprintf "Loading GTK TreeView %d of %d (%.2f%%)",
         $count, $total, $count*100 / $total ) if ($count % 1000) == 0;
   }

   progress();
}

$bytetotal_label->set_text( $bytes . " bytes" );

my $table = Gtk2::Table->new( 1, 3 );
$hpane->add2( $table );

$svlist_view->signal_connect( row_activated => sub {
   my( $self, $path, $column ) = @_;
   my $iter = $svlist_model->get_iter( $path );
   my $addr = $svlist_model->get( $iter, 1 );

   my $sv = $df->sv_at( $addr );
   history_nav( $sv );
});

$vpane->pack2( App::Devel::MAT::Explorer::GTK::Shell->build_widget( $pmat ), FALSE, TRUE );

progress();

$win->show_all;
Gtk2->main;

sub display_sv
{
   my ( $sv ) = @_;

   $table->remove( $_ ) foreach $table->get_children;
   $table->resize( 1, 1 );

   App::Devel::MAT::Explorer::GTK::SVDetail::display_sv_in_table( $sv, $table );

   $table->show_all;

   for( my $iter = $svlist_model->get_iter_first; $iter; $iter = $svlist_model->iter_next( $iter ) ) {
      my $addr = $svlist_model->get_value( $iter, 1 );

      if( $sv->addr == $addr ) {
         my $path = $svlist_model->get_path( $iter );
         $svlist_view->scroll_to_cell( $path, $svlist_view->get_column( 0 ), '' );
         $svlist_view->get_selection->select_path( $path );
         last;
      }
   }
}

sub add_submenu
{
   my ( $menu, $name ) = @_;

   my $mi = Gtk2::MenuItem->new( $name );
   my $submenu = Gtk2::Menu->new;
   $mi->set_submenu( $submenu );

   $menu->append( $mi );

   return $submenu;
}

sub add_menuitem
{
   my ( $menu, $name, $code ) = @_;

   my $mi = Gtk2::MenuItem->new( $name );
   $mi->signal_connect( activate => $code );

   $menu->append( $mi );
}

sub entry_dialog
{
   my ( $question ) = @_;

   my $d = Gtk2::Dialog->new( $question, $win,
      [ qw( modal destroy-with-parent )],
      'gtk-cancel' => 'reject',
      'gtk-ok'     => 'accept',
   );
   $d->set_default_response( 'accept' );

   my $entry = Gtk2::Entry->new();
   $entry->set_activates_default( TRUE );

   my $vbox = $d->vbox;
   $vbox->pack_start( $entry, 0, 0, 4 );
   $vbox->show_all;

   my $response = $d->run;
   my $text = $entry->get_text;

   $d->destroy;

   return $text if $response eq 'accept';
   return;
}

sub Devel::MAT::UI::provides_radiobutton_set
{
   shift;

   $toolbar->append_space;

   my $group;
   foreach my $button ( @_ ) {
      my $code = $button->{code};

      my $button = $toolbar->append_element(
         "radiobutton", undef, $button->{text}, $button->{tooltip}, "",
         $button->{icon} ? Gtk2::Image->new_from_pixbuf( get_icon( $button->{icon} ) // die "No icon $button->{icon}" ) : undef,
         sub {
            my ( $button ) = @_;
            return unless $button->get_active;

            goto &$code;
         },
      );

      $button->set_group( $group ) if $group;
      $group //= $button->get_group;
   }
}

my %COLTYPES; BEGIN { %COLTYPES = (
   int  => { store_type => "Glib::Int",    renderer => "Gtk2::CellRendererText",   attr => "text"   },



( run in 0.654 second using v1.01-cache-2.11-cpan-5735350b133 )