基于文档的OSX应用程序 - 将打开文档的数量限制为一个

时间:2013-04-13 21:46:56

标签: objective-c macos cocoa nsdocument

我正在试图弄清楚如何一次将基于NSDocument的应用程序限制为一个打开的文档。它很快变得一团糟。

有没有人能够直截了当地做到这一点。可靠的方式?

//// //// EDIT 我希望能够提示用户保存现有的打开文档并在创建/打开新文档之前将其关闭。

////编辑2 我现在试图只是在任何文档打开的情况下用适当的消息返回错误 - 但是,错误消息没有显示我的NSLocalizedKeyDescription。这是在我的NSDocumentController子类中。

-(id)openUntitledDocumentAndDisplay:(BOOL)displayDocument error:(NSError **)outError{


if([self.documents count]){

    NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObject:@"Only one document can be open at a time. Please close your document." forKey:NSLocalizedDescriptionKey];

    *outError = [NSError errorWithDomain:@"Error" code:192 userInfo:dict];

    return nil;
}
return     [super openUntitledDocumentAndDisplay:displayDocument error:outError];
}

2 个答案:

答案 0 :(得分:3)

这不是一个简单的解决方案,因为它是一个非常复杂的类,但我建议你继承NSDocumentController并注册你自己的禁用超过一定数量文档的开放。这将允许您通过将文件放在停靠栏中的应用程序图标或在查找程序中打开来阻止打开文件等操作,这两个文件都绕过Open菜单项。

您仍需要覆盖GUI /菜单激活码,以防止在您打开文档时Open...可用,但这只是为了确保您不会混淆用户。

您的文档控制器需要在任何其他文档控制器之前创建,但通过在DocumentController中放置MainMenu.xib实例并确保将类设置为您的子类,这很容易实现。 (这将使它调用-sharedDocumentController,这将创建你的实例。)

然后,在文档控制器中,您需要覆盖:

- makeDocumentForURL:withContentsOfURL:ofType:error:
- makeUntitledDocumentOfType:error:
- makeDocumentWithContentsOfURL:ofType:error:

检查并查看文档是否已打开并返回nil,将错误指针设置为新创建的错误,该错误显示相应的消息(NSLocalizedDescriptionKey)。

这应该处理拖放,苹果等情况。

修改 至于你对开幕活动的关闭/保存提示的额外请求,这是一个更糟糕的问题。你可以:

  1. 保存信息(基本上是make请求的参数)
  2. -closeAllDocumentsWithDelegate:didCloseAllSelector:contextInfo:作为代理发送self,将新创建的例程作为选择器发送
  3. 当您收到选择器时,请清除已保存的参数,或使用您保存的参数重新执行命令。
  4. 请注意,步骤2和3可能需要在performSelector

    的延迟时间内完成

    我自己没有尝试过(其余的我以前做过),但它似乎应该有效。

答案 1 :(得分:0)

这是我最终解决的问题。所有这些都在NSDocumentController子类中。

- (NSInteger)runModalOpenPanel:(NSOpenPanel *)openPanel forTypes:(NSArray *)extensions{

    [openPanel setAllowsMultipleSelection:NO];

    return [super runModalOpenPanel:openPanel forTypes:extensions];
}

-(NSUInteger)maximumRecentDocumentCount{
    return 0;
}


-(void)newDocument:(id)sender{

    if ([self.documents count]) {

        [super closeAllDocumentsWithDelegate:self
                         didCloseAllSelector:@selector(newDocument:didCloseAll:contextInfo:) contextInfo:(void*)sender];

    }
    else{
        [super newDocument:sender];
    }
}

- (void)newDocument:(NSDocumentController *)docController  didCloseAll: (BOOL)didCloseAll contextInfo:(void *)contextInfo{

    if([self.documents count])return;

    else [super newDocument:(__bridge id)contextInfo];

}

-(void)openDocument:(id)sender{

    if ([self.documents count]) {

        [super closeAllDocumentsWithDelegate:self
                         didCloseAllSelector:@selector(openDocument:didCloseAll:contextInfo:) contextInfo:(void*)sender];

    }
    else{
        [super openDocument:sender];
    }



}

- (void)openDocument:(NSDocumentController *)docController  didCloseAll: (BOOL)didCloseAll contextInfo:(void *)contextInfo{

    if([self.documents count])return;
    else [super openDocument:(__bridge id)contextInfo];

}

另外,我很遗憾地需要从主菜单中删除“打开最近”选项。我还没弄清楚如何解决这种情况。