Python - MenuMaker 日本語化 - その後の修正 - JWM

 クラウディア
1. JWM
2. 変更点

1. JWM

 これは、「JWM」の処理を行うモジュールです。  おさらい。  「JWM」のメニューの構造は

<Menu icon="アイコンファイル名" label="カテゴリ名">
    <Program icon="アイコンファイル名" label="アイテム名">ロードモジュール</Program>
    <Program icon="アイコンファイル名" label="アイテム名">ロードモジュール</Program>
</Menu>
 という形式になっています。  また、これを定義しているのが

~/.jwmrc
 というファイルなのですが、このファイルには、メニューの項目以外に、ショートカットキーの定義やら、フォントの定義やら、全部詰まっているので、なかなかややこしいことになります。  サブカテゴリを分ける場合は、「Menu」タグをネストさせます。  「アイコンファイル名」は、オリジナルの「MenuMaker」では、カテゴリがすべて「folder」(フォルダのアイコン)となっており、「Program」の行はすべて、「icon=""」自体が存在しません。  「.svg」は、表示できないので、変換が必要です。

2. 変更点

 これも長いソースですので、前回との変更点のみ・・・。

########## カスタムアイコンディレクトリ
        self.directory_custom = os.environ.get('HOME') + '/.config/icons'
 カスタマイズしたアイコンのディレクトリを追加します。

########## カスタムアイコンディレクトリ
        self.icon_directory = os.environ.get('HOME') + '/.config/icons'

        if (not os.path.exists(self.icon_directory)):                         ## ないディレクトリは作成する
            os.makedirs(self.icon_directory)

#####
    # メニューのカテゴリ行を日本語に変える
    # @param env            環境クラス
    # @param line           対象行
    # @param label_en       カテゴリ名英語
    # @param label_jp       カテゴリ名日本語
    # @param directory_icon カテゴリアイコンのディレクトリ
    # @param icon           アイコンファイル(拡張子なし)

    def update_category(self, env, line, label_en, label_jp, directory_icon, icon):

        ## カテゴリ名を英語から日本語へ

        line = line.replace(self.prefix + label_en + self.suffix, self.prefix + label_jp + self.suffix)

        ## メニューアイコンの .svg は使えないので .png に変換して使用する

        if (not os.path.exists(self.directory_custom)):                         ## カスタムディレクトリがなければ
            os.mkdir(self.directory_custom)                                     ## 作成する

        icon_fullpath = self.directory_custom + '/' + icon + '.png'             ## アイコンのフルパス
 ディレクトリの変数名を変更しています。

#####
    # メニューのカテゴリ行を日本語に変える
    # @param env            環境クラス
    # @param line           対象行
    # @param label_en       カテゴリ名英語
    # @param label_jp       カテゴリ名日本語
    # @param directory_icon カテゴリアイコンのディレクトリ
    # @param icon           アイコンファイル(拡張子なし)

    def update_category(self, env, line, label_en, label_jp, directory_icon, icon):

        ## カテゴリ名を英語から日本語へ

        line = line.replace(self.prefix + label_en + self.suffix, self.prefix + label_jp + self.suffix)

        ## メニューアイコンの .svg は使えないので .png に変換して使用する

        if (not os.path.exists(self.icon_directory)):                         ## カスタムディレクトリがなければ
            os.mkdir(self.icon_directory)                                     ## 作成する

        icon_fullpath = self.icon_directory + '/' + icon + '.png'             ## アイコンのフルパス
 以下は、まるまる追加。  「LibreOffice」の個別起動とアイコン設定です。

#####
    # メニューの LibreOffice 行にアイコンを追加して、個別の実行文にする
    # @param line           対象行
    # @param nextline       対象行の次の行(本クラスでは使用しない)
    # @param label          項目名
    # @param exe_sentence   実行文
    # @param directory_icon アプリケーションアイコンのディレクトリ
    # @param icon           アイコンファイル(拡張子なし)

    def update_libreoffice(self, line, nextline, label, exe_sentence, icon):
        line = line.replace('<Program label="'+label+'">libreoffice</Program>', '<Program icon="'+icon+'" label="'+label+'">'+exe_sentence+'</Program>')
        return [line, nextline]

#####
    # 終了メニュー設定
    # @param env   環境変数クラス
    # @param lines メニューファイル全行

    def set_end_menu(self, env, lines):

        ## オリジナルのメニュー用アイコン作成
        ## [0]再起動 [1]ログアウト [2]シャットダウン

        icon_list = []

        for icon in [ 'system-restart', 'computer-log-out', 'system-shutdown' ]:
            to_full_pass = self.directory_custom + '/' + icon + '.png'

            if (not os.path.exists(to_full_pass)):                              ## ファイルがなければ
                from_full_pass = env.directory_icon_category + '/' + icon + '.svg'

                env.convert(from_full_pass, to_full_pass)                       ## .svg を変換

            icon_list.append(to_full_pass)

        for i in range(0, len(lines)-1):
            lines[i] = lines[i].replace('Sans-9', 'MigMix 1M-8')

        line_key = '<Restart label="再起動" icon="restart.png"/>' + "\n"

        if  line_key in lines:
            i = lines.index(line_key)
            lines[i] = lines[i].replace(line_key, '<Restart label="JWM 再起動" icon="'+icon_list[0]+'"/>'+"\n")


        line_key = '<Exit label="終了" confirm="true" icon="quit.png"/>' + "\n"

        if  line_key in lines:
            i = lines.index(line_key)
            lines[i] = lines[i].replace(line_key, '<Exit label="終了" confirm="true" icon="'+icon_list[1]+'"/>'+"\n")

        line_key = '</RootMenu>' + "\n"

        if  line_key in lines:
            point = len(lines) - lines.index(line_key)

        lines.insert(-point, '<Program label="再起動" icon="'+icon_list[0]+'">sudo /sbin/reboot</Program>'+"\n")
        lines.insert(-point, '<Program label="シャットダウン" icon="'+icon_list[2]+'">sudo /sbin/poweroff</Program>'+"\n")

        lines.insert(-1, '    <Key keycode="107">exec: mate-screenshot</Key>'+"\n")
        lines.insert(-1, '    <Key mask="C" keycode="107">exec: mate-screenshot -w</Key>'+"\n")
 「メニュー更新」「再起動」「シャットダウン」をメニューに追加。  「Conky」がインストールされていれば、自動起動するように設定しています。

#####
    # 終了メニュー設定
    # @param env   環境変数クラス(本メソッドでは未使用)
    # @param  dic_exec_icon exec → icon 辞書
    # @param lines メニューファイル全行

    def set_end_menu(self, env, dic_exec_icon, lines):
        for i in range(0, len(lines)-1):
            lines[i] = lines[i].replace('Sans-9', 'MigMix 1M-8')

        line_key = '<Restart label="再起動" icon="restart.png"/>' + "\n"

        if  line_key in lines:
            i = lines.index(line_key)
            lines[i] = lines[i].replace(line_key, '<Restart label="JWM 再起動" icon="'+dic_exec_icon['reboot']+'"/>'+"\n")


        line_key = '<Exit label="終了" confirm="true" icon="quit.png"/>' + "\n"

        if  line_key in lines:
            i = lines.index(line_key)
            lines[i] = lines[i].replace(line_key, '<Exit label="終了" confirm="true" icon="'+dic_exec_icon['logout']+'"/>'+"\n")

        line_key = '</RootMenu>' + "\n"

        if  line_key in lines:
            point = len(lines) - lines.index(line_key)

        lines.insert(-point-2, '<Program label="メニュー更新" icon="'+dic_exec_icon['update']+'">~/jmenumaker/update_jwm.sh</Program>'+"\n")
        lines.insert(-point, '<Program label="再起動" icon="'+dic_exec_icon['reboot']+'">sudo /sbin/reboot</Program>'+"\n")
        lines.insert(-point, '<Program label="シャットダウン" icon="'+dic_exec_icon['shutdown']+'">sudo /sbin/poweroff</Program>'+"\n")

        ## mate-screenshot がインストールされていれば <Print> <Ctrl+Print> にショートカット割り当て
        ## <Print Screen> キーは、書き直す必要があるときもあるので注意

        if (os.path.exists('/usr/local/bin/mate-screenshot')):
            lines.insert(-1, '    <Key keycode="111">exec: mate-screenshot</Key>'+"\n")
            lines.insert(-1, '    <Key mask="C" keycode="111">exec: mate-screenshot -w</Key>'+"\n")

        ## conky がインストールされていれば、自動起動を設定

        if (os.path.exists('/usr/local/bin/conky')):
            lines.insert(-1, '    <StartupCommand>/usr/local/bin/conky</StartupCommand>'+"\n")

#####
    # @brief applications/*.desktop を検索して
    #    プログラム名 → アイコンファイル名の辞書を返す
    #    Fluxbox と違って png で良い
    # @param env           環境変数クラス
    # @param dic_exec_icon .desktop より取得した編集前の exec → icon 辞書
    # @return exec → icon ファイル名フルパス の辞書

    def get_dic_exec_icon(self, env, dic_exec_icon):

        ## exe → icon 辞書の妥当性をチェック
        ## 妥当でなければ変更

        ## 有効な拡張子、ディレクトリ(どちらも優先順位順)

        effect_extend = [ '.xpm', '.png', '.svg' ]
        effect_directory = [ env.directory_xpm, env.directory_png, env.directory_icon_apps ]

        for key, value in dic_exec_icon.items():                                ## exec → icon 辞書作成
            if (os.path.exists(value)):                                         ## icon が存在する
                continue                                                        ## 終了

            if (not '.' in value):                                              ## icon が存在しない . を含まない
                for extend in effect_extend:                                    ## 拡張子として有効なものを検索

                    for directory in effect_directory:
                        icon = directory + '/' + value + extend                 ## icon ファイル名組み立て

                        if (os.path.exists(icon)):                              ## 存在する
                            if (extend == '.svg'):                              ## 拡張子が .svg であれば
                                to_icon = self.directory_custom + '/' + value + '.png'

                                env.convert(icon, to_icon)                      ## .png として作成しなおし
                                icon = to_icon

                            dic_exec_icon[key] = icon                           ## icon として設定する
                            break                                               ## break
                    else:
                        continue
                    break
            else:                                                               ## . を含む
                ## 苦し紛れの特殊処理(これは、あんまりだけれども)

                if (value == 'org.gnome.nautilus'):
                    value += '.svg'

                for directory in effect_directory:                              ## 有効なディレクトリ順に検索
                    icon = directory + "/" + value

                    if (os.path.exists(icon)):                                  ## フルパス/ファイル名 が存在する
                        dirname, name, extend = env.mysplit(icon)               ## フルパスを分解

                        for ef_extend in effect_extend:                         ## 拡張子として有効なものを検索
                            if (ef_extend == extend):                           ## 有効なものであれば

                                if (extend == '.svg'):                          ## 拡張子が .svg であれば

                                    to_icon = self.directory_custom + '/' + value.rstrip('.svg') + '.png'
 「更新」「ログアウト」「再起動」「シャットダウン」のアイコン検索を追加しています。  その他、ディレクトリ名の変数を変更しています。

#####
    # @brief applications/*.desktop を検索して
    #    プログラム名 → アイコンファイル名の辞書を返す
    #    Fluxbox と違って png で良い
    # @param env           環境変数クラス
    # @param dic_exec_icon .desktop より取得した編集前の exec → icon 辞書
    # @return exec → icon ファイル名フルパス の辞書

    def get_dic_exec_icon(self, env, dic_exec_icon):

        ## 有効な拡張子、ディレクトリ(どちらも優先順位順)

        effect_extend = [ '.xpm', '.png', '.svg' ]
        effect_directory = [ env.directory_xpm, env.directory_png, env.directory_icon_apps ]

        dic_exec_icon['update'] = 'system-software-update'
        dic_exec_icon['logout'] = 'computer-log-out'
        dic_exec_icon['reboot'] = 'system-reboot'
        dic_exec_icon['shutdown'] = 'system-shutdown'

        ## exe → icon 辞書の妥当性をチェック
        ## 妥当でなければ変更

        for key, value in dic_exec_icon.items():                                ## exec → icon 辞書作成
            if (os.path.exists(value)):                                         ## icon が存在する
                continue                                                        ## 終了

            if (not '.' in value):                                              ## icon が存在しない . を含まない
                for extend in effect_extend:                                    ## 拡張子として有効なものを検索

                    for directory in effect_directory:
                        icon = directory + '/' + value + extend                 ## icon ファイル名組み立て

                        if (os.path.exists(icon)):                              ## 存在する
                            if (extend == '.svg'):                              ## 拡張子が .svg であれば
                                to_icon = self.icon_directory + '/' + value + '.png'
earthcar(アースカー)
それがだいじWi-Fi
マイニングベース
U-NEXT
ネットオークションの相場、統計、価格比較といえばオークファン