Test Failed
Push — master ( 705b0f...728f1f )
by Yoshihiro
03:24
created

neditor.fp   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 318
Duplicated Lines 16.98 %

Importance

Changes 0
Metric Value
eloc 166
dl 54
loc 318
rs 10
c 0
b 0
f 0
wmc 24

12 Methods

Rating   Name   Duplication   Size   Complexity  
A FindProcessingClass.push_keys() 0 10 1
A FindProcessingClass.search_forward() 27 27 3
A FindProcessingClass.__init__() 0 2 1
A FindProcessingClass.find_dialog() 0 39 1
A FindProcessingClass.next_pos_input() 0 10 1
B FindProcessingClass.search_next() 0 54 6
A FindProcessingClass.search() 27 27 3
A FindProcessingClass.replacement() 0 35 4
A FindProcessingClass.find_text_input() 0 10 1
B FindProcessingClass.replacement_dialog() 0 53 1
A FindProcessingClass.replacement_dialog_on_closing() 0 7 1
A FindProcessingClass.replacement_check_input() 0 10 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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