2 ##############################################################################
3 # generates a file.menu format for Enlightenment out of menu hierarchies
5 # Copyright (C) 2003-2008 Kim Woelders
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to
9 # deal in the Software without restriction, including without limitation the
10 # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11 # sell copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies of the Software, its documentation and marketing & publicity
16 # materials, and acknowledgment shall be given in the documentation, materials
17 # and software packages that this Software was used.
19 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 # THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23 # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 ##############################################################################
28 $Prefixes = "/usr/local:/usr:/opt:/opt/kde:$ENV{'KDEDIR'}";
29 $Prefixes = "$Prefixes:/opt/kde3:/opt/gnome"; # SUSE
30 $Prefixes = RemoveDuplcates($Prefixes);
32 # Where to look for GNOME/KDE stuff
33 $AppDirs = MkDirList($Prefixes, "/share/applications:/share/applications/kde:/share/applications/kde4");
35 $IconDirs = MkDirList($Prefixes, "/share/pixmaps:/share/icons");
36 $IconDirs2 = MkDirList($Prefixes, "/share/icons");
37 $Themes = "default.kde:gnome:hicolor";
38 $IconCats = "apps:filesystems:actions:devices:categories:places";
40 # Where to look for GNOME1 apps
41 $OldGnomeDirs = MkDirList($Prefixes, "/share/gnome/apps");
42 # Where to look for KDE1/2 apps
43 $OldKdeDirs = MkDirList($Prefixes, "/share/applnk");
46 $EdirUser = "$ENV{'ECONFDIR'}";
47 $EdirRoot = "$ENV{'EROOT'}";
48 $EdirBin = "$ENV{'EBIN'}";
50 # Localization bits. There may be better ways to do this.
51 $Lang = "$ENV{'LANG'}";
52 $loc1 = $loc2 = $loc3 = $Lang;
53 $loc2 =~ s/[\.\@].*//;
55 $loc1 = "" if ($loc1 eq $loc2);
57 $EdirUser = "$ENV{'HOME'}/.e16" unless $EdirUser;
58 $EdirRoot = "/usr/share/enlightenment" unless $EdirRoot;
59 $EdirBin = "/usr/bin" unless $EdirBin;
61 $EdirMenus = "$EdirUser/menus";
63 $dbg = "$ENV{'E_MENUGEN_DBG'}";
65 # Put EBIN first in path
66 $ENV{'PATH'} = "$EdirBin:$ENV{'PATH'}";
69 $DoIconv = `which iconv`;
85 "m:User Application List:user_apps.menu",
86 "m:GNOME:menus_GNOME/index.menu",
87 "m:KDE:menus_KDE/index.menu",
88 "m:Other:menus_Other/index.menu",
89 "m:Epplets:epplets.menu",
90 "c:Restart:exit restart",
91 "c:Log Out:exit logout"
95 "t:User Application List",
97 "x:Terminal:Terminal",
102 "x:Seamonkey:seamonkey",
106 "x:Gmplayer:gmplayer",
120 # Remove duplicates and nulls in ':' separated dir list
121 sub RemoveDuplcates {
125 foreach $p (split(':', $dl)) {
131 return join(':', @r);
134 # Make : separated directory list, check that they exist
140 foreach $p (split(':', $dl)) {
141 foreach $q (split(':', $sf)) {
143 push(@r, "$d") if -d "$d";
146 return join(':', @r);
149 # Make dir if non-existing
152 mkdir("$d") unless (-d "$d");
160 $f = "$EdirMenus/$f";
164 ($t, $n, $p) = split(':', $e);
167 } elsif ($t eq "m") {
168 print FD "\"$n\" NULL menu \"$p\"\n";
169 } elsif ($t eq "x") {
170 print FD "\"$n\" NULL exec \"$p\"\n";
171 } elsif ($t eq "c") {
172 print FD "\"$n\" NULL \"$p\"\n";
178 # Process a .desktop file
181 local $Name, $Exec, $Icon, $Cats, $Type, $File;
185 print "Not found: $f\n" if $dbg ge 1;
192 $Name = $Exec = $Icon = "";
193 $Nam1 = $Nam2 = $Nam3 = "";
197 open(FI,$f) or return;
201 } elsif ($loc1 && /^Name\[$loc1\]=(.*)$/) {
203 } elsif ($loc2 && /^Name\[$loc2\]=(.*)$/) {
205 } elsif ($loc3 && /^Name\[$loc3\]=(.*)$/) {
207 } elsif (/^Exec=(.*)$/) {
209 } elsif (/^Icon=(.*)$/) {
211 } elsif (/^OnlyShowIn=(.*);$/) {
213 } elsif (/^Categories=(.*)$/) {
214 next if "$Cats"; # Given
215 CF: foreach $cf (split(';', $1)) {
220 foreach $cr (@CatsRemove) {
221 next CF if ($cf =~ /^$cr$/);
225 } elsif (/^Type=(.*)$/) {
226 if ($1 ne "Application") {
231 if ($Nam1 || $Nam2 || $Nam3) {
232 if ($Nam1) { $Name = $Nam1; }
233 elsif ($Nam2) { $Name = $Nam2; }
234 else { $Name = $Nam3; }
235 $Name = `echo "$Name" | iconv -f UTF-8` if $DoIconv;
242 if (!$Name || !$Exec || !$Cats) {
243 printf("Skipped: %-24s %-24s %-20s %-20s %s\n",
244 $f, $Name, $Exec, $Icon, $Cats) if $dbg ge 1;
249 $File = $f; $File =~ s/^.*\///;
251 printf("%-24s: %-24s %-20s %-20s %s\n",
252 $File, $Name, $Exec, $Icon, $Cats) if $dbg ge 3;
255 if ($File =~ /^gnome/) {
257 } elsif ($File =~ /^kde/) {
264 $Namx = "$Name-$N"; # Make key unique
265 $Namx =~ tr/A-Z/a-z/; # To lower case (for sorting)
266 $Exec =~ s/\s*%(f|F|i|k|m|n|N|u|U|v)//g; # Strip unwanted args
267 $Exec =~ s/\s*-\w+\s*"%c"//g; # Strip option with caption
268 # $Exec =~ s/"%c"/'$Name'/g; # Alternatively - Substitute caption
269 $File{$Namx} = $File;
270 $Name{$Namx} = $Name;
271 $Exec{$Namx} = $Exec;
272 $Icon{$Namx} = $Icon;
273 $Cats{$Namx} = $Cats;
274 $Type{$Namx} = $Type;
277 # Process all .desktop files in a directory
285 @l = grep /\.desktop$/, ReadDir($d);
288 print "- File $f\n" if $dbg ge 2;
289 ProcessFile("$f", "$dx", "$t");
293 # Process old style GNOME/KDE directories
294 sub ProcessOldStyle {
300 foreach $d (split(':', $dl)) {
301 print "Processing directory: $d\n" if $dbg ge 1;
303 print "- Not found\n" if $dbg ge 1;
306 @d2l = grep !/^\./, ReadDir($d);
308 print " Subdir: $d/$d2\n" if $dbg ge 1;
309 next unless -d "$d/$d2";
310 ProcessDir("$d/$d2", "$d2", "$t");
315 # Find that $#@! thing
322 return $f if (-f $f);
324 foreach $d (split(':', $IconDirs)) {
327 next if ($f =~ /\.png$/);
334 foreach $d (split(':', $IconDirs2)) {
335 next unless (-d "$d");
336 foreach $t (split(':', $Themes)) {
337 next unless (-d "$d/$t");
338 foreach $s (split(':', "48:32:24:16")) {
340 next unless (-d "$S");
341 if ($f =~ /^stock/) {
342 $i = "$S/stock/*/$f.png";
344 print "Testing $i\n" if $dbg >= 2;
345 return $ii if (-f $ii);
347 foreach $u (split(':', $IconCats)) {
348 next unless (-d "$S/$u");
350 if ($f =~ /\.png|\.xpm$/) {
351 print "Testing $i\n" if $dbg >= 2;
352 return $i if (-f $i);
355 print "Testing $ii\n" if $dbg >= 2;
356 return $ii if (-f $ii);
358 print "Testing $ii\n" if $dbg >= 2;
359 return $ii if (-f $ii);
370 # Make the Epplets menu
375 open(FD, ">$EdirMenus/$f");
376 print FD "\"Enlightenment Epplets\"\n";
377 foreach $d (split(':', $ENV{'PATH'})) {
381 print "Looking for epplets in $d\n" if $dbg ge 1;
382 @el = grep /\.epplet$/, ReadDir($d);
385 $i = "$EdirRoot/epplet_icons/$e.icon";
386 print FD "\"$e\" \"$i\" exec \"$d/$e.epplet\"\n";
392 # Make the menu for a given app type
398 $dir = "$EdirMenus/menus_$type";
399 $mdir = "menus_$type";
400 print "Generating Menu: $type in $dir\n" if $dbg ge 1;
403 # Sort the apps into categories
404 foreach $k (sort(keys(%Name))) {
405 next if ($Type{$k} ne $type);
409 push(@{$menus{$c}}, $k);
412 # Make top- and sub-menus
413 open(FTopM, ">$dir/index.menu") or die "*** Couldn't create $dir/index.menu\n";
414 print FTopM "\"$type Menu\"\n";
415 foreach $m (sort(keys(%menus))) {
416 open(FSubM, ">$dir/$m.menu") or die "*** Couldn't create $dir/$m.menu\n";
417 print "- Submenu: $m\n" if $dbg ge 2;
418 print FTopM "\"$m\" \"\" menu \"$mdir/$m.menu\"\n";
419 print FSubM "\"$m\"\n";
420 foreach $k (sort(@{$menus{$m}})) {
421 print " - Item: $k\n" if $dbg ge 2;
422 $icon = FindIcon($Icon{$k});
423 printf FSubM "\"%s\" \"%s\" exec \"%s\"\n",
424 $Name{$k}, $icon, $Exec{$k};
431 # Return list of files in dir
435 if (!opendir DH, $dir) { print "*** Could not open: $dir\n"; return 0; }
441 # Close all windows named "Message" (we assume they are E dialogs)
442 sub CloseMessageWindows {
443 system("eesh -e 'wop Message* close' >/dev/null");
447 ##############################################################################
449 ##############################################################################
452 CloseMessageWindows();
453 system("eesh -e \"dialog_ok Menus are being generated... Please Wait.\"");
455 # Process old style GNOME directories
456 ProcessOldStyle("GNOME", "$OldGnomeDirs");
458 # Process old style KDE directories
459 ProcessOldStyle("KDE", "$OldKdeDirs");
461 # Process new style (GNOME2, KDE2/3) directories
462 foreach $d (split(':', $AppDirs)) {
463 print "Processing directory: $d\n" if $dbg ge 1;
465 print "- Not found\n" if $dbg ge 1;
471 # Make menu dir and scaled icon dir
475 MakeMenu("file.menu", \@MainMenu);
476 MakeMenu("user_apps.menu", \@UserAppsMenu);
477 MakeEppsMenu("epplets.menu");
478 MakeAppsMenu("GNOME");
480 MakeAppsMenu("Other");
482 CloseMessageWindows();
483 system("eesh -e 'menus reload'");
484 system("eesh -e 'dialog_ok Menu generation complete.'");