Passed
Push — master ( 63399a...705b0f )
by Yoshihiro
02:57
created

NovelEditor.CW   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 464
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 315
dl 0
loc 464
ccs 137
cts 137
cp 1
rs 10
c 0
b 0
f 0
wmc 6

6 Methods

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