Test Failed
Push — master ( b264b0...0ab505 )
by Yoshihiro
03:23
created

FindProcessingClass.search_next()   B

Complexity

Conditions 6

Size

Total Lines 57
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 57
rs 8.0346
c 0
b 0
f 0
cc 6
nop 4

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
#!/usr/bin/env python3
2
import tkinter as tk
3
import tkinter.ttk as ttk
4
import tkinter.messagebox as messagebox
5
from . import Definition
6
7
8
class FindProcessingClass(Definition.DefinitionClass):
9
    """検索置換のクラス.
10
11
    ・検索置換するためのプログラム群
12
13
    Args:
14
        app (instance): MainProcessingClass のインスタンス
15
        locale_var (str): ロケーション
16
        master (instance): toplevel のインスタンス
17
    """
18
    replacement_check = False
19
    """検索ダイアログが表示されているTrue."""
20
    next_pos = ""
21
    """次の検索位置 例.(1.0)."""
22
    find_text = ""
23
    """検索文字列."""
24
25
    def __init__(self, app, locale_var, master=None):
26
        super().__init__(locale_var, master)
27
        self.app = app
28
29
    def push_keys(self, event=None):
30
        """キーが押されたときの処理.
31
32
        ・何かキーが押されたときに検索処理を中断する。
33
34
        Args:
35
            event (instance): tkinter.Event のインスタンス
36
        """
37
        # 検索処理を中断する
38
        self.replacement_check_input(False)
39
40
    def find_dialog(self, event=None):
41
        """検索ダイアログを作成.
42
43
        ・検索ダイアログを作成する。
44
45
        Args:
46
            event (instance): tkinter.Event のインスタンス
47
        """
48
        search_win = tk.Toplevel(self.app)
49
        self.text_var = ttk.Entry(search_win, width=40)
50
        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
        button = ttk.Button(
60
            search_win,
61
            text=self.app.dic.get_dict("Find"),
62
            width=str(self.app.dic.get_dict("Find")),
63
            padding=(10, 5),
64
            command=self.search
65
        )
66
        button.grid(row=1, column=0)
67
        button2 = ttk.Button(
68
            search_win,
69
            text=self.app.dic.get_dict("Asc find"),
70
            width=str(self.app.dic.get_dict("Asc find")),
71
            padding=(10, 5),
72
            command=self.search_forward
73
        )
74
        button2.grid(row=1, column=1)
75
        # 最前面に表示し続ける
76
        search_win.attributes("-topmost", True)
77
        search_win.resizable(False, False)
78
        search_win.title(self.app.dic.get_dict("Find"))
79
        self.text_var.focus()
80
81
    def replacement_dialog(self, event=None):
82
        """置換ダイアログを作成.
83
84
        ・置換ダイアログを作成する。
85
86
        Args:
87
            event (instance): tkinter.Event のインスタンス
88
        """
89
        self.replacement_win = tk.Toplevel(self.app)
90
        self.text_var = ttk.Entry(self.replacement_win, width=40)
91
        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
        self.replacement_var = ttk.Entry(self.replacement_win, width=40)
101
        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
        button = ttk.Button(
111
            self.replacement_win,
112
            text=self.app.dic.get_dict("Find"),
113
            width=str(self.app.dic.get_dict("Find")),
114
            padding=(10, 5),
115
            command=self.search
116
        )
117
        button.grid(row=2, column=0)
118
        button2 = ttk.Button(
119
            self.replacement_win,
120
            text=self.app.dic.get_dict("Replacement"),
121
            width=str(self.app.dic.get_dict("Replacement")),
122
            padding=(10, 5),
123
            command=self.replacement
124
        )
125
        button2.grid(row=2, column=1)
126
        # 最前面に表示し続ける
127
        self.replacement_win.attributes("-topmost", True)
128
        self.replacement_win.resizable(False, False)
129
        self.replacement_win.title(
130
            self.app.dic.get_dict("Replacement")
131
        )
132
        self.text_var.focus()
133
        # ウインドウが閉じられたときの処理
134
        self.replacement_win.protocol(
135
            "WM_DELETE_WINDOW",
136
            self.replacement_dialog_on_closing
137
            )
138
139
    def replacement_dialog_on_closing(self):
140
        """検索ウインドウが閉じられたときの処理.
141
142
        ・検索ダイアログが閉じられたことがわかるようにする。
143
        """
144
        self.replacement_check_input(False)
145
        self.replacement_win.destroy()
146
147
    def search(self, event=None):
148
        """検索処理.
149
150
        ・検索処理をする。空欄なら処理しない、違うなら最初から、
151
        同じなら次のを検索する。
152
153
        Args:
154
            event (instance): tkinter.Event のインスタンス
155
        """
156
        # 現在選択中の部分を解除
157
        self.app.NovelEditor.tag_remove('sel', '1.0', 'end')
158
159
        # 現在検索ボックスに入力されてる文字
160
        now_text = self.text_var.get()
161
        if not now_text:
162
            # 空欄だったら処理しない
163
            pass
164
        elif now_text != self.find_text:
165
            # 前回の入力と違う文字なら、検索を最初から行う
166
            index = '0.0'
167
            self.search_next(now_text, index, 0)
168
        else:
169
            # 前回の入力と同じなら、検索の続きを行う
170
            self.search_next(now_text, self.next_pos, 1)
171
172
        # 今回の入力を、「前回入力文字」にする
173
        self.find_text_input(now_text)
174
175
    def replacement(self, event=None):
176
        """置換処理.
177
178
        ・置換処理をする。空欄なら処理しない、違うなら初めから、
179
        同じなら次を検索する。
180
181
        Args:
182
            event (instance): tkinter.Event のインスタンス
183
        """
184
        # 現在選択中の部分を解除
185
        self.app.NovelEditor.tag_remove('sel', '1.0', 'end')
186
187
        # 現在検索ボックスに入力されてる文字
188
        now_text = self.text_var.get()
189
        replacement_text = self.replacement_var.get()
190
        if not now_text or not replacement_text:
191
            # 空欄だったら処理しない
192
            pass
193
        elif now_text != self.find_text:
194
            # 前回の入力と違う文字なら、検索を最初から行う
195
            self.replacement_check_input(True)
196
            index = '0.0'
197
            self.search_next(now_text, index, 0)
198
        else:
199
            # 前回の入力と同じなら、検索の続きを行う
200
            self.replacement_check_input(True)
201
            # 検索文字の置換を行なう
202
            start = self.next_pos
203
            end = '{0} + {1}c'.format(self.next_pos, len(now_text))
204
            self.app.NovelEditor.delete(start, end)
205
            self.app.NovelEditor.insert(start, replacement_text)
206
            self.search_next(now_text, self.next_pos, 1)
207
208
        # 今回の入力を、「前回入力文字」にする
209
        self.find_text_input(now_text)
210
211
    def search_forward(self, event=None):
212
        """昇順検索処理.
213
214
        ・昇順検索をする。空欄なら処理しない、違うなら初めから、
215
        同じなら次を検索する。
216
217
        Args:
218
            event (instance): tkinter.Event のインスタンス
219
        """
220
        # 現在選択中の部分を解除
221
        self.app.NovelEditor.tag_remove('sel', '1.0', 'end')
222
223
        # 現在検索ボックスに入力されてる文字
224
        text = self.text_var.get()
225
        if not text:
226
            # 空欄だったら処理しない
227
            pass
228
        elif text != self.find_text:
229
            # 前回の入力と違う文字なら、検索を最初から行う
230
            index = 'end'
231
            self.search_next(text, index, 2)
232
        else:
233
            # 前回の入力と同じなら、検索の続きを行う
234
            self.search_next(text, self.next_pos, 2)
235
236
        # 今回の入力を、「前回入力文字」にする
237
        self.find_text_input(text)
238
239
    def search_next(self, search, index, case):
240
        """検索のメイン処理.
241
242
        ・検索できれば選択をする。できなければ、ダイアログを出して終了。
243
244
        Args:
245
            search (str): 検索文字列
246
            index (str): 検索位置 ex. (1.0)
247
            case (int): 0.初めから検索 1.次に検索 2.昇順検索
248
        """
249
        if case == 2:
250
            backwards = True
251
            stopindex = '0.0'
252
            index = '{0}'.format(index)
253
        elif case == 0:
254
            backwards = False
255
            stopindex = 'end'
256
            index = '{0}'.format(index)
257
        else:
258
            backwards = False
259
            stopindex = 'end'
260
            index = '{0} + 1c'.format(index)
261
262
        pos = self.app.NovelEditor.search(
263
            search, index,
264
            stopindex=stopindex,
265
            backwards=backwards
266
        )
267
        if not pos:
268
            if case == 2:
269
                index = "end"
270
            else:
271
                index = "0.0"
272
273
            pos = self.app.NovelEditor.search(
274
                search, index,
275
                stopindex=stopindex,
276
                backwards=backwards
277
            )
278
            if not pos:
279
                messagebox.showinfo(
280
                    self.app.dic.get_dict("Find"),
281
                    self.app.dic.get_dict(
282
                        "I searched to the end,"
283
                        " but there were no search characters."
284
                    )
285
                )
286
                self.replacement_check_input(False)
287
                return
288
289
        self.next_pos_input(pos)
290
        start = pos
291
        end = '{0} + {1}c'.format(pos, len(search))
292
        self.app.NovelEditor.tag_add('sel', start, end)
293
        self.app.NovelEditor.mark_set('insert', start)
294
        self.app.NovelEditor.see('insert')
295
        self.app.NovelEditor.focus()
296
297
    @classmethod
298
    def replacement_check_input(cls, replacement_check):
299
        """検索ダイアログが表示されているかを入力.
300
301
        ・検索ダイアログが表示されているかを入力する。
302
303
        Args:
304
            replacement_check (bool): 検索ダイアログが表示されているTrue
305
        """
306
        cls.replacement_check = replacement_check
307
308
    @classmethod
309
    def find_text_input(cls, find_text):
310
        """検索文字を入力.
311
312
        ・検索文字をクラス変数に入力する。
313
314
        Args:
315
            find_text (str): 検索文字
316
        """
317
        cls.find_text = find_text
318
319
    @classmethod
320
    def next_pos_input(cls, next_pos):
321
        """検索位置を入力.
322
323
        ・検索位置をクラス変数に入力する。
324
325
        Args:
326
            next_pos (str): 検索位置
327
        """
328
        cls.next_pos = next_pos
329