2010-12-03 23 views
5

Mon application permet à l'utilisateur de renommer les documents actuellement ouverts. Ceci est trivial, et fonctionne bien, avec un bug vraiment ennuyeux que je ne peux pas comprendre. Lorsqu'un fichier est renommé, AppKit (avec gentillesse) avertit l'utilisateur lors de la prochaine tentative de sauvegarde du document. L'utilisateur dit "OK" et tout continue comme d'habitude. Cela a du sens quand quelque chose d'extérieur à l'application a changé le document, mais pas quand il a été réellement fait par le document lui-même.Empêche l'avertissement lorsque le fichier NSDocument est renommé (par programme)

Le code ressemble à ceci:

-(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]]; 
} 

On pourrait penser que la mise expressément la nouvelle date d'URL et de modification sur le document serait suffisant, mais malheureusement, ce n'est pas. Le cacao génère toujours l'avertissement.

J'ai essayé de changer l'ordre (en définissant la nouvelle URL sur le document, puis en renommant le fichier) mais cela n'aide pas.

J'ai aussi essayé une solution proposée par un utilisateur sur un ancien poste sur au CocoaDev:

[self performSelector:@selector(_resetMoveAndRenameSensing)]; 

Même cela ne l'empêche pas l'avertissement cependant, et je devine il a être une bonne façon de le faire en utilisant l'API documentée. Comment Xcode gère-t-il les choses lorsqu'un utilisateur clique sur un fichier dans l'arborescence du projet et le renomme en autre chose? Il ne prévient pas l'utilisateur du changement de nom, car l'utilisateur a effectivement renommé le fichier.

Si quelqu'un peut faire la lumière sur ce que je devrais faire, ce serait génial, merci!

+0

J'ai commencé la générosité pour l'aide avec ceci. Je n'arrive vraiment à rien avec ça malheureusement. Un cas de test simple consiste simplement à créer une application de document vierge qui ouvre un fichier .txt (ou quelque chose de vraiment), ajouter un élément de menu dont l'action renomme le fichier ouvert en autre chose (et met à jour les objets document avec la nouvelle URL). J'essaie de contourner l'avertissement quand essayer de sauver le fichier la première fois après le renommer. – d11wtq

+0

Oh, et cela doit fonctionner si le document est en cours d'édition. L'enregistrement sur le disque, la fermeture du document, le déplacement du fichier et sa réouverture peuvent avoir des effets indésirables si des modifications non enregistrées existent. – d11wtq

Répondre

3

Il n'y a pas beaucoup à ce sujet dans les docs principaux. Au lieu de cela, jetez un oeil aux notes de version 10.5: http://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes sous la rubrique "NSDocument Vérification des fichiers modifiés au moment de l'épargne"

(Dans le cas de Xcode, il a une longue histoire et je ne serais pas surpris si si n'utilise pas NSDocument pour les fichiers dans le projet)

Il est à noter que le déplacement d'un fichier ne modifie pas sa date de modification, il est donc peu probable que l'appel -setFileModificationDate: ait un effet.

donc une possibilité pourrait être de contourner avertissement habituel de NSDocument comme ceci:

- (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]; 
    } 
} 

Idéalement, vous devez également vérifier la possibilité de:

  1. Demandez l'application de renommer le doc
  2. Le fichier renommé est ensuite modifié/déplacé par une autre application
  3. L'utilisateur va enregistrer le document

À ce moment-là, vous voulez que l'avertissement habituel apparaisse. Pourrait probablement être accompli par quelque chose comme:

- (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]; 
} 

Sinon, votre seul autre choix que je peux voir est d'appeler l'une des méthodes standard d'enregistrement/écriture avec des paramètres personnalisés qui demandent à votre sous-classe de documents pour déplacer la doc actuel plutôt que réellement le sauver.Serait plus compliqué je pense. Peut-être définir votre propre NSSaveOperationType?

Avec cette technique, le système doc devrait comprendre que le renommage faisait partie d'une opération de sauvegarde, mais il aurait besoin de beaucoup d'expérimentation pour être sûr.

+0

Bonne réponse, merci. J'avais déjà essayé votre deuxième suggestion sans succès, même si cela peut probablement être forcé de travailler, d'une manière ou d'une autre. Je pense que votre première suggestion (override saveDocument: et en utilisant un drapeau wasRenamed transitoire) devrait bien fonctionner. Juste sur le point de le tester maintenant. – d11wtq

+0

Ça marche! Merci beaucoup :) – d11wtq

0

N'est-il pas possible de répondre par programme à la question pour l'utilisateur? Ou vous pouvez enregistrer immédiatement après avoir renommé, de cette façon un utilisateur obtient toutes les réponses en une seule fois.

Je vois que ce problème est en cours d'exécution pendant un certain temps, de sorte que vous dire de lire le reference ne fera pas bon, je suppose ..

Espoir j'ai aidé un peu mais il ne fixe pas Votre problème directement

0

Très inspiré de la réponse de @ Mike, j'ai reçu le message "déplacé vers" pour ne plus apparaître en redirigeant NSSaveOperation vers NSSaveAsOperation. Dans ma sous-classe NSDocument:

  • Je surchargez saveDocumentWithDelegate:didSaveSelector:contextInfo: pour déterminer l'URL de sauvegarde et le type de document (affectation à ceux self); si l'ancien fileURL existe, je propose que le nouvel emplacement
  • intérieur saveDocumentWithDelegate:didSaveSelector:contextInfo: rediriger l'appel à [self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...] au lieu de [super saveDocumentWithDelegate:didSaveSelector:contextInfo:]

Cela fonctionne pour moi.