SaveDialogsEnhanced.pas 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. unit SaveDialogsEnhanced;
  2. interface
  3. uses
  4. {$IFDEF MACOS}
  5. Macapi.AppKit, Macapi.ObjectiveC, Macapi.Foundation, Macapi.Helpers,
  6. FMX.Platform.Mac, Macapi.CocoaTypes,
  7. {$ENDIF}
  8. System.SysUtils, System.Classes, FMX.Dialogs, FMX.Types;
  9. type
  10. TEnhancedSaveDialog = class(TSaveDialog)
  11. private
  12. FFileType: string;
  13. public
  14. constructor Create(AOwner: TComponent); override;
  15. function Execute: Boolean; override;
  16. property FileType: string read FFileType;
  17. end;
  18. implementation
  19. { TEnhancedSaveDialog }
  20. constructor TEnhancedSaveDialog.Create(AOwner: TComponent);
  21. begin
  22. inherited Create(AOwner);
  23. end;
  24. function TEnhancedSaveDialog.Execute: Boolean;
  25. {$IFDEF MACOS}
  26. const
  27. NSControlStateValueOn = 1;
  28. var
  29. SavePanel: NSSavePanel;
  30. AccessoryView: NSView;
  31. FileTypeLabel: NSTextField;
  32. FileTypeCombo: NSPopUpButton;
  33. Response: NSInteger;
  34. FilterParts: TArray<string>;
  35. i: Integer;
  36. {$ENDIF}
  37. begin
  38. {$IFDEF MACOS}
  39. // 在 macOS 上使用自定义实现
  40. Result := False;
  41. try
  42. // 创建保存面板
  43. SavePanel := TNSSavePanel.Wrap(TNSSavePanel.OCClass.SavePanel);
  44. // 设置基本属性
  45. if FileName <> '' then
  46. SavePanel.setNameFieldStringValue(StrToNSStr(ExtractFileName(FileName)));
  47. if InitialDir <> '' then
  48. SavePanel.setDirectoryURL(TNSUrl.Wrap(TNSUrl.OCClass.fileURLWithPath(StrToNSStr(InitialDir))));
  49. // 创建AccessoryView
  50. AccessoryView := TNSView.Create;
  51. AccessoryView.initWithFrame(NSMakeRect(0, 0, 350, 50));
  52. // 文件类型下拉框
  53. FileTypeLabel := TNSTextField.Create;
  54. FileTypeLabel.initWithFrame(NSMakeRect(43, 15, 80, 20));
  55. FileTypeLabel.setStringValue(StrToNSStr('类型:'));
  56. FileTypeLabel.setBezeled(False);
  57. FileTypeLabel.setDrawsBackground(False);
  58. FileTypeLabel.setEditable(False);
  59. FileTypeLabel.setSelectable(False);
  60. AccessoryView.addSubview(FileTypeLabel);
  61. FileTypeCombo := TNSPopUpButton.Create;
  62. FileTypeCombo.initWithFrame(NSMakeRect(78, 15, 245, 20), False);
  63. // 解析 Filter 并添加到下拉框
  64. if Filter <> '' then
  65. begin
  66. FilterParts := Filter.Split(['|']);
  67. // Filter 格式为: "描述|扩展名|描述|扩展名|..."
  68. i := 0;
  69. while i < Length(FilterParts) - 1 do
  70. begin
  71. if (i mod 2 = 0) and (i + 1 < Length(FilterParts)) then
  72. begin
  73. // 组合描述和扩展名
  74. FileTypeCombo.addItemWithTitle(StrToNSStr(FilterParts[i] + ' (' + FilterParts[i + 1] + ')'));
  75. end;
  76. Inc(i, 2);
  77. end;
  78. end;
  79. // 如果没有 Filter 或解析失败,添加默认选项
  80. if FileTypeCombo.numberOfItems = 0 then
  81. begin
  82. FileTypeCombo.addItemWithTitle(StrToNSStr('所有文件 (*.*)'));
  83. end;
  84. // 设置默认选择,基于 FilterIndex(从1开始)
  85. if (FilterIndex > 0) and (FilterIndex <= FileTypeCombo.numberOfItems) then
  86. begin
  87. FileTypeCombo.selectItemAtIndex(FilterIndex - 1);
  88. end
  89. else
  90. begin
  91. FileTypeCombo.selectItemAtIndex(0);
  92. end;
  93. AccessoryView.addSubview(FileTypeCombo);
  94. SavePanel.setAccessoryView(AccessoryView);
  95. // 显示保存面板
  96. Response := SavePanel.runModal;
  97. if Response = NSModalResponseOK then
  98. begin
  99. Result := True;
  100. // 获取选择的文件名
  101. FileName := NSStrToStr(SavePanel.FileName);
  102. // 保存用户的选择
  103. FFileType := NSStrToStr(FileTypeCombo.titleOfSelectedItem);
  104. // 更新 FilterIndex(从1开始)
  105. FilterIndex := FileTypeCombo.indexOfSelectedItem + 1;
  106. end;
  107. except
  108. on E: Exception do
  109. begin
  110. // 如果自定义实现失败,回退到标准实现
  111. Result := inherited Execute;
  112. end;
  113. end;
  114. {$ELSE}
  115. // 在非 macOS 平台上使用标准实现
  116. Result := inherited Execute;
  117. {$ENDIF}
  118. end;
  119. initialization
  120. end.