>-----Ursprüngliche Nachricht----- >Von: "Thomas Adam" <tho...@fvwm.org> >Gesendet: 20.10.2011 15:00:58 >An: "Thomas Funk" <t.f...@web.de> >Betreff: Re: Reworked fvwm-menu-desktop > >>Some very quick observations... [...]
>>Can you describe the internal data overall, and now it's derived, and then >>we can look at how best to process it. That way, we can reduce a lot of the >>clutter, and define a more cleaner interface for all of this. Hi Thomas, sorry for the delay, but I was seriously ill the last days. But now I've done the description of merge_fvwm2_menus. Hope it's ok: sub merge_fvwm2_menus { my $weight = 0; my $reference_menu; # check first if xdg_menu_prefix is set if (defined $xdg_menu_prefix) { $reference_menu = $xdg_menu_prefix; } else { # check if applications.menu exist # question: correct to disable autovivification? if (ref $fvwm2_menus{''} eq 'HASH') { $reference_menu = ''; } else { # get the biggest menu as reference foreach my $prefix (keys %fvwm2_menus) { my $size = scalar keys %{$fvwm2_menus{$prefix}}; if ($size > $weight) { $reference_menu = $prefix; $weight = $size; } } } } ## compare the other menus with reference and delete same entries # create an fvwm menu hash %{$fvwm2_menus{'fvwm-'}} = %{$fvwm2_menus{$reference_menu}}; # get the first hash key ('gnome-', 'kde-', 'fvwm-') foreach my $compare_menu (keys %fvwm2_menus) { # don't check the reference or the fvwm menu next if ($compare_menu eq $reference_menu || $compare_menu eq 'fvwm-'); # get the menu names from the reference menu (check the known menus for same entries) foreach my $refkey (keys %{$fvwm2_menus{$reference_menu}}) { # get the menu names from the menu should compared foreach my $compkey (keys %{$fvwm2_menus{$compare_menu}}) { # compare array A (@{$fvwm2_menus{$compare_menu}{$compkey}}) to Array B (@{$fvwm2_menus{$reference_menu}{$refkey}}) # and removing B elements from A. Exception: DestroyMenu and AddToMenu entires my @rest = grep { my $x = $_; not grep { $x =~ /\Q$_/i and $x !~ /DestroyMenu|AddToMenu/} @{$fvwm2_menus{$reference_menu}{$refkey}} } @{$fvwm2_menus{$compare_menu}{$compkey}}; # clear compared array undef @{ $fvwm2_menus{$compare_menu}{$compkey} }; # push cleared array into compare array push @{ $fvwm2_menus{$compare_menu}{$compkey} }, @rest; # if only DestroyMenu or AddToMenu entries exist, delete this menu name hash if (scalar @{ $fvwm2_menus{$compare_menu}{$compkey} } == 2) { delete $fvwm2_menus{$compare_menu}{$compkey}; } } } ## check if double entries in the compare menu exist and delete them # this happens on OpenSuSE 11.4 where in System AND Settings the same app entries exist foreach my $refkey (keys %{$fvwm2_menus{$compare_menu}}) { foreach my $compkey (keys %{$fvwm2_menus{$compare_menu}}) { next if ($compkey eq $refkey); my @rest = grep { my $x = $_; not grep { $x =~ /\Q$_/i and $x !~ /DestroyMenu|AddToMenu/} @{$fvwm2_menus{$compare_menu}{$refkey}} } @{$fvwm2_menus{$compare_menu}{$compkey}}; undef @{ $fvwm2_menus{$compare_menu}{$compkey} }; push @{ $fvwm2_menus{$compare_menu}{$compkey} }, @rest; } # if only DestroyMenu or AddToMenu entries exist in a reference menu, delete the menu name hash if (scalar @{ $fvwm2_menus{$compare_menu}{$refkey} } == 2) { delete $fvwm2_menus{$compare_menu}{$refkey}; } } ## merge all '+' entries in existing ref menus foreach my $key (keys %{$fvwm2_menus{$compare_menu}}) { # don't check the fvwm root menu. This we will do later next if ($key eq 'FvwmMenu'); # if menu name from compare menu exists in reference menu try merging # question: is defined correct to disable autovivification? if (defined $fvwm2_menus{$reference_menu}{$key}) { # get all + entries except with Popup|DestroyMenu|AddToMenu my @entries = (grep (/\+/, @{$fvwm2_menus{$compare_menu}{$key}}) and grep (!/Popup|DestroyMenu|AddToMenu/, @{$fvwm2_menus{$compare_menu}{$key}})); # if entries array has values, push lines into reference menu if (@entries) { push @{ $fvwm2_menus{$reference_menu}{$key} }, @entries; # get the rest like Popup|DestroyMenu|AddToMenu entries to create the # compare menu without the + entries moved to the reference my @rest = grep (/Popup|DestroyMenu|AddToMenu/, @{$fvwm2_menus{$compare_menu}{$key}}); undef @{ $fvwm2_menus{$compare_menu}{$key} }; push @{ $fvwm2_menus{$compare_menu}{$key} }, @rest; # if only DestroyMenu or AddToMenu entries exist, delete this menu name hash if (scalar @{ $fvwm2_menus{$compare_menu}{$key} } == 2) { delete $fvwm2_menus{$compare_menu}{$key}; } } } } ## check, if non existing Popup entries available and delete them foreach my $key (keys %{$fvwm2_menus{$compare_menu}}) { my @rest; # check each available array foreach my $entry (@{$fvwm2_menus{$compare_menu}{$key}}) { # push an DestroyMenu|AddToMenu entry into rest array if ($entry =~ m/DestroyMenu|AddToMenu/) { push @rest, $entry; } else { # push entry into the rest array if menu name is included foreach (keys %{$fvwm2_menus{$compare_menu}}) { # exclude: same menu name hash which is checking and # the root menu. This we will do later next if ($_ eq $key || $_ eq 'FvwmMenu'); if ($entry =~ m/$_\b/) { push @rest, $entry; } } } } #foreach (@rest) { print "$_\n"; } undef @{ $fvwm2_menus{$compare_menu}{$key} }; push @{ $fvwm2_menus{$compare_menu}{$key} }, @rest; if (scalar @{ $fvwm2_menus{$compare_menu}{$key} } == 2) { delete $fvwm2_menus{$compare_menu}{$key}; } } ## check if menus available which not exist in the reference menu # and merge them into it. foreach my $key (keys %{$fvwm2_menus{$compare_menu}}) { my @entry; # if it is the root menu push only the + entries into the entry array # else the complete menu if ($key eq 'FvwmMenu') { @entry = (grep (/\+/, @{$fvwm2_menus{$compare_menu}{$key}}) and grep (!/DestroyMenu|AddToMenu/, @{$fvwm2_menus{$compare_menu}{$key}})); } else { @entry = @{$fvwm2_menus{$compare_menu}{$key}}; } # push the missing parts into the reference menu push @{ $fvwm2_menus{$reference_menu}{$key} }, @entry; # delete compare menu for cleanup. Only for debugging delete $fvwm2_menus{$compare_menu}{$key}; } } } The fvwm2_menu structure looks like this (made with Data::Dumper under OpenSuSE 11.4): $VAR1 = { 'fvwm-' => { 'FvwmMenu-Graphics' => [ 'DestroyMenu "FvwmMenu-Graphics"', 'AddToMenu "FvwmMenu-Graphics" "Graphics" Title', '+ "Image Editing" Popup "FvwmMenu-Graphics-RasterGraphics"', '+ "Photography" Popup "FvwmMenu-Graphics-Photography"', '+ "Scanning" Popup "FvwmMenu-Graphics-Scanning"', '+ "Vector Drawing" Popup "FvwmMenu-Graphics-VectorGraphics"', '+ "Viewer" Popup "FvwmMenu-Graphics-Viewer"' ], : }, '' => { 'FvwmMenu-Graphics' => $VAR1->{'fvwm-'}{'FvwmMenu-Graphics'}, : }, 'kde4-' => { 'FvwmMenu-Games' => [ 'DestroyMenu "FvwmMenu-Games"', 'AddToMenu "FvwmMenu-Games" "Games" Title', '+ "Logic Games" Popup "FvwmMenu-Games-Logic"' ], : } }; Btw, I haven't changed the '' bug here ;) Follows later Regards, Thomas ___________________________________________________________ SMS schreiben mit WEB.DE FreeMail - einfach, schnell und kostenguenstig. Jetzt gleich testen! http://f.web.de/?mc=021192