from pathlib import Path
import pickle
import tkinter as tk
import tkinter.filedialog


def open_dialog(**opt):
    """Parameters
    ----------
    Options will be passed to `tkinter.filedialog.askopenfilename`.
    See also tkinter's document.
    Followings are example of frequently used options.
    - filetypes=[(label, ext), ...]
        - label: str
        - ext: str, semicolon separated extentions
    - initialdir: str, default Path.cwd()
    - multiple: bool, default False

    Returns
    --------
    filename, str
    """
    root = tk.Tk()
    root.withdraw()
    root.wm_attributes("-topmost", True)

    opt_default = dict(initialdir=Path.cwd())
    _opt = dict(opt_default, **opt)

    return tk.filedialog.askopenfilename(**_opt)


def saveas_dialog(**opt):
    """Parameters
    ----------
    Options will be passed to `tkinter.filedialog.asksaveasfilename`.
    See also tkinter's document.
    Followings are example of frequently used options.
    - filetypes=[(label, ext), ...]
        - label: str
        - ext: str, semicolon separated extentions
    - initialdir: str, default Path.cwd()
    - initialfile: str, default isn't set

    Returns
    --------
    filename, str
    """
    root = tk.Tk()
    root.withdraw()
    root.wm_attributes("-topmost", True)

    opt_default = dict(initialdir=Path.cwd())
    _opt = dict(opt_default, **opt)

    return tk.filedialog.asksaveasfilename(**_opt)


def load_pickle_with_dialog(mode='rb', **opt):
    """Load a pickled object with a filename assigned by tkinter's open dialog.

    kwargs will be passed to saveas_dialog.
    """
    opt_default = dict(filetypes=[('pickled data', '*.pkl'), ('all', '*')])
    _opt = dict(opt_default, **opt)
    fn = open_dialog(**_opt)
    if fn == '':  # canceled
        return None

    with Path(fn).open(mode) as f:
        data = pickle.load(f)
    return data


def dump_pickle_with_dialog(obj, mode='wb', **opt):
    """Pickle an object with a filename assigned by tkinter's saveas dialog.

    kwargs will be passed to saveas_dialog.

    Returns
    --------
    filename: str
    """
    opt_default = dict(filetypes=[('pickled data', '*.pkl'), ('all', '*')])
    _opt = dict(opt_default, **opt)
    fn = saveas_dialog(**_opt)
    if fn == '':  # canceled
        return ''
    # note: 上書き確認はtkinterがやってくれるのでここではチェックしない

    with Path(fn).open(mode) as f:
        pickle.dump(obj, f)

    return fn

[((550, 557), 'tkinter.Tk', 'tk.Tk', ([], {}), '()\n', (555, 557), True, 'import tkinter as tk\n'), ((714, 751), 'tkinter.filedialog.askopenfilename', 'tk.filedialog.askopenfilename', ([], {}), '(**_opt)\n', (743, 751), True, 'import tkinter as tk\n'), ((1226, 1233), 'tkinter.Tk', 'tk.Tk', ([], {}), '()\n', (1231, 1233), True, 'import tkinter as tk\n'), ((1390, 1429), 'tkinter.filedialog.asksaveasfilename', 'tk.filedialog.asksaveasfilename', ([], {}), '(**_opt)\n', (1421, 1429), True, 'import tkinter as tk\n'), ((1853, 1867), 'pickle.load', 'pickle.load', (['f'], {}), '(f)\n', (1864, 1867), False, 'import pickle\n'), ((2392, 2411), 'pickle.dump', 'pickle.dump', (['obj', 'f'], {}), '(obj, f)\n', (2403, 2411), False, 'import pickle\n'), ((654, 664), 'pathlib.Path.cwd', 'Path.cwd', ([], {}), '()\n', (662, 664), False, 'from pathlib import Path\n'), ((1330, 1340), 'pathlib.Path.cwd', 'Path.cwd', ([], {}), '()\n', (1338, 1340), False, 'from pathlib import Path\n'), ((1812, 1820), 'pathlib.Path', 'Path', (['fn'], {}), '(fn)\n', (1816, 1820), False, 'from pathlib import Path\n'), ((2358, 2366), 'pathlib.Path', 'Path', (['fn'], {}), '(fn)\n', (2362, 2366), False, 'from pathlib import Path\n')]