@@ -29,6 +29,17 @@ void OMCDelegateObserverCallback(OmcObserverMessage inMessage, CFIndex inTaskID,
2929 }
3030}
3131
32+ static inline
33+ bool IsFileOrFolderActivation (UInt32 activationType)
34+ {
35+ return ((activationType == kActiveFile ) ||
36+ (activationType == kActiveFolder ) ||
37+ (activationType == kActiveFileOrFolder ) ||
38+ (activationType == kActiveFinderWindow ) ||
39+ (activationType == kActiveFolderExcludeFinderWindow ) ||
40+ (activationType == kActiveFileOrFolderExcludeFinderWindow ));
41+ }
42+
3243@interface OMCCommandExecutor ()
3344+ (CFPropertyListRef)cachedPlistForCommandFile : (NSString *)inFileName ;
3445+ (CFPropertyListRef)cachedPlistForURL : (NSURL *)inURL ;
@@ -40,7 +51,7 @@ @implementation OMCCommandExecutor
4051// when useNavDialog = TRUE, missing file context is obtained from nav dialog
4152// otherwise when the file context is missing the command is not executed
4253// if USE_NAV_DIALOG_FOR_MISSING_FILE_CONTEXT is false, the command always executes and no nav dialog is shown
43- + (OSStatus)runCommand : (NSString *)inCommandNameOrId forCommandFile : (NSString *)inFileName withContext : (id )inContext useNavDialog : (BOOL )useNavDialog delegate : (id )delegate
54+ + (OSStatus)runCommand : (NSString *)inCommandNameOrId forCommandFile : (NSString *)inFileName withContext : (id )inContext useNavDialog : (BOOL )clientAllowsNavDialog delegate : (id )delegate
4455{
4556 OSStatus error = userCanceledErr;// pessimistic scenario
4657
@@ -61,91 +72,97 @@ + (OSStatus)runCommand:(NSString *)inCommandNameOrId forCommandFile:(NSString *)
6172 if ( OMCIsValidCommandRef (commandRef) )
6273 {
6374 error = noErr;
64-
65- UInt32 objectsInfo = kOmcCommandNoSpecialObjects ;
66- OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_CommandObjects , &objectsInfo);
67- CFArrayRef docList = NULL ;
68- BOOL hasFiles = FALSE ;
69- if ( inContext != NULL )
70- {
75+
76+ // evaluate if we have a path object context for requested path OR file or folder activation
77+ bool hasFiles = false ;
78+ if (inContext != NULL )
79+ {
7180 CFTypeID contextType = CFGetTypeID ((__bridge CFTypeRef)inContext);
72- hasFiles = ((contextType == CFArrayGetTypeID ()) || (contextType == CFURLGetTypeID ()));
73- }
74-
75- Boolean useNavDialogForMissingFileContext = true ;
76- UInt32 executionOptions = 0 ;
77- OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_ExecutionOptions , &executionOptions);
78- if ( (executionOptions & kExecutionOption_UseNavDialogForMissingFileContext ) == 0 )
79- useNavDialogForMissingFileContext = false ;
80-
81- if ( ((objectsInfo & kOmcCommandContainsFileObject ) != 0 ) && !hasFiles && useNavDialogForMissingFileContext )
82- {
83- error = userCanceledErr;// command will not execute if we don't specify files
84- if (useNavDialog)
85- {
86- UInt32 activationType = kActiveAlways ;
87- error = OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_ActivationType , &activationType);
88-
89- CFStringRef theMessage = CFCopyLocalizedStringFromTable (CFSTR (" Choose Objects To Process" ), CFSTR (" Localizable" ), " " );
90-
91- NSBundle *appBundle = [NSBundle mainBundle ];
92- NSString *appName = [appBundle objectForInfoDictionaryKey: @" CFBundleName" ];
93- if (appName == NULL )
94- appName = @" OMCApplet" ;
95-
96- switch (activationType)
97- {
98- case kActiveFile :
99- {
100- docList = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseFiles | kOMCFilePanelAllowMultipleItems );
101- }
102- break ;
103-
104- case kActiveFolder :
105- case kActiveFinderWindow :
106- case kActiveFolderExcludeFinderWindow :
107- {
108- docList = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseDirectories | kOMCFilePanelAllowMultipleItems );
109- }
110- break ;
111-
112- default :
113- {
114- docList = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseFiles | kOMCFilePanelCanChooseDirectories | kOMCFilePanelAllowMultipleItems );
115- }
116- break ;
117- }
118- CFRelease (theMessage);
119- error = (docList != NULL ) ? noErr : userCanceledErr;
120- }
121-
122- if ( error == noErr )
123- {
124- error = OMCExamineContext ( omcExec, commandRef, docList );
125-
126- if ( (error == noErr) && (delegate != nil ) && [delegate respondsToSelector: @selector (noteNewRecentDocumentURL: )] )
127- {
128- // add to open recent
129- NSArray <NSURL *> *__weak absoluteURLArray = (__bridge NSArray <NSURL *> *)docList;
130- for (NSURL *oneFileURL in absoluteURLArray)
131- {
132- [delegate noteNewRecentDocumentURL: oneFileURL];
133- }
134- }
135- }
136- }
137- else
81+ hasFiles = ((contextType == CFArrayGetTypeID ()) || (contextType == CFURLGetTypeID ()));
82+ }
83+
84+ bool requiresNavDialog = false ;
85+ UInt32 activationType = kActiveAlways ;
86+ CFArrayRef selectedFiles = NULL ;
87+
88+ if (!hasFiles) // no file context provided. consider carefully whether the command needs files and allows displaying nav dialog
89+ {
90+ // does the command description allows using nav dialogs for missing file context (default = true, must be explicitly disallowed)
91+ UInt32 executionOptions = 0 ;
92+ OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_ExecutionOptions , &executionOptions);
93+ if ((executionOptions & kExecutionOption_UseNavDialogForMissingFileContext ) != 0 )
94+ {
95+ // do we have file/dir objects referenced in command or declared in environment variables?
96+ UInt32 objectsInfo = kOmcCommandNoSpecialObjects ;
97+ OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_CommandObjects , &objectsInfo);
98+
99+ // does the command activation require file/dir?
100+ OMCGetCommandInfo (omcExec, commandRef, kOmcInfo_ActivationType , &activationType);
101+ requiresNavDialog = ((objectsInfo & kOmcCommandContainsFileObject ) != 0 ) || IsFileOrFolderActivation (activationType);
102+ }
103+ }
104+
105+ if (requiresNavDialog && clientAllowsNavDialog) // all good to go with nav dialog
138106 {
139- error = OMCExamineContext ( omcExec, commandRef, (__bridge CFTypeRef)inContext );
107+ CFStringRef theMessage = CFCopyLocalizedStringFromTable (CFSTR (" Choose Objects To Process" ), CFSTR (" Localizable" ), " " );
108+
109+ NSBundle *appBundle = [NSBundle mainBundle ];
110+ NSString *appName = [appBundle objectForInfoDictionaryKey: @" CFBundleName" ];
111+ if (appName == NULL )
112+ appName = @" OMCApplet" ;
113+
114+ switch (activationType)
115+ {
116+ case kActiveFile :
117+ {
118+ selectedFiles = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseFiles | kOMCFilePanelAllowMultipleItems );
119+ }
120+ break ;
121+
122+ case kActiveFolder :
123+ case kActiveFinderWindow :
124+ case kActiveFolderExcludeFinderWindow :
125+ {
126+ selectedFiles = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseDirectories | kOMCFilePanelAllowMultipleItems );
127+ }
128+ break ;
129+
130+ default :
131+ {
132+ selectedFiles = CreateCFURLsFromOpenDialog ( (__bridge CFStringRef)appName, theMessage, NULL , NULL , kOMCFilePanelCanChooseFiles | kOMCFilePanelCanChooseDirectories | kOMCFilePanelAllowMultipleItems );
133+ }
134+ break ;
135+ }
136+ CFRelease (theMessage);
137+ error = (selectedFiles != NULL ) ? noErr : userCanceledErr;
140138 }
141-
142- if (docList != NULL )
139+ else if (requiresNavDialog)
140+ { // we don't have files, we need the nav dialog but command description explicitly disallows it
141+ error = userCanceledErr; // command will not execute if we don't specify files
142+ }
143+
144+ if (error == noErr)
145+ {
146+ error = OMCExamineContext ( omcExec, commandRef, (selectedFiles != NULL ) ? selectedFiles : (__bridge CFTypeRef)inContext );
147+ }
148+
149+ if (selectedFiles != NULL )
143150 {
144- CFRelease (docList);
145- docList = NULL ;
151+ if ((error == noErr) && (delegate != nil ) && [delegate respondsToSelector: @selector (noteNewRecentDocumentURL: )])
152+ {
153+ // add to open recent
154+ NSArray <NSURL *> *__weak absoluteURLArray = (__bridge NSArray <NSURL *> *)selectedFiles;
155+ for (NSURL *oneFileURL in absoluteURLArray)
156+ {
157+ [delegate noteNewRecentDocumentURL: oneFileURL];
158+ }
159+ }
160+
161+ CFRelease (selectedFiles);
162+ selectedFiles = NULL ;
146163 }
147164
148- if ( error == noErr )
165+ if ( error == noErr)
149166 {
150167 // Check if delegate wants to observe task execution
151168 if ((delegate != nil ) && [delegate conformsToProtocol: @protocol (OMCObserverDelegate)])
@@ -172,7 +189,7 @@ + (OSStatus)runCommand:(NSString *)inCommandNameOrId forCommandFile:(NSString *)
172189 }
173190 }
174191
175- OMCReleaseExecutor ( omcExec );// safe to release here. task lives on if execution is asynchronous
192+ OMCReleaseExecutor ( omcExec ); // safe to release here. task lives on if execution is asynchronous
176193 }
177194
178195 return error;
0 commit comments