【问题标题】:Applescript command in document class文档类中的 Applescript 命令
【发布时间】:2014-06-27 22:14:00
【问题描述】:

我正在尝试在我的文档类中创建一个 applescript 命令。我知道我做错了什么,但我不知道该怎么做。

据我了解(可能不正确),当我创建一个新命令时 我需要为该命令指定一个新类。但是从那个新班级,让我们称之为 ScriptResetCommand,如何通过performDefaultImplementation 方法访问文档对象? applescript 调用类似于

tell document 1 of application "DocScript" to simple reset

这是我当前的代码: ScriptResetCommand.m 文件:

@implementation ScriptResetCommand
- (id)performDefaultImplementation {
    // Somehow I need to access the correct document class and
    // perform my reset.
    NSLog(@"ScriptResetCommand performDefaultImplementation");
    return @"Reset Stuff";
}

ScriptResetCommand.h 文件:

@interface ScriptResetCommand : NSScriptCommand
- (id)performDefaultImplementation;

.sdef 文件:

    <command name="simple reset" code="jDsgSrst" description="run a simple reset">
        <cocoa class="ScriptResetCommand"/>
        <result type="text" description="returns the result"/>
    </command>

因此,使用此代码,我可以成功调用 ScriptResetCommand 类中的 performDefaultImplementation 方法,但是如何访问其中包含所需 reset 命令的 Document 对象?

提前致谢。

【问题讨论】:

    标签: objective-c macos cocoa applescript


    【解决方案1】:

    您应该能够使用方法-[NSScriptCommand evaluatedReceivers] 访问文档对象。试试这样的:

    - (id)performDefaultImplementation {
        NSDocument *document = [self.evaluatedReceivers firstObject];
        if (![document isKindOfClass:[NSDocument class]]) {
            // I'm just guessing how this error should be handled; untested (for example, you'll want to make sure your app returns an error if you run "reset stuff" without specifying a document)
            [self setScriptErrorExpectedTypeDescriptor:[NSAppleEventDescriptor descriptorWithTypeCode:cDocument]];
            return nil;
        }
    
        NSLog(@"Got document: %@", document);
    
        return @"Reset Stuff";
    }
    

    【讨论】:

    • 感谢您的建议。出于某种原因,上面的文档对象是零。我还尝试了NSDocument *doc2 = [self directParameter];,它也返回 nil。
    • 有趣,你试过打印self. receiversSpecifier、self.arguments和self.evaluatedArguments进行调试吗?其中之一可能有一些有趣的东西。见developer.apple.com/library/Mac/documentation/Cocoa/Reference/…
    【解决方案2】:

    我不知道是什么

    tell document 1 of application "DocScript" to simple reset
    

    可以,但要对其进行处理,请将其分解为动词(简单重置)和目标(应用程序“DocScript”的文档 1)。执行命令时,[command directParameter]中会提供对目标的引用,您可以从中获取文档的objectSpecifier。

    以下是我在可编写脚本的文本编辑器 Ted 中实现文本选择的方法。动词(命令)是“选择”,目标是“文档 1 的第 5 段”。

    tell application "Ted"
        select paragraph 5 of document 1
    end tell
    

    SDEF:命令在 Text Suite 对象中定义:

    <suite name="Text Suite" code="????">
        ...
        <class name="paragraph" code="cpar" inherits="item" >
            ...
            <responds-to command="select">
                <cocoa method="handleSelectCommand:"/>
            </responds-to>
        </class>
        ...
    </suite>
    

    “选择”命令实际上包含在文本套件中可以选择的每个类中:例如段落,行,单词,字符。

    实施:

    由于所有各种可编写脚本的文本对象都表示为 NSTextStorage 类,因此我只使用 NSTextStorage 上的一个类别来实现该命令。

    @implementation NSTextStorage (Scriptability)
    -   (void) handleSelectCommand:(NSScriptCommand *)command
    {
        NSScriptObjectSpecifier *directParameter =[command directParameter];
    
        NSScriptObjectSpecifier *container = [directParameter containerSpecifier];
    
        TedDocument *document = [self extractDocument:container];
    
        NSString *contents = document.textView.string;
        NSRange selRange;
    
        [self getRangeForSelectCommand:directParameter contents:contents range:&selRange];
    
        [document.textView setSelectedRange:selRange];
    }
    @end
    

    directParameter 提供了对文档的引用,但它是包含层次结构的一部分,在本例中为“应用程序“Ted”的文档 1 的第 5 段”,因此我们需要一个遍历该层次结构以从中提取文档的方法。这是那个函数:

    // 如有必要,使用递归导航包含层次结构。

    - (TedDocument *) extractDocument:(NSScriptObjectSpecifier *)container
    {
        if (container == nil)
        {
            NSLog(@"%@", @"ERROR: extractDocument received nil container reference");
    
            return nil;
        }
    
        FourCharCode containerClass =  [[container keyClassDescription] appleEventCode];
    
        if (containerClass != 'docu')
        {
            return [self extractDocument:[container containerSpecifier]];
        }
    
        return [container objectsByEvaluatingSpecifier];
    }
    

    【讨论】:

      猜你喜欢
      • 2021-02-03
      • 1970-01-01
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多