Запретить предупреждение, когда файл NSDocument (программно) переименован - PullRequest
5 голосов
/ 03 декабря 2010

Мое приложение позволяет пользователю переименовывать документы, которые в данный момент открыты. Это тривиально, и работает отлично, с одной действительно раздражающей ошибкой, которую я не могу понять. Когда файл переименовывается, AppKit (любезно) предупреждает пользователя при следующей попытке сохранить документ. Пользователь говорит «ОК», и все продолжается как обычно. Это имеет смысл, когда что-то внешнее по отношению к приложению изменило документ, но не тогда, когда это было фактически сделано самим документом.

Код выглядит примерно так:

-(void)renameDocumentTo:(NSString *)newName {
  NSURL *newURL = [[[self fileURL] URLByDeletingLastPathComponent]
                                   URLByAppendingPathComponent:newName];

  NSFileManager *fileManager = [NSFileManager defaultManager];
  [fileManager moveItemAtURL:[self fileURL] toURL:newURL];
  NSDictionary *attrs = [fileManager attributesForItemAtPath:[newURL path] error:NULL];

  [self setFileURL:newURL];
  [self setFileModificationDate:[attrs fileModificationDate]];
}

Можно подумать, что явной установки нового URL-адреса и даты изменения в документе будет достаточно, но, к сожалению, это не так. Какао по-прежнему выдает предупреждение.

Я пытался изменить порядок (установка нового URL-адреса в документе, затем переименование файла), но это не помогает.

Я также попробовал исправить, предложенное пользователем в старом сообщении на CocoaDev:

[self performSelector:@selector(_resetMoveAndRenameSensing)];

Однако даже это не останавливает предупреждение, и я предполагаю, что имеет , чтобы быть правильным способом сделать это с помощью документированного API. Как Xcode обрабатывает вещи, когда пользователь щелкает файл в дереве проекта и переименовывает его во что-то другое. Он не предупреждает пользователя о переименовании, поскольку пользователь фактически выполнил переименование.

Если кто-нибудь сможет пролить свет на то, что мне может понадобиться, это было бы здорово, спасибо!

Ответы [ 3 ]

3 голосов
/ 10 декабря 2010

В основных документах об этом мало. Вместо этого взгляните на примечания к выпуску 10.5: http://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes под заголовком «Проверка NSDocument на наличие модифицированных файлов во время сохранения»

(В случае XCode у него длинная история, и я не удивлюсь, если не использовать NSDocument для файлов в проекте)

Стоит отметить, что перемещение файла не меняет дату его изменения, поэтому вызов -setFileModificationDate: вряд ли окажет какое-либо влияние.

Таким образом, одна возможность могла бы обойти обычное предупреждение NSDocument следующим образом:

- (void)saveDocument:(id)sender;
{
    if (wasRenamed)
    {
        [self saveToURL:[self fileURL] ofType:[self fileType] forSaveOperation:NSSaveOperation delegate:nil didSaveSelector:nil contextInfo:NULL];
        wasRenamed = NO;
    }
    else
    {
        [super saveDocument:sender];
    }
}

В идеале вам также необходимо проверить возможность:

  1. Попросить приложение переименовать документ
  2. Переименованный файл затем изменяется / перемещается другим приложением
  3. Пользователь идет, чтобы сохранить документ

В этот момент вы хотите, чтобы появился обычный лист предупреждения. Возможно, может быть достигнуто что-то вроде:

- (void)renameDocumentTo:(NSString *)newName
{
    // Do the rename

    [self setFileURL:newURL];
    wasRenamed = YES; // MUST happen after -setFileURL:
}

- (void)setFileURL:(NSURL *)absoluteURL;
{
    if (![absoluteURL isEqual:[self fileURL]]) wasRenamed = NO;
    [super setFileURL:absoluteURL];
}

- (void)setFileModificationDate:(NSDate *)modificationDate;
{
    if (![modificationDate isEqualToDate:[self fileModificationDate]]) wasRenamed = NO;
    [super setFileModificationDate:modificationDate];
}

В противном случае ваш единственный другой выбор, который я вижу, - это вызвать один из стандартных методов сохранения / записи с некоторыми пользовательскими параметрами, которые побуждают ваш подкласс документа перемещать текущий документ, а не сохранять его. Было бы хитрее, я думаю. Возможно, определите свой NSSaveOperationType?

При использовании этой техники система документации должна понимать, что переименование является частью операции, подобной операции сохранения, но для уверенности потребуется немало экспериментов.

0 голосов
/ 11 декабря 2015

Воодушевленный ответом @ Майка, я получил сообщение "переехал", чтобы больше не появляться, перенаправив NSSaveOperation на NSSaveAsOperation.В моем подклассе NSDocument:

  • Я перегружаю saveDocumentWithDelegate:didSaveSelector:contextInfo:, чтобы определить URL сохранения и тип документа (назначая их для self);если старый fileURL существует, я перемещаю его в новое место
  • Внутри saveDocumentWithDelegate:didSaveSelector:contextInfo: Я перенаправляю вызов на [self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...] вместо [super saveDocumentWithDelegate:didSaveSelector:contextInfo:]

Это работает для меня

0 голосов
/ 10 декабря 2010

Разве нельзя программно ответить на вопрос для пользователя?Или вы можете сохранить сразу после переименования, таким образом, пользователь получает каждый ответ за один раз.

Я вижу, что эта проблема работает и какое-то время работает, поэтому советую вам прочитать ссылку не принесет пользы, я думаю ..

Надеюсь, я немного помог, хотя это не решит вашу проблему напрямую

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...