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

neditor.cw.CreateWindowClass.frame_character()   B

Complexity

Conditions 1

Size

Total Lines 117
Code Lines 93

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 93
nop 1
dl 0
loc 117
rs 7.229
c 0
b 0
f 0

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
5
from . import pm
6
7
class CreateWindowClass():
8
    """画面の描画のクラス.
9
10
    ・画面描画にあるプログラム群
11
12
    Args:
13
        app (instance): MainProcessingClass のインスタンス
14
    """
15
    def __init__(self, app):
16
        self.APP = app
17
        self.BLANK_IMAGE = '''R0lGODlhHgAeAPcAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz
18
            /wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDM
19
            mQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMz
20
            MzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ
21
            /zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYA
22
            mWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZ
23
            M2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb/
24
            /5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplm
25
            mZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/
26
            M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz
27
            /8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszM
28
            mczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8z
29
            M/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z
30
            ///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///8DAwICAgIAAAACA
31
            AAAAgICAAIAAgACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
32
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
33
            AAAAAAAAAAAAAAAAACwAAAAAHgAeAAAIMgABCBxIsKDBgwgTKlzIsKHDhxAjSpxI
34
            saLFixgzatzIsaPHjyBDihxJsqTJkyhTngwIADs=
35
            '''
36
37
    def create_widgets(self):
38
        """画面の描画.
39
40
        ・メインウインドウにウェジットを配置する。
41
        """
42
        # メニューの配置
43
        File_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
44
        Edit_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
45
        List_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
46
        Processing_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
47
        Help_menu = tk.Menu(self.APP.menu_bar, tearoff=0)
48
        # ファイルメニュー
49
        File_menu.add_command(
50
            label=u'新規作成(N)',
51
            under=5,
52
            accelerator='Ctrl+N',
53
            command=self.APP.fmc.new_open
54
        )
55
        File_menu.add_command(
56
            label=u'開く(O)',
57
            under=3,
58
            accelerator='Ctrl+E',
59
            command=self.APP.fmc.open_file
60
        )
61
        File_menu.add_separator()
62
        File_menu.add_command(
63
            label=u'保存(S)',
64
            under=3,
65
            accelerator='Ctrl+S',
66
            command=self.APP.fmc.overwrite_save_file
67
        )
68
        File_menu.add_command(
69
            label=u'名前を付けて保存(W)',
70
            under=9,
71
            accelerator='Ctrl+W',
72
            command=self.APP.fmc.save_file
73
        )
74
        File_menu.add_separator()
75
        File_menu.add_command(
76
            label=u'閉じる(C)',
77
            under=4,
78
            accelerator='Ctrl+C',
79
            command=self.APP.fmc.on_closing
80
        )
81
        self.APP.menu_bar.add_cascade(
82
            label=u'ファイル(F)',
83
            under=5,
84
            menu=File_menu
85
        )
86
        # 編集メニュー
87
        Edit_menu.add_command(
88
            label=u'やり直し(R)',
89
            under=5,
90
            accelerator='Ctrl+Shift+Z',
91
            command=self.APP.emc.redo
92
        )
93
        Edit_menu.add_command(
94
            label=u'戻る(U)',
95
            under=3,
96
            accelerator='Ctrl+Z',
97
            command=self.APP.emc.undo
98
        )
99
        Edit_menu.add_separator()
100
        Edit_menu.add_command(
101
            label=u'切り取り(X)',
102
            under=5,
103
            accelerator='Ctrl+X',
104
            command=self.APP.emc.cut
105
        )
106
        Edit_menu.add_command(
107
            label=u'コピー(C)',
108
            under=4,
109
            accelerator='Ctrl+C',
110
            command=self.APP.emc.copy
111
        )
112
        Edit_menu.add_command(
113
            label=u'貼り付け(V)',
114
            under=5,
115
            accelerator='Ctrl+V',
116
            command=self.APP.emc.paste
117
        )
118
        Edit_menu.add_separator()
119
        Edit_menu.add_command(
120
            label=u'検索(F)',
121
            under=3,
122
            accelerator='Ctrl+F',
123
            command=self.APP.fpc.find_dialog
124
        )
125
        Edit_menu.add_command(
126
            label=u'置換(L)',
127
            under=3,
128
            accelerator='Ctrl+L',
129
            command=self.APP.fpc.replacement_dialog
130
        )
131
        self.APP.menu_bar.add_cascade(
132
            label=u'編集(E)',
133
            under=3,
134
            menu=Edit_menu
135
        )
136
        # 処理メニュー
137
        Processing_menu.add_command(
138
            label=u'ルビをふる(R)',
139
            under=6,
140
            accelerator='Ctrl+R',
141
            command=self.APP.pmc.ruby_huri
142
        )
143
        Processing_menu.add_command(
144
            label=u'文字数のカウント(C)',
145
            under=9,
146
            accelerator='Ctrl+Shift+C',
147
            command=self.APP.pmc.count_moji
148
        )
149
        Processing_menu.add_command(
150
            label=u'選択文字の意味(M)',
151
            under=8,
152
            accelerator='Ctrl+Shift+F',
153
            command=self.APP.pmc.find_wikipedia
154
        )
155
        Processing_menu.add_command(
156
            label=u'文章の読み上げ(B)',
157
            under=8,
158
            accelerator='Ctrl+Shift+R',
159
            command=self.APP.pmc.read_text
160
        )
161
        Processing_menu.add_command(
162
            label=u'文章校正(Y)',
163
            under=5,
164
            accelerator='Ctrl+Y',
165
            command=self.APP.pmc.yahoo
166
        )
167
        Processing_menu.add_separator()
168
        Processing_menu.add_command(
169
            label=u'フォントサイズの変更(F)',
170
            under=11,
171
            accelerator='Ctrl+Shift+F',
172
            command=self.APP.pmc.font_dialog
173
        )
174
        Processing_menu.add_separator()
175
        Processing_menu.add_command(
176
            label=u'「小説家になろう」のページを開く(U)',
177
            under=17,
178
            accelerator='Ctrl+U',
179
            command=self.APP.pmc.open_becoming_novelist_page
180
        )
181
        self.APP.menu_bar.add_cascade(
182
            label=u'処理(P)',
183
            under=3,
184
            menu=Processing_menu
185
        )
186
        # リストメニュー
187
        List_menu.add_command(
188
            label=u'項目を増やす(U)',
189
            under=7,
190
            accelerator='選択右クリック',
191
            command=self.APP.lmc.message_window
192
        )
193
        List_menu.add_command(
194
            label=u'項目を削除(D)',
195
            under=6,
196
            accelerator='選択右クリック',
197
            command=self.APP.lmc.message_window
198
        )
199
        List_menu.add_command(
200
            label=u'項目の名前を変更(C)',
201
            under=9,
202
            accelerator='Ctrl+G',
203
            command=self.APP.lmc.on_name_click
204
        )
205
        self.APP.menu_bar.add_cascade(
206
            label=u'リスト(L)',
207
            under=4,
208
            menu=List_menu
209
        )
210
        # ヘルプメニュー
211
        Help_menu.add_command(
212
            label=u'ヘルプ(H)',
213
            under=4,
214
            accelerator='Ctrl+H',
215
            command=self.APP.hmc.help
216
        )
217
        Help_menu.add_command(
218
            label=u'バージョン情報(V)',
219
            under=8,
220
            accelerator='Ctrl+Shift+V',
221
            command=self.APP.hmc.version
222
        )
223
        self.APP.menu_bar.add_cascade(
224
            label=u'ヘルプ(H)',
225
            under=4,
226
            menu=Help_menu
227
        )
228
        # ツリーコントロール、入力欄、行番号欄、スクロール部分を作成
229
        self.APP.tree = ttk.Treeview(self.APP, show="tree")
230
        self.APP.tree.grid(row=0, column=0, sticky=(tk.N, tk.S))
231
        self.frame()
232
        self.APP.fmc.tree_get_loop()
233
234
    def frame(self):
235
        """フレーム内にテキストボックスを表示.
236
237
        ・メインウインドウの右側に行番号、テキストボックス、スクロールバー
238
        を表示する。
239
        """
240
        # f1フレームにテキストエディタを表示
241
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
242
        self.APP.text = CustomText(
243
            self.APP.f1,
244
            font=(self.APP.font, self.APP.pmc.font_size),
245
            undo=True
246
        )
247
        self.APP.line_numbers = tk.Canvas(self.APP.f1, width=30)
248
        self.APP.ysb = ttk.Scrollbar(
249
            self.APP.f1,
250
            orient=tk.VERTICAL,
251
            command=self.APP.text.yview
252
        )
253
        # 入力欄にスクロールを紐付け
254
        self.APP.text.configure(yscrollcommand=self.APP.ysb.set)
255
        # 左から行番号、入力欄、スクロールウィジェット
256
        self.APP.line_numbers.grid(row=0, column=0, sticky=(tk.N, tk.S))
257
        self.APP.text.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
258
        self.APP.ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
259
        self.APP.f1.columnconfigure(1, weight=1)
260
        self.APP.f1.rowconfigure(0, weight=1)
261
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
262
        # テキスト入力欄のみ拡大されるように
263
        self.APP.columnconfigure(1, weight=1)
264
        self.APP.rowconfigure(0, weight=1)
265
        # テキストを読み取り専用にする
266
        self.APP.text.configure(state='disabled')
267
        # テキストにフォーカスを当てる
268
        self.APP.text.focus()
269
        self.APP.epc.create_event_text()
270
271
    def frame_image(self):
272
        """フレーム内にイメージフレーム表示.
273
274
        ・メインウインドウの右側にイメージキャンバス、スクロールバーを表示する。
275
        """
276
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
277
        self.APP.image_space = tk.Canvas(self.APP.f1, bg="black", width=30)
278
        self.APP.image_ysb = ttk.Scrollbar(
279
            self.APP.f1,
280
            orient=tk.VERTICAL,
281
            command=self.APP.image_space.yview
282
        )
283
        self.APP.image_xsb = ttk.Scrollbar(
284
            self.APP.f1,
285
            orient=tk.HORIZONTAL,
286
            command=self.APP.image_space.xview
287
        )
288
        self.APP.image_space.configure(xscrollcommand=self.APP.image_xsb.set)
289
        self.APP.image_space.configure(yscrollcommand=self.APP.image_ysb.set)
290
        self.APP.image_space.grid(
291
            row=0,
292
            column=1,
293
            sticky=(tk.N, tk.S, tk.W, tk.E)
294
        )
295
        self.APP.image_ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
296
        self.APP.image_xsb.grid(row=1, column=1, sticky=(tk.W, tk.E))
297
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
298
        self.APP.f1.columnconfigure(1, weight=1)
299
        self.APP.f1.rowconfigure(0, weight=1)
300
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
301
        # デフォルトの画像を設定する
302
        self.APP.image_space.photo = tk.PhotoImage(data=self.BLANK_IMAGE)
303
        self.APP.image_on_space = self.APP.image_space.create_image(
304
            0,
305
            0,
306
            anchor='nw',
307
            image=self.APP.image_space.photo
308
        )
309
        self.APP.epc.create_event_image()
310
311
    def frame_character(self):
312
        """フレーム内にイメージフレーム表示.
313
314
        ・メインウインドウの右側に呼び名、似顔絵、名前、誕生日、略歴を表示する。
315
        """
316
        # チェック有無変数
317
        self.APP.var = tk.IntVar()
318
        # value=0のラジオボタンにチェックを入れる
319
        self.APP.var.set(0)
320
        self.APP.f1 = tk.Frame(self.APP, relief=tk.RIDGE, bd=2)
321
        self.APP.label1 = tk.Label(self.APP.f1, text=u"呼び名")
322
        self.APP.txt_yobi_name = ttk.Entry(
323
            self.APP.f1, width=30,
324
            font=(self.APP.font, pm.ProcessingMenuClass.font_size)
325
        )
326
        self.APP.label2 = tk.Label(self.APP.f1, text=u"名前")
327
        self.APP.txt_name = ttk.Entry(
328
            self.APP.f1, width=40,
329
            font=(self.APP.font, pm.ProcessingMenuClass.font_size)
330
        )
331
        self.APP.f2 = tk.LabelFrame(
332
            self.APP.f1,
333
            relief=tk.RIDGE,
334
            bd=2,
335
            text=u"性別"
336
        )
337
        self.APP.rdo1 = tk.Radiobutton(
338
            self.APP.f2, value=0,
339
            variable=self.APP.var,
340
            text=u'男'
341
        )
342
        self.APP.rdo2 = tk.Radiobutton(
343
            self.APP.f2, value=1,
344
            variable=self.APP.var,
345
            text=u'女'
346
        )
347
        self.APP.rdo3 = tk.Radiobutton(
348
            self.APP.f2, value=2,
349
            variable=self.APP.var,
350
            text=u'その他'
351
        )
352
        self.APP.rdo1.grid(row=0, column=1)
353
        self.APP.rdo2.grid(row=1, column=1)
354
        self.APP.rdo3.grid(row=2, column=1)
355
        self.APP.f3 = tk.LabelFrame(
356
            self.APP.f1,
357
            relief=tk.RIDGE,
358
            bd=2,
359
            text=u"似顔絵"
360
        )
361
        self.APP.cv = self.APP.foto_canvas = tk.Canvas(
362
            self.APP.f3,
363
            bg="black",
364
            width=149,
365
            height=199
366
        )
367
        self.APP.foto_canvas.grid(row=0, column=0)
368
        self.APP.label3 = tk.Label(self.APP.f1, text=u"誕生日")
369
        self.APP.txt_birthday = ttk.Entry(
370
            self.APP.f1, width=40,
371
            font=(self.APP.font, pm.ProcessingMenuClass.font_size)
372
        )
373
        self.APP.f4 = tk.Frame(self.APP.f1)
374
        self.APP.foto_button = ttk.Button(
375
            self.APP.f4,
376
            width=5,
377
            text=u'挿入',
378
            command=self.APP.spc.btn_click
379
        )
380
        self.APP.foto_button_calcel = ttk.Button(
381
            self.APP.f4,
382
            width=5,
383
            text=u'消去',
384
            command=self.APP.spc.clear_btn_click
385
        )
386
        self.APP.foto_button.grid(row=0, column=1)
387
        self.APP.foto_button_calcel.grid(row=1, column=1)
388
        self.APP.label4 = tk.Label(self.APP.f1, text=u"略歴")
389
        self.APP.text_body = tk.Text(
390
            self.APP.f1,
391
            width=80,
392
            font=(self.APP.font, pm.ProcessingMenuClass.font_size)
393
        )
394
        self.APP.label1.grid(row=0, column=1, columnspa=2)
395
        self.APP.txt_yobi_name.grid(row=1, column=1, columnspa=2)
396
        self.APP.f2.grid(row=2, column=1, rowspan=2)
397
        self.APP.f4.grid(row=3, column=2)
398
        self.APP.f3.grid(row=0, column=3, rowspan=4)
399
        self.APP.label2.grid(row=0, column=4, sticky=(tk.N, tk.S, tk.W, tk.E))
400
        self.APP.txt_name.grid(row=1, column=4)
401
        self.APP.label3.grid(row=2, column=4)
402
        self.APP.txt_birthday.grid(row=3, column=4)
403
        self.APP.label4.grid(row=4, column=1, columnspa=4)
404
        self.APP.text_body.grid(
405
            row=5,
406
            column=1,
407
            columnspa=4,
408
            sticky=(tk.N, tk.S, tk.W, tk.E)
409
        )
410
        self.APP.f1.columnconfigure(1, weight=1)
411
        self.APP.f1.columnconfigure(4, weight=1)
412
        self.APP.f1.rowconfigure(5, weight=1)
413
414
        self.APP.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
415
        self.APP.columnconfigure(1, weight=1)
416
        self.APP.rowconfigure(0, weight=1)
417
        # デフォルトの画像を設定する
418
        self.APP.cv.photo = tk.PhotoImage(data=self.BLANK_IMAGE)
419
        self.APP.image_on_canvas = self.APP.cv.create_image(
420
            0,
421
            0,
422
            anchor='nw',
423
            image=self.APP.cv.photo
424
        )
425
426
        # キャラクターイベントを追加
427
        self.APP.epc.create_event_character()
428
429
430
class CustomText(tk.Text):
431
    """Textのイベントを拡張したウィジェット.
432
433
    ・TCl/TKを使って、textに<<Scroll>>イベントと、<<Change>>イベントを追加する。
434
435
    Args:
436
        master (instance): toplevel のインスタンス
437
    """
438
    def __init__(self, master, **kwargs):
439
        super().__init__(master, **kwargs)
440
        self.tk.eval('''
441
            proc widget_proxy {widget widget_command args} {
442
                # 引数を使用してtkウィジェットコマンドを呼び出す
443
                set result [uplevel [linsert $args 0 $widget_command]]
444
                # ビューが移動した場合、バインドできるイベントを生成する
445
                if {([lrange $args 0 1] == {xview moveto}) ||
446
                    ([lrange $args 0 1] == {xview scroll}) ||
447
                    ([lrange $args 0 1] == {yview moveto}) ||
448
                    ([lrange $args 0 1] == {yview scroll})} {
449
                    event generate  $widget <<Scroll>> -when tail
450
                }
451
                # 内容が変更された場合、バインドできるイベントを生成する
452
                if {([lindex $args 0] in {insert replace delete})} {
453
                    event generate  $widget <<Change>> -when tail
454
                }
455
                # ウィジェットコマンドから結果を返す
456
                return $result
457
            }
458
            ''')
459
        self.tk.eval('''
460
            # コマンドをリネームする
461
            rename {widget} _{widget}
462
            # コマンドを置き換える
463
            interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}
464
        '''.format(widget=str(self)))
465