デスクトップ環境構築 - 共通事項 - メニュー - MenuMaker - トラブルシュート - LibreOffice の謎

クラウディア 
1. 概要
2. 解析
3. マージ処理
4. 逃げ道その1
5. 逃げ道その2

1. 概要

 「LibreOffice」をインストールして、「mmaker」でメニューを再作成すると・・・。
「MenuMaker」-「LibreOffice インストール後」

 何故か、「LibreOffice Impress」しか、メニューに取り込まれないのだ。

 よりによって、わたしの一番使わない「Impress」ですじゃ。

 以前、「GNOME」で、「libreoffice-startcenter.desktop」内に、「NotShowIn=GNOME;」の記述があるがために、メニューに取り込まれないということはありましたが。
 そもそも、「GNOME」は、オプションではずしたいくらいだ・・・。

2. 解析

 上位のページに書いてある、「-v」オプションの重ね書きと、ソースデバッグで、わかりました。  「-v」オプション重ね書きの注意すべきものだけ、抜き出します。

> mmaker -f --no-legacy --no-debian FluxBox -v -v
* scanning
  desktop...
entering /usr/local/share/applications

・・・	略	・・・

parsing libreoffice-calc.desktop...ok
parsing libreoffice-draw.desktop...ok
parsing libreoffice-impress.desktop...ok
parsing libreoffice-math.desktop...ok
parsing libreoffice-startcenter.desktop...ok
parsing libreoffice-writer.desktop...ok
parsing libreoffice-xsltfilter.desktop...REJECTED : NoDisplay is True
parsing libreoffice-base.desktop...ok

・・・	略	・・・

 26 apps found
  skipping legacy
  skipping Debian
* merging... 6 coincidings detected
* generating
  no terminal emulator specified; will use the default
  using Xterm as terminal emulator
* writing to ~/.fluxbox/menu
* done
 「libreoffice-xsltfilter.desktop」は、「NoDisplay=true」の記述があるので、取り込まれるのはわかります。  その結果、「libreoffice-*.desktop」のうち、6個取り込まれるわけです。  それが、「merging... 6 coincidings detected」ちゅうことで、マージ時に、6個の重複とみなされ、1つしか残らんわけです。

3. マージ処理

 マージ処理を見てみますと、「/usr/local/share/menumaker/Prophet/__init__.py」に書いてあって

def merge(entries):
    """Removes repeating entries from the list using fuzzy matching technique"""
    # NOTE : this is the deliberate violation of the immutability principle
    # __matched attribute is set for the entries that have been successfully matched before
    # Such entries should be skipped
    # It is thought that this approach is faster than keeping them in separate
    # list
    msg("* merging...", newline=False)
    result = []
    esz = len(entries)
    for i in range(0, esz - 1):
        e = entries[i]
        if hasattr(e, "__matched"):
            continue
        matching = [e]  # List containing matching entries
        for j in range(i + 1, esz):
            x = entries[j]
            if hasattr(x, "__matched"):
                continue
            # Matching e and x
            if os.path.basename(e.exename) == os.path.basename(x.exename):
                # The main criteria is the considence of the executables
                try:
                    eargs = e.exeargs
                except AttributeError:
                    eargs = None
                try:
                    xargs = x.exeargs
                except AttributeError:
                    xargs = None
                if not eargs and not xargs:
                    # Both entries don't have arguments, consider them matching
                    matching.append(x)
                elif eargs and xargs:
                    # Both entries do have arguments, match them
                    if Kw(eargs) == Kw(xargs):
                        # Squeeze the spaces and don't consider the case of the
                        # characters
                        matching.append(x)

        if len(matching) < 2:
            # Only one candidate, no choice
            winner = e
        else:
            # Several candidates, must choose the most relevant
            winner = None
            for m in matching:
                if winner:
                    if m.pref > winner.pref:
                        winner = m
                    elif m.pref == winner.pref:
                        # For now the longer name is the better
                        if len(m.name) > len(winner.name):
                            winner = m

                else:
                    winner = m

        result.append(winner)
        # This is done in the last step to mark e which was put in matching
        for m in matching:
            m.__matched = True

    msg(" %d coincidings detected" % (len(entries) - len(result)))
    return result
 と書いておる。  297行目あたりで、ロードモジュールが一致した場合は、重複とみなしているようです。  「LibreOffice」は、すべてロードモジュールが、「libreoffice」なのだ。  317~333行あたりで、重複時に残す方を決めていますが、詳細は調べていませんが、「Name」の文字列だか、「Exec」のパラメータを含む文字列だかの、文字列が長い方を残しているのだ。  きゃ~、なんて乱暴な・・・。

4. 逃げ道その1

 とりあえず、「libreoffice-startcenter.desktop」を残せば、そこから、他のモジュールを起動することができます。  「libreoffice-startcenter.desktop」を残すには

vi /usr/local/share/applications/libreoffice-startcenter.desktop

Name=LibreOffice
 を

Name=LibreOffice Startcenter
 に書き換えてやります。  そうすれば、「MenuMaker」実行後に「LibreOffice Startcenter」が生き残ります。
「MenuMaker」-「libreoffice-startcenter.desktop 変更後」

 ちなみに、全角空白をいれれば、見た目わかんないかなと思いましたが、末尾に全角空白をいれても文字列長にみなしてくれないようです。

5. 逃げ道その2

 マージそのものを行わないオプションを作る。  ソースは、極力いじりたくなかったのですが・・・。仕方ない。  著作権の問題があるので、配布はやめておきますが、ソース自体を見せるのは、問題ないかな・・・?

vi /usr/local/share/menumaker/MenuMaker/CLI.py

noDebian = False  # Exclude Debian apps database
 マージしないオプション用の変数を追加。

noDebian = False  # Exclude Debian apps database
noMerge = False  # Exclude Merge proccess

    raise optparse.OptionValueError(
        "wrong argument %s for option %s" % (value, opt))


class OP(_OP):
 オプション付きであれば、変数を「true」に設定する処理を追加。

    raise optparse.OptionValueError(
        "wrong argument %s for option %s" % (value, opt))


nmStr = "skip merging"

def nmOpt(option, opt, value, parser):
    global noMerge
    noMerge = True


class OP(_OP):

op.add_option("-s", "--skip", metavar="list", nargs=1,
              type="string", action="callback", callback=sOpt, help=sStr)

opts, args = op.parse_args()
 「--no-merge」という、オプション・処理の追加。

op.add_option("-s", "--skip", metavar="list", nargs=1,
              type="string", action="callback", callback=sOpt, help=sStr)

op.add_option("--no-merge", action="callback", callback=nmOpt, help=nmStr)


opts, args = op.parse_args()

merged = Prophet.merge(legacy + desktop + debian)
 「--no-merge」オプション時は、マージしないように。

if noMerge:
    msg("  skipping Merge")
    merged = legacy + desktop + debian
else:
    merged = Prophet.merge(legacy + desktop + debian)
 「Python」という言語は、よう知らんのですが、さほど量も多くなく、なんとか処理を追加することがでけました。  これで、「libreoffice-startcenter.desktop」は、元の状態でも、「MenuMaker」を実行すると。
「MenuMaker」-「--no-merge オプション実行後」

 全部出てきました。

ハイスピードプランJETBOY