Passed
Push — master ( 63399a...705b0f )
by Yoshihiro
02:57
created

NovelEditor.CP   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Test Coverage

Coverage 97.01%

Importance

Changes 0
Metric Value
eloc 75
dl 0
loc 155
ccs 65
cts 67
cp 0.9701
rs 10
c 0
b 0
f 0
wmc 17

7 Methods

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