Passed
Pull Request — master (#57)
by Yoshihiro
04:03
created

neditor.fm.FileMenuClass.new_open()   A

Complexity

Conditions 4

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4.25

Importance

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