ファイルを保存する場所を選ばせる

Recipe ID: dlg-005

ユーザーにファイルの保存先(パス)を指定させるための「名前を付けて保存」ダイアログを表示する方法を紹介します。

前提条件

プラグインの追加

ダイアログ機能を利用するには dialog プラグインが必要です。

npm run tauri add dialog

src-tauri/src/lib.rs.plugin(tauri_plugin_dialog::init()) が追加されていることを確認してください。

Permissions (権限) の設定

src-tauri/capabilities/default.jsondialog:allow-save 権限を追加します。

{
  "permissions": [
    ...,
    "dialog:default",
    "dialog:allow-save"
  ]
}

1. フロントエンドから作成する (TypeScript)

@tauri-apps/plugin-dialogsave() 関数を使用します。

基本的な保存ダイアログ

ユーザーが保存先を選択すると、その絶対パスが文字列として返されます。キャンセルされた場合は null が返ります。

import { save } from '@tauri-apps/plugin-dialog';

// 単純な保存ダイアログ
const path = await save({
  defaultPath: 'untitled.txt', // デフォルトのファイル名
});

if (path) {
  console.log('保存先:', path);
  // ここで実際にファイルを書き込む処理(fsプラグインなどを使用)を行います
} else {
  console.log('キャンセルされました');
}

拡張子フィルタを設定する

特定のファイル形式のみを保存対象としたい場合に使用します。

import { save } from '@tauri-apps/plugin-dialog';

const path = await save({
  filters: [{
    name: 'Markdown & Text',
    extensions: ['md', 'txt']
  }],
  defaultPath: 'note.md' 
});

実際のファイル書き込みと組み合わせる例

ダイアログでパスを取得した後、実際にそのパスにデータを書き込む一連の流れです。

⚠️ 注意: fs プラグインのセットアップが必要です

このコードサンプルを実行するには、@tauri-apps/plugin-fs プラグインのインストールと初期化が必要です。

1. インストール: npm run tauri add fs
2. 権限設定: src-tauri/capabilities/default.jsonfs:allow-write-text-file (または fs:default) を追加
3. 初期化: src-tauri/src/lib.rs.plugin(tauri_plugin_fs::init()) を追加
import { save } from '@tauri-apps/plugin-dialog';
import { writeTextFile } from '@tauri-apps/plugin-fs';

async function saveMyContent(content: string) {
  // 1. 保存先ユーザーに尋ねる
  const path = await save({
    filters: [{
      name: 'Text File',
      extensions: ['txt']
    }]
  });

  // 2. パスが取得できたら書き込む
  if (path) {
    try {
      await writeTextFile(path, content);
      console.log('保存完了!');
    } catch (e) {
      console.error('保存に失敗しました:', e);
    }
  }
}

2. バックエンドから作成する (Rust)

Rust 側で保存ダイアログを表示する場合は、コマンドを作成し app.dialog().file().save_file(...) を使用します。これによりフロントエンドから invoke で呼び出すことができます。

保存ダイアログの表示

#[tauri::command]
fn save_file_dialog(app: tauri::AppHandle) {
    use tauri_plugin_dialog::DialogExt;

    app.dialog().file()
        .add_filter("Text", &["txt", "md"])
        .set_file_name("untitled.txt")
        .save_file(|file_path| {
            match file_path {
                Some(path) => println!("Save to: {:?}", path),
                None => println!("Cancelled"),
            }
        });
}

// main関数などでハンドラを登録します
// .invoke_handler(tauri::generate_handler![save_file_dialog])

補足

  • save 関数の役割: この関数自体はファイルを保存しません。ユーザーが指定したパス(文字列)を返すだけです。
  • 実際の書き込み: 取得したパスを使用して、@tauri-apps/plugin-fswriteTextFilewriteFile 関数を使って実際にデータを保存する必要があります。
  • 上書き確認: 多くの OS(Windows, macOS)では、既存のファイルを選択した場合、自動的に「上書きしますか?」という確認ダイアログが表示されます。これは OS のネイティブ機能として提供されます。