UPD: refactoring serviceMenu from uMyDarwin to uDarwinApplication

This commit is contained in:
rich2014 2025-12-11 18:12:34 +08:00
commit 4d0a1966cf
4 changed files with 95 additions and 110 deletions

View file

@ -6,10 +6,13 @@ unit uDarwinApplication;
interface
uses
Classes, SysUtils, fgl,
Classes, SysUtils, fgl, Menus, uLng,
MacOSAll, CocoaAll,
CocoaInt, CocoaPrivate, Cocoa_Extra, CocoaMenus, CocoaUtils, CocoaConst,
uDarwinUtil;
uDarwinUtil, uDarwinFinder;
const
FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION = #$EF#$BF#$BC'FinderFavoriteTags';
type
// MacOS Service Integration
@ -57,6 +60,7 @@ type
const serveCallback: TDarwinServiceProviderCallBack;
const isReadyFunc: TDarwinServiceMenuIsReadyFunc;
const getFilenamesFunc: TDarwinServiceMenuGetFilenamesFunc );
class procedure popUpMenuWithServiceSubmenu( const menu: TPopupMenu; const caption: String; const paths: TStringArray );
class procedure performService( const serviceName: String );
class procedure openSystemSecurityPreferences_PrivacyAllFiles;
public
@ -111,6 +115,8 @@ begin
end;
end;
{ TDarwinServiceProvider }
procedure TDarwinServiceProvider.openWithNewTab( pboard:NSPasteboard; userData:NSString; error:NSStringPtr );
var
filenameArray: NSArray;
@ -238,6 +244,36 @@ begin
DCApp.registerServicesMenuSendTypes_returnTypes( sendTypes, returnTypes );
end;
type
TDarwinServiceMenuManager = class
private
oldMenuPopupHandler: TNotifyEvent;
serviceSubMenuCaption: String;
tagFilePaths: TStringArray;
procedure attachSystemMenu( Sender: TObject );
procedure attachServicesMenu( Sender: TObject );
procedure attachFinderTagsMenu( Sender: TObject );
procedure privilegeAction( Sender: TObject );
end;
class procedure TDarwinApplicationUtil.popUpMenuWithServiceSubmenu(const menu: TPopupMenu;
const caption: String; const paths: TStringArray);
var
menuManager: TDarwinServiceMenuManager;
begin
menuManager:= TDarwinServiceMenuManager.Create;
// because the menu item handle will be destroyed in TPopupMenu.PopUp()
// we can only call NSApplication.setServicesMenu() in OnMenuPopupHandler()
menuManager.oldMenuPopupHandler:= OnMenuPopupHandler;
OnMenuPopupHandler:= @menuManager.attachSystemMenu;
menuManager.serviceSubMenuCaption:= caption;
menuManager.tagFilePaths:= paths;
menu.PopUp();
menuManager.Free;
end;
class procedure TDarwinApplicationUtil.performService(const serviceName: String
);
var
@ -261,6 +297,59 @@ begin
NSWorkspace.sharedWorkspace.openURL( url );
end;
procedure TDarwinServiceMenuManager.attachSystemMenu(Sender: TObject);
begin
self.attachServicesMenu( Sender );
self.attachFinderTagsMenu( Sender );
end;
procedure TDarwinServiceMenuManager.attachServicesMenu( Sender: TObject );
var
menu: TPopupMenu Absolute Sender;
servicesItem: TMenuItem;
subMenu: TCocoaMenu;
begin
// call the previous OnMenuPopupHandler and restore it
if Assigned(oldMenuPopupHandler) then oldMenuPopupHandler( Sender );
OnMenuPopupHandler:= oldMenuPopupHandler;
oldMenuPopupHandler:= nil;
// attach the Services Sub Menu by calling NSApplication.setServicesMenu()
servicesItem:= menu.Items.Find(serviceSubMenuCaption);
if servicesItem<>nil then
begin
subMenu:= TCocoaMenu.alloc.initWithTitle(NSString.string_);
TCocoaMenuItem(servicesItem.Handle).setSubmenu( subMenu );
subMenu.release;
NSApp.setServicesMenu( NSMenu(servicesItem.Handle) );
end;
end;
procedure TDarwinServiceMenuManager.attachFinderTagsMenu( Sender: TObject );
var
menu: TPopupMenu Absolute Sender;
menuItem: TMenuItem;
menuIndex: Integer;
success: Boolean;
begin
menuIndex:= menu.Items.IndexOfCaption( FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION );
if menuIndex < 0 then
Exit;
success:= uDarwinFinderUtil.attachFinderTagsMenu( self.tagFilePaths, menu, menuIndex );
if success then
Exit;
menuItem:= menu.Items[menuIndex];
menuItem.Caption:= rsMenuMacOSGrantPermissionToSupportFinderTags;
menuItem.OnClick:= @self.privilegeAction;
end;
procedure TDarwinServiceMenuManager.privilegeAction(Sender: TObject);
begin
TDarwinApplicationUtil.openSystemSecurityPreferences_PrivacyAllFiles;
end;
procedure darwinOnMainMenuCreate( menu: NSMenu );
var
lclForm: TObject;

View file

@ -36,113 +36,9 @@ uses
CocoaUtils, CocoaInt, CocoaPrivate, CocoaConst, CocoaMenus, Cocoa_Extra,
uDarwinApplication, uDarwinFSWatch, uDarwinFinder, uDarwinFinderModel, uDarwinUtil;
const
FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION = #$EF#$BF#$BC'FinderFavoriteTags';
type
{ TMacosServiceMenuHelper }
TMacosServiceMenuHelper = class
private
oldMenuPopupHandler: TNotifyEvent;
serviceSubMenuCaption: String;
tagFilePaths: TStringArray;
procedure attachSystemMenu( Sender: TObject );
procedure attachServicesMenu( Sender: TObject );
procedure attachFinderTagsMenu( Sender: TObject );
procedure privilegeAction( Sender: TObject );
public
procedure PopUp( const menu: TPopupMenu; const caption: String; const paths: TStringArray );
end;
var
MacosServiceMenuHelper: TMacosServiceMenuHelper;
implementation
uses
DynLibs;
procedure TMacosServiceMenuHelper.attachSystemMenu(Sender: TObject);
begin
self.attachServicesMenu( Sender );
self.attachFinderTagsMenu( Sender );
end;
procedure TMacosServiceMenuHelper.attachServicesMenu( Sender: TObject );
var
menu: TPopupMenu Absolute Sender;
servicesItem: TMenuItem;
subMenu: TCocoaMenu;
begin
// call the previous OnMenuPopupHandler and restore it
if Assigned(oldMenuPopupHandler) then oldMenuPopupHandler( Sender );
OnMenuPopupHandler:= oldMenuPopupHandler;
oldMenuPopupHandler:= nil;
// attach the Services Sub Menu by calling NSApplication.setServicesMenu()
servicesItem:= menu.Items.Find(serviceSubMenuCaption);
if servicesItem<>nil then
begin
subMenu:= TCocoaMenu.alloc.initWithTitle(NSString.string_);
TCocoaMenuItem(servicesItem.Handle).setSubmenu( subMenu );
subMenu.release;
NSApp.setServicesMenu( NSMenu(servicesItem.Handle) );
end;
end;
procedure TMacosServiceMenuHelper.attachFinderTagsMenu( Sender: TObject );
var
menu: TPopupMenu Absolute Sender;
menuItem: TMenuItem;
menuIndex: Integer;
success: Boolean;
begin
menuIndex:= menu.Items.IndexOfCaption( FINDER_FAVORITE_TAGS_MENU_ITEM_CAPTION );
if menuIndex < 0 then
Exit;
success:= uDarwinFinderUtil.attachFinderTagsMenu( self.tagFilePaths, menu, menuIndex );
if success then
Exit;
menuItem:= menu.Items[menuIndex];
menuItem.Caption:= rsMenuMacOSGrantPermissionToSupportFinderTags;
menuItem.OnClick:= self.privilegeAction;
end;
procedure TMacosServiceMenuHelper.privilegeAction(Sender: TObject);
begin
TDarwinApplicationUtil.openSystemSecurityPreferences_PrivacyAllFiles;
end;
procedure TMacosServiceMenuHelper.PopUp( const menu: TPopupMenu;
const caption: String; const paths: TStringArray );
begin
// because the menu item handle will be destroyed in TPopupMenu.PopUp()
// we can only call NSApplication.setServicesMenu() in OnMenuPopupHandler()
oldMenuPopupHandler:= OnMenuPopupHandler;
OnMenuPopupHandler:= attachSystemMenu;
serviceSubMenuCaption:= caption;
tagFilePaths:= paths;
menu.PopUp();
end;
procedure Initialize;
begin
MacosServiceMenuHelper:= TMacosServiceMenuHelper.Create;
end;
procedure Finalize;
begin
FreeAndNil( MacosServiceMenuHelper );
end;
initialization
Initialize;
finalization
Finalize;
end.

View file

@ -78,7 +78,7 @@ uses
uOSUtils, uFileProcs, uShellExecute, uLng, uPixMapManager, uMyUnix, uOSForms,
fMain, fFileProperties, DCOSUtils, DCStrUtils, uExts, uArchiveFileSourceUtil, uSysFolders
{$IF DEFINED(DARWIN)}
, LCLStrConsts, MacOSAll, CocoaAll, uMyDarwin, uDarwinPanel, uDarwinUtil
, LCLStrConsts, MacOSAll, CocoaAll, uMyDarwin, uDarwinApplication, uDarwinPanel, uDarwinUtil
{$ELSEIF NOT DEFINED(HAIKU)}
, uKeyFile, uMimeActions
{$IF DEFINED(LINUX)}
@ -629,7 +629,7 @@ var
begin
addDelimiterMenuItem( self );
// attach Services Menu in TMacosServiceMenuHelper
// attach Services Menu in TDarwinApplicationUtil.popUpMenuWithServiceSubmenu()
mi:=TMenuItem.Create(Self);
mi.Caption:=LCLStrConsts.rsMacOSMenuServices;
Self.Items.Add(mi);

View file

@ -147,7 +147,7 @@ uses
{$IF DEFINED(DARWIN)}
, LCLStrConsts
, BaseUnix, Errors, fFileProperties
, uQuickLook, uOpenDocThumb, uMyDarwin, uDarwinFileUtil, uDefaultTerminal
, uQuickLook, uOpenDocThumb, uMyDarwin, uDarwinApplication, uDarwinFileUtil, uDefaultTerminal
{$ELSEIF DEFINED(UNIX)}
, BaseUnix, Errors, fFileProperties, uJpegThumb, uOpenDocThumb
{$IF NOT DEFINED(HAIKU)}
@ -787,7 +787,7 @@ begin
ShellContextMenu.OnClose := CloseEvent;
frmMain.ActiveFrame.FileSource.QueryContextMenu(contextFiles, TPopupMenu(ShellContextMenu));
// Show context menu
MacosServiceMenuHelper.PopUp( ShellContextMenu, rsMacOSMenuServices, getFilepaths(contextFiles) );
TDarwinApplicationUtil.popUpMenuWithServiceSubmenu( ShellContextMenu, rsMacOSMenuServices, getFilepaths(contextFiles) );
finally
// Free created menu
FreeAndNil(ShellContextMenu);