Passed
Push — master ( acaf9b...fbbf97 )
by Yoshihiro
44s queued 10s
created

CP   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 163
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 75
dl 0
loc 163
rs 10
c 0
b 0
f 0
wmc 17

7 Methods

Rating   Name   Duplication   Size   Complexity  
B ComplementProcessingClass.get_current_insert_word() 0 40 5
A ComplementProcessingClass.remove_list() 0 11 1
A ComplementProcessingClass.selection() 0 20 2
A ComplementProcessingClass.auto_complete() 0 28 2
A ComplementProcessingClass.get_keywords() 0 24 4
A ComplementProcessingClass.tab() 0 15 2
A ComplementProcessingClass.__init__() 0 9 1
1
import tkinter as tk
2
3
4
class ComplementProcessingClass():
5
    """ 補完処理のクラス
6
7
    ・補完処理にあるプログラム群
8
9
    """
10
    def __init__(self, app, tokenizer):
11
        """
12
        Args:
13
            app (instance): lineframeインスタンス
14
            tokenizer (instance): Tokenizerインスタンス
15
16
        """
17
        self.APP = app
18
        self.TOKENIZER = tokenizer
19
20
    def tab(self, event=None):
21
        """タブ押下時の処理
22
23
        ・タブキーを押したときに補完リストを出す。
24
25
        Args:
26
            event (instance): tkinter.Event のインスタンス
27
28
        """
29
        # 文字を選択していないとき
30
        sel_range = self.APP.text.tag_ranges('sel')
31
        if not sel_range:
32
            return self.auto_complete()
33
        else:
34
            return
35
36
    def auto_complete(self):
37
        """補完リストの設定
38
39
        ・補完リストの設定をする。
40
41
        """
42
        self.auto_complete_list = tk.Listbox(self.APP.text)
43
        # エンターでそのキーワードを選択
44
        self.auto_complete_list.bind('<Return>', self.selection)
45
        self.auto_complete_list.bind('<Double-1>', self.selection)
46
        # エスケープ、タブ、他の場所をクリックで補完リスト削除
47
        self.auto_complete_list.bind('<Escape>', self.remove_list)
48
        self.auto_complete_list.bind('<Tab>', self.remove_list)
49
        self.auto_complete_list.bind('<FocusOut>', self.remove_list)
50
        # (x,y,width,height,baseline)
51
        x, y, width, height, _ = self.APP.text.dlineinfo(
52
            'insert'
53
        )
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
        """
74
        text = ''
75
        text, _, _ = self.get_current_insert_word()
76
        my_func_and_class = set()
77
        # コード補完リストをTreeviewにある'名前'から得る
78
        children = self.APP.tree.get_children('data/character')
79
        for child in children:
80
            childname = self.APP.tree.item(child, "text")
81
            # 前列の文字列と同じものを選び出す
82
            if childname.startswith(text) or childname.startswith(
83
                text.title()
84
            ):
85
                my_func_and_class.add(childname)
86
87
        result = list(my_func_and_class)
88
        return result
89
90
    def remove_list(self, event=None):
91
        """補完リストの削除処理
92
93
        ・補完リストを削除し、テキストボックスにフォーカスを戻す。
94
95
        Args:
96
            event (instance): tkinter.Event のインスタンス
97
98
        """
99
        self.auto_complete_list.destroy()
100
        self.APP.text.focus()  # テキストウィジェットにフォーカスを戻す
101
102
    def selection(self, event=None):
103
        """補完リストでの選択後の処理
104
105
        ・補完リストを選択したときにその文字を入力する。
106
107
        Args:
108
            event (instance): tkinter.Event のインスタンス
109
110
        """
111
        # リストの選択位置を取得
112
        select_index = self.auto_complete_list.curselection()
113
        if select_index:
114
            # リストの表示名を取得
115
            value = self.auto_complete_list.get(select_index)
116
117
            # 現在入力中の単語位置の取得
118
            _, start, end = self.get_current_insert_word()
119
            self.APP.text.delete(start, end)
120
            self.APP.text.insert('insert', value)
121
            self.remove_list()
122
123
    def get_current_insert_word(self):
124
        """現在入力中の単語と位置を取得
125
126
        ・現在入力している単語とその位置を取得する。
127
128
        """
129
        text = ''
130
        start_i = 1
131
        end_i = 0
132
        while True:
133
            start = 'insert-{0}c'.format(start_i)
134
            end = 'insert-{0}c'.format(end_i)
135
            text = self.APP.text.get(start, end)
136
            # 1文字ずつ見て、スペース、改行、タブ、空文字、句読点にぶつかったら終わり
137
            if text in (' ', ' ', '\t', '\n', '', '、', '。'):
138
                text = self.APP.text.get(end, 'insert')
139
140
                # 最終単語を取得する
141
                pri = [
142
                    token.surface for token in self.TOKENIZER.tokenize(
143
                        text
144
                    )
145
                ]
146
                hin = [
147
                    token.part_of_speech.split(',')[0] for token
148
                    in self.TOKENIZER.tokenize(text)
149
                ]
150
                if len(pri) > 0:
151
                    if hin[len(pri)-1] == u'名詞':
152
                        text = pri[len(pri)-1]
153
                    else:
154
                        text = ""
155
                else:
156
                    text = ""
157
158
                end = 'insert-{0}c'.format(len(text))
159
                return text, end, 'insert'
160
161
            start_i += 1
162
            end_i += 1
163