Coverage for graphica/gui/datasets/actions_menu.py: 100.0%

69 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-12 16:38 +0000

1"""データセット操作メニュー(ツリーの右クリックとツールバーのボタンで同じものを出す)。""" 

2from PySide6.QtCore import Qt 

3from PySide6.QtWidgets import QMenu 

4 

5from graphica.core.i18n import tr 

6 

7 

8def populate_dataset_actions_menu(app, menu): 

9 """ 

10 app(1つのタブ)の今の選択に合わせて menu の中身を作り直す。 

11 

12 選択に応じて出し入れする項目があるので、開くたびに作り直す。PySide6 が途中で 

13 サブメニューを回収しないよう、Python 側の参照はメニュー自身に持たせる(_graphica_submenus)。 

14 """ 

15 menu.clear() 

16 submenus = [] 

17 

18 def add_submenu(title): 

19 """空のまま出さないよう、項目が入ったものだけ最後に menu へ繋ぐ。""" 

20 sub = QMenu(title, menu) 

21 submenus.append(sub) 

22 return sub 

23 

24 data_proc_menu = add_submenu(tr("データ処理")) 

25 analysis_menu = add_submenu(tr("解析・注釈")) 

26 multi_menu = add_submenu(tr("複数データセット")) 

27 export_menu = add_submenu(tr("エクスポート")) 

28 tab_menu = add_submenu(tr("タブ操作")) 

29 

30 menu.addAction(tr("新しいフォルダ")).triggered.connect(app._on_new_folder) 

31 if app.project.datasets: 

32 menu.addAction(tr("すべて表示")).triggered.connect(app._on_show_all_datasets) 

33 menu.addAction(tr("すべて非表示")).triggered.connect(app._on_hide_all_datasets) 

34 

35 current_item = app.ui.dataset_list_widget.currentItem() 

36 if current_item is not None and current_item.data(0, Qt.ItemDataRole.UserRole) is None: 

37 menu.addAction(tr("フォルダ名を変更...")).triggered.connect(app._on_rename_dataset_folder) 

38 menu.addAction(tr("フォルダ内を全て表示")).triggered.connect(app._on_show_all_in_folder) 

39 menu.addAction(tr("フォルダ内を全て非表示")).triggered.connect(app._on_hide_all_in_folder) 

40 

41 current = app._get_current_dataset() 

42 if current is not None: 

43 menu.addSeparator() 

44 menu.addAction(tr("スタイルをコピー")).triggered.connect(app.transfer.copy_style) 

45 paste_style_action = menu.addAction(tr("スタイルを貼り付け")) 

46 paste_style_action.setEnabled(app.transfer.copied_style is not None) 

47 paste_style_action.triggered.connect(app.transfer.paste_style) 

48 # 元ファイルを持たないデータセット(貼り付け・演算・プラグインの生成物など)では使えない 

49 reload_action = menu.addAction(tr("元ファイルから再読み込み")) 

50 reload_action.setEnabled(bool(current.source_file)) 

51 reload_action.triggered.connect(app.transfer.reload_from_source) 

52 

53 processing = app.processing 

54 for title, handler in ( 

55 ("規格化(ノーマライズ)...", processing.normalize), 

56 ("Savitzky-Golayフィルタ(平滑化/微分)...", processing.savgol_smooth), 

57 ("ベースライン補正...", processing.baseline_correction), 

58 ("区間積分(台形則/Simpson則)...", processing.interval_integral), 

59 ("累積積分(台形則/Simpson則)...", processing.cumulative_integral), 

60 ("共通X格子へのリサンプリング/補間...", processing.resample), 

61 ("重複X値の検出...", processing.detect_duplicate_x), 

62 ("行フィルタ...", processing.filter_rows), 

63 ("列の値で系列に分割...", processing.split_by_column), 

64 ("外れ値検出(Z-score/IQR)...", processing.detect_outliers), 

65 ): 

66 data_proc_menu.addAction(tr(title)).triggered.connect(handler) 

67 

68 for title, handler in ( 

69 ("統計値アンカーラベルを追加...", app.overlays.add_stat_label), 

70 ("インセット(拡大図)を追加...", app.overlays.add_inset), 

71 ("ピーク位置に自動ラベルを追加...", app.peaks.add_peak_labels), 

72 ("ヒストグラム / KDE...", processing.histogram_or_kde), 

73 ): 

74 analysis_menu.addAction(tr(title)).triggered.connect(handler) 

75 

76 # 対象外でも隠さずグレーアウトする(ある機能に気づけるように) 

77 export_fit_action = export_menu.addAction(tr("フィット結果のエクスポート...")) 

78 export_fit_action.setEnabled(current.fit_result is not None) 

79 export_fit_action.triggered.connect(app.fitting.show_fit_result) 

80 copy_methods_text_action = export_menu.addAction(tr("「方法」文をコピー...")) 

81 copy_methods_text_action.setEnabled(current.provenance is not None) 

82 copy_methods_text_action.triggered.connect(app.transfer.copy_methods_text) 

83 

84 selected = app._get_selected_datasets() 

85 if len(selected) >= 2: 

86 if len(selected) == 2: 

87 multi_menu.addAction(tr("データセット間演算...")).triggered.connect(app.processing.arithmetic) 

88 multi_menu.addAction(tr("X軸アライメント(相互相関)...")).triggered.connect(app.processing.align_selected) 

89 multi_menu.addAction(tr("平均±SD生成...")).triggered.connect(app.processing.mean_and_sd_of_selected) 

90 multi_menu.addAction(tr("バッチ列計算...")).triggered.connect(app.processing.batch_column_calculate) 

91 multi_menu.addAction(tr("バッチカーブフィット...")).triggered.connect(app.fitting.batch_fit_selected) 

92 

93 if selected: 

94 export_menu.addAction(tr("データ表をファイルに書き出す...")).triggered.connect(app.transfer.export_data) 

95 # 他のタブが無くても出しておき、選んだときに案内する 

96 tab_menu.addAction(tr("別のタブへコピー...")).triggered.connect( 

97 lambda: app.transfer.copy_or_move_to_tab(move=False)) 

98 tab_menu.addAction(tr("別のタブへ移動...")).triggered.connect( 

99 lambda: app.transfer.copy_or_move_to_tab(move=True)) 

100 

101 attached_any = False 

102 for sub in submenus: 

103 if sub.actions(): 

104 if not attached_any: 

105 menu.addSeparator() 

106 attached_any = True 

107 menu.addMenu(sub) 

108 

109 if app.ui.dataset_list_widget.selectedItems(): 

110 menu.addSeparator() 

111 menu.addAction(tr("削除")).triggered.connect(app._on_remove_dataset) 

112 

113 menu._graphica_submenus = submenus 

114 return menu