Test Failed
Push — master ( b264b0...0ab505 )
by Yoshihiro
03:23
created

NovelEditor.FileMenu.FileMenuClass.__init__()   A

Complexity

Conditions 1

Size

Total Lines 4
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nop 4
1
#!/usr/bin/env python3
2
import os
3
import zipfile
4
import shutil
5
import tkinter as tk
6
import tkinter.messagebox as messagebox
7
import tkinter.filedialog as filedialog
8
9
from . import ListMenuClass
10
from . import Definition
11
12
13
class FileMenuClass(Definition.DefinitionClass):
14
    """ファイルメニューバーのクラス.
15
16
    ・ファイルメニューバーにあるプログラム群
17
18
    Args:
19
        app (instance): MainProcessingClass のインスタンス
20
        locale_var (str): ロケーション
21
        master (instance): toplevel のインスタンス
22
    """
23
    now_path = ""
24
    """今の処理しているファイルのパス."""
25
    file_path = ""
26
    """現在開いているファイル."""
27
28
    def __init__(self, app, locale_var, master=None):
29
        super().__init__(locale_var, master)
30
        self.app = app
31
        self.master = master
32
33
    def new_open(self, event=None):
34
        """新規作成.
35
36
        ・変更があれば、ファイル保存するか尋ねて、新規作成する。
37
38
        Args:
39
            event (instance): tkinter.Event のインスタンス
40
        """
41
        if not self.app.NovelEditor.get(
42
                    '1.0',
43
                    'end - 1c'
44
                ) == ListMenuClass.ListMenuClass.text_text:
45
            if messagebox.askokcancel(
46
                self.app.dic.get_dict("Novel Editor"),
47
                self.app.dic.get_dict("Do you want to overwrite?")
48
            ):
49
                self.overwrite_save_file()
50
                self.new_file()
51
52
            elif messagebox.askokcancel(
53
                    self.app.dic.get_dict("Novel Editor"),
54
                    self.app.dic.get_dict(
55
                        "Do you want to discard the current edit"
56
                        " and create a new one?"
57
                    )
58
            ):
59
                self.new_file()
60
        else:
61
            self.new_file()
62
63
    def open_file(self, event=None):
64
        """ファイルを開く処理.
65
66
        ・ファイルを開くダイアログを作成しファイルを開く。
67
68
        Args:
69
            event (instance): tkinter.Event のインスタンス
70
        """
71
        # ファイルを開くダイアログを開く
72
        fTyp = [(self.app.dic.get_dict("Novel Editor"), '*.ned')]
73
        iDir = os.path.abspath(os.path.dirname(__file__))
74
        filepath = filedialog.askopenfilename(
75
            filetypes=fTyp,
76
            initialdir=iDir
77
        )
78
        # ファイル名があるとき
79
        if not filepath == "":
80
            # 初期化する
81
            self.app.initialize()
82
            # ファイルを開いてdataフォルダに入れる
83
            with zipfile.ZipFile(filepath) as existing_zip:
84
                existing_zip.extractall('./data')
85
            # ツリービューを削除する
86
            for val in self.TREE_FOLDER:
87
                self.app.tree.delete(val[0])
88
89
            # ツリービューを表示する
90
            self.tree_get_loop()
91
            # ファイルパスを拡張子抜きで表示する
92
            file_path = os.path.splitext(filepath)[0]
93
            self.file_path_input(file_path)
94
            self.now_path_input("")
95
            # テキストビューを新にする
96
            self.app.cwc.frame()
97
98
    def overwrite_save_file(self, event=None):
99
        """上書き保存処理.
100
101
        ・上書き保存するための処理。ファイルがあれば保存して、
102
        なければ保存ダイアログを出す。
103
104
        Args:
105
            event (instance): tkinter.Event のインスタンス
106
        """
107
        # ファイルパスが存在するとき
108
        if not self.file_path == "":
109
            # 編集中のファイルを保存する
110
            self.open_file_save(self.now_path)
111
            # zipファイルにまとめる
112
            shutil.make_archive(self.file_path, "zip", "./data")
113
            # 拡張子の変更を行う
114
            shutil.move(
115
                "{0}.zip".format(self.file_path),
116
                "{0}.ned".format(self.file_path)
117
            )
118
        # ファイルパスが存在しないとき
119
        else:
120
            # 保存ダイアログを開く
121
            self.save_file()
122
123
    def save_file(self, event=None):
124
        """ファイルを保存処理.
125
126
        ・ファイルを保存する。ファイル保存ダイアログを作成し保存をおこなう。
127
128
        Args:
129
            event (instance): tkinter.Event のインスタンス
130
        """
131
        # ファイル保存ダイアログを表示する
132
        fTyp = [(self.app.dic.get_dict("Novel Editor"), ".ned")]
133
        iDir = os.path.abspath(os.path.dirname(__file__))
134
        filepath = filedialog.asksaveasfilename(
135
            filetypes=fTyp,
136
            initialdir=iDir
137
        )
138
        # ファイルパスが決まったとき
139
        if not filepath == "":
140
            # 拡張子を除いて保存する
141
            file_path = os.path.splitext(filepath)[0]
142
            self.file_path_input(file_path)
143
            # 上書き保存処理
144
            self.overwrite_save_file()
145
146
    def on_closing(self):
147
        """終了時の処理.
148
149
        ・ソフトを閉じるか確認してから閉じる。
150
        """
151
        if messagebox.askokcancel(
152
                self.app.dic.get_dict("Novel Editor"),
153
                self.app.dic.get_dict("Quit this program?")
154
        ):
155
            shutil.rmtree("./data")
156
            if os.path.isfile("./userdic.csv"):
157
                os.remove("./userdic.csv")
158
159
            self.master.destroy()
160
161
    def new_file(self):
162
        """新規作成をするための準備.
163
164
        ・ファイルの新規作成をするための準備処理をおこなう。
165
        """
166
        self.app.initialize()
167
        for val in self.TREE_FOLDER:
168
            self.app.tree.delete(val[0])
169
170
        # ツリービューを表示する
171
        self.tree_get_loop()
172
        self.app.cwc.frame()
173
        self.app.winfo_toplevel().title(
174
            self.app.dic.get_dict("Novel Editor")
175
        )
176
        # テキストを読み取り専用にする
177
        self.app.NovelEditor.configure(state='disabled')
178
        # テキストにフォーカスを当てる
179
        self.app.NovelEditor.focus()
180
181
    def open_file_save(self, path):
182
        """開いてるファイルを保存.
183
184
        ・開いてるファイルをそれぞれの保存形式で保存する。
185
186
        Args:
187
            path (str): 保存ファイルのパス
188
        """
189
        # 編集ファイルを保存する
190
        if not path == "":
191
            with open(path, mode='w', encoding='utf-8') as f:
192
                if not path.find(self.TREE_FOLDER[0][0]) == -1:
193
                    f.write(
194
                        self.save_charactor_file(self.app.EntryCallName.get())
195
                    )
196
                    self.charactor_file = ""
197
                elif not path.find(self.TREE_FOLDER[4][0]) == -1:
198
                    f.write(str(self.app.spc.zoom))
199
                else:
200
                    f.write(self.app.NovelEditor.get("1.0", tk.END+'-1c'))
201
202
            self.now_path_input(path)
203
204
    def save_charactor_file(self, name):
205
        """キャラクターファイルの保存準備.
206
207
        ・それぞれの項目をxml形式で保存する。
208
209
        Args:
210
            name (str): 名前
211
        Return:
212
            str: セーブメタデータ
213
        """
214
        return '<?xml version="1.0"?>\n<data>\n\t<call>{0}</call>\
215
        \n\t<name>{1}</name>\n\t<sex>{2}</sex>\n\t<birthday>{3}</birthday>\
216
        \n\t<body>{4}</body>\n</data>'.format(
217
            name,
218
            self.app.EntryName.get(),
219
            self.app.var.get(),
220
            self.app.EntryBirthday.get(),
221
            self.app.TextboxBiography.get(
222
                '1.0',
223
                'end -1c'
224
            )
225
        )
226
227
    def tree_get_loop(self):
228
        """ツリービューに挿入.
229
230
        ・保存データからファイルを取得してツリービューに挿入する。
231
        """
232
        for val in self.TREE_FOLDER:
233
            self.app.tree.insert('', 'end', val[0], text=val[1])
234
            # フォルダのファイルを取得
235
            path = "./{0}".format(val[0])
236
            files = os.listdir(path)
237
            for filename in files:
238
                if os.path.splitext(filename)[1] == ".txt":
239
                    self.app.tree.insert(
240
                        val[0],
241
                        'end',
242
                        text=os.path.splitext(filename)[0]
243
                    )
244
245
    @classmethod
246
    def now_path_input(cls, now_path):
247
        """今の処理しているファイルのパスを入力.
248
249
        ・今の処理しているファイルのパスをクラス変数に入力する。
250
251
        Args:
252
            now_path (str): 今の処理ししているファイルのパス
253
        """
254
        cls.now_path = now_path
255
256
    @classmethod
257
    def file_path_input(cls, file_path):
258
        """現在開いているファイルを入力.
259
260
        ・現在開いているファイルをクラス変数に入力する。
261
262
        Args:
263
            file_path (str): 今の処理ししているファイルのパス
264
        """
265
        cls.file_path = file_path
266