vfmg: vfmg - merged from DEVEL
sparky
sparky at pld-linux.org
Tue Apr 18 18:08:58 CEST 2006
Author: sparky Date: Tue Apr 18 16:08:58 2006 GMT
Module: vfmg Tag: HEAD
---- Log message:
- merged from DEVEL
---- Files affected:
vfmg:
vfmg (1.83 -> 1.84)
---- Diffs:
================================================================
Index: vfmg/vfmg
diff -u vfmg/vfmg:1.83 vfmg/vfmg:1.84
--- vfmg/vfmg:1.83 Tue Mar 15 20:01:25 2005
+++ vfmg/vfmg Tue Apr 18 18:08:53 2006
@@ -2,269 +2,482 @@
#$Id$
use strict;
-use File::Find;
-use Getopt::Long;
-use Encode;
+use File::Find qw(find);
+use Getopt::Long qw(GetOptions :config bundling);
+use Encode qw(encode decode);
+# header {{{
+# default options {{{
my $o_help=0;
my $o_tags=0;
my $o_end=0;
-my $o_icons=0;
-my $o_exec=0;
-my $o_clear=0;
-my $o_promote=0;
my $o_verbose=0;
-my $o_full=0;
-my $o_strip=0;
-my $o_output="";
-my $o_utf=0;
-my $o_enc="";
-my $o_xterm="xterm -name xterm-%1 -e %2";
-my $o_nomenu=0;
-
-$o_xterm="$ENV{'VFMG_TERM'}" if $ENV{'VFMG_TERM'};
-
-GetOptions('help'=>\$o_help,
- 'tags'=>\$o_tags,
- 'end|e'=>\$o_end,
- 'icons'=>\$o_icons,
- 'exec|x'=>\$o_exec,
- 'clear'=>\$o_clear,
- 'promote'=>\$o_promote,
- 'verbose'=>\$o_verbose,
- 'full'=>\$o_full,
- 'strip'=>\$o_strip,
- 'utf8'=>\$o_utf,
- 'nomenu|m'=>\$o_nomenu,
- 'output=s'=>\$o_enc,
- 'xterm|r=s'=>\$o_xterm
- );
+my %defopt = (
+ exec => 0,
+ exec_full => 0,
+ icons => 1,
+ icons_ext => 0,
+ icons_full => 0,
+ icons_scale => 0,
+ icons_fork => 0,
+ icons_dir => "",
+ icons_oext => "png",
+
+ utf => 0,
+ encoding => "",
+
+ clear => 0,
+ promote => 0,
+ strip => 0,
+ nomenu => 0,
+ only_in => "",
+ xterm => "xterm -name xterm-%1 -e %2",
+ convert => "convert -geometry 16x16 \%in \%out",
+ full_regen => 0,
+ destdir => "",
+
+);
+my %opt;
+my $o_output;
+$defopt{xterm}="$ENV{'VFMG_TERM'}" if $ENV{'VFMG_TERM'};
+
+my @wms = qw(ASCII DR17 aewm afterstep blackbox enlightenment fbpanel fluxbox
+ fvwm fvwm2 icewm metisse olvwm openbox qvwm wmaker wmaker-old wmii xfce4
+ xpde);
+
+# %destdir and %iconsdir should only contain directories propsed by WM
+my %destdir = (
+ DR17 => "$ENV{'HOME'}/.e/e/applications/favorite",
+ afterstep => "$ENV{'HOME'}/GNUstep/Library/AfterStep/start",
+ enlightenment => "$ENV{'HOME'}/.enlightenment/menus",
+ xpde => "$ENV{'HOME'}/.xpde/Start Menu/Programs",
+);
+my %iconsdir = (
+ DR17 => "$ENV{'HOME'}/.e/e/applications/all",
+ enlightenment => "$ENV{'HOME'}/.enlightenment/icons",
+);
+# }}}
+
+GetOptions( # {{{
+ 'help|h' => \$o_help,
+ 'tags|t' => \$o_tags,
+ 'end|e' => \$o_end,
+ 'verbose|v' => \$o_verbose,
+
+ 'exec|x!' => \$opt{exec},
+ 'exec-full|full-exec|X!'
+ => \$opt{exec_full},
+ 'icons|i!' => \$opt{icons},
+ 'icons-ext|T!' => \$opt{icons_ext},
+ 'icons-full|full-icons|I!'
+ => \$opt{icons_full},
+ 'icons-scale|scale-icons|S!'
+ => \$opt{icons_scale},
+ 'icons-fork!' => \$opt{icons_fork},
+ 'icons-dir|d=s' => \$opt{icons_dir},
+ 'icons-oext|O=s'
+ => \$opt{icons_oext},
+ 'text-icon=s' => \$opt{text_icon},
+
+ 'wcnt-file=s' => \$opt{wcnt_file},
+ 'termapp-class=s'
+ => \$opt{termapp_class},
+ 'termapp-name=s'
+ => \$opt{termapp_name},
+
+
+ 'utf8|u!' => \$opt{utf},
+ 'encoding|E=s' => \$opt{encoding},
+
+ 'clear|c!' => \$opt{clear},
+ 'promote|p!' => \$opt{promote},
+ 'strip|s!' => \$opt{strip},
+ 'nomenu|m!' => \$opt{nomenu},
+ 'only-in|o=s' => \$opt{only_in},
+
+ 'xterm|r=s' => \$opt{xterm},
+ 'convert|C=s' => \$opt{convert},
+ 'full-regen|f!' => \$opt{full_regen},
+ 'destdir|D=s' => \$opt{destdir},
+ ); # }}}
+
+if($o_help) { # {{{
+ local $" = ", ";
+ print<<EOF;
+Usage: $0 [options] {@wms}
+
+Options:
+ -h, --help - print this help
+
+ Diagnostics:
+ -t, --tags - echo omitted tags to stderr
+ -e, --end - echo omitted XDG file ending to stderr
+ -v, --verbose - verbose stderr output
+
+ Executables and icons:
+ -x, --exec - check for binaries existence
+ -X, --exec-full - extend binaries to full path (implies -x)
+ -i, --icons - add icons to menu (default: yes)
+ -T, --icons-ext - check for icons existence and add extension if required
+ -I, --icons-full - check for icons existence and extend to full path
+
+ -S, --icons-scale - scale (shrink) icons (implies -i -I)
+ --icons-fork - scale icons after fork
+ -d, --icons-dir= - output dir for icons
+ -O, --icons-oext= - output icons extension (default: png)
+
+ Output encoding:
+ -u, --utf8 - output in utf8 (default is locale setting)
+ -E, --encoding= - output in given encoding (e.g. iso-8859-2)
+
+ Menu structure:
+ -c, --clear - remove empty menus
+ -p, --promote - promote submenus with single entry
+ -s, --strip - strip 1st level menu
+ -m, --nomenu - don't add additional menu info
+ (valid for blackbox, fluxbox, openbox, xfce4)
+ -o, --only-in - coma separated list of accepted OnlyShowIn= WMs
+
+ -r, --xterm= - set x terminal application
+ default: "$defopt{xterm}"
+ example "gnome-terminal -t Terminal.%1 -x %2"
+ -C, --convert= - command to use to scale icons
+ default: "$defopt{convert}"
+
+ -f, --full-regen - regenerate everything (delete scaled icons)
+ -D, --destdir= - directory to save multifile menu
+EOF
+ print " (used in: ",
+ (join ", ", sort keys %destdir), ")\n";
+ print<<EOF;
+
+ All but diagnostics boolean options have oposite --no-<name> version too.
-if($o_help) {
- print "Usage: $0 [options] {aewm, afterstep, blackbox, enlightenment, fbpanel, fluxbox, fvwm, fvwm2, icewm, metisse, openbox, olvwm, qvwm, wmaker, wmaker-old, xfce4, xpde}
- -h, --help - print this help
- -t, --tags - echo omitted tags to stderr
- -e, --end - echo omitted XDG file ending to stderr
- -v, --verbose - verbose stderr output
- -i, --icons - check for icons existence
- -x, --exec - check for binaries existence
- -f, --full - extend icons and binaries to full path (needs -i or -x)
- -c, --clear - remove empty menus
- -p, --promote - promote submenus with single entry
- -s, --strip - strip 1st level menu
- -u, --utf8 - output in utf8 (default is locale setting)
- -m, --nomenu - don't add additional menu info (valid for blackbox, fluxbox, openbox, xfce4)
- -o, --output= - output in given encoding (e.g. iso-8859-2)
- -r, --xterm= - set x terminal application (default \"xterm -name xterm-%1 -e %2\")
- example \"gnome-terminal -t Terminal.%1 -x %2\"\n";
+EOF
exit;
-}
+} # }}}
-die "Missing argument {aewm, afterstep, blackbox, enlightenment, fbpanel, fluxbox, fvwm, fvwm2, icewm, metisse, openbox, olvwm, qvwm, wmaker, wmaker-old, xfce4, xpde}\n"
- unless exists $ARGV[0];
+unless (exists $ARGV[0]) {
+ local $" = ", ";
+ die "Missing argument {@wms}\n";
+}
$o_output=$ARGV[0];
die "Unrecognized argument: $o_output\n"
- unless $o_output=~/^(aewm|afterstep|blackbox|enlightenment|fbpanel|fluxbox|fvwm|fvwm2|icewm|metisse|openbox|olvwm|qvwm|wmaker|wmaker-old|xfce4|xpde)$/;
+ unless grep { $o_output eq $_ } @wms;
-$o_full=1 if $o_icons and $o_output=~/^(enlightenment|metisse)$/;
-
-my $tmp="$ENV{'HOME'}/.local/share";
-$tmp="$ENV{'XDG_DATA_HOME'}" if $ENV{'XDG_DATA_HOME'};
-my @tmp=("/usr/local/share","/usr/share");
- at tmp=split(/:+/,$ENV{'XDG_DATA_DIRS'}) if $ENV{'XDG_DATA_DIRS'};
-my @xdg_data_dirs=grep -d, $tmp, at tmp;
-
-$tmp="$ENV{'HOME'}/.config";
-$tmp="$ENV{'XDG_CONFIG_HOME'}" if $ENV{'XDG_CONFIG_HOME'};
- at tmp=("/etc/xdg");
- at tmp=split(/:+/,$ENV{'XDG_CONFIG_DIRS'}) if $ENV{'XDG_CONFIG_DIRS'};
-my @xdg_config_dirs=map{"$_/menus"} grep -d, $tmp, at tmp;
+# vfmgrc {{{
+my @rcFiles = (qw(/etc/vfmgrc), "$ENV{'HOME'}/.vfmgrc");
+push @rcFiles, "$ENV{'HOME_ETC'}/.vfmgrc" if exists $ENV{'HOME_ETC'};
+ at rcFiles = grep -r, @rcFiles;
+
+my @rcBody;
+foreach my $rc (@rcFiles) {
+ open F_IN, $rc or next;
+ my $read = 1;
+ while (<F_IN>) {
+ next if ( /^\s*#/ );
+ $_ .= <F_IN> while s/\\\n$//;
+ $read = 0 if /^\[/;
+ if ( /^\[$o_output\]/ ) {
+ $read = 1;
+ next;
+ }
+ push @rcBody, $_ if $read;
+ }
+ close F_IN;
+}
- at tmp=map {"$_/icons/"} @xdg_data_dirs;
-my @icondirs=(grep (-d, ("$ENV{'HOME'}/.icons/", at tmp,"/usr/share/pixmaps/","/usr/share/icons/default.kde/48x48/apps/","/usr/share/icons/hicolor/48x48/apps/")), "");
+my %rcopt = map { /^\s*(.*?)\s*=\s*(.*)\s*$/ } @rcBody;
+# }}}
+
+foreach my $opt (keys %opt) {
+ $opt{$opt} = $rcopt{$opt} unless defined $opt{$opt};
+ $opt{$opt} = $defopt{$opt} unless defined $opt{$opt};
+ next unless defined $opt{$opt};
+ $opt{$opt} =~ s/\${HOME}/$ENV{'HOME'}/go;
+}
+
+# check dependencies
+$opt{exec}=1 if $opt{exec_full};
+if ( grep { $o_output eq $_ } keys %iconsdir ) {
+ $opt{icons_dir} = $iconsdir{$o_output} unless (length $opt{icons_dir});
+}
+if ($opt{icons_scale}) {
+ if ( length $opt{icons_dir} ) {
+ my $conv = (split /\s/, $opt{convert})[0];
+ if ( length `which $conv` ) {
+ $opt{icons} = 1;
+ $opt{icons_full} = 1;
+ } else {
+ $opt{icons_scale} = 0;
+ warn "$conv is not executable, not scaling icons.\n";
+ }
+ } else {
+ $opt{icons_scale} = 0;
+ warn "Icons destination directory is not specified, not scaling.\n";
+ }
+}
+$opt{icons_ext} = 1 if $opt{icons_full};
+$opt{encoding}="utf8" if $opt{utf};
+if ( grep { $o_output eq $_ } keys %destdir ) {
+ $opt{destdir} = $destdir{$o_output} unless (length $opt{destdir});
+} else {
+ delete $opt{destdir};
+}
+my @OSI_accept;
+if ( defined $opt{only_in} ) {
+ foreach my $cat ( split /[,\s]+/, $opt{only_in} ) {
+ push @OSI_accept, $cat;
+ }
+}
+# header }}}
+
+# search dirs {{{
+my @xdg_data_dirs = grep -d,
+ ( exists $ENV{'XDG_DATA_HOME'}
+ ? $ENV{'XDG_DATA_HOME'}
+ : "$ENV{'HOME'}/.local/share"
+ ),
+ ( exists $ENV{'XDG_DATA_DIRS'}
+ ? split /:+/, $ENV{'XDG_DATA_DIRS'}
+ : qw(/usr/local/share /usr/share)
+ );
+
+my @xdg_config_dirs = map { "$_/menus" } grep -d,
+ ( exists $ENV{'XDG_CONFIG_HOME'}
+ ? $ENV{'XDG_CONFIG_HOME'}
+ : "$ENV{'HOME'}/.config"
+ ),
+ ( exists $ENV{'XDG_CONFIG_DIRS'}
+ ? split /:+/, $ENV{'XDG_CONFIG_DIRS'}
+ : qw(/etc/xdg)
+ );
+
+my @icondirs = (
+ grep (-d,
+ "$ENV{'HOME'}/.icons/",
+ map({"$_/icons/"} @xdg_data_dirs),
+ qw(/usr/share/pixmaps/
+ /usr/share/icons/default.kde/48x48/apps/
+ /usr/share/icons/hicolor/48x48/apps/)
+ ),
+ '',
+);
my @path;
-if($o_exec) {
+if ( $opt{exec} ) {
@path=(grep (-d, split(/:+/,$ENV{'PATH'})), "");
- if($o_xterm) {
+ if( length $opt{xterm} ) {
my $exists=0;
- my $bin=$o_xterm;
+ my $bin=$opt{xterm};
$bin=~s/(\S+).*/$1/; #v---------v
foreach my $dir(@path) { # would be "//dir/.../file" correct?
- if(-x "$dir/$bin") {#----^
+ if (-x "$dir/$bin") {#----^
$exists=1;
- $o_xterm="$dir/$o_xterm" if $o_full;
+ $opt{xterm}="$dir/$opt{xterm}" if $opt{exec_full};
last;
}
}
- $o_xterm="" unless $exists;
+ unless ($exists) {
+ $opt{xterm}="";
+ warn "Can't find $bin.",
+ " Terminal applications will not be included.\n";
+ }
}
}
-
-# get locale (for Name[*])
-
-my $lang4="";
-$lang4=$ENV{'LANG'} if exists $ENV{'LANG'};
-$lang4=$ENV{'LC_MESSAGES'} if exists $ENV{'LC_MESSAGES'};
-$lang4=$ENV{'LC_ALL'} if exists $ENV{'LC_ALL'};
-my $lang3=$lang4;
-$lang3=~s/@.*//;
-my $lang2=$lang3;
-$lang2=~s/\..*//;
-my $lang1=$lang2;
-$lang1=~s/_.*//;
+# search dirs }}}
+
+# get locale (for Name[*]) {{{
+my @lang;
+sub addlang {
+ my $l = $_[0];
+ push @lang, $l unless grep {$_ eq $l} @lang;
+ $l =~ s/@.*//;
+ push @lang, $l unless grep {$_ eq $l} @lang;
+ $l =~ s/\..*//;
+ push @lang, $l unless grep {$_ eq $l} @lang;
+ $l =~ s/_.*//;
+ push @lang, $l unless grep {$_ eq $l} @lang;
+}
+addlang($ENV{'LC_ALL'}) if exists $ENV{'LC_ALL'};
+addlang($ENV{'LC_MESSAGES'}) if exists $ENV{'LC_MESSAGES'};
+if (exists $ENV{'LANGUAGE'}) {
+ foreach my $lang (split /:/, $ENV{'LANGUAGE'}) {
+ addlang($lang);
+ }
+}
+addlang($ENV{'LANG'}) if exists $ENV{'LANG'};
+my $langs = join "|", @lang;
+sub findfirstlang {
+ foreach my $lang (@lang) {
+ foreach (@_) {
+ return $_ if /\[$lang\]/;
+ }
+ }
+ return (grep !/\[.*\]/, @_)[0];
+} # }}}
# what is $DESKTOP_FILE_PATH?
my @apps; # $apps{name}{category}=[icon,exec]
-my @happs;
+my @desktop;
find(\&wanted, grep -d, map {"$_/applications"} @xdg_data_dirs);
-sub wanted {
- return if (!-f || /^\./ || !/\.desktop$/);
- my $file=$_;
- my $name="";
- my $exec="";
- my $icon="";
- my $cats="";
- my $term=0;
- my $lang=0;
- my $app=0;
- my $enc="iso-8859-1";
- open F_IN, "$file" or warn "$File::Find::name: $!\n" and return;
- while(<F_IN>) {
- if (/^\s*Name\s*=\s*(.+?)\s*$/ && $lang<1) {
- $name=$1;
- }
- if (/^\s*Name\[$lang1\]\s*=\s*(.+?)\s*$/ && $lang<2) {
- $name=$1;
- $lang=1;
- }
- if (/^\s*Name\[$lang2\]\s*=\s*(.+?)\s*$/ && $lang<3) {
- $name=$1;
- $lang=2;
- }
- if (/^\s*Name\[$lang3\]\s*=\s*(.+?)\s*$/ && $lang<4) {
- $name=$1;
- $lang=3;
- }
- if (/^\s*Name\[$lang4\]\s*=\s*(.+?)\s*$/ && $lang<5) {
- $name=$1;
- $lang=4;
- }
- $icon=$1 if /^\s*Icon\s*=\s*(.+?)\s*$/;
- $exec=$1 if /^\s*Exec\s*=\s*(.+?)\s*$/;
- $cats=$1 if /^\s*Categories\s*=\s*(.+?)\s*$/;
- $term=1 if /^\s*Terminal\s*=\s*(?i:1|true)/;
- $app=1 if /^\s*Type\s*=\s*(?i:application)/;
- $enc=$1 if /^\s*Encoding\s*=\s*(.+?)\s*$/;
- }
+sub wanted { # {{{
+ return unless -f && /^[^.].*\.desktop$/;
+ my $file = $_;
+
+ open F_IN, $file or warn "$File::Find::name: $!\n" and return;
+ my %tags = (
+ file => $file,
+ Icon => '',
+ Categories => '',
+ Type => '',
+ NoDisplay => 'false',
+ map {
+ ## "foo = bar" or "Name[baz] = bar"
+ /^\s*
+ (Name(?:\[(?:$langs)\])?
+ |GenericName(?:\[(?:$langs)\])?
+ |Comment(?:\[(?:$langs)\])?
+ |Icon|Exec|Categories|Terminal|Type|Encoding|NoDisplay
+ |OnlyShowIn)
+ \s* = \s* (.+?)
+ \s*$/ox
+ } <F_IN>,
+ );
close F_IN;
- return unless $app;
- return if $term and not $o_xterm;
- my $bin=$exec;
- $bin=~s/(\S+).*/$1/; #v---------v
- if($o_exec) {
- my $exists=0;
- foreach my $dir(@path) { # would be "//dir/.../file" correct?
- if(-x "$dir/$bin") {#----^
- $exists=1;
- $exec="$dir/$exec" if $o_full;
+
+ return unless lc $tags{Type} eq 'application';
+ return if lc $tags{NoDisplay} eq 'true';
+ if ( defined $tags{OnlyShowIn} ) {
+ my $found = 0;
+ foreach my $cat ( split /;+/, $tags{OnlyShowIn} ) {
+ $found++ if grep {$cat eq $_} @OSI_accept;
+ }
+ return unless $found;
+ }
+
+ $tags{term} =
+ ($tags{Terminal} && $tags{Terminal} =~ /^(?:1|true)$/i) ? 1 : 0;
+ return if $tags{term} and not $opt{xterm};
+
+ ($tags{bin}) = ($tags{Exec} =~ /(\S+)/); #v---------v
+ if ( $opt{exec} ) {
+ my $exists;
+ foreach my $dir (@path) { # would be "//dir/.../file" correct?
+ if (-x "$dir/$tags{bin}") { #----^
+ $exists++;
+ $tags{Exec} = "$dir/$tags{Exec}" if $opt{exec_full};
last;
}
}
return unless $exists;
}
- if($term) {
- $bin=~s|.*/||;
- $_=$o_xterm;
- s/%1/$bin/;
- s/%2/$exec/;
- $exec=$_;
- }
- if($o_icons) {
- my $exists=0;
- foreach my $dir(@icondirs) {
- if(-f "$dir$icon") {
- } elsif(-f "$dir$icon.svg") {
- $icon.=".svg";
- } elsif(-f "$dir$icon.xpm") {
- $icon.=".xpm";
- } elsif(-f "$dir$icon.png") {
- $icon.=".png";
- } else {
- next;
+ if ( $tags{term} ) {
+ $tags{bin} =~ s|.*/||;
+ $_ = $opt{xterm};
+ s/%1/$tags{bin}/;
+ s/%2/$tags{Exec}/;
+ $tags{Exec} = $_;
+ }
+ if ( $opt{icons_ext} ) {
+ my $exists = 0;
+ ALLDIRS: foreach my $dir (@icondirs) {
+ foreach my $ext ('', qw(.svg .xpm .png)) {
+ if (-f $dir . $tags{Icon} . $ext) {
+ $tags{Icon} .= $ext;
+ $tags{Icon} = $dir . $tags{Icon} if $opt{icons_full};
+ $exists = 1;
+ last ALLDIRS;
+ }
}
- $exists=1;
- $icon="$dir$icon" if $o_full;
- last;
- }
- $icon="" unless $exists;
- }
- my $utfname;
- if($name ne "") {
- if($enc eq "Legacy-Mixed") {
+ }
+ $tags{Icon} = '' unless $exists;
+ }
+
+ $tags{Encoding} = exists $tags{Encoding} ? $tags{Encoding} : 'iso-8859-1';
+
+ my @to_decode = qw(Name);
+ push @to_decode, qw(GenericName Comment)
+ if $o_output eq "DR17" or $o_output eq "ASCII";
+ foreach my $tag_name (@to_decode) {
+ my @all = (grep /^$tag_name/, keys %tags);
+ next if ($#all < 0);
+ my $first = findfirstlang(@all);
+ my $enc = $tags{Encoding};
+
+ if ($enc eq 'Legacy-Mixed') {
warn "$File::Find::name: Legacy-Mixed encoding is depreciated.\n";
- if(!$lang) {
- $enc="iso-8859-1";
- } elsif ($lang==1) {
- warn "$File::Find::name: cannot get encoding name for `$lang1'. Assuming iso-8859-1\n";
- $enc="iso-8859-1";
+
+ # this code is untested
+ # --radek
+ my ($lang) = ($first =~ /^$tag_name\[([^\]]+)/);
+ if ($lang !~ /_/) {
+ warn "$File::Find::name: cannot get encoding name for"
+ . " `$lang'. Assuming iso-8859-1\n";
+ $enc = "iso-8859-1";
} else {
- use POSIX qw(locale_h);
- my $old_locale=setlocale(LC_ALL);
<<Diff was trimmed, longer than 597 lines>>
---- CVS-web:
http://cvs.pld-linux.org/vfmg/vfmg?r1=1.83&r2=1.84&f=u
More information about the pld-cvs-commit
mailing list