Passed
Push — master ( 3731d5...59a60b )
by Yoshihiro
02:04
created

FP.FindProcessingClass.replacement()   A

Complexity

Conditions 4

Size

Total Lines 36
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 4.0032

Importance

Changes 0
Metric Value
cc 4
eloc 17
nop 2
dl 0
loc 36
ccs 16
cts 17
cp 0.9412
crap 4.0032
rs 9.55
c 0
b 0
f 0
1
#!/usr/bin/env python3
2 1
import tkinter as tk
3 1
import tkinter.ttk as ttk
4 1
import tkinter.messagebox as messagebox
5
6
7 1
class FindProcessingClass():
8
    """検索置換のクラス.
9
10
    ・検索置換するためのプログラム群
11
12
    Args:
13
        app (instance): MainProcessingClassインスタンス
14
15
    Attributes:
16
        replacement_check (bool): 検索ダイアログが表示されているTrue
17
        next_pos (str): 次の検索位置 例.(1.0)
18
        find_text (str): 検索文字列
19
20
    """
21 1
    def __init__(self, app):
22 1
        self.replacement_check = 0
23 1
        self.next_pos = ""
24 1
        self.find_text = ""
25 1
        self.APP = app
26
27 1
    def push_keys(self, event=None):
28
        """キーが押されたときの処理.
29
30
        ・何かキーが押されたときに検索処理を中断する。
31
32
        Args:
33
            event (instance): tkinter.Event のインスタンス
34
35
        """
36
        # 検索処理を中断する
37 1
        self.replacement_check = 0
38
39 1
    def find_dialog(self, event=None):
40
        """検索ダイアログを作成.
41
42
        ・検索ダイアログを作成する。
43
44
        Args:
45
            event (instance): tkinter.Event のインスタンス
46
47
        """
48 1
        search_win = tk.Toplevel(self.APP)
49 1
        self.text_var = ttk.Entry(search_win, width=40)
50 1
        self.text_var.grid(
51
            row=0,
52
            column=0,
53
            columnspan=2,
54
            padx=5,
55
            pady=5,
56
            sticky=tk.W+tk.E,
57
            ipady=3
58
        )
59 1
        button = ttk.Button(
60
            search_win,
61
            text=u'検索',
62
            width=str(u'検索'),
63
            padding=(10, 5),
64
            command=self.search
65
        )
66 1
        button.grid(row=1, column=0)
67 1
        button2 = ttk.Button(
68
            search_win,
69
            text=u'昇順検索',
70
            width=str(u'昇順検索'),
71
            padding=(10, 5),
72
            command=self.search_forward
73
        )
74 1
        button2.grid(row=1, column=1)
75
        # 最前面に表示し続ける
76 1
        search_win.attributes("-topmost", True)
77 1
        search_win.title(u'検索')
78 1
        self.text_var.focus()
79
80 1
    def replacement_dialog(self, event=None):
81
        """置換ダイアログを作成.
82
83
        ・置換ダイアログを作成する。
84
85
        Args:
86
            event (instance): tkinter.Event のインスタンス
87
88
        """
89 1
        self.replacement_win = tk.Toplevel(self.APP)
90 1
        self.text_var = ttk.Entry(self.replacement_win, width=40)
91 1
        self.text_var.grid(
92
            row=0,
93
            column=0,
94
            columnspan=2,
95
            padx=5,
96
            pady=5,
97
            sticky=tk.W+tk.E,
98
            ipady=3
99
        )
100 1
        self.replacement_var = ttk.Entry(self.replacement_win, width=40)
101 1
        self.replacement_var.grid(
102
            row=1,
103
            column=0,
104
            columnspan=2,
105
            padx=5,
106
            pady=5,
107
            sticky=tk.W+tk.E,
108
            ipady=3
109
        )
110 1
        button = ttk.Button(
111
            self.replacement_win,
112
            text=u'検索',
113
            width=str(u'検索'),
114
            padding=(10, 5),
115
            command=self.search
116
        )
117 1
        button.grid(row=2, column=0)
118 1
        button2 = ttk.Button(
119
            self.replacement_win,
120
            text=u'置換',
121
            width=str(u'置換'),
122
            padding=(10, 5),
123
            command=self.replacement
124
        )
125 1
        button2.grid(row=2, column=1)
126
        # 最前面に表示し続ける
127 1
        self.replacement_win.attributes("-topmost", True)
128 1
        self.replacement_win.title(u'置換')
129 1
        self.text_var.focus()
130
        # ウインドウが閉じられたときの処理
131 1
        self.replacement_win.protocol(
132
            "WM_DELETE_WINDOW",
133
            self.replacement_dialog_on_closing
134
            )
135
136 1
    def replacement_dialog_on_closing(self):
137
        """検索ウインドウが閉じられたときの処理.
138
139
        ・検索ダイアログが閉じられたことがわかるようにする。
140
141
        """
142 1
        self.replacement_check = 0
143 1
        self.replacement_win.destroy()
144
145 1
    def search(self, event=None):
146
        """検索処理.
147
148
        ・検索処理をする。空欄なら処理しない、違うなら最初から、
149
        同じなら次のを検索する。
150
151
        Args:
152
            event (instance): tkinter.Event のインスタンス
153
154
        """
155
        # 現在選択中の部分を解除
156 1
        self.APP.text.tag_remove('sel', '1.0', 'end')
157
158
        # 現在検索ボックスに入力されてる文字
159 1
        now_text = self.text_var.get()
160 1
        if not now_text:
161
            # 空欄だったら処理しない
162
            pass
163 1
        elif now_text != self.find_text:
164
            # 前回の入力と違う文字なら、検索を最初から行う
165 1
            index = '0.0'
166 1
            self.search_next(now_text, index, 0)
167
        else:
168
            # 前回の入力と同じなら、検索の続きを行う
169 1
            self.search_next(now_text, self.next_pos, 1)
170
171
        # 今回の入力を、「前回入力文字」にする
172 1
        self.find_text = now_text
173
174 1
    def replacement(self, event=None):
175
        """置換処理.
176
177
        ・置換処理をする。空欄なら処理しない、違うなら初めから、
178
        同じなら次を検索する。
179
180
        Args:
181
            event (instance): tkinter.Event のインスタンス
182
183
        """
184
        # 現在選択中の部分を解除
185 1
        self.APP.text.tag_remove('sel', '1.0', 'end')
186
187
        # 現在検索ボックスに入力されてる文字
188 1
        now_text = self.text_var.get()
189 1
        replacement_text = self.replacement_var.get()
190 1
        if not now_text or not replacement_text:
191
            # 空欄だったら処理しない
192
            pass
193 1
        elif now_text != self.find_text:
194
            # 前回の入力と違う文字なら、検索を最初から行う
195 1
            self.replacement_check = 1
196 1
            index = '0.0'
197 1
            self.search_next(now_text, index, 0)
198
        else:
199
            # 前回の入力と同じなら、検索の続きを行う
200 1
            self.replacement_check = 1
201
            # 検索文字の置換を行なう
202 1
            start = self.next_pos
203 1
            end = '{0} + {1}c'.format(self.next_pos, len(now_text))
204 1
            self.APP.text.delete(start, end)
205 1
            self.APP.text.insert(start, replacement_text)
206 1
            self.search_next(now_text, self.next_pos, 1)
207
208
        # 今回の入力を、「前回入力文字」にする
209 1
        self.find_text = now_text
210
211 1
    def search_forward(self, event=None):
212
        """昇順検索処理.
213
214
        ・昇順検索をする。空欄なら処理しない、違うなら初めから、
215
        同じなら次を検索する。
216
217
        Args:
218
            event (instance): tkinter.Event のインスタンス
219
220
        """
221
        # 現在選択中の部分を解除
222 1
        self.APP.text.tag_remove('sel', '1.0', 'end')
223
224
        # 現在検索ボックスに入力されてる文字
225 1
        text = self.text_var.get()
226 1
        if not text:
227
            # 空欄だったら処理しない
228
            pass
229 1
        elif text != self.find_text:
230
            # 前回の入力と違う文字なら、検索を最初から行う
231 1
            index = 'end'
232 1
            self.search_next(text, index, 2)
233
        else:
234
            # 前回の入力と同じなら、検索の続きを行う
235 1
            self.search_next(text, self.next_pos, 2)
236
237
        # 今回の入力を、「前回入力文字」にする
238 1
        self.find_text = text
239
240 1
    def search_next(self, search, index, case):
241
        """検索のメイン処理.
242
243
        ・検索できれば選択をする。できなければ、ダイアログを出して終了。
244
245
        Args:
246
            search (str): 検索文字列
247
            index (str): 検索位置 ex. (1.0)
248
            case (int): 0.初めから検索 1.次に検索 2.昇順検索
249
250
        """
251 1
        if case == 2:
252 1
            backwards = True
253 1
            stopindex = '0.0'
254 1
            index = '{0}'.format(index)
255 1
        elif case == 0:
256 1
            backwards = False
257 1
            stopindex = 'end'
258 1
            index = '{0}'.format(index)
259
        else:
260 1
            backwards = False
261 1
            stopindex = 'end'
262 1
            index = '{0} + 1c'.format(index)
263
264 1
        pos = self.APP.text.search(
265
            search, index,
266
            stopindex=stopindex,
267
            backwards=backwards
268
        )
269 1
        if not pos:
270 1
            if case == 2:
271 1
                index = "end"
272
            else:
273 1
                index = "0.0"
274
275 1
            pos = self.APP.text.search(
276
                search, index,
277
                stopindex=stopindex,
278
                backwards=backwards
279
            )
280 1
            if not pos:
281 1
                messagebox.showinfo(
282
                    "検索",
283
                    "最後まで検索しましたが検索文字はありませんでした。"
284
                )
285 1
                self.replacement_check = 0
286 1
                return
287
288 1
        self.next_pos = pos
289 1
        start = pos
290 1
        end = '{0} + {1}c'.format(pos, len(search))
291 1
        self.APP.text.tag_add('sel', start, end)
292 1
        self.APP.text.mark_set('insert', start)
293 1
        self.APP.text.see('insert')
294
        self.APP.text.focus()
295