Parent

Class/Module Index [+]

Quicksearch

Pasteboard

Pasteboard wraps the OS X pasteboard (clipboard) allowing you to paste multiple flavors of a pasteboard item. Currently it only supports the general clipboard.

To add data to the clipboard:

item = [
  Pasteboard::Type::UTF_8,      'π'],
  Pasteboard::Type::PLAIN_TEXT, 'pi'],
]

pasteboard.put item

See also put, put_url and put_jpeg_url

To retrieve data from the clipboard:

data = pasteboard.first Pasteboard::Type::UTF_8

If the item cannot be found nil will be returned.

See also first, #[] and each.

Pasteboard also provides direct access to the C API through clear, copy_item_flavors, copy_item_flavor_data, get_item_count, get_item_identifier, name, put_item_flavor and sync.

Public Class Methods

new type = Pasteboard::CLIPBOARD click to toggle source

Creates a new pasteboard of the specified type.

static VALUE
pb_init(int argc, VALUE* argv, VALUE self) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  CFStringRef pasteboard_type = NULL;
  VALUE type = Qnil;

  if (argc == 0) {
    pasteboard_type = kPasteboardClipboard;
  } else {
    rb_scan_args(argc, argv, "01", &type);
  }

  if (!NIL_P(type)) {
    pasteboard_type = CFStringCreateWithCString(NULL,
        value_to_utf8_cstr(type),
        kCFStringEncodingUTF8);

    if (pasteboard_type == NULL)
      rb_raise(ePBError, "unable to allocate memory for pasteboard type");
  }

  err = PasteboardCreate(pasteboard_type, &pasteboard);

  if (pasteboard_type)
    CFRelease(pasteboard_type);

  pb_error(err);

  DATA_PTR(self) = (void *)pasteboard;

  return self;
}

Public Instance Methods

[](index, flavor = nil) click to toggle source

Synchronizes the pasteboard and returns the item at index in the pasteboard.

If flavor is given only the given flavor’s data is returned. If no flavor matches nil is returned.

An item is an Array of pairs in the order of preference which looks like this:

[
  ["public.utf8-plain-text", "Pasteboard"],
  ["public.utf16-external-plain-text",
   "\377\376P\000a\000s\000t\000e\000b\000o\000a\000r\000d\000"],
  ["com.apple.traditional-mac-plain-text", "Pasteboard"],
  ["public.utf16-plain-text",
   "P\000a\000s\000t\000e\000b\000o\000a\000r\000d\000"],
]
# File lib/pasteboard.rb, line 98
def [] index, flavor = nil
  flags = sync

  raise Error, 'pasteboard sync error' if (flags & MODIFIED) != 0

  id = get_item_identifier index + 1

  get id, flavor
rescue Missing
  return nil
end
clear click to toggle source

Clears the contents of the pasteboard.

static VALUE
pb_clear(VALUE self) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;

  pasteboard = pb_get_pasteboard(self);

  err = PasteboardClear(pasteboard);

  pb_error(err);

  return self;
}
copy_item_flavor_data identifier, flavor click to toggle source

Retrieves pasteboard data from identifier of flavor

static VALUE
pb_copy_item_flavor_data(VALUE self, VALUE identifier, VALUE flavor) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  PasteboardItemID id = 0;
  CFIndex data_length = 0;
  CFDataRef flavor_data = NULL;
  CFStringRef flavor_type = NULL;
  UInt8 *buffer = NULL;
  VALUE data = Qnil;
  VALUE encoding = Qnil;

  pasteboard = pb_get_pasteboard(self);

  id = (PasteboardItemID)NUM2ULONG(identifier);

  flavor_type = CFStringCreateWithCString(NULL,
      value_to_usascii_cstr(flavor),
      kCFStringEncodingASCII);

  if (flavor_type == NULL)
    rb_raise(ePBError, "unable to allocate memory for flavor type");

  err = PasteboardCopyItemFlavorData(pasteboard, id, flavor_type, &flavor_data);

  pb_error(err);

  data_length = CFDataGetLength(flavor_data);

  buffer = (UInt8 *)malloc(data_length);

  if (buffer == NULL) {
    CFRelease(flavor_data);
    rb_raise(ePBError, "unable to allocate memory for data");
  }

  CFDataGetBytes(flavor_data, CFRangeMake(0, data_length), buffer);

  CFRelease(flavor_data);

  data = rb_str_new((char *)buffer, data_length);

  free(buffer);

#if HAVE_RB_STR_ENCODE
  encoding = rb_hash_aref(cPBTypeEncodings, flavor);

  if (rb_str_equal(flavor, utf16_external_flavor) ||
      rb_str_equal(flavor, utf16_internal_flavor)) {
    handle_bom(data, encoding);
  } else {
    rb_enc_associate(data, rb_to_encoding(encoding));
  }
#endif

  return data;
}
copy_item_flavors identifier click to toggle source

Returns an Array of flavors for the pasteboard item at identifier.

static VALUE
pb_copy_item_flavors(VALUE self, VALUE identifier) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  PasteboardItemID item_id;
  CFArrayRef flavor_types = NULL;
  CFIndex i, flavor_count = 0;
  VALUE flavors = Qnil;

  item_id = (PasteboardItemID)NUM2ULONG(identifier);

  pasteboard = pb_get_pasteboard(self);

  err = PasteboardCopyItemFlavors(pasteboard, item_id, &flavor_types);

  pb_error(err);

  flavors = rb_ary_new();

  flavor_count = CFArrayGetCount(flavor_types);

  for (i = 0; i < flavor_count; i++) {
    CFStringRef flavor_type =
      (CFStringRef)CFArrayGetValueAtIndex(flavor_types, i);

    rb_ary_push(flavors, string_ref_to_value(flavor_type));
  }

  CFRelease(flavor_types);

  return flavors;
}
each(flavor = nil) click to toggle source

Synchronizes the pasteboard and yields each item in the pasteboard.

If flavor is given only the given flavor’s data is yielded. If no flavor matches nil is yielded.

See #[] for a description of an item.

# File lib/pasteboard.rb, line 118
def each flavor = nil # :yields: item
  unless block_given? then
    enum = defined?(Enumerator) ? Enumerator : Enumerable::Enumerator # 1.8.7
    return enum.new(self, :each, flavor)
  end

  flags = sync

  raise Error, 'pasteboard sync error' if (flags & MODIFIED) != 0

  ids.each do |id|
    yield get(id, flavor)
  end

  self
end
first(flavor = nil) click to toggle source

Retrieves the first item in the pasteboard.

If flavor is given only the given flavor’s data is returned. If no flavor matches nil is returned.

See #[] for a description of an item.

# File lib/pasteboard.rb, line 143
def first flavor = nil
  self[0, flavor]
end
get(id, flavor = nil) click to toggle source

Returns the item with id in the pasteboard.

If flavor is given only the given flavor’s data is returned. If no flavor matches nil is returned.

See #[] for a description of an item.

# File lib/pasteboard.rb, line 155
def get id, flavor = nil
  item = copy_item_flavors(id).map do |item_flavor|
    if flavor then
      return copy_item_flavor_data(id, item_flavor) if item_flavor == flavor
      next
    end

    [item_flavor, copy_item_flavor_data(id, item_flavor)]
  end

  return nil if item.compact.empty?

  item
end
get_item_count click to toggle source

The number of items on the pasteboard

static VALUE
pb_get_item_count(VALUE self) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  ItemCount item_count = 0;

  pasteboard = pb_get_pasteboard(self);

  err = PasteboardGetItemCount(pasteboard, &item_count);

  pb_error(err);

  return ULONG2NUM(item_count);
}
get_item_identifier index click to toggle source

The identifier of the pasteboard item at index which is 1-based.

static VALUE
pb_get_item_identifier(VALUE self, VALUE index) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  CFIndex item_index = 0;
  PasteboardItemID item_id = 0;

  item_index = NUM2ULONG(index);

  pasteboard = pb_get_pasteboard(self);

  err = PasteboardGetItemIdentifier(pasteboard, item_index, &item_id);

  pb_error(err);

  return ULONG2NUM((unsigned long)item_id);
}
ids() click to toggle source

An array of item ids in the pasteboard. You must sync the clipboard to get the latest ids.

# File lib/pasteboard.rb, line 174
def ids
  (1..get_item_count).map do |index|
    get_item_identifier index
  end
end
name click to toggle source

The name of this pasteboard.

static VALUE
pb_name(VALUE self) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  CFStringRef pasteboard_name = NULL;
  VALUE name = Qnil;

  pasteboard = pb_get_pasteboard(self);

  err = PasteboardCopyName(pasteboard, &pasteboard_name);

  pb_error(err);

  name = string_ref_to_value(pasteboard_name);

  if (pasteboard_name)
    CFRelease(pasteboard_name);

  return name;
}
put(*items) click to toggle source

Clears the pasteboard and adds items to the pasteboard. Each item is added with a consecutive id starting at 0.

An item must be an Enumerable with pairs of item flavors and items. For example:

item = [
  [Pasteboard::Type::TIFF,     tiff],
  [Pasteboard::Type::URL,      url],
  [Pasteboard::Type::URL_NAME, url],
  [Pasteboard::Type::UTF_8,    url],
]

pasteboard.put item

The pasteboard considers flavors added earlier in an item to have a higher preference.

# File lib/pasteboard.rb, line 203
def put *items
  clear
  flags = sync

  raise Error, 'pasteboard sync error' if (flags & MODIFIED)        != 0
  raise Error, 'pasteboard not owned'  if (flags & CLIENT_IS_OWNER) == 0

  items.each_with_index do |item, id|
    item.each do |flavor, data|
      put_item_flavor id, flavor, data
    end
  end

  self
end
put_item_flavor id, flavor, data click to toggle source

Puts an item into the pasteboard. id is used to identify an item, flavor is the item’s type and data is the pasteboard data for the item.

static VALUE
pb_put_item_flavor(VALUE self, VALUE id, VALUE flavor, VALUE data) {
  OSStatus err = noErr;
  PasteboardRef pasteboard;
  CFDataRef pasteboard_data = NULL;
  CFStringRef item_flavor = NULL;

  pasteboard = pb_get_pasteboard(self);

  item_flavor = CFStringCreateWithCString(NULL,
      value_to_usascii_cstr(flavor),
      kCFStringEncodingASCII);

  if (item_flavor == NULL)
    rb_raise(ePBError, "unable to allocate memory for item flavor");

  pasteboard_data = CFDataCreate(kCFAllocatorDefault,
      (UInt8 *)StringValuePtr(data), RSTRING_LEN(data));

  if (pasteboard_data == NULL) {
    CFRelease(item_flavor);
    rb_raise(ePBError, "unable to allocate memory for pasteboard data");
  }

  err = PasteboardPutItemFlavor(pasteboard,
      (PasteboardItemID)NUM2ULONG(id),
      item_flavor,
      pasteboard_data,
      kPasteboardFlavorNoFlags);

  CFRelease(item_flavor);
  CFRelease(pasteboard_data);

  pb_error(err);

  return self;
}
put_jpeg_url(image, url, url_name = url) click to toggle source

Adds JPEG data image to the pasteboard with a url and optional url_name.

# File lib/pasteboard.rb, line 236
def put_jpeg_url image, url, url_name = url
  item = [
    [Pasteboard::Type::JPEG,     image],
    [Pasteboard::Type::URL,      url],
    [Pasteboard::Type::URL_NAME, url_name],
    [Pasteboard::Type::UTF_8,    url],
  ]

  put item
end
put_url(url, url_name = url) click to toggle source

Adds url to the pasteboard with an optional url_name.

# File lib/pasteboard.rb, line 222
def put_url url, url_name = url
  item = [
    [Pasteboard::Type::URL,      url],
    [Pasteboard::Type::URL_NAME, url_name],
    [Pasteboard::Type::UTF_8,    url],
  ]

  put item
end
sync click to toggle source

Synchronizes the local pasteboard to reflect the contents of the global pasteboard.

static VALUE
pb_sync(VALUE self) {
  PasteboardSyncFlags flags;
  PasteboardRef pasteboard;

  pasteboard = pb_get_pasteboard(self);

  flags = PasteboardSynchronize(pasteboard);

  return ULONG2NUM(flags);
}

[Validate]

Generated with the Darkfish Rdoc Generator 2.