FindProcessingClass.search_next()   B
last analyzed

Complexity

Conditions 6

Size

Total Lines 52
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

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