2010-08-31 14 views
6

En mi aplicación deseo recibir una notificación si se agrega algo a NSPasteboard. Si copio un texto de cualquier otro programa, quiero que mi aplicación lo sepa.Obtenga una notificación cuando se agregue algo a NSPasteboard

En algún lugar que lo haya leído no se puede hacer de esa manera. Debería crear un temporizador y verificar el contenido de NSPasteboard yo mismo.

¿Es esta la manera de hacerlo? ¿O hay algún tipo de notificaciones?

Respuesta

11

Sí, básicamente tiene que sondear la mesa de trabajo para ver si su contenido ha cambiado. No es ideal, pero es posible. Básicamente, tiene un temporizador que dispara una o dos veces por segundo y verifica el -[NSPasteboard changeCount]. Si el changeCount cambia, eso significa que el contenido del portapapeles también ha cambiado (o hay al menos un nuevo propietario).

+0

Argh, me hizo mientras estaba escribiendo ... Bueno, para agregar al poste, se puede establecer algún código como este (http://pastie.org/1129293) para observar los cambios. –

3

Sobre la base de las respuestas proporcionada por Dave DeLong me ocurrió aplicación similar pero en Swift, aquí está el enlace a su GIST: PasteboardWatcher.swift

fragmento de código desde la misma:

class PasteboardWatcher : NSObject { 

    // assigning a pasteboard object 
    private let pasteboard = NSPasteboard.generalPasteboard() 

    // to keep track of count of objects currently copied 
    // also helps in determining if a new object is copied 
    private var changeCount : Int 

    // used to perform polling to identify if url with desired kind is copied 
    private var timer: NSTimer? 

    // the delegate which will be notified when desired link is copied 
    var delegate: PasteboardWatcherDelegate? 

    // the kinds of files for which if url is copied the delegate is notified 
    private let fileKinds : [String] 

    /// initializer which should be used to initialize object of this class 
    /// - Parameter fileKinds: an array containing the desired file kinds 
    init(fileKinds: [String]) { 
     // assigning current pasteboard changeCount so that it can be compared later to identify changes 
     changeCount = pasteboard.changeCount 

     // assigning passed desired file kinds to respective instance variable 
     self.fileKinds = fileKinds 

     super.init() 
    } 
    /// starts polling to identify if url with desired kind is copied 
    /// - Note: uses an NSTimer for polling 
    func startPolling() { 
     // setup and start of timer 
     timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: Selector("checkForChangesInPasteboard"), userInfo: nil, repeats: true) 
    } 

    /// method invoked continuously by timer 
    /// - Note: To keep this method as private I referred this answer at stackoverflow - [Swift - NSTimer does not invoke a private func as selector](http://stackoverflow.com/a/30947182/217586) 
    @objc private func checkForChangesInPasteboard() { 
     // check if there is any new item copied 
     // also check if kind of copied item is string 
     if let copiedString = pasteboard.stringForType(NSPasteboardTypeString) where pasteboard.changeCount != changeCount { 

      // obtain url from copied link if its path extension is one of the desired extensions 
      if let fileUrl = NSURL(string: copiedString) where self.fileKinds.contains(fileUrl.pathExtension!){ 

       // invoke appropriate method on delegate 
       self.delegate?.newlyCopiedUrlObtained(copiedUrl: fileUrl) 
      } 

      // assign new change count to instance variable for later comparison 
      changeCount = pasteboard.changeCount 
     } 
    } 
} 

Nota : en el código compartido Estoy tratando de identificar si el usuario ha copiado una url de archivo o no, el código proporcionado puede modificarse fácilmente para otros fines generales de .

Cuestiones relacionadas