2010-12-03 18 views
5

Mi aplicación permite al usuario cambiar el nombre de los documentos que están actualmente abiertos. Esto es trivial, y funciona bien, con un error realmente molesto que no puedo descifrar. Cuando se cambia el nombre de un archivo, AppKit (amablemente) advierte al usuario la próxima vez que intente guardar el documento. El usuario dice "OK" y todo continúa normalmente. Esto tiene sentido cuando algo externo a la aplicación cambió el documento, pero no cuando el documento lo hizo realmente.Prevenga la advertencia cuando el archivo NSDocument se renombra (programáticamente)

El código es algo como esto:

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

Uno podría pensar que la fijación de forma expresa la nueva URL y la fecha de modificación en el documento sería suficiente, pero por desgracia no lo es. Cacao todavía genera la advertencia.

He intentado cambiar el orden (establecer la nueva URL en el documento, ENTONCES renombrar el archivo) pero esto no ayuda.

He intentado también una solución sugerida por un usuario en un antiguo puesto encima en CocoaDev:

[self performSelector:@selector(_resetMoveAndRenameSensing)]; 

Incluso esto no impide que la advertencia sin embargo, y supongo que hay tiene que ser una forma adecuada de hacerlo utilizando la API documentada. ¿Cómo maneja Xcode las cosas cuando un usuario hace clic en un archivo en el árbol del proyecto y lo renombra a otra cosa? No advierte al usuario sobre el cambio de nombre, ya que el usuario realmente realizó el cambio de nombre.

Si alguien puede arrojar alguna luz sobre lo que podría necesitar hacer, sería genial, ¡gracias!

+0

He comenzado la recompensa por ayuda con esto. Realmente estoy llegando a ninguna parte con ella, lamentablemente. Un caso de prueba simple es simplemente crear una aplicación de documento en blanco que abre un archivo .txt (o cualquier cosa en realidad), agregar un elemento de menú cuya acción cambia el nombre del archivo abierto a otra cosa (y actualiza los objetos del documento con la nueva URL). Estoy intentando eludir la advertencia cuando intento guardar el archivo la primera vez después del cambio de nombre. – d11wtq

+0

Ah, y esto debe funcionar si el documento está actualmente editado. Guardar en el disco, cerrar el documento, mover el archivo y luego volver a abrirlo podría tener efectos no deseados si existen cambios no guardados. – d11wtq

Respuesta

3

No hay mucho sobre esto en los documentos principales. En su lugar, eche un vistazo a las notas de la versión 10.5: http://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes bajo el encabezado "NSDocument Comprobación de archivos modificados en el tiempo de ahorro"

(En el caso de Xcode, tiene una larga historia y no me sorprendería si no utiliza NSDocument para archivos dentro del proyecto)

Vale la pena señalar que mover un archivo no cambia su fecha de modificación, por lo que es poco probable que llamar -setFileModificationDate: tenga algún efecto.

Así que una posibilidad podría ser la de evitar NSDocument 's advertencia habitual de este modo:

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

Lo ideal sería que también necesita para comprobar si hay la posibilidad de:

  1. Pregunta aplicación para cambiar el nombre del documento
  2. El archivo renombrado es luego modificado/movido por otra aplicación
  3. El usuario va a guardar el documento

En ese momento, desea que aparezca la hoja de advertencia habitual. Probablemente podría llevarse a cabo por algo como:

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

De lo contrario, su única otra opción que puedo ver es llamar a uno de los estándar de guardar los métodos de lectura/escritura con algunos parámetros personalizados que estimulan al documento subclase para mover el documento actual en lugar de guardarlo realmente.Sería más complicado, creo. Tal vez defina su propio NSSaveOperationType?

Con esta técnica, el sistema de documentación debería entender que el cambio de nombre era parte de una operación de guardar, pero para estar seguro necesitaría un poco de experimentación.

+0

Buena respuesta, gracias. Ya había intentado su segunda sugerencia sin éxito, aunque probablemente se la pueda forzar a trabajar, de alguna manera. Creo que su primera sugerencia (sobreescribir saveDocument: y usar una bandera transient wasRenamed) debería funcionar bien. A punto de probarlo ahora. – d11wtq

+0

¡Funciona! Muchas gracias :) – d11wtq

0

¿No es posible responder a la pregunta mediante programación para el usuario? O puede guardar inmediatamente después de cambiar el nombre, de esta manera un usuario recibe todas las respuestas de una vez.

veo que este problema está en marcha desde hace algún tiempo, por lo que le dice a leer la reference no servirá de nada, supongo ..

Espero que me ayudó un poco a pesar de que no se soluciona su problema directamente

0

Muy inspirado en la respuesta de @ Mike, recibí el mensaje "movido a" para que no apareciera más reencaminando NSSaveOperation a NSSaveAsOperation. En mi NSDocument subclase:

  • me sobrecargue saveDocumentWithDelegate:didSaveSelector:contextInfo: para determinar la URL Guardar y tipo de documento (la asignación de aquellos a self); si existe la vieja fileURL, propongo que a la nueva ubicación
  • Dentro saveDocumentWithDelegate:didSaveSelector:contextInfo: puedo redirigir la llamada a [self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...] en lugar de [super saveDocumentWithDelegate:didSaveSelector:contextInfo:]

Esto funciona para mí.

Cuestiones relacionadas