yhdev/pub/download/code/grenamr-0.1.pl
Yorhel 6242b2ee9c Rewrite to static site
With a complete reorganisation of the directory structure and most of
the content converted to pandoc-flavoured markdown.

Some TODO's left before this can go live:
- Main page
- Atom feeds
- Bug tracker
2019-03-23 11:56:53 +01:00

248 lines
6.6 KiB
Perl

#!/usr/bin/perl
# grenamr v0.1
# 2008-08-01
# Yoran Heling
# License: MIT
use warnings;
use strict;
use Gtk2 -init;
our $VERSION = '0.1';
my %w;
my $m;
use constant {
C_OLD => 0,
C_NEW => 1,
C_FLG => 2,
F_REG => 0x01,
F_MAN => 0x02, # not implemented yet...
F_CON => 0x04,
};
create();
Gtk2->main;
sub create {
$w{win} = Gtk2::Window->new('toplevel');
$w{win}->signal_connect(destroy => \&close);
$w{win}->resize(500, 500);
$w{win}->move(300, 300);
$w{win}->set(title => 'GRenamR v'.$VERSION);
$w{vbGlobal} = Gtk2::VBox->new(0, 0);
$w{win}->add($w{vbGlobal});
$w{hbDir} = Gtk2::HBox->new(0, 0);
$w{vbGlobal}->pack_start($w{hbDir}, 0, 1, 0);
$w{lbDir} = Gtk2::Label->new('_Directory');
$w{hbDir}->pack_start($w{lbDir}, 0, 0, 5);
$w{fcDir} = Gtk2::FileChooserButton->new('Select a directory', 'select-folder');
$w{fcDir}->signal_connect('current-folder-changed', \&fetchdir);
$w{hbDir}->pack_start($w{fcDir}, 1, 1, 0);
$w{lbDir}->set(mnemonic_widget => $w{fcDir}, use_underline => 1);
$w{swFiles} = Gtk2::ScrolledWindow->new;
$w{swFiles}->set_policy('automatic', 'automatic');
$w{vbGlobal}->pack_start($w{swFiles}, 1, 1, 0);
$w{tvFiles} = Gtk2::TreeView->new;
$w{swFiles}->add($w{tvFiles});
$m = $w{lsFiles} = Gtk2::ListStore->new('Glib::String', 'Glib::String', 'Glib::Int');
$w{tvFiles}->set_model($w{lsFiles});
$w{tvFiles}->insert_column_with_data_func(0, '', Gtk2::CellRendererPixbuf->new, \&column_func, 0);
my $c = Gtk2::CellRendererText->new;
$w{tvFiles}->insert_column_with_data_func(1, 'Old', $c, \&column_func, 1);
$w{tvFiles}->insert_column_with_data_func(2, 'New', $c, \&column_func, 2);
$w{tvFiles}->get_column(1)->set(sizing => 'autosize');
$w{tvFiles}->get_column(2)->set(sizing => 'autosize');
$w{hbPerl} = Gtk2::HBox->new(0, 0);
$w{vbGlobal}->pack_start($w{hbPerl}, 0, 1, 0);
$w{lbPerl} = Gtk2::Label->new('_Expression');
$w{hbPerl}->pack_start($w{lbPerl}, 0, 0, 5);
$w{enPerl} = Gtk2::Entry->new;
$w{enPerl}->signal_connect('changed', \&applyfilter);
$w{hbPerl}->pack_start($w{enPerl}, 1, 1, 0);
$w{lbPerl}->set(mnemonic_widget => $w{enPerl}, use_underline => 1);
$w{imPerl} = Gtk2::Image->new_from_stock('gtk-yes', 'menu');
$w{hbPerl}->pack_start($w{imPerl}, 0, 1, 0);
$w{hbBottom} = Gtk2::HBox->new(0, 0);
$w{vbGlobal}->pack_start($w{hbBottom}, 0, 1, 0);
$w{alStatus} = Gtk2::Alignment->new(0,0.8,0,0);
$w{hbBottom}->pack_start($w{alStatus}, 1, 1, 5);
$w{lbStatus} = Gtk2::Label->new('');
$w{alStatus}->add($w{lbStatus});
$w{alBottom} = Gtk2::Alignment->new(1,1,0,1);
$w{hbBottom}->pack_start($w{alBottom}, 0, 1, 0);
$w{bbBottom} = Gtk2::HButtonBox->new;
$w{bbBottom}->set(spacing => 5);
$w{alBottom}->add($w{bbBottom});
$w{btApply} = Gtk2::Button->new('_Rename');
$w{btApply}->signal_connect('clicked', \&dorename);
$w{bbBottom}->pack_start($w{btApply}, 0, 0, 5);
$w{btClose} = Gtk2::Button->new('_Close');
$w{btClose}->signal_connect('clicked', \&close);
$w{bbBottom}->pack_start($w{btClose}, 0, 0, 5);
$w{win}->show_all;
$w{enPerl}->grab_focus;
if($ARGV[0] && -d $ARGV[0]) {
$w{fcDir}->set_current_folder($ARGV[0]);
} else {
fetchdir();
}
}
sub column_func {
my ($column, $cell, $model, $iter, $col) = @_;
my $flags = $model->get($iter, 2);
$cell->set(
$col > 0 ? (
text => $model->get($iter, $col-1),
) : (
'stock-id' => $flags & F_CON ? 'gtk-dialog-error'
: $flags & F_REG ? 'gtk-edit'
: $flags & F_MAN ? 'gtk-apply'
: 'gtk-file',
),
$flags & F_CON ? ( cell_background => '#ffcccc' ) :
$flags & F_REG ? ( cell_background => '#ccffcc' ) :
$flags & F_MAN ? ( cell_background => '#ffffcc' ) :
( cell_background_set => 0 ),
);
}
sub close {
Gtk2->main_quit;
}
sub fetchdir {
Gtk2->main_iteration_do(0);
my $d = $w{fcDir}->get_current_folder;
$w{lbStatus}->set(label => 'Loading...');
my @lst;
opendir(my $D, $d)
|| return $w{lbStatus}->set(label => 'Unable to open the selected directory');
-f $d.'/'.$_ and push @lst, $_ for (readdir $D);
closedir $D;
$m->clear;
$m->set($m->append, C_OLD, $_, C_NEW, $_, C_FLG, 0)
for (sort @lst);
$w{lbStatus}->set(label => sprintf '%d files found.', scalar @lst);
applyfilter();
}
sub applyfilter {
my $p = $w{enPerl}->get_text;
# create a list of files
my @list;
my $i = $m->get_iter_first;
do {
push @list, $m->get($i, C_OLD)
} while ($i = $m->iter_next($i));
# eval using a for loop
$i=-1;
eval 'no strict; no warnings; for (@list) { ++$i; '.$p.' }';
my $e = $@;
$w{imPerl}->set(stock => $e ? 'gtk-no' : 'gtk-yes');
# compare and update the list
my $j=0; my $matched=0;
$i = $m->get_iter_first;
do {{
next if $m->get($i, C_FLG) & F_MAN;
my $match = $e || $m->get($i, C_OLD) eq $list[$j] ? 0 : 1;
$m->set($i, C_NEW, $list[$j++], C_FLG, $match);
$matched += $match;
}} while ($i = $m->iter_next($i));
# update status
$w{lbStatus}->set(label => $e
? 'Invalid expression'
: sprintf 'Matched %d/%d files.', $matched, scalar @list);
findconflicts();
}
sub findconflicts {
# create a list of old filenames
my @old;
my $i = $m->get_iter_first;
do {
push @old, $m->get($i, C_OLD);
} while ($i = $m->iter_next($i));
# search for modified items having a new filename in that list
my $e=0;
$i = $m->get_iter_first;
do {{
next if !$m->get($i, C_FLG);
my $new = $m->get($i, C_NEW);
my $match = $new eq '' || $new =~ /\// || grep $_ eq $new, @old;
$m->set($i, C_FLG, $m->get($i, C_FLG) | F_CON)
if $match;
$e++ if $match;
}} while ($i = $m->iter_next($i));
$w{lbStatus}->set(label => 'Errors found!') if $e;
}
sub dorename {
my $d = $w{fcDir}->get_current_folder;
# count number of renamable files
my $i = $m->get_iter_first;
my $count=0;
do {
$count++ if $m->get($i, C_FLG) && !($m->get($i, C_FLG) & F_CON);
} while ($i = $m->iter_next($i));
return $w{lbStatus}->set(label => 'Nothing to do...') if !$count;
$w{lbStatus}->set(label => 'Renaming...');
my $j=0;
$i = $m->get_iter_first;
do {{
next if !$m->get($i, C_FLG) || $m->get($i, C_FLG) & F_CON;
rename $d.'/'.$m->get($i, C_OLD), $d.'/'.$m->get($i, C_NEW);
$m->set($i, C_OLD, $m->get($i, C_NEW), C_FLG, 0);
$w{lbStatus}->set(label => sprintf 'Renaming file %d/%d...', ++$j, $count);
Gtk2->main_iteration_do(0);
}} while ($i = $m->iter_next($i));
$w{lbStatus}->set(label => sprintf 'Renamed %d files.', $j);
}