2010-12-03 4 views
5

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

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

-(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 обрабатывает вещи, когда пользователь щелкает файл в дереве проекта и переименовывает его в другое. Он не предупреждает пользователя о переименовании, поскольку пользователь действительно выполнил переименование.

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

+0

Я начал щедрость за помощь в этом. К сожалению, я действительно не получаю нигде. Простой тестовый пример - просто создать приложение для пустого документа, которое открывает файл .txt (или что-то действительно), добавляет элемент меню, действие которого переименовывает открытый файл в другое (и обновляет объекты документа новым URL-адресом). Я пытаюсь обойти предупреждение, когда пытаюсь сохранить файл в первый раз после переименования. – d11wtq 2010-12-07 11:27:19

+0

О, и это должно работать, если документ в настоящее время редактируется. Сохранение на диск, закрытие документа, перемещение файла, а затем его повторное открытие могут иметь нежелательные последствия, если существуют несохраненные изменения. – d11wtq 2010-12-07 11:28:41

ответ

3

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

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

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

Так один из вариантов мог бы обойти NSDocument «S обычное предупреждение, как так:

- (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?

С помощью этого метода система doc должна понимать, что переименование было частью операции, подобной сохранению, но для этого потребуется довольно много экспериментов.

0

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

Я вижу, что эта проблема и работает в течение некоторого времени, так что говорит вам, чтобы читать reference не будет делать ничего хорошего я предполагаю ..

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

0

Многое из того, что было вызвано ответом Майка, я получил сообщение «переехал», чтобы больше не появляться, перенаправляя 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:]

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

Смежные вопросы