>-----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

Reply via email to