ComplementProcessingClass.selection()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 19
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 19
rs 10
c 0
b 0
f 0
cc 2
nop 2
1
#!/usr/bin/env python3
2
import tkinter as tk
3
4
from . import Definition
5
6
7
class ComplementProcessingClass(Definition.DefinitionClass):
8
    """補完処理のクラス.
9
10
    ・補完処理にあるプログラム群
11
12
    Args:
13
        app (instance): MainProcessingClass のインスタンス
14
        tokenizer (instance): Tokenizer のインスタンス
15
        locale_var (str): ロケーション
16
        master (instance): toplevel のインスタンス
17
    """
18
19
    def __init__(self, app, tokenizer, locale_var, master=None):
20
        super().__init__(locale_var, master)
21
        self.app = app
22
        self.tokenizer = tokenizer
23
24
    def tab(self, event=None):
25
        """タブ押下時の処理.
26
27
        ・タブキーを押したときに補完リストを出す。
28
29
        Args:
30
            event (instance): tkinter.Event のインスタンス
31
        """
32
        # 文字を選択していないとき
33
        sel_range = self.app.NovelEditor.tag_ranges("sel")
34
        if not sel_range:
35
            return self.auto_complete()
36
        else:
37
            return
38
39
    def auto_complete(self):
40
        """補完リストの設定.
41
42
        ・補完リストの設定をする。
43
        """
44
        self.auto_complete_list = tk.Listbox(self.app.NovelEditor)
45
        # エンターでそのキーワードを選択
46
        self.auto_complete_list.bind("<Return>", self.selection)
47
        self.auto_complete_list.bind("<Double-1>", self.selection)
48
        # エスケープ、タブ、他の場所をクリックで補完リスト削除
49
        self.auto_complete_list.bind("<Escape>", self.remove_list)
50
        self.auto_complete_list.bind("<Tab>", self.remove_list)
51
        self.auto_complete_list.bind("<FocusOut>", self.remove_list)
52
        # (x,y,width,height,baseline)
53
        x, y, width, height, _ = self.app.NovelEditor.dlineinfo("insert")
54
        # 現在のカーソル位置のすぐ下に補完リストを貼る
55
        self.auto_complete_list.place(x=x + width, y=y + height)
56
        # 補完リストの候補を作成
57
        for word in self.get_keywords():
58
            self.auto_complete_list.insert(tk.END, word)
59
60
        # 補完リストをフォーカスし、0番目を選択している状態に
61
        self.auto_complete_list.focus_set()
62
        self.auto_complete_list.selection_set(0)
63
        return "break"
64
65
    def get_keywords(self):
66
        """補完リストの候補キーワードを作成.
67
68
        ・補完リストに表示するキーワードを得る。
69
70
        Returns:
71
            str: 補完リスト配列
72
        """
73
        text = ""
74
        text, _, _ = self.get_current_insert_word()
75
        my_func_and_class = set()
76
        # コード補完リストをTreeviewにある'名前'から得る
77
        children = self.app.tree.get_children("data/character")
78
        for child in children:
79
            childname = self.app.tree.item(child, "text")
80
            # 前列の文字列と同じものを選び出す
81
            if childname.startswith(text) or childname.startswith(text.title()):
82
                my_func_and_class.add(childname)
83
84
        result = list(my_func_and_class)
85
        return result
86
87
    def remove_list(self, event=None):
88
        """補完リストの削除処理.
89
90
        ・補完リストを削除し、テキストボックスにフォーカスを戻す。
91
92
        Args:
93
            event (instance): tkinter.Event のインスタンス
94
        """
95
        self.auto_complete_list.destroy()
96
        self.app.NovelEditor.focus()  # テキストウィジェットにフォーカスを戻す
97
98
    def selection(self, event=None):
99
        """補完リストでの選択後の処理.
100
101
        ・補完リストを選択したときにその文字を入力する。
102
103
        Args:
104
            event (instance): tkinter.Event のインスタンス
105
        """
106
        # リストの選択位置を取得
107
        select_index = self.auto_complete_list.curselection()
108
        if select_index:
109
            # リストの表示名を取得
110
            value = self.auto_complete_list.get(select_index)
111
112
            # 現在入力中の単語位置の取得
113
            _, start, end = self.get_current_insert_word()
114
            self.app.NovelEditor.delete(start, end)
115
            self.app.NovelEditor.insert("insert", value)
116
            self.remove_list()
117
118
    def get_current_insert_word(self):
119
        """現在入力中の単語と位置を取得.
120
121
        ・現在入力している単語とその位置を取得する。
122
        """
123
        text = ""
124
        start_i = 1
125
        end_i = 0
126
        while True:
127
            start = "insert-{0}c".format(start_i)
128
            end = "insert-{0}c".format(end_i)
129
            text = self.app.NovelEditor.get(start, end)
130
            # 1文字ずつ見て、スペース、改行、タブ、空文字、句読点にぶつかったら終わり
131
            if text in (" ", " ", "\t", "\n", "", "、", "。"):
132
                text = self.app.NovelEditor.get(end, "insert")
133
134
                # 最終単語を取得する
135
                pri = [token.surface for token in self.tokenizer.tokenize(text)]
136
                hin = [
137
                    token.part_of_speech.split(",")[0]
138
                    for token in self.tokenizer.tokenize(text)
139
                ]
140
                if len(pri) > 0:
141
                    if hin[len(pri) - 1] == "名詞":
142
                        text = pri[len(pri) - 1]
143
                    else:
144
                        text = ""
145
                else:
146
                    text = ""
147
148
                end = "insert-{0}c".format(len(text))
149
                return text, end, "insert"
150
151
            start_i += 1
152
            end_i += 1
153