FileMenuClass.overwrite_save_file()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 23
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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