Completed
Pull Request — master (#52)
by Yoshihiro
04:22
created

novel_editor.LineFrame.open_version()   A

Complexity

Conditions 1

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 21
nop 2
dl 0
loc 32
rs 9.376
c 0
b 0
f 0
1
#!/usr/bin/env python3
2
# -*- coding: utf8 -*-
3
import os
4
import sys
5
import zipfile
6
import shutil
7
import platform
8
import tkinter as tk
9
import tkinter.ttk as ttk
10
import tkinter.messagebox as messagebox
11
import tkinter.filedialog as filedialog
12
import xml.etree.ElementTree as ET
13
14
import wikipediaapi
15
from PIL import Image, ImageTk
16
from janome.tokenizer import Tokenizer
17
18
import subfunction
19
import mydialog
20
import highlight
21
import editmenu
22
import helpmenu
23
import processingmenu
24
25
26
class CustomText(tk.Text):
27
    """Textのイベントを拡張したウィジェット
28
29
    ・textに<<Scroll>>イベントと、<<Change>>イベントを追加する。
30
31
    """
32
33
    def __init__(self, master, **kwargs):
34
        super().__init__(master, **kwargs)
35
        self.tk.eval('''
36
            proc widget_proxy {widget widget_command args} {
37
                set result [uplevel [linsert $args 0 $widget_command]]
38
                if {([lrange $args 0 1] == {xview moveto}) ||
39
                    ([lrange $args 0 1] == {xview scroll}) ||
40
                    ([lrange $args 0 1] == {yview moveto}) ||
41
                    ([lrange $args 0 1] == {yview scroll})} {
42
                    event generate  $widget <<Scroll>> -when tail
43
                }
44
                if {([lindex $args 0] in {insert replace delete})} {
45
                    event generate  $widget <<Change>> -when tail
46
                }
47
                # return the result from the real widget command
48
                return $result
49
            }
50
            ''')
51
        self.tk.eval('''
52
            rename {widget} _{widget}
53
            interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}
54
        '''.format(widget=str(self)))
55
56
57
class LineFrame(ttk.Frame):
58
    """メインフレーム処理
59
60
    ・メインに表示される画面の処理をする。
61
62
    """
63
64
    def __init__(self, master=None, **kwargs):
65
        """初期設定
66
67
        ・初期化、メニューバーの作成、画面の描画、イベントの追加をする。
68
69
        """
70
        super().__init__(master, **kwargs)
71
        self.initialize()
72
73
        self.menu_bar = tk.Menu(self.master)
74
        self.master.config(menu=self.menu_bar)
75
76
        self.create_widgets()
77
        self.create_event()
78
79
    def initialize(self):
80
        """初期化処理
81
82
        ・変数の初期化及び起動準備をする。
83
84
        """
85
        # 今の処理ししているファイルのパス
86
        self.now_path = ""
87
        # 現在開いているファイル
88
        self.file_path = ""
89
        # 検索文字列
90
        self.last_text = ""
91
        # 現在入力中の初期テキスト
92
        self.text_text = ""
93
        # 文字の大きさ
94
        self.font_size = 16
95
        self.APPID = ""
96
        if os.path.isfile("./appid.txt"):
97
            f = open("./appid.txt", "r", encoding="utf-8")
98
            self.APPID = f.read()
99
            f.close()
100
        if u"ここを消して、" in self.APPID:
101
            self.APPID = ""
102
        # フォントをOSごとに変える
103
        pf = platform.system()
104
        if pf == 'Windows':
105
            self.font = "メイリオ"
106
        elif pf == 'Darwin':  # MacOS
107
            self.font = "Osaka-等幅"
108
        elif pf == 'Linux':
109
            self.font = "IPAゴシック"
110
        # dataフォルダがあるときは、削除する
111
        if os.path.isdir('./data'):
112
            shutil.rmtree('./data')
113
        # 新しくdataフォルダを作成する
114
        for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
115
            os.makedirs('./{0}'.format(val[0]))
116
117
        # メニューバーのクラスを割り当てる
118
        self.sfc = subfunction.SubFunctionClass(self)
119
        self.hlc = highlight.HighLightClass(self, tokenizer)
0 ignored issues
show
introduced by
The variable tokenizer does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
120
        self.emc = editmenu.EditMenuClass(self)
121
        self.pmc = processingmenu.ProcessingMenuClass(
122
            self,
123
            wiki_wiki,
0 ignored issues
show
introduced by
The variable wiki_wiki does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
124
            tokenizer
125
        )
126
        self.hmc = helpmenu.HelpMenuClass(self, datas)
0 ignored issues
show
introduced by
The variable datas does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
127
128
    def create_widgets(self):
129
        """画面の描画
130
131
        ・メインウインドウにウェジットを配置する。
132
133
        """
134
        # メニューの配置
135
        File_menu = tk.Menu(self.menu_bar, tearoff=0)
136
        Edit_menu = tk.Menu(self.menu_bar, tearoff=0)
137
        List_menu = tk.Menu(self.menu_bar, tearoff=0)
138
        Processing_menu = tk.Menu(self.menu_bar, tearoff=0)
139
        Help_menu = tk.Menu(self.menu_bar, tearoff=0)
140
        # ファイルメニュー
141
        File_menu.add_command(
142
            label=u'新規作成(N)',
143
            under=5,
144
            accelerator='Ctrl+N',
145
            command=self.new_open
146
        )
147
        File_menu.add_command(
148
            label=u'開く(O)',
149
            under=3,
150
            accelerator='Ctrl+E',
151
            command=self.open_file
152
        )
153
        File_menu.add_separator()
154
        File_menu.add_command(
155
            label=u'保存(S)',
156
            under=3,
157
            accelerator='Ctrl+S',
158
            command=self.overwrite_save_file
159
        )
160
        File_menu.add_command(
161
            label=u'名前を付けて保存(W)',
162
            under=9,
163
            accelerator='Ctrl+W',
164
            command=self.save_file
165
        )
166
        File_menu.add_separator()
167
        File_menu.add_command(
168
            label=u'閉じる(C)',
169
            under=4,
170
            accelerator='Ctrl+C',
171
            command=on_closing
172
        )
173
        self.menu_bar.add_cascade(
174
            label=u'ファイル(F)',
175
            under=5,
176
            menu=File_menu
177
        )
178
        # 編集メニュー
179
        Edit_menu.add_command(
180
            label=u'やり直し(R)',
181
            under=5,
182
            accelerator='Ctrl+Shift+Z',
183
            command=self.emc.redo
184
        )
185
        Edit_menu.add_command(
186
            label=u'戻る(U)',
187
            under=3,
188
            accelerator='Ctrl+Z',
189
            command=self.emc.undo
190
        )
191
        Edit_menu.add_separator()
192
        Edit_menu.add_command(
193
            label=u'切り取り(X)',
194
            under=5,
195
            accelerator='Ctrl+X',
196
            command=self.emc.cut
197
        )
198
        Edit_menu.add_command(
199
            label=u'コピー(C)',
200
            under=4,
201
            accelerator='Ctrl+C',
202
            command=self.emc.copy
203
        )
204
        Edit_menu.add_command(
205
            label=u'貼り付け(V)',
206
            under=5,
207
            accelerator='Ctrl+V',
208
            command=self.emc.paste
209
        )
210
        Edit_menu.add_separator()
211
        Edit_menu.add_command(
212
            label=u'検索(F)',
213
            under=3,
214
            accelerator='Ctrl+F',
215
            command=self.find_dialog
216
        )
217
        Edit_menu.add_command(
218
            label=u'置換(L)',
219
            under=3,
220
            accelerator='Ctrl+L',
221
            command=self.replacement_dialog
222
        )
223
        self.menu_bar.add_cascade(
224
            label=u'編集(E)',
225
            under=3,
226
            menu=Edit_menu
227
        )
228
        # 処理メニュー
229
        Processing_menu.add_command(
230
            label=u'ルビをふる(R)',
231
            under=6,
232
            accelerator='Ctrl+R',
233
            command=self.pmc.ruby_huri
234
        )
235
        Processing_menu.add_command(
236
            label=u'文字数のカウント(C)',
237
            under=9,
238
            accelerator='Ctrl+Shift+C',
239
            command=self.pmc.count_moji
240
        )
241
        Processing_menu.add_command(
242
            label=u'選択文字の意味(M)',
243
            under=8,
244
            accelerator='Ctrl+Shift+F',
245
            command=self.pmc.find_wikipedia
246
        )
247
        Processing_menu.add_command(
248
            label=u'文章の読み上げ(B)',
249
            under=8,
250
            accelerator='Ctrl+Shift+R',
251
            command=self.pmc.read_text
252
        )
253
        Processing_menu.add_command(
254
            label=u'文章校正(Y)',
255
            under=5,
256
            accelerator='Ctrl+Y',
257
            command=self.pmc.yahoo
258
        )
259
        Processing_menu.add_separator()
260
        Processing_menu.add_command(
261
            label=u'フォントサイズの変更(F)',
262
            under=11,
263
            accelerator='Ctrl+Shift+F',
264
            command=self.font_dialog
265
        )
266
        Processing_menu.add_separator()
267
        Processing_menu.add_command(
268
            label=u'「小説家になろう」のページを開く(U)',
269
            under=17,
270
            accelerator='Ctrl+U',
271
            command=self.pmc.open_becoming_novelist_page
272
        )
273
        self.menu_bar.add_cascade(
274
            label=u'処理(P)',
275
            under=3,
276
            menu=Processing_menu
277
        )
278
        # リストメニュー
279
        List_menu.add_command(
280
            label=u'項目を増やす(U)',
281
            under=7,
282
            accelerator='選択右クリック',
283
            command=self.message_window
284
        )
285
        List_menu.add_command(
286
            label=u'項目を削除(D)',
287
            under=6,
288
            accelerator='選択右クリック',
289
            command=self.message_window
290
        )
291
        List_menu.add_command(
292
            label=u'項目の名前を変更(C)',
293
            under=9,
294
            accelerator='Ctrl+G',
295
            command=self.on_name_click
296
        )
297
        self.menu_bar.add_cascade(
298
            label=u'リスト(L)',
299
            under=4,
300
            menu=List_menu
301
        )
302
        # ヘルプメニュー
303
        Help_menu.add_command(
304
            label=u'ヘルプ(H)',
305
            under=4,
306
            accelerator='Ctrl+H',
307
            command=self.hmc.help
308
        )
309
        Help_menu.add_command(
310
            label=u'バージョン情報(V)',
311
            under=8,
312
            accelerator='Ctrl+Shift+V',
313
            command=self.hmc.version
314
        )
315
        self.menu_bar.add_cascade(
316
            label=u'ヘルプ(H)',
317
            under=4,
318
            menu=Help_menu
319
        )
320
        # ツリーコントロール、入力欄、行番号欄、スクロール部分を作成
321
        self.tree = ttk.Treeview(self, show="tree")
322
        self.tree.grid(row=0, column=0, sticky=(tk.N, tk.S))
323
        self.frame()
324
        self.tree_get_loop()
325
326
    def frame(self):
327
        """フレーム内にテキストボックスを表示
328
329
        ・メインウインドウの右側に行番号、テキストボックス、スクロールバー
330
        を表示する。
331
332
        """
333
        # f1フレームにテキストエディタを表示
334
        self.f1 = tk.Frame(self, relief=tk.RIDGE, bd=2)
335
        self.text = CustomText(
336
            self.f1,
337
            font=(self.font, self.font_size),
338
            undo=True
339
        )
340
        self.line_numbers = tk.Canvas(self.f1, width=30)
341
        self.ysb = ttk.Scrollbar(
342
            self.f1,
343
            orient=tk.VERTICAL,
344
            command=self.text.yview
345
        )
346
        # 入力欄にスクロールを紐付け
347
        self.text.configure(yscrollcommand=self.ysb.set)
348
        # 左から行番号、入力欄、スクロールウィジェット
349
        self.line_numbers.grid(row=0, column=0, sticky=(tk.N, tk.S))
350
        self.text.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
351
        self.ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
352
        self.f1.columnconfigure(1, weight=1)
353
        self.f1.rowconfigure(0, weight=1)
354
        self.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
355
        # テキスト入力欄のみ拡大されるように
356
        self.columnconfigure(1, weight=1)
357
        self.rowconfigure(0, weight=1)
358
        # テキストを読み取り専用にする
359
        self.text.configure(state='disabled')
360
        # テキストにフォーカスを当てる
361
        self.text.focus()
362
        self.create_event_text()
363
364
    def frame_image(self):
365
        """フレーム内にイメージフレーム表示
366
367
        ・メインウインドウの右側にイメージキャンバス、スクロールバーを表示する。
368
369
        """
370
        self.f1 = tk.Frame(self, relief=tk.RIDGE, bd=2)
371
        self.image_space = tk.Canvas(self.f1, bg="black", width=30)
372
        self.image_ysb = ttk.Scrollbar(
373
            self.f1,
374
            orient=tk.VERTICAL,
375
            command=self.image_space.yview
376
        )
377
        self.image_xsb = ttk.Scrollbar(
378
            self.f1,
379
            orient=tk.HORIZONTAL,
380
            command=self.image_space.xview
381
        )
382
        self.image_space.configure(xscrollcommand=self.image_xsb.set)
383
        self.image_space.configure(yscrollcommand=self.image_ysb.set)
384
        self.image_space.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
385
        self.image_ysb.grid(row=0, column=2, sticky=(tk.N, tk.S))
386
        self.image_xsb.grid(row=1, column=1, sticky=(tk.W, tk.E))
387
        self.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
388
        self.f1.columnconfigure(1, weight=1)
389
        self.f1.rowconfigure(0, weight=1)
390
        self.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
391
        # デフォルトの画像を設定する
392
        self.image_space.photo = tk.PhotoImage(data=original_image)
0 ignored issues
show
introduced by
The variable original_image does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
393
        self.image_on_space = self.image_space.create_image(
394
            0,
395
            0,
396
            anchor='nw',
397
            image=self.image_space.photo
398
        )
399
        self.create_event_image()
400
401
    def frame_character(self):
402
        """フレーム内にイメージフレーム表示
403
404
        ・メインウインドウの右側に呼び名、似顔絵、名前、誕生日、略歴を表示する。
405
406
        """
407
        # チェック有無変数
408
        self.var = tk.IntVar()
409
        # value=0のラジオボタンにチェックを入れる
410
        self.var.set(0)
411
        self.f1 = tk.Frame(self, relief=tk.RIDGE, bd=2)
412
        self.label1 = tk.Label(self.f1, text=u"呼び名")
413
        self.txt_yobi_name = ttk.Entry(
414
            self.f1, width=30,
415
            font=(self.font, self.font_size)
416
        )
417
        self.label2 = tk.Label(self.f1, text=u"名前")
418
        self.txt_name = ttk.Entry(
419
            self.f1, width=40,
420
            font=(self.font, self.font_size)
421
        )
422
        self.f2 = tk.LabelFrame(self.f1, relief=tk.RIDGE, bd=2, text=u"性別")
423
        self.rdo1 = tk.Radiobutton(
424
            self.f2, value=0,
425
            variable=self.var,
426
            text=u'男'
427
        )
428
        self.rdo2 = tk.Radiobutton(
429
            self.f2, value=1,
430
            variable=self.var,
431
            text=u'女'
432
        )
433
        self.rdo3 = tk.Radiobutton(
434
            self.f2, value=2,
435
            variable=self.var,
436
            text=u'その他'
437
        )
438
        self.rdo1.grid(row=0, column=1)
439
        self.rdo2.grid(row=1, column=1)
440
        self.rdo3.grid(row=2, column=1)
441
        self.f3 = tk.LabelFrame(self.f1, relief=tk.RIDGE, bd=2, text=u"似顔絵")
442
        self.cv = self.foto_canvas = tk.Canvas(
443
            self.f3,
444
            bg="black",
445
            width=149,
446
            height=199
447
        )
448
        self.foto_canvas.grid(row=0, column=0)
449
        self.label3 = tk.Label(self.f1, text=u"誕生日")
450
        self.txt_birthday = ttk.Entry(
451
            self.f1, width=40,
452
            font=(self.font, self.font_size)
453
        )
454
        self.f4 = tk.Frame(self.f1)
455
        self.foto_button = ttk.Button(
456
            self.f4,
457
            width=5,
458
            text=u'挿入',
459
            command=self.sfc.btn_click
460
        )
461
        self.foto_button_calcel = ttk.Button(
462
            self.f4,
463
            width=5,
464
            text=u'消去',
465
            command=self.sfc.clear_btn_click
466
        )
467
        self.foto_button.grid(row=0, column=1)
468
        self.foto_button_calcel.grid(row=1, column=1)
469
        self.label4 = tk.Label(self.f1, text=u"略歴")
470
        self.text_body = tk.Text(
471
            self.f1,
472
            width=80,
473
            font=(self.font, self.font_size)
474
        )
475
        self.label1.grid(row=0, column=1, columnspa=2)
476
        self.txt_yobi_name.grid(row=1, column=1, columnspa=2)
477
        self.f2.grid(row=2, column=1, rowspan=2)
478
        self.f4.grid(row=3, column=2)
479
        self.f3.grid(row=0, column=3, rowspan=4)
480
        self.label2.grid(row=0, column=4, sticky=(tk.N, tk.S, tk.W, tk.E))
481
        self.txt_name.grid(row=1, column=4)
482
        self.label3.grid(row=2, column=4)
483
        self.txt_birthday.grid(row=3, column=4)
484
        self.label4.grid(row=4, column=1, columnspa=4)
485
        self.text_body.grid(
486
            row=5,
487
            column=1,
488
            columnspa=4,
489
            sticky=(tk.N, tk.S, tk.W, tk.E)
490
        )
491
        self.f1.columnconfigure(1, weight=1)
492
        self.f1.columnconfigure(4, weight=1)
493
        self.f1.rowconfigure(5, weight=1)
494
495
        self.f1.grid(row=0, column=1, sticky=(tk.N, tk.S, tk.W, tk.E))
496
        self.columnconfigure(1, weight=1)
497
        self.rowconfigure(0, weight=1)
498
        # デフォルトの画像を設定する
499
        self.cv.photo = tk.PhotoImage(data=original_image)
0 ignored issues
show
introduced by
The variable original_image does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
500
        self.image_on_canvas = self.cv.create_image(
501
            0,
502
            0,
503
            anchor='nw',
504
            image=self.cv.photo
505
        )
506
507
        # キャラクターイベントを追加
508
        self.create_event_character()
509
510
    def create_event_text(self):
511
        """テキストイベントの設定
512
513
        ・テキストボックスにイベントを追加する。
514
515
        """
516
        # テキスト内でのスクロール時
517
        self.text.bind('<<Scroll>>', self.update_line_numbers)
518
        self.text.bind('<Up>', self.update_line_numbers)
519
        self.text.bind('<Down>', self.update_line_numbers)
520
        self.text.bind('<Left>', self.update_line_numbers)
521
        self.text.bind('<Right>', self.update_line_numbers)
522
        # テキストの変更時
523
        self.text.bind('<<Change>>', self.change_setting)
524
        # キー場押されたときの処理
525
        self.text.bind("<Any-KeyPress>", self.push_keys)
526
        # ウィジェットのサイズが変わった際。行番号の描画を行う
527
        self.text.bind('<Configure>', self.update_line_numbers)
528
        # Tab押下時(インデント、又はコード補完)
529
        self.text.bind('<Tab>', self.tab)
530
        # ルビを振る
531
        self.text.bind('<Control-Key-r>', self.pmc.ruby_huri)
532
        # 開くダイアロクを表示する
533
        self.text.bind('<Control-Key-e>', self.open_file)
534
        # 保存ダイアロクを表示する
535
        self.text.bind('<Control-Key-w>', self.save_file)
536
        # 小説家になろうを開く
537
        self.text.bind('<Control-Key-u>', self.pmc.open_becoming_novelist_page)
538
        # 検索ダイアログを開く
539
        self.text.bind('<Control-Key-f>', self.find_dialog)
540
        # 置換ダイアログを開く
541
        self.text.bind('<Control-Key-l>', self.replacement_dialog)
542
        # 上書き保存する
543
        self.text.bind('<Control-Key-s>', self.overwrite_save_file)
544
        # 新規作成する
545
        self.text.bind('<Control-Key-n>', self.new_open)
546
        # helpページを開く
547
        self.text.bind('<Control-Key-h>', self.hmc.help)  # helpページを開く
548
        # Versionページを開く
549
        self.text.bind('<Control-Shift-Key-V>', self.hmc.version)
550
        # 文字数と行数をカウントすShift-る
551
        self.text.bind('<Control-Shift-Key-C>', self.pmc.count_moji)
552
        # redo処理
553
        self.text.bind('<Control-Shift-Key-Z>', self.emc.redo)
554
        # uedo処理
555
        self.text.bind('<Control-Key-z>', self.emc.undo)
556
        # フォントサイズの変更
557
        self.text.bind('<Control-Shift-Key-F>', self.font_dialog)
558
        # 意味を検索
559
        self.text.bind('<Control-Shift-Key-D>', self.pmc.find_wikipedia)
560
        # 文章を読み上げ
561
        self.text.bind('<Control-Shift-Key-R>', self.pmc.read_text)
562
        # yahoo文字列解析
563
        self.text.bind('<Control-Key-y>', self.pmc.yahoo)
564
565
    def create_event_image(self):
566
        """イメージイベントの設定
567
568
        ・イメージキャンバスにイベントを追加する。
569
570
        """
571
        self.image_space.bind('<MouseWheel>', self.sfc.mouse_y_scroll)
572
        self.image_space.bind('<Control-MouseWheel>', self.mouse_image_scroll)
573
574
    def create_event_character(self):
575
        """キャラクター欄のイベント設定
576
577
        ・キャラクター関係のボックスにイベントを追加する。
578
579
        """
580
        # 開くダイアロクを表示する
581
        self.txt_yobi_name.bind('<Control-Key-e>', self.open_file)
582
        self.txt_name.bind('<Control-Key-e>', self.open_file)
583
        self.txt_birthday.bind('<Control-Key-e>', self.open_file)
584
        self.text_body.bind('<Control-Key-e>', self.open_file)
585
        # 保存ダイアロクを表示する
586
        self.txt_yobi_name.bind('<Control-Key-w>', self.save_file)
587
        self.txt_name.bind('<Control-Key-w>', self.save_file)
588
        self.txt_birthday.bind('<Control-Key-w>', self.save_file)
589
        self.text_body.bind('<Control-Key-w>', self.save_file)
590
        # 小説家になろうを開く
591
        self.txt_yobi_name.bind(
592
            '<Control-Key-u>',
593
            self.pmc.open_becoming_novelist_page
594
        )
595
        self.txt_name.bind(
596
            '<Control-Key-u>',
597
            self.pmc.open_becoming_novelist_page
598
        )
599
        self.txt_birthday.bind(
600
            '<Control-Key-u>',
601
            self.pmc.open_becoming_novelist_page
602
        )
603
        self.text_body.bind(
604
            '<Control-Key-u>',
605
            self.pmc.open_becoming_novelist_page
606
        )
607
        # 検索ダイアログを開く
608
        self.txt_yobi_name.bind('<Control-Key-f>', self.find_dialog)
609
        self.txt_name.bind('<Control-Key-f>', self.find_dialog)
610
        self.txt_yobi_name.bind('<Control-Key-f>', self.find_dialog)
611
        self.text_body.bind('<Control-Key-f>', self.find_dialog)
612
        # 上書き保存する
613
        self.txt_yobi_name.bind('<Control-Key-s>', self.overwrite_save_file)
614
        self.txt_name.bind('<Control-Key-s>', self.overwrite_save_file)
615
        self.txt_birthday.bind('<Control-Key-s>', self.overwrite_save_file)
616
        self.text_body.bind('<Control-Key-s>', self.overwrite_save_file)
617
        # 新規作成する
618
        self.txt_yobi_name.bind('<Control-Key-n>', self.new_open)
619
        self.txt_name.bind('<Control-Key-n>', self.new_open)
620
        self.txt_yobi_name.bind('<Control-Key-n>', self.new_open)
621
        self.text_body.bind('<Control-Key-n>', self.new_open)
622
        # helpページを開く
623
        self.txt_yobi_name.bind('<Control-Key-h>', self.hmc.help)
624
        self.txt_name.bind('<Control-Key-h>', self.hmc.help)
625
        self.txt_birthday.bind('<Control-Key-h>', self.hmc.help)
626
        self.text_body.bind('<Control-Key-h>', self.hmc.help)
627
        # Versionページを開く
628
        self.txt_yobi_name.bind('<Control-Shift-Key-V>', self.hmc.version)
629
        self.txt_name.bind('<Control-Shift-Key-V>', self.hmc.version)
630
        self.txt_birthday.bind('<Control-Shift-Key-V>', self.hmc.version)
631
        self.txt_yobi_name.bind('<Control-Shift-Key-V>', self.hmc.version)
632
        # redo処理
633
        self.txt_yobi_name.bind('<Control-Shift-Key-Z>', self.emc.redo)
634
        self.txt_name.bind('<Control-Shift-Key-Z>', self.emc.redo)
635
        self.txt_birthday.bind('<Control-Shift-Key-Z>', self.emc.redo)
636
        self.text_body.bind('<Control-Shift-Key-Z>', self.emc.redo)
637
        # フォントサイズの変更
638
        self.txt_yobi_name.bind('<Control-Shift-Key-F>', self.font_dialog)
639
        self.txt_name.bind('<Control-Shift-Key-F>', self.font_dialog)
640
        self.txt_birthday.bind('<Control-Shift-Key-F>', self.font_dialog)
641
        self.text_body.bind('<Control-Shift-Key-F>', self.font_dialog)
642
643
    def create_event(self):
644
        """ツリービューイベントの設定
645
646
        ・ツリービューにイベントを追加する。
647
648
        """
649
        # ツリービューをダブルクリックしたときにその項目を表示する
650
        self.tree.bind("<Double-1>", self.on_double_click)
651
        # ツリービューの名前を変更する
652
        self.tree.bind("<Control-Key-g>", self.on_name_click)
653
        # ツリービューで右クリックしたときにダイアログを表示する
654
        self.tree.bind("<Button-3>", self.message_window)
655
656
    def push_keys(self, event=None):
657
        """キーが押されたときの処理
658
659
        ・何かキーが押されたときに検索処理を中断する。
660
661
        Args:
662
            event (instance): tkinter.Event のインスタンス
663
664
        """
665
        # 検索処理を中断する
666
        self.replacement_dialog = 0
667
668
    def mouse_image_scroll(self, event=None):
669
        """Ctrl+マウスホイールの拡大縮小設定
670
671
        ・イメージキャンバスでCtrl+マウスホイールを回したときに画像を
672
        拡大縮小する。
673
674
        Args:
675
            event (instance): tkinter.Event のインスタンス
676
677
        """
678
        curItem = self.tree.focus()
679
        self.select_list_item = self.tree.item(curItem)["text"]
680
        title = "./{0}/{1}.txt".format(
681
            tree_folder[4][0],
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
682
            self.select_list_item
683
        )
684
        f = open(title, 'r', encoding='utf-8')
685
        zoom = f.read()
686
        self.zoom = int(zoom)
687
        f.close()
688
        if event.delta > 0:
689
            self.zoom -= 5
690
            if self.zoom < 10:
691
                self.zoom = 10
692
        elif event.delta < 0:
693
            self.zoom += 5
694
695
        f = open(title, 'w', encoding='utf-8')
696
        f.write(str(self.zoom))
697
        f.close()
698
        self.path_read_image(
699
                    tree_folder[4][0],
700
                    self.select_list_item,
701
                    self.zoom
702
                )
703
704
    def font_dialog(self, event=None):
705
        """フォントサイズダイアログを作成
706
707
        ・フォントサイズダイアログを作成し表示する。
708
709
        Args:
710
            event (instance): tkinter.Event のインスタンス
711
712
        """
713
        self.sub_wins = tk.Toplevel(self)
714
        self.intSpin = ttk.Spinbox(self.sub_wins, from_=12, to=72)
715
        self.intSpin.grid(
716
            row=0,
717
            column=0,
718
            columnspan=2,
719
            padx=5,
720
            pady=5,
721
            sticky=tk.W+tk.E,
722
            ipady=3
723
        )
724
        button = ttk.Button(
725
            self.sub_wins,
726
            text=u'サイズ変更',
727
            width=str(u'サイズ変更'),
728
            padding=(10, 5),
729
            command=self.font_size_Change
730
        )
731
        button.grid(row=1, column=1)
732
        self.intSpin.set(self.font_size)
733
        self.sub_wins.title(u'フォントサイズの変更')
734
735
    def font_size_Change(self):
736
        """フォントのサイズを変える
737
738
        ・サイズ変更を押されたときにサイズを変更する。
739
        上は72ptまで下は12ptまでにする。
740
741
        """
742
        # 比較のため数値列に変更
743
        self.font_size = int(self.intSpin.get())
744
        if self.font_size < 12:  # 12より下の値を入力した時、12にする
745
            self.font_size = 12
746
        elif 72 < self.font_size:  # 72より上の値を入力した時、72にする
747
            self.font_size = 72
748
        # 文字列にもどす
749
        self.font_size = str(self.font_size)
750
        self.sub_wins.destroy()
751
        # フォントサイズの変更
752
        self.text.configure(font=(self.font, self.font_size))
753
        # ハイライトのやり直し
754
        self.hlc.all_highlight()
755
756
    def new_file(self):
757
        """新規作成をするための準備
758
759
        ・ファイルの新規作成をするための準備処理をおこなう。
760
761
        """
762
        self.initialize()
763
        for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
764
            self.tree.delete(val[0])
765
766
        # ツリービューを表示する
767
        self.tree_get_loop()
768
        self.frame()
769
        self.winfo_toplevel().title(u"小説エディタ")
770
        # テキストを読み取り専用にする
771
        self.text.configure(state='disabled')
772
        # テキストにフォーカスを当てる
773
        self.text.focus()
774
775
    def new_open(self, event=None):
776
        """新規作成
777
778
        ・変更があれば、ファイル保存するか尋ねて、新規作成する。
779
780
        Args:
781
            event (instance): tkinter.Event のインスタンス
782
783
        """
784
        if not self.text.get('1.0', 'end - 1c') == self.text_text:
785
            if messagebox.askokcancel(
786
                u"小説エディタ",
787
                u"上書き保存しますか?"
788
            ):
789
                self.overwrite_save_file()
790
                self.new_file()
791
792
            elif messagebox.askokcancel(u"小説エディタ", u"今の編集を破棄して新規作成しますか?"):
793
                self.new_file()
794
        else:
795
            self.new_file()
796
797
    def overwrite_save_file(self, event=None):
798
        """上書き保存処理
799
800
        ・上書き保存するための処理。ファイルがあれば保存して、
801
        なければ保存ダイアログを出す。
802
803
        Args:
804
            event (instance): tkinter.Event のインスタンス
805
806
        """
807
        # ファイルパスが存在するとき
808
        if not self.file_path == "":
809
            # 編集中のファイルを保存する
810
            self.open_file_save(self.now_path)
811
            # zipファイルにまとめる
812
            shutil.make_archive(self.file_path, "zip", "./data")
813
            # 拡張子の変更を行う
814
            shutil.move(
815
                "{0}.zip".format(self.file_path),
816
                "{0}.ned".format(self.file_path)
817
            )
818
        # ファイルパスが存在しないとき
819
        else:
820
            # 保存ダイアログを開く
821
            self.save_file()
822
823
    def save_file(self, event=None):
824
        """ファイルを保存処理
825
826
        ・ファイルを保存する。ファイル保存ダイアログを作成し保存をおこなう。
827
828
        Args:
829
            event (instance): tkinter.Event のインスタンス
830
831
        """
832
        # ファイル保存ダイアログを表示する
833
        fTyp = [(u"小説エディタ", ".ned")]
834
        iDir = os.path.abspath(os.path.dirname(__file__))
835
        filepath = filedialog.asksaveasfilename(
836
            filetypes=fTyp,
837
            initialdir=iDir
838
        )
839
        # ファイルパスが決まったとき
840
        if not filepath == "":
841
            # 拡張子を除いて保存する
842
            self.file_path, ___ = os.path.splitext(filepath)
843
            # 上書き保存処理
844
            self.overwrite_save_file()
845
846
    def open_file(self, event=None):
847
        """ファイルを開く処理
848
849
        ・ファイルを開くダイアログを作成しファイルを開く。
850
851
        Args:
852
            event (instance): tkinter.Event のインスタンス
853
854
        """
855
        # ファイルを開くダイアログを開く
856
        fTyp = [(u'小説エディタ', '*.ned')]
857
        iDir = os.path.abspath(os.path.dirname(__file__))
858
        filepath = filedialog.askopenfilename(
859
            filetypes=fTyp,
860
            initialdir=iDir
861
        )
862
        # ファイル名があるとき
863
        if not filepath == "":
864
            # 初期化する
865
            self.initialize()
866
            # ファイルを開いてdataフォルダに入れる
867
            with zipfile.ZipFile(filepath) as existing_zip:
868
                existing_zip.extractall('./data')
869
            # ツリービューを削除する
870
            for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
871
                self.tree.delete(val[0])
872
873
            # ツリービューを表示する
874
            self.tree_get_loop()
875
            # ファイルパスを拡張子抜きで表示する
876
            filepath, ___ = os.path.splitext(filepath)
877
            self.file_path = filepath
878
            self.now_path = ""
879
            # テキストビューを新にする
880
            self.frame()
881
882
    def tree_get_loop(self):
883
        """ツリービューに挿入
884
885
        ・保存データからファイルを取得してツリービューに挿入する。
886
887
        """
888
        for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
889
            self.tree.insert('', 'end', val[0], text=val[1])
890
            # フォルダのファイルを取得
891
            path = "./{0}".format(val[0])
892
            files = os.listdir(path)
893
            for filename in files:
894
                if os.path.splitext(filename)[1] == ".txt":
895
                    self.tree.insert(
896
                        val[0],
897
                        'end',
898
                        text=os.path.splitext(filename)[0]
899
                    )
900
901
    def find_dialog(self, event=None):
902
        """検索ダイアログを作成
903
904
        ・検索ダイアログを作成する。
905
906
        Args:
907
            event (instance): tkinter.Event のインスタンス
908
909
        """
910
        search_win = tk.Toplevel(self)
911
        self.text_var = ttk.Entry(search_win, width=40)
912
        self.text_var.grid(
913
            row=0,
914
            column=0,
915
            columnspan=2,
916
            padx=5,
917
            pady=5,
918
            sticky=tk.W+tk.E,
919
            ipady=3
920
        )
921
        button = ttk.Button(
922
            search_win,
923
            text=u'検索',
924
            width=str(u'検索'),
925
            padding=(10, 5),
926
            command=self.search
927
        )
928
        button.grid(row=1, column=0)
929
        button2 = ttk.Button(
930
            search_win,
931
            text=u'昇順検索',
932
            width=str(u'昇順検索'),
933
            padding=(10, 5),
934
            command=self.search_forward
935
        )
936
        button2.grid(row=1, column=1)
937
        # 最前面に表示し続ける
938
        search_win.attributes("-topmost", True)
939
        search_win.title(u'検索')
940
        self.text_var.focus()
941
942
    def replacement_dialog(self, event=None):
943
        """置換ダイアログを作成
944
945
        ・置換ダイアログを作成する。
946
947
        Args:
948
            event (instance): tkinter.Event のインスタンス
949
950
        """
951
        self.replacement_win = tk.Toplevel(self)
952
        self.text_var = ttk.Entry(self.replacement_win, width=40)
953
        self.text_var.grid(
954
            row=0,
955
            column=0,
956
            columnspan=2,
957
            padx=5,
958
            pady=5,
959
            sticky=tk.W+tk.E,
960
            ipady=3
961
        )
962
        self.replacement_var = ttk.Entry(self.replacement_win, width=40)
963
        self.replacement_var.grid(
964
            row=1,
965
            column=0,
966
            columnspan=2,
967
            padx=5,
968
            pady=5,
969
            sticky=tk.W+tk.E,
970
            ipady=3
971
        )
972
        button = ttk.Button(
973
            self.replacement_win,
974
            text=u'検索',
975
            width=str(u'検索'),
976
            padding=(10, 5),
977
            command=self.search
978
        )
979
        button.grid(row=2, column=0)
980
        button2 = ttk.Button(
981
            self.replacement_win,
982
            text=u'置換',
983
            width=str(u'置換'),
984
            padding=(10, 5),
985
            command=self.replacement
986
        )
987
        button2.grid(row=2, column=1)
988
        # 最前面に表示し続ける
989
        self.replacement_win.attributes("-topmost", True)
990
        self.replacement_win.title(u'置換')
991
        self.text_var.focus()
992
        # ウインドウが閉じられたときの処理
993
        self.replacement_win.protocol(
994
            "WM_DELETE_WINDOW",
995
            self.replacement_dialog_on_closing
996
            )
997
998
    def replacement_dialog_on_closing(self):
999
        """検索ウインドウが閉じられたときの処理
1000
1001
        ・検索ダイアログが閉じられたことがわかるようにする。
1002
1003
        """
1004
        self.replacement_dialog = 0
1005
        self.replacement_win.destroy()
1006
1007
    def search(self, event=None):
1008
        """検索処理
1009
1010
        ・検索処理をする。空欄なら処理しない、違うなら最初から、
1011
        同じなら次のを検索する。
1012
1013
        Args:
1014
            event (instance): tkinter.Event のインスタンス
1015
1016
        """
1017
        # 現在選択中の部分を解除
1018
        self.text.tag_remove('sel', '1.0', 'end')
1019
1020
        # 現在検索ボックスに入力されてる文字
1021
        now_text = self.text_var.get()
1022 View Code Duplication
        if not now_text:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1023
            # 空欄だったら処理しない
1024
            pass
1025
        elif now_text != self.last_text:
1026
            # 前回の入力と違う文字なら、検索を最初から行う
1027
            index = '0.0'
1028
            self.search_next(now_text, index, 0)
1029
        else:
1030
            # 前回の入力と同じなら、検索の続きを行う
1031
            self.search_next(now_text, self.next_pos, 1)
1032
1033
        # 今回の入力を、「前回入力文字」にする
1034
        self.last_text = now_text
1035
1036
    def replacement(self, event=None):
1037
        """置換処理
1038
1039
        ・置換処理をする。空欄なら処理しない、違うなら初めから、
1040
        同じなら次を検索する。
1041
1042
        Args:
1043
            event (instance): tkinter.Event のインスタンス
1044
1045
        """
1046
        # 現在選択中の部分を解除
1047
        self.text.tag_remove('sel', '1.0', 'end')
1048
1049
        # 現在検索ボックスに入力されてる文字
1050
        now_text = self.text_var.get()
1051
        replacement_text = self.replacement_var.get()
1052
        if not now_text or not replacement_text:
1053
            # 空欄だったら処理しない
1054
            pass
1055
        elif now_text != self.last_text:
1056
            # 前回の入力と違う文字なら、検索を最初から行う
1057
            self.replacement_dialog = 1
1058
            index = '0.0'
1059
            self.search_next(now_text, index, 0)
1060
        else:
1061
            # 前回の入力と同じなら、検索の続きを行う
1062
            self.replacement_dialog = 1
1063
            # 検索文字の置換を行なう
1064
            start = self.next_pos
1065
            end = '{0} + {1}c'.format(self.next_pos, len(now_text))
1066
            self.text.delete(start, end)
1067
            self.text.insert(start, replacement_text)
1068
            self.search_next(now_text, self.next_pos, 1)
1069
1070
        # 今回の入力を、「前回入力文字」にする
1071
        self.last_text = now_text
1072
1073
    def search_forward(self, event=None):
1074
        """昇順検索処理
1075
1076
        ・昇順検索をする。空欄なら処理しない、違うなら初めから、
1077
        同じなら次を検索する。
1078
1079
        Args:
1080
            event (instance): tkinter.Event のインスタンス
1081
1082
        """
1083
        # 現在選択中の部分を解除
1084
        self.text.tag_remove('sel', '1.0', 'end')
1085
1086
        # 現在検索ボックスに入力されてる文字
1087
        now_text = self.text_var.get()
1088 View Code Duplication
        if not now_text:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1089
            # 空欄だったら処理しない
1090
            pass
1091
        elif now_text != self.last_text:
1092
            # 前回の入力と違う文字なら、検索を最初から行う
1093
            index = 'end'
1094
            self.search_next(now_text, index, 2)
1095
        else:
1096
            # 前回の入力と同じなら、検索の続きを行う
1097
            self.search_next(now_text, self.next_pos, 2)
1098
1099
        # 今回の入力を、「前回入力文字」にする
1100
        self.last_text = now_text
1101
1102
    def search_next(self, search, index, case):
1103
        """検索のメイン処理
1104
1105
        ・検索できれば選択をする。できなければ、ダイアログを出して終了。
1106
1107
        Args:
1108
            search (str): 検索文字列
1109
            index (str): 検索位置 ex. (1.0)
1110
            case (int): 0.初めから検索 1.次に検索 2.昇順検索
1111
1112
        """
1113
        if case == 2:
1114
            backwards = True
1115
            stopindex = '0.0'
1116
            index = '{0}'.format(index)
1117
        elif case == 0:
1118
            backwards = False
1119
            stopindex = 'end'
1120
            index = '{0}'.format(index)
1121
        else:
1122
            backwards = False
1123
            stopindex = 'end'
1124
            index = '{0} + 1c'.format(index)
1125
1126
        pos = self.text.search(
1127
            search, index,
1128
            stopindex=stopindex,
1129
            backwards=backwards
1130
        )
1131
        if not pos:
1132
            if case == 2:
1133
                index = "end"
1134
            else:
1135
                index = "0.0"
1136
1137
            pos = self.text.search(
1138
                search, index,
1139
                stopindex=stopindex,
1140
                backwards=backwards
1141
            )
1142
            if not pos:
1143
                messagebox.showinfo(
1144
                    "検索",
1145
                    "最後まで検索しましたが検索文字はありませんでした。"
1146
                )
1147
                self.replacement_dialog = 0
1148
                return
1149
1150
        self.next_pos = pos
1151
        start = pos
1152
        end = '{0} + {1}c'.format(pos, len(search))
1153
        self.text.tag_add('sel', start, end)
1154
        self.text.mark_set('insert', start)
1155
        self.text.see('insert')
1156
        self.text.focus()
1157
1158
    def message_window(self, event=None):
1159
        """ツリービューを右クリックしたときの処理
1160
1161
        ・子アイテムならば削除ダイアログを表示する。
1162
        親アイテムならば追加を行う。
1163
1164
        Args:
1165
            event (instance): tkinter.Event のインスタンス
1166
1167
        """
1168
        curItem = self.tree.focus()              # 選択アイテムの認識番号取得
1169
        parentItem = self.tree.parent(curItem)   # 親アイテムの認識番号取得
1170
        # 親アイテムをクリックしたとき
1171
        if self.tree.item(curItem)["text"] == tree_folder[4][1]:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1172
            # imageタグを選択したとき
1173
            fTyp = [(u'小説エディタ', '*.gif')]
1174
            iDir = os.path.abspath(os.path.dirname(__file__))
1175
            filepath = filedialog.askopenfilename(
1176
                filetypes=fTyp,
1177
                initialdir=iDir
1178
            )
1179
            # ファイル名があるとき
1180
            if not filepath == "":
1181
                file_name = os.path.splitext(os.path.basename(filepath))[0]
1182
                path = "./{0}/{1}.gif".format(tree_folder[4][0], file_name)
1183
                shutil.copy2(filepath, path)
1184
                self.frame_image()
1185
                path = "./{0}/{1}.txt".format(tree_folder[4][0], file_name)
1186
                tree = self.tree.insert(
1187
                    tree_folder[4][0],
1188
                    'end',
1189
                    text=file_name
1190
                )
1191
                self.tree.see(tree)
1192
                self.tree.selection_set(tree)
1193
                self.tree.focus(tree)
1194
                self.select_list_item = file_name
1195
                self.now_path = path
1196
                f = open(path, 'w', encoding='utf-8')
1197
                self.zoom = 100
1198
                f.write(str(self.zoom))
1199
                f.close()
1200
                self.frame_image()
1201
                self.path_read_image(
1202
                    tree_folder[4][0],
1203
                    file_name,
1204
                    0
1205
                )
1206
1207
        else:
1208
            if str(
1209
                self.tree.item(curItem)["text"]
1210
            ) and (not str(
1211
                    self.tree.item(parentItem)["text"]
1212
                )
1213
            ):
1214
                # サブダイヤログを表示する
1215
                title = u'{0}に挿入'.format(self.tree.item(curItem)["text"])
1216
                dialog = mydialog.Mydialog(self, "挿入", True, title, False)
1217
                root.wait_window(dialog.sub_name_win)
0 ignored issues
show
introduced by
The variable root does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1218
                file_name = dialog.txt
1219
                del dialog
1220
                if not file_name == "":
1221
                    self.open_file_save(self.now_path)
1222
                    curItem = self.tree.focus()              # 選択アイテムの認識番号取得
1223
                    text = self.tree.item(curItem)["text"]
1224
                    path = ""
1225
                    # 選択されているフォルダを見つける
1226
                    for val in tree_folder:
1227
                        if text == val[1]:
1228
                            if val[0] == tree_folder[0][0]:
1229
                                self.frame_character()
1230
                                self.txt_yobi_name.insert(tk.END, file_name)
1231
                            else:
1232
                                self.frame()
1233
1234
                            path = "./{0}/{1}.txt".format(val[0], file_name)
1235
                            tree = self.tree.insert(
1236
                                val[0],
1237
                                'end',
1238
                                text=file_name
1239
                            )
1240
                            self.now_path = path
1241
                            break
1242
1243
                    # パスが存在すれば新規作成する
1244
                    if not path == "":
1245
                        f = open(path, 'w', encoding='utf-8')
1246
                        f.write("")
1247
                        f.close()
1248
                        # ツリービューを選択状態にする
1249
                        self.tree.see(tree)
0 ignored issues
show
introduced by
The variable tree does not seem to be defined for all execution paths.
Loading history...
1250
                        self.tree.selection_set(tree)
1251
                        self.tree.focus(tree)
1252
                        self.select_list_item = file_name
1253
                        self.winfo_toplevel().title(
1254
                            u"小説エディタ\\{0}\\{1}"
1255
                            .format(text, file_name)
1256
                        )
1257
                        self.text.focus()
1258
                        # テキストを読み取り専用を解除する
1259
                        self.text.configure(state='normal')
1260
                        self.hlc.create_tags()
1261
            # 子アイテムを右クリックしたとき
1262
            else:
1263
                if str(self.tree.item(curItem)["text"]):
1264
                    # 項目を削除する
1265
                    file_name = self.tree.item(curItem)["text"]
1266
                    text = self.tree.item(parentItem)["text"]
1267
                    # OK、キャンセルダイアログを表示し、OKを押したとき
1268
                    if messagebox.askokcancel(
1269
                        u"項目削除",
1270
                        "{0}を削除しますか?".format(file_name)
1271
                    ):
1272
                        # パスを取得する
1273
                        for val in tree_folder:
1274
                            if text == val[1]:
1275
                                path = "./{0}/{1}.txt".format(
1276
                                    val[0],
1277
                                    file_name
1278
                                )
1279
                                image_path = "./{0}/{1}.gif".format(
1280
                                    val[0],
1281
                                    file_name
1282
                                )
1283
                                self.tree.delete(curItem)
1284
                                self.now_path = ""
1285
                                break
1286
                        # imageパスが存在したとき
1287
                        if os.path.isfile(image_path):
0 ignored issues
show
introduced by
The variable image_path does not seem to be defined for all execution paths.
Loading history...
1288
                            os.remove(image_path)
1289
1290
                        # パスが存在したとき
1291
                        if not path == "":
0 ignored issues
show
introduced by
The variable path does not seem to be defined for all execution paths.
Loading history...
1292
                            os.remove(path)
1293
                            self.frame()
1294
                            self.text.focus()
1295
1296
    def save_charactor_file(self):
1297
        """キャラクターファイルの保存準備
1298
1299
        ・それぞれの項目をxml形式で保存する。
1300
1301
        """
1302
        return '<?xml version="1.0"?>\n<data>\n\t<call>{0}</call>\
1303
        \n\t<name>{1}</name>\n\t<sex>{2}</sex>\n\t<birthday>{3}</birthday>\
1304
        \n\t<body>{4}</body>\n</data>'.format(
1305
            self.txt_yobi_name.get(),
1306
            self.txt_name.get(),
1307
            self.var.get(),
1308
            self.txt_birthday.get(),
1309
            self.text_body.get(
1310
                '1.0',
1311
                'end -1c'
1312
            )
1313
        )
1314
1315
    def open_file_save(self, path):
1316
        """開いてるファイルを保存する
1317
1318
        ・開いてるファイルをそれぞれの保存形式で保存する。
1319
1320
        Args:
1321
            path (str): 保存ファイルのパス
1322
1323
        """
1324
        # 編集ファイルを保存する
1325
        if not path == "":
1326
            f = open(path, 'w', encoding='utf-8')
1327
            if not path.find(tree_folder[0][0]) == -1:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1328
                f.write(self.save_charactor_file())
1329
                self.charactor_file = ""
1330
            elif not path.find(tree_folder[4][0]) == -1:
1331
                f.write(str(self.zoom))
1332
            else:
1333
                f.write(self.text.get("1.0", tk.END+'-1c'))
1334
1335
            f.close()
1336
            self.now_path = path
1337
1338
    def on_double_click(self, event=None):
1339
        """ツリービューをダブルクリック
1340
1341
        ・ファイルを保存して閉じて、選択されたアイテムを表示する。
1342
1343
        Args:
1344
            event (instance): tkinter.Event のインスタンス
1345
1346
        """
1347
        curItem = self.tree.focus()              # 選択アイテムの認識番号取得
1348
        parentItem = self.tree.parent(curItem)   # 親アイテムの認識番号取得
1349
        text = self.tree.item(parentItem)["text"]
1350
        # 開いているファイルを保存
1351
        self.open_file_save(self.now_path)
1352
        # テキストを読み取り専用を解除する
1353
        self.frame()
1354
        self.text.configure(state='disabled')
1355
        # 条件によって分離
1356
        self.select_list_item = self.tree.item(curItem)["text"]
1357
        path = ""
1358
        for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1359
            if text == val[1]:
1360
                if val[0] == tree_folder[4][0]:
1361
                    path = "./{0}/{1}.txt".format(
1362
                        val[0],
1363
                        self.select_list_item
1364
                    )
1365
                    f = open(path, 'r', encoding='utf-8')
1366
                    zoom = f.read()
1367
                    self.zoom = int(zoom)
1368
                    self.now_path = path
1369
                    self.frame_image()
1370
                    self.path_read_image(
1371
                        tree_folder[4][0],
1372
                        self.select_list_item,
1373
                        self.zoom
1374
                    )
1375
                else:
1376
                    path = "./{0}/{1}.txt".format(
1377
                        val[0],
1378
                        self.select_list_item
1379
                    )
1380
                    self.now_path = path
1381
                    if val[0] == tree_folder[0][0]:
1382
                        self.frame_character()
1383
                    else:
1384
                        # テキストを読み取り専用を解除する
1385
                        self.text.configure(state='normal')
1386
                        self.text.focus()
1387
1388
                    self.path_read_text(text, self.select_list_item)
1389
1390
                return
1391
1392
        self.now_path = ""
1393
        self.winfo_toplevel().title(u"小説エディタ")
1394
1395
    def path_read_image(self, image_path, image_name, scale):
1396
        """イメージを読み込んで表示
1397
1398
        ・パスが存在すればイメージファイルを読み込んで表示する。
1399
1400
        Args:
1401
            image_path (str): イメージファイルの相対パス
1402
            image_name (str): イメージファイルの名前
1403
            scale (int): 拡大率(%)
1404
1405
        """
1406
        if not self.now_path == "":
1407
            title = "{0}/{1}.gif".format(
1408
                image_path,
1409
                image_name
1410
            )
1411
            giffile = Image.open(title)
1412
            if scale > 0:
1413
                giffile = giffile.resize(
1414
                    (
1415
                        int(giffile.width / 100*scale),
1416
                        int(giffile.height / 100*scale)
1417
                    ),
1418
                    resample=Image.LANCZOS
1419
                )
1420
1421
            self.image_space.photo = ImageTk.PhotoImage(giffile)
1422
            self.image_space.itemconfig(
1423
                self.image_on_space,
1424
                image=self.image_space.photo
1425
            )
1426
            # イメージサイズにキャンバスサイズを合わす
1427
            self.image_space.config(
1428
                scrollregion=(
1429
                    0,
1430
                    0,
1431
                    giffile.size[0],
1432
                    giffile.size[1]
1433
                )
1434
            )
1435
            giffile.close()
1436
1437
        self.winfo_toplevel().title(
1438
                u"小説エディタ\\{0}\\{1}".format(tree_folder[4][1], image_name)
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1439
            )
1440
1441
    def path_read_text(self, text_path, text_name):
1442
        """テキストを読み込んで表示
1443
1444
        ・パスが存在すればテキストを読み込んで表示する。
1445
1446
        Args:
1447
            text_path (str): テキストファイルの相対パス
1448
            text_name (str): テキストファイルの名前
1449
1450
        """
1451
        if not self.now_path == "":
1452
            if not self.now_path.find(tree_folder[0][0]) == -1:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1453
                self.txt_yobi_name.delete('0', tk.END)
1454
                self.txt_name.delete('0', tk.END)
1455
                self.txt_birthday.delete('0', tk.END)
1456
                self.text_body.delete('1.0', tk.END)
1457
                tree = ET.parse(self.now_path)
1458
                elem = tree.getroot()
1459
                self.txt_yobi_name.insert(tk.END, elem.findtext("call"))
1460
                self.txt_name.insert(tk.END, elem.findtext("name"))
1461
                self.var.set(elem.findtext("sex"))
1462
                self.txt_birthday.insert(tk.END, elem.findtext("birthday"))
1463
                self.text_body.insert(tk.END, elem.findtext("body"))
1464
                title = "{0}/{1}.gif".format(
1465
                    tree_folder[0][0],
1466
                    elem.findtext("call")
1467
                )
1468
                if os.path.isfile(title):
1469
                    self.print_gif(title)
1470
            else:
1471
                self.text.delete('1.0', tk.END)
1472
                f = open(self.now_path, 'r', encoding='utf-8')
1473
                self.text_text = f.read()
1474
                self.text.insert(tk.END, self.text_text)
1475
                f.close()
1476
1477
            self.winfo_toplevel().title(
1478
                u"小説エディタ\\{0}\\{1}".format(text_path, text_name)
1479
            )
1480
            # シンタックスハイライトをする
1481
            self.hlc.all_highlight()
1482
1483
    def on_name_click(self, event=None):
1484
        """名前の変更
1485
1486
        ・リストボックスの名前を変更する。
1487
1488
        Args:
1489
            event (instance): tkinter.Event のインスタンス
1490
1491
        """
1492
        curItem = self.tree.focus()              # 選択アイテムの認識番号取得
1493
        parentItem = self.tree.parent(curItem)   # 親アイテムの認識番号取得
1494
        text = self.tree.item(parentItem)["text"]
1495
        if not text == "":
1496
            sub_text = self.tree.item(curItem)["text"]
1497
            title = u'{0}の名前を変更'.format(sub_text)
1498
            dialog2 = mydialog.Mydialog(self, u"変更", True, title, sub_text)
1499
            root.wait_window(dialog2.sub_name_win)
0 ignored issues
show
introduced by
The variable root does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1500
            # テキストを読み取り専用を解除する
1501
            self.text.configure(state='normal')
1502
            co_text = dialog2.txt
1503
            del dialog2
1504
            for val in tree_folder:
0 ignored issues
show
introduced by
The variable tree_folder does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1505
                if text == val[1]:
1506
                    path1 = "./{0}/{1}.txt".format(val[0], sub_text)
1507
                    path2 = "./{0}/{1}.txt".format(val[0], co_text)
1508
                    self.now_path = path2
1509
                    # テキストの名前を変更する
1510
                    os.rename(path1, path2)
1511
                    self.tree.delete(curItem)
1512
                    Item = self.tree.insert(parentItem, 'end', text=co_text)
1513
                    self.tree.selection_set(Item)
1514
                    self.path_read_text(val[0], co_text)
1515
                    return
1516
1517
    def update_line_numbers(self, event=None):
1518
        """行番号の描画
1519
1520
        ・行番号をつけて表示する。
1521
1522
        Args:
1523
            event (instance): tkinter.Event のインスタンス
1524
1525
        """
1526
        # 現在の行番号を全て消す
1527
        self.line_numbers.delete(tk.ALL)
1528
1529
        # Textの0, 0座標、つまり一番左上が何行目にあたるかを取得
1530
        i = self.text.index("@0,0")
1531
        while True:
1532
            # dlineinfoは、その行がどの位置にあり、どんなサイズか、を返す
1533
            # (3, 705, 197, 13, 18) のように帰る(x,y,width,height,baseline)
1534
            dline = self.text.dlineinfo(i)
1535
            # dlineinfoに、存在しない行や、スクロールしないと見えない行を渡すとNoneが帰る
1536
            if dline is None:
1537
                break
1538
            else:
1539
                y = dline[1]  # y座標を取得
1540
1541
            # (x座標, y座標, 方向, 表示テキスト)を渡して行番号のテキストを作成
1542
            linenum = str(i).split(".")[0]
1543
            self.line_numbers.create_text(
1544
                3,
1545
                y,
1546
                anchor=tk.NW,
1547
                text=linenum,
1548
                font=("", 12)
1549
            )
1550
            i = self.text.index("%s+1line" % i)
1551
1552
    def change_setting(self, event=None):
1553
        """テキストの変更時
1554
1555
        ・テキストを変更したときに行番号とハイライトを変更する。
1556
1557
        Args:
1558
            event (instance): tkinter.Event のインスタンス
1559
1560
        """
1561
        self.update_line_numbers()
1562
        # その行のハイライトを行う
1563
        self.hlc.line_highlight()
1564
1565
    def tab(self, event=None):
1566
        """タブ押下時の処理
1567
1568
        ・タブキーを押したときに補完リストを出す。
1569
1570
        Args:
1571
            event (instance): tkinter.Event のインスタンス
1572
1573
        """
1574
        # 文字を選択していないとき
1575
        sel_range = self.text.tag_ranges('sel')
1576
        if not sel_range:
1577
            return self.auto_complete()
1578
        else:
1579
            return
1580
1581
    def auto_complete(self):
1582
        """補完リストの設定
1583
1584
        ・補完リストの設定をする。
1585
1586
        """
1587
        auto_complete_list = tk.Listbox(self.text)
1588
        # エンターでそのキーワードを選択
1589
        auto_complete_list.bind('<Return>', self.selection)
1590
        auto_complete_list.bind('<Double-1>', self.selection)
1591
        # エスケープ、タブ、他の場所をクリックで補完リスト削除
1592
        auto_complete_list.bind('<Escape>', self.remove_list)
1593
        auto_complete_list.bind('<Tab>', self.remove_list)
1594
        auto_complete_list.bind('<FocusOut>', self.remove_list)
1595
        # (x,y,width,height,baseline)
1596
        x, y, width, height, _ = self.text.dlineinfo(
1597
            'insert'
1598
        )
1599
        # 現在のカーソル位置のすぐ下に補完リストを貼る
1600
        auto_complete_list.place(x=x+width, y=y+height)
1601
        # 補完リストの候補を作成
1602
        for word in self.get_keywords():
1603
            auto_complete_list.insert(tk.END, word)
1604
1605
        # 補完リストをフォーカスし、0番目を選択している状態に
1606
        auto_complete_list.focus_set()
1607
        auto_complete_list.selection_set(0)
1608
        self.auto_complete_list = auto_complete_list  # self.でアクセスできるように
1609
        return 'break'
1610
1611
    def get_keywords(self):
1612
        """補完リストの候補キーワードを作成
1613
1614
        ・補完リストに表示するキーワードを得る。
1615
1616
        """
1617
        text = ''
1618
        text, _, _ = self.get_current_insert_word()
1619
        my_func_and_class = set()
1620
        # コード補完リストをTreeviewにある'名前'から得る
1621
        children = self.tree.get_children('data/character')
1622
        for child in children:
1623
            childname = self.tree.item(child, "text")
1624
            # 前列の文字列と同じものを選び出す
1625
            if childname.startswith(text) or childname.startswith(
1626
                text.title()
1627
            ):
1628
                my_func_and_class.add(childname)
1629
1630
        result = list(my_func_and_class)
1631
        return result
1632
1633
    def remove_list(self, event=None):
1634
        """補完リストの削除処理
1635
1636
        ・補完リストを削除し、テキストボックスにフォーカスを戻す。
1637
1638
        Args:
1639
            event (instance): tkinter.Event のインスタンス
1640
1641
        """
1642
        self.auto_complete_list.destroy()
1643
        self.text.focus()  # テキストウィジェットにフォーカスを戻す
1644
1645
    def selection(self, event=None):
1646
        """補完リストでの選択後の処理
1647
1648
        ・補完リストを選択したときにその文字を入力する。
1649
1650
        Args:
1651
            event (instance): tkinter.Event のインスタンス
1652
1653
        """
1654
        # リストの選択位置を取得
1655
        select_index = self.auto_complete_list.curselection()
1656
        if select_index:
1657
            # リストの表示名を取得
1658
            value = self.auto_complete_list.get(select_index)
1659
1660
            # 現在入力中の単語位置の取得
1661
            _, start, end = self.get_current_insert_word()
1662
            self.text.delete(start, end)
1663
            self.text.insert('insert', value)
1664
            self.remove_list()
1665
1666
    def get_current_insert_word(self):
1667
        """現在入力中の単語と位置を取得
1668
1669
        ・現在入力している単語とその位置を取得する。
1670
1671
        """
1672
        text = ''
1673
        start_i = 1
1674
        end_i = 0
1675
        while True:
1676
            start = 'insert-{0}c'.format(start_i)
1677
            end = 'insert-{0}c'.format(end_i)
1678
            text = self.text.get(start, end)
1679
            # 1文字ずつ見て、スペース、改行、タブ、空文字、句読点にぶつかったら終わり
1680
            if text in (' ', ' ', '\t', '\n', '', '、', '。'):
1681
                text = self.text.get(end, 'insert')
1682
1683
                # 最終単語を取得する
1684
                pri = [token.surface for token in tokenizer.tokenize(text)]
0 ignored issues
show
introduced by
The variable tokenizer does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1685
                hin = [
1686
                    token.part_of_speech.split(',')[0] for token
1687
                    in tokenizer.tokenize(text)
1688
                ]
1689
                if len(pri) > 0:
1690
                    if hin[len(pri)-1] == u'名詞':
1691
                        text = pri[len(pri)-1]
1692
                    else:
1693
                        text = ""
1694
                else:
1695
                    text = ""
1696
1697
                end = 'insert-{0}c'.format(len(text))
1698
                return text, end, 'insert'
1699
1700
            start_i += 1
1701
            end_i += 1
1702
1703
1704
def on_closing():
1705
    """終了時の処理
1706
1707
    ・ソフトを閉じるか確認してから閉じる。
1708
1709
    """
1710
    if messagebox.askokcancel(u"小説エディタ", u"終了してもいいですか?"):
1711
        shutil.rmtree("./data")
1712
        if os.path.isfile("./userdic.csv"):
1713
            os.remove("./userdic.csv")
1714
1715
        root.destroy()
0 ignored issues
show
introduced by
The variable root does not seem to be defined in case __name__ == "__main__" on line 1718 is False. Are you sure this can never be the case?
Loading history...
1716
1717
1718
if __name__ == "__main__":
1719
    root = tk.Tk()
1720
    root.withdraw()
1721
    if os.path.isdir("./data"):
1722
        messagebox.showerror(u"小説エディタ", u"二重起動はできません")
1723
        sys.exit()
1724
1725
    # タイトル横の画像ファイルのbase 64データ
1726
    data = '''R0lGODlhgACAAPcAAAAAAAQEBAcHBwkJCQoKCg8PDxAQEBERERMTExUVFRgYGBkZ
1727
        GRoaGhwcHB0dHR4eHh8fHyAgICEhISIiIiMjIyQkJCUlJSYmJicnJygoKCkpKSoq
1728
        KisrKywsLC0tLS4uLi8vLzAwMDExMTIyMjMzMzQ0NDU1NTc3Nzg4ODo6Ojs7Ozw8
1729
        PD4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1N
1730
        TU5OTk9PT1BQUFJSUlNTU1RUVFVVVVZWVldXV1lZWVpaWltbW1xcXF1dXV5eXl9f
1731
        X2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra21tbW5ubm9vb3Bw
1732
        cHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CA
1733
        gIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQ
1734
        kJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6Cg
1735
        oKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7Cw
1736
        sLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DA
1737
        wMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ
1738
        0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg
1739
        4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw
1740
        8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///wAA
1741
        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
1742
        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
1954
        8AzX8A3n8A738A8H8RDP8IAAADs=
1955
        '''
1956
    # アイコンを設定
1957
    root.geometry('600x300')
1958
    root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(data=data))
1959
    root.title(u"小説エディタ")
1960
    # タイトルの画像ファイルのbase 64データ
1961
    datas = '''R0lGODlhWAIsAfcAAAAAAQ0AAwAABQAAC0oXCzQMEC0VFBAAFQAAGFIfHQ0KHhIT
1962
        IAAAISQBJgBuJwBuKSUkKgAAKzEbK3hBLTwYLh0bMWAyMYZZMRcAMwEMMw0SM2s/
1963
        M1c5NEooNZdlNYNJNyESODQyOHlIOhcYOxwoO5FTOzw7PTovQQAGQh4NQkwvQqt4
1964
        QwAQRCEgRKJnRC0oSUk/SQAYTHNRTD9DTQcbTj88TpJuUV1KUiIzU1FQU0ZGVDY1
1965
        Vqp6V1dXWahzWVpaWgAcW7eIW3lfXsOXZRElZ2hoaCs2ajVBaxkubD1LbAAibWFg
1966
        bcuccXZzckNSc86hdhlAd6OEeAsze3l6e1BffNWpgX9+gyNFhR5JhjFPhtuwhiBM
1967
        iq6Si+O6jI6Ojl6/j1/AjypUkXFwkZOTk+7Bk5aWljVfl8CSmW97m4aFnNq5nZyb
1968
        n3+/n4DAoDxqoaGhocSpo+XEoy5opKWlpXzTp6ioqHvSqDxsrDBxrICRra6urrW1
1969
        tVl6tse1tsG2t7e3t//ht42Rubm5uUp8u7u7u/XQu/fYu0J4vcu+vlyNv7+/v/rf
1970
        wk6HxMTExMbGxm+bycnJyYChymKWy8zMzKezzeHNzc7Ozs/Pz2eZ0NDQ0P/m0NHR
1971
        0aCu0tTU1P/u1NbW1uPW1oOv2NjY2G6j2nqs2tra2tzc3L+/3d3d3f/13b3/3t/f
1972
        3/Di4Yi44r7H4uPj4+Xl5cX/5f//5ufn58j/53u16Ojo6P/w6erq6v//6uvr6+zs
1973
        7O3t7ZrG7vXr7u7u7v/z7v//7pHD7+/v78XX8PDw8PHx8fLy8v//8rTS8+Do8/Pz
1974
        887c9PT09PX19f/59f/79f//9fb29rng9/f39///9/j4+Pn5+f//+YW++vr6+ubt
1975
        +/v7+///+/z8/P39/f///f7+/v///p7N/6vZ/6Lb/7nh/8Dn/8rp/77v/+fz/9H2
1976
        /9v3//H6//v6/+v8///+/9P//9z//+X//+v//+7///D///P///T///n///r///z/
1977
        //3///7//////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQAAAAAACwAAAAAWAIs
1978
        AQAI/gBVCRxIsKDBgwZj2XkAhhbChxAjSpxIsaLFixgzatzIsaPHjyBDihxJsqRJ
1979
        jrTAPLAT66RLVQoZOnxJs6bNmzhz6tzJs6fPlylXtvypMWZDokiTKl3KtKnTp02D
1980
        soQa0ehMqlizat3KtatXkVKHfrX6tazZs2jTqr0Z1izZtXDjyp1L12zbsm/r6t3L
1981
        t6/fknfHLjz6t7Dhw4gLB/aaN7Hjx5AjY13ctbHky5gzaz5JmavlzaBDix59sPPW
1982
        z6RTq16d2LRW1Kxjy5691nVW2LRz69791DZW3LyDCx/OVuVUvIOvEl/OvPlI31SB
1983
        O59OvbpB6FClW9/OnTj2p9q7/osfL/u70/Dk06sHbb4p+vXw4ztuz/S9/Pv499Jf
1984
        aj+///9p7adUfwAWaKBWAiZF4IEMNqhUgkgt6OCEFOYEIVESVqjhhoAZJxZjyXEo
1985
        4og6XfhThiSmqKJEJvqE4oowxihQiz29KOONJNLIk4049qihjjvx6OOQDQKpk5BE
1986
        JgmgkQfF4uSTUEYp5ZRS0kKHTFRmqeWWXHbp5ZdghinmmGSWaeaZaKap5ppstunm
1987
        m3CaGRQdtMQZCx145qnnnnz22ecXD3zh56CEFmrooYgmquiijDbq6KOQRirppJRW
1988
        aumlmGaqqaSACrrplQ+EKuqopJZq6qkPOKDqqqy26uqr/rDGKuustNZq66245qrr
1989
        rrz26uuvwAYr7LDEFmvsscSiquyyp37h7LPQRivttNKCAagTbbCh7bbcduvtt+CG
1990
        K+645JZr7rnopqvuuuy26+678MYr77z01mvvvfK24USg1lLr77/S0iLwwAQXbPDB
1991
        B9PhQBv+NOzwwxBHLPHEFFds8cUYZ6zxxhx37PHHIIcs8sgkl2zyySinrPLJbThA
1992
        J8Iwx3ywSwotvPLNOOes88489+zzz0AHLXTKLR8nmM1DJ6300kw37fTTUEfNsgNG
1993
        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
2330
        '''
2331
    img = tk.PhotoImage(data=datas)
2332
    label = tk.Label(image=img)
2333
    # タイトルを表示する
2334
    label.pack()
2335
    # センターに表示する
2336
    root.update_idletasks()
2337
    ww = root.winfo_screenwidth()
2338
    lw = root.winfo_width()
2339
    wh = root.winfo_screenheight()
2340
    lh = root.winfo_height()
2341
    root.geometry(
2342
        "{0}x{1}+{2}+{3}".format(
2343
            str(lw),
2344
            str(lh),
2345
            str(int(ww/2-lw/2)),
2346
            str(int(wh/2-lh/2))
2347
        )
2348
    )
2349
    root.deiconify()
2350
2351
    # windowsのみタイトルバーを削除
2352
    # OS別判断
2353
    if os.name == 'nt':
2354
        root.overrideredirect(True)
2355
    elif os.name == 'posix':
2356
        root.wm_attributes('-type', 'splash')
2357
    # 描画するが処理は止めない
2358
    root.update()
2359
    # Janomeを使って日本語の形態素解析を起動
2360
    tokenizer = Tokenizer()
2361
    wiki_wiki = wikipediaapi.Wikipedia('ja')
2362
    # メイン画面を削除
2363
    root.destroy()
2364
    # 初期処理
2365
    original_image = '''R0lGODlhHgAeAPcAAAAAAAAAMwAAZgAAmQAAzAAA/wAzAAAzMwAzZgAzmQAzzAAz
2366
        /wBmAABmMwBmZgBmmQBmzABm/wCZAACZMwCZZgCZmQCZzACZ/wDMAADMMwDMZgDM
2367
        mQDMzADM/wD/AAD/MwD/ZgD/mQD/zAD//zMAADMAMzMAZjMAmTMAzDMA/zMzADMz
2368
        MzMzZjMzmTMzzDMz/zNmADNmMzNmZjNmmTNmzDNm/zOZADOZMzOZZjOZmTOZzDOZ
2369
        /zPMADPMMzPMZjPMmTPMzDPM/zP/ADP/MzP/ZjP/mTP/zDP//2YAAGYAM2YAZmYA
2370
        mWYAzGYA/2YzAGYzM2YzZmYzmWYzzGYz/2ZmAGZmM2ZmZmZmmWZmzGZm/2aZAGaZ
2371
        M2aZZmaZmWaZzGaZ/2bMAGbMM2bMZmbMmWbMzGbM/2b/AGb/M2b/Zmb/mWb/zGb/
2372
        /5kAAJkAM5kAZpkAmZkAzJkA/5kzAJkzM5kzZpkzmZkzzJkz/5lmAJlmM5lmZplm
2373
        mZlmzJlm/5mZAJmZM5mZZpmZmZmZzJmZ/5nMAJnMM5nMZpnMmZnMzJnM/5n/AJn/
2374
        M5n/Zpn/mZn/zJn//8wAAMwAM8wAZswAmcwAzMwA/8wzAMwzM8wzZswzmcwzzMwz
2375
        /8xmAMxmM8xmZsxmmcxmzMxm/8yZAMyZM8yZZsyZmcyZzMyZ/8zMAMzMM8zMZszM
2376
        mczMzMzM/8z/AMz/M8z/Zsz/mcz/zMz///8AAP8AM/8AZv8Amf8AzP8A//8zAP8z
2377
        M/8zZv8zmf8zzP8z//9mAP9mM/9mZv9mmf9mzP9m//+ZAP+ZM/+ZZv+Zmf+ZzP+Z
2378
        ///MAP/MM//MZv/Mmf/MzP/M////AP//M///Zv//mf//zP///8DAwICAgIAAAACA
2379
        AAAAgICAAIAAgACAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2380
        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
2381
        AAAAAAAAAAAAAAAAACwAAAAAHgAeAAAIMgABCBxIsKDBgwgTKlzIsKHDhxAjSpxI
2382
        saLFixgzatzIsaPHjyBDihxJsqTJkyhTngwIADs=
2383
        '''
2384
    tree_folder = [
2385
        ['data/character', u'キャラクター'],
2386
        ['data/occupation', u'職種'],
2387
        ['data/space', u'場所'],
2388
        ['data/event', u'イベント'],
2389
        ['data/image', u'イメージ'],
2390
        ['data/nobel', u'小説']
2391
    ]
2392
    # 再度メイン画面を作成
2393
    root = tk.Tk()
2394
    # アイコンを設定
2395
    root.tk.call('wm', 'iconphoto', root._w, tk.PhotoImage(data=data))
2396
    # タイトルの表示
2397
    root.title(u"小説エディタ")
2398
    # フレームを表示する
2399
    app = LineFrame(root)
2400
    app.grid(column=0, row=0, sticky=(tk.N, tk.S, tk.E, tk.W))
2401
    # 終了時にon_closingを行う
2402
    root.protocol("WM_DELETE_WINDOW", on_closing)
2403
    root.columnconfigure(0, weight=1)
2404
    root.rowconfigure(0, weight=1)
2405
    pf = platform.system()
2406
    if pf == 'Windows':
2407
        root.state('zoomed')
2408
    else:
2409
        root.attributes("-zoomed", "1")
2410
2411
# テスト環境ではループを抜ける
2412
    value = sys.argv
2413
    if len(value) > 1:
2414
        for arg in value:
2415
            if arg == "test":
2416
                root.update_idletasks()
2417
2418
    else:
2419
        root.mainloop()
2420