Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pasteboard UTI #1213

Merged
merged 4 commits into from Dec 20, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions Quicksilver/Code-QuickStepCore/QSObject_Pasteboard.h
Expand Up @@ -4,6 +4,9 @@

#import "QSObject.h"

extern NSString *QSPasteboardObjectIdentifier;
extern NSString *QSPasteboardObjectAddress;

@interface QSObject (Pasteboard)
+ (id)objectWithPasteboard:(NSPasteboard *)pasteboard;
- (id)initWithPasteboard:(NSPasteboard *)pasteboard;
Expand Down
51 changes: 35 additions & 16 deletions Quicksilver/Code-QuickStepCore/QSObject_Pasteboard.m
Expand Up @@ -3,6 +3,11 @@
#import "QSObject_FileHandling.h"
#import "QSObject_StringHandling.h"

NSString *QSPasteboardObjectIdentifier = @"QSObjectID";
NSString *QSPasteboardObjectAddress = @"QSObjectAddress";

#define QSPasteboardIgnoredTypes [NSArray arrayWithObjects:QSPasteboardObjectAddress, @"CorePasteboardFlavorType 0x4D555246", @"CorePasteboardFlavorType 0x54455854", nil]

id objectForPasteboardType(NSPasteboard *pasteboard, NSString *type) {
if ([PLISTTYPES containsObject:type])
return [pasteboard propertyListForType:type];
Expand Down Expand Up @@ -40,14 +45,14 @@ @implementation QSObject (Pasteboard)
+ (id)objectWithPasteboard:(NSPasteboard *)pasteboard {
id theObject = nil;

if ([[pasteboard types] containsObject:QSPrivatePboardType] || [[pasteboard types] containsObject:@"de.petermaurer.TransientPasteboardType"])
if ([pasteboard isTransient] || [pasteboard isAutoGenerated])
return nil;

if ([[pasteboard types] containsObject:@"QSObjectID"])
theObject = [QSObject objectWithIdentifier:[pasteboard stringForType:@"QSObjectID"]];
if ([[pasteboard types] containsObject:QSPasteboardObjectIdentifier])
theObject = [QSObject objectWithIdentifier:[pasteboard stringForType:QSPasteboardObjectIdentifier]];

if (!theObject && [[pasteboard types] containsObject:@"QSObjectAddress"]) {
NSArray *objectIdentifier = [[pasteboard stringForType:@"QSObjectAddress"] componentsSeparatedByString:@":"];
if (!theObject && [[pasteboard types] containsObject:QSPasteboardObjectAddress]) {
NSArray *objectIdentifier = [[pasteboard stringForType:QSPasteboardObjectAddress] componentsSeparatedByString:@":"];
if ([[objectIdentifier objectAtIndex:0] intValue] == [[NSProcessInfo processInfo] processIdentifier]) {
QSObject *anObject = nil;
sscanf([[objectIdentifier lastObject] cStringUsingEncoding:NSUTF8StringEncoding], "%p", &anObject);
Expand All @@ -64,6 +69,7 @@ + (id)objectWithPasteboard:(NSPasteboard *)pasteboard {
- (id)initWithPasteboard:(NSPasteboard *)pasteboard {
return [self initWithPasteboard:pasteboard types:nil];
}

- (void)addContentsOfClipping:(NSString *)path { // Not thread safe?
NSPasteboard *pasteboard = [NSPasteboard pasteboardByFilteringClipping:path];
[self addContentsOfPasteboard:pasteboard types:nil];
Expand All @@ -72,9 +78,8 @@ - (void)addContentsOfClipping:(NSString *)path { // Not thread safe?

- (void)addContentsOfPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types {
NSMutableArray *typeArray = [NSMutableArray arrayWithCapacity:1];
NSArray *ignoreTypes = [NSArray arrayWithObjects:@"QSObjectAddress", @"CorePasteboardFlavorType 0x4D555246", @"CorePasteboardFlavorType 0x54455854", nil];
for(NSString *thisType in (types?types:[pasteboard types])) {
if ([[pasteboard types] containsObject:thisType] && ![ignoreTypes containsObject:thisType]) {
if ([[pasteboard types] containsObject:thisType] && ![QSPasteboardIgnoredTypes containsObject:thisType]) {
id theObject = objectForPasteboardType(pasteboard, thisType);
if (theObject && thisType)
[self setObject:theObject forType:thisType];
Expand Down Expand Up @@ -132,7 +137,7 @@ - (id)initWithPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types {
if ([self objectForType:kQSObjectPrimaryName])
[self setName:[self objectForType:kQSObjectPrimaryName]];
else {
[self setName:@"Unknown Clipboard Object"];
[self setName:NSLocalizedString(@"Unknown Clipboard Object", @"Name for an unknown clipboard object")];
[self guessName];
}
[self loadIcon];
Expand All @@ -159,11 +164,25 @@ - (void)guessName {
// Sometimes no dataForType:NSStringPboardType exists, so fall back to using the word "text" (avoids a crash)
NSString *textString = [itemForKey(NSStringPboardType) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
if (!textString) {
textString = @"Text";
textString = NSLocalizedString(@"Text", @"Name of text object");
}
NSDictionary *namesAndKeys = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:textString, @"PDF Image", @"Finder Icon", @"PostScript Image", @"TIFF Image", @"Color Data", @"File Contents", @"Font Information", @"HTML Data", @"Paragraph Formatting", @"Tabular Text", @"VCard Data", @"Promised Files",nil]
forKeys:[NSArray arrayWithObjects:NSStringPboardType, NSPDFPboardType, [@"'icns'" encodedPasteboardType], NSPostScriptPboardType, NSTIFFPboardType, NSColorPboardType, NSFileContentsPboardType, NSFontPboardType, NSHTMLPboardType, NSRulerPboardType, NSTabularTextPboardType, NSVCardPboardType, NSFilesPromisePboardType,nil]];

NSDictionary *namesAndKeys = [NSDictionary dictionaryWithObjectsAndKeys:
textString, NSStringPboardType,
NSLocalizedString(@"PDF Image", @"Name of PDF image "), NSPDFPboardType,
NSLocalizedString(@"Finder Icon", @"Name of icon file object"), [@"'icns'" encodedPasteboardType],
NSLocalizedString(@"PostScript Image", @"Name of PostScript image object"), NSPostScriptPboardType,
NSLocalizedString(@"TIFF Image", @"Name of TIFF image object"), NSTIFFPboardType,
NSLocalizedString(@"Color Data", @"Name of Color data object"), NSColorPboardType,
NSLocalizedString(@"File Contents", @"Name of File contents object"), NSFileContentsPboardType,
NSLocalizedString(@"Font Information", @"Name of Font information object"), NSFontPboardType,
NSLocalizedString(@"HTML Data", @"Name of HTML data object"), NSHTMLPboardType,
NSLocalizedString(@"Paragraph Formatting", @"Name of Paragraph Formatting object"), NSRulerPboardType,
NSLocalizedString(@"Tabular Text", @"Name of Tabular text object"), NSTabularTextPboardType,
NSLocalizedString(@"VCard Data", @"Name of VCard data object"), NSVCardPboardType,
NSLocalizedString(@"Promised Files", @"Name of Promised files object"), NSFilesPromisePboardType,
nil];

for (NSString *key in [namesAndKeys allKeys]) {
if (itemForKey(key) ) {
[self setName:[namesAndKeys objectForKey:key]];
Expand Down Expand Up @@ -244,18 +263,18 @@ - (BOOL)putOnPasteboard:(NSPasteboard *)pboard declareTypes:(NSArray *)types inc
}
}
if ([self identifier]) {
[pboard addTypes:[NSArray arrayWithObject:@"QSObjectID"] owner:self];
writeObjectToPasteboard(pboard, @"QSObjectID", [self stringValue]);
[pboard addTypes:[NSArray arrayWithObject:QSPasteboardObjectIdentifier] owner:self];
writeObjectToPasteboard(pboard, QSPasteboardObjectIdentifier, [self stringValue]);
}

[pboard addTypes:[NSArray arrayWithObject:@"QSObjectAddress"] owner:self];
[pboard addTypes:[NSArray arrayWithObject:QSPasteboardObjectAddress] owner:self];
// NSLog(@"types %@", [pboard types]);
return YES;
}

- (void)pasteboard:(NSPasteboard *)sender provideDataForType:(NSString *)type {
//if (VERBOSE) NSLog(@"Provide: %@", [type decodedPasteboardType]);
if ([type isEqualToString:@"QSObjectAddress"]) {
if ([type isEqualToString:QSPasteboardObjectAddress]) {
writeObjectToPasteboard(sender, type, [NSString stringWithFormat:@"%d:%p", [[NSProcessInfo processInfo] processIdentifier] , self]);
} else {
id theData = nil;
Expand Down
18 changes: 1 addition & 17 deletions Quicksilver/Code-QuickStepCore/QSTypes.h
Expand Up @@ -20,20 +20,4 @@ extern NSString *QSIMAccountType; //NSString ("AIM:accountname") also MSN, I
extern NSString *QSIMMultiAccountType; //NSSet of ("AIM:accountname") also MSN, ICQ, Jabber, Yahoo
extern NSString *QSCommandType; //QSCommand
extern NSString *QSHandledType; //NSDictionary
extern NSString *QSRemoteHostsType; // NSString (remote hostname or FQDN)

// Pasteboard types
#define QSPrivatePboardType @"QSPrivatePboardType" // This pasteboard type prevents recording by the Clip History


#define standardPasteboardTypes [NSArray arrayWithObjects:@"Apple URL pasteboard type", NSColorPboardType, NSFileContentsPboardType, NSFilenamesPboardType, NSFontPboardType, NSHTMLPboardType, NSPDFPboardType, NSPostScriptPboardType, NSRulerPboardType, NSRTFPboardType, NSRTFDPboardType, NSStringPboardType, NSTabularTextPboardType, NSTIFFPboardType, NSURLPboardType, NSVCardPboardType, NSFilesPromisePboardType, nil]

#define clippingTypes [NSSet setWithObjects:@"textClipping", @"pictClipping", @"'clpp'", @"'clpt'", @"webloc", @"inetloc", @"'ilht'", @"'ilaf'", nil]
#define PLISTTYPES [NSArray arrayWithObjects:NSFilenamesPboardType, @"ABPeopleUIDsPboardType", @"WebURLsWithTitlesPboardType", @"AddressesPboardType", nil]
#define TEXTTYPES [NSSet setWithObjects:@"QSObjectID", NSStringPboardType, @"NeXT plain ascii pasteboard type", NSTabularTextPboardType, NSHTMLPboardType, nil]
#define SYLETYPES [NSSet setWithObjects:NSStringPboardType, @"NeXT Rich Text Format v1.0 pasteboard type", @"NeXT Rich Text Format v1.0 pasteboard type", nil]
#define URLTYPES [NSSet setWithObjects:NSURLPboardType, nil]
#define IMAGETYPES [NSSet setWithArray:[NSImage imagePasteboardTypes]]
#define OTHERTYPES [NSSet setWithObjects:NSColorPboardType, nil]
#define CONTACTTYPES [NSSet setWithObjects:NSVCardPboardType, nil]

extern NSString *QSRemoteHostsType; // NSString (remote hostname or FQDN)
22 changes: 22 additions & 0 deletions Quicksilver/Code-QuickStepFoundation/NSPasteboard_BLTRExtensions.h
Expand Up @@ -6,8 +6,30 @@
// Copyright (c) 2003 Blacktree, Inc.. All rights reserved.
//

extern NSString *QSPasteboardTransientType;
extern NSString *QSPasteboardAutoGeneratedType;

#define QSPasteboardTransientTypes [NSArray arrayWithObjects:QSPasteboardTransientType, @"QSPrivatePboardType", \
@"de.petermaurer.TransientPasteboardType", @"com.typeit4me.clipping", @"Pasteboard generator type", \
nil]

void QSForcePaste();

@interface NSPasteboard (Clippings)
+ (NSPasteboard *)pasteboardByFilteringClipping:(NSString *)pacg;
- (BOOL)isTransient;
- (BOOL)isAutoGenerated;
@end

#define QSPrivatePboardType QSPasteboardTransientType // Deprecated, use QSPasteboardTransientType or -[NSPasteboard isTransient]

#define standardPasteboardTypes [NSArray arrayWithObjects:@"Apple URL pasteboard type", NSColorPboardType, NSFileContentsPboardType, NSFilenamesPboardType, NSFontPboardType, NSHTMLPboardType, NSPDFPboardType, NSPostScriptPboardType, NSRulerPboardType, NSRTFPboardType, NSRTFDPboardType, NSStringPboardType, NSTabularTextPboardType, NSTIFFPboardType, NSURLPboardType, NSVCardPboardType, NSFilesPromisePboardType, nil]

#define clippingTypes [NSSet setWithObjects:@"textClipping", @"pictClipping", @"'clpp'", @"'clpt'", @"webloc", @"inetloc", @"'ilht'", @"'ilaf'", nil]
#define PLISTTYPES [NSArray arrayWithObjects:NSFilenamesPboardType, @"ABPeopleUIDsPboardType", @"WebURLsWithTitlesPboardType", @"AddressesPboardType", nil]
#define TEXTTYPES [NSSet setWithObjects:@"QSObjectID", NSStringPboardType, @"NeXT plain ascii pasteboard type", NSTabularTextPboardType, NSHTMLPboardType, nil]
#define SYLETYPES [NSSet setWithObjects:NSStringPboardType, @"NeXT Rich Text Format v1.0 pasteboard type", @"NeXT Rich Text Format v1.0 pasteboard type", nil]
#define URLTYPES [NSSet setWithObjects:NSURLPboardType, nil]
#define IMAGETYPES [NSSet setWithArray:[NSImage imagePasteboardTypes]]
#define OTHERTYPES [NSSet setWithObjects:NSColorPboardType, nil]
#define CONTACTTYPES [NSSet setWithObjects:NSVCardPboardType, nil]
Expand Up @@ -10,8 +10,10 @@
#import "NSString_BLTRExtensions.h"
#import "NDResourceFork.h"

NSString *QSPasteboardTransientType = @"org.nspasteboard.TransientType";
NSString *QSPasteboardAutoGeneratedType = @"org.nspasteboard.AutoGeneratedType";

void QSForcePaste() {

CGKeyCode pasteKeyCode = [[NDKeyboardLayout keyboardLayout] keyCodeForCharacter:'v'];

CGEventSourceRef source = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
Expand Down Expand Up @@ -60,4 +62,12 @@ + (NSPasteboard *)pasteboardByFilteringClipping:(NSString *)path { // Not thread

return [NSPasteboard pasteboardByFilteringTypesInPasteboard:pboard];
}

- (BOOL)isTransient {
return [self availableTypeFromArray:QSPasteboardTransientTypes] != nil;
}

- (BOOL)isAutoGenerated {
return [self availableTypeFromArray:[NSArray arrayWithObject:QSPasteboardAutoGeneratedType]] != nil;
}
@end