Title Banner

Previous Book Contents Book Index Next

Inside Macintosh: OpenDoc Programmer's Guide / Part 2 - Programming
Chapter 8 - Data Transfer


Clipboard Transfer

The clipboard commands Cut, Copy, and Paste constitute a common mechanism for transferring data within and across conventional documents, even documents of different data formats. For OpenDoc documents, these commands perform the same tasks, but with added capabilities.

As with data placed in a conventional clipboard, if your part editor stores multiple formats on the clipboard--including standard formats--the user has a greater chance of being able to incorporate (rather than embed) the data into more kinds of parts.

Clipboard Concepts

This section discusses some basic clipboard operations common to both reading and writing, such as acquiring the clipboard focus and using the clipboard update ID. It also presents some special considerations related to updating the clipboard and cutting data from your part.

Enabling the Cut and Paste menu items
OpenDoc does not permit changes to your draft (and therefore your part's content) if the draft permissions are read-only. You should check your draft permissions (see "Drafts") before enabling the Cut, Paste, or Paste As items in the Edit menu or before allowing the user to perform a cut or paste operation using keyboard equivalents.

Acquiring and Relinquishing the Clipboard Focus

Your part can access the clipboard only when your part is in the foreground process; access from a background process is meaningless. Furthermore, to be thread-safe, you must always acquire the clipboard focus before writing or reading clipboard data. As long as you hold the clipboard focus, no other part should access or modify the data.

Typically, your part needs to inspect the contents of the clipboard before deciding whether to enable Edit menu items, so your AdjustMenus method can include a call to the arbitrator's RequestFocus method to acquire the clipboard focus.

After acquiring the clipboard focus, you can access the clipboard when responding to a menu command (or its keyboard equivalent) with your HandleEvent method by calling the session object's GetClipboard method. You should then unilaterally relinquish the clipboard focus in your HandleEvent method, after having handled the clipboard command. (Your HandleEvent method is always called after AdjustMenus is called, even if the user does not choose a menu command.)

These are the steps you take to acquire the clipboard focus and prepare to write to the clipboard or read from it:

  1. Acquire the clipboard focus, using the Arbitrator's RequestFocus method (as described in "Requesting Foci").
  2. Gain access to the clipboard object, using the session object's GetClipboard method.
  3. If you are writing to the clipboard, remove any existing data on the clipboard with the clipboard's Clear method. (Do not take this step if you are reading from the clipboard.)
  4. Gain access to the clipboard's content storage unit, using the clipboard's GetContentStorageUnit method.

You relinquish the clipboard focus unilaterally by calling the arbitrator's RelinquishFocus method.

Clipboard Update ID

Whenever you copy data to the clipboard, you should get and save the clipboard's current update ID, a number used to identify this particular instance of clipboard contents. You typically obtain the update ID in this situation by calling the clipboard's ActionDone method. In other situations, you may need to inspect the clipboard's current update ID; you can do so by calling the clipboard's GetUpdateID method.

If a link specification that you have written to the clipboard becomes invalid because of changes to your content that was copied to the clipboard, you must remove the link specification from the clipboard, as described under "Removing a Link Specification From the Clipboard" (next). You can examine the clipboard's current update ID at any time and compare it with your saved update ID; if they are identical, the clipboard has not changed.

Removing a Link Specification From the Clipboard

If your part copies some of its content to the clipboard and the user then modifies the equivalent content in your part (without copying anything else to the clipboard), the clipboard data no longer matches the source data in your part. The potential link represented by the link specification you wrote in the clipboard therefore no longer reflects the content at the source of the link. If your source content has changed to the extent that creating a link is no longer feasible, your part must remove the link specification.

By saving the update ID of the clipboard whenever you copy data to it, you can check that ID against the current update ID of the clipboard whenever your source data changes to the extent that creating a link to the previous data is impossible. If the IDs match, the clipboard still contains the data that you placed in it, and you should remove the link specification.

You can follow these steps to remove a link specification:

  1. Acquire the clipboard focus as described in the section "Acquiring and Relinquishing the Clipboard Focus".
  2. Get the clipboard's update ID and compare it to your stored update ID. If they don't match, skip to step 5.
  3. Access the clipboard's content storage unit. (Unlike when writing to the clipboard, do not clear the clipboard data.)
  4. Focus the storage unit on the link-specification property (type kODLinkSpec) and remove that property, using the storage unit's Remove method. Be sure to focus on the entire property (by specifying a null value type), so that you remove the entire property and not just one value.
  5. Relinquish the clipboard focus.

Undo for Clipboard

If your part supports cutting or pasting, it must also support undoing those operations. (Note that data transfer between parts is undoable only if both parts involved have undo support.) Undo support in general is described in the section "Undo".

Whenever your part performs a cut, copy, or paste operation, it must call the clipboard's ActionDone method to notify the clipboard of the kind of cloning transaction that took place. ActionDone returns a clipboard ID that identifies the current clipboard contents. Save that update ID.

When your part cuts an object to the clipboard, it should remove the object from its content data structures. However, your part should not release the object, but instead save a reference to the object in an undo action. (For a cut embedded frame, you also set its in-limbo flag to true, as shown in Table 6-4UndoAction method is called, your part should

If the user subsequently chooses the Redo command and your part's RedoAction method is called, your part should

Calling ActionDone, ActionUndone, and ActionRedone notifies the clipboard whether it is involved in a cut, a copy, or the restoration of a cut or a copy; the clipboard's internal handling of its objects differs in each case.

If and when your part's DisposeActionState method is called, you can at that point release (not remove from your draft) the object referenced in your undo action. (For an embedded frame, you either release or remove it, as shown in Table 6-4.)

To undo a cut, copy, or paste operation requires the restoration of the previous state of the document involved, but it does not require the restoration of the previous state of the clipboard. Therefore, if you redo a paste operation that has been undone, you cannot assume that the clipboard once again contains the original data that had been pasted. You must implement the redo from your own data. For this reason, you should retain a copy of pasted data in a private cache.

Copying or Cutting to the Clipboard

You write data to the clipboard as a result of the user selecting the Cut command or the Copy command from the Edit menu (or their keyboard equivalents). These are the basic steps to take:

  1. Acquire the clipboard focus and access the clipboard's content storage unit, as described in the section "Acquiring and Relinquishing the Clipboard Focus".
  2. Write the data to the clipboard.

    • If the selection consists of a combination of your part's intrinsic content plus zero or more embedded parts, you need to write your own intrinsic content to the clipboard, and you need to clone the embedded frames and parts as well (or you can write a promise). Follow the steps listed in the section "Writing Intrinsic Content".
    • If the selection consists of a single frame of an embedded part with no surrounding intrinsic content, you need to clone the part and provide a frame for it. Follow the steps listed in the section "Writing a Single Embedded Part".

      In either case, when you call the BeginClone method, specify either kODCloneCopy or kODCloneCut, depending on whether you are copying or cutting the data to the clipboard.

  3. When you have finished, call the clipboard's ActionDone method, specifying either kODCloneCopy or kODCloneCut. Save the clipboard's current update ID (see "Clipboard Update ID"), which is returned from ActionDone, in case you later have to undo the cut or copy, remove a link specification, or fulfill a promise you wrote.
  4. If this operation was a cut rather than a copy, it must be undoable. Add a single action to the action history, as described in "Adding an Action to the Undo Action History", including setting the in-limbo flag of any cut frame to true.
  5. Delete the cut selection from your part's content.
  6. Relinquish the clipboard focus (see "Acquiring and Relinquishing the Clipboard Focus"

Pasting From the Clipboard

You read data from the clipboard as a result of the user selecting the Paste command or the Paste As command from the Edit menu. These are the basic steps to take:

  1. Acquire the clipboard focus and access the clipboard's content storage unit, as described in the section "Acquiring and Relinquishing the Clipboard Focus". (Do not clear the clipboard data, of course.)
  2. Read the data from the clipboard.

    • If the data consists of intrinsic content plus zero or more embedded frames, and if the intrinsic content is of a part kind that you can incorporate into your part, you need to read the intrinsic content and possibly clone embedded parts, links, or other objects. Follow the steps listed in the section "Incorporating Intrinsic Content".
    • If you need to embed the data as a single part with no surrounding intrinsic content, you need to clone the part and either extract its frame or create a frame for it. Follow the steps listed in the section "Embedding a Single Part". That section lists the conditions under which you must embed rather than incorporate clipboard data.

      In either case, when you call the BeginClone method, specify kODClonePaste.

  3. Pasting must be an undoable operation. Call the clipboard's ActionDone method, specifying kODClonePaste. Save the current clipboard update ID, returned by ActionDone, in a single undo action (see "Adding an Action to the Undo Action History". In this case, save the current value of the frame's in-limbo flag and then set the flag to false.

    Clipboard content is not transferred when a link is pasted. Thus, your part should not call the clipboard's ActionDone method.

  4. Notify OpenDoc and your containing part that your part's content has changed; see "Making Content Changes Known".
  5. Relinquish the clipboard focus (see "Acquiring and Relinquishing the Clipboard Focus"


Previous Book Contents Book Index Next

© Apple Computer, Inc.
16 JUL 1996




Navigation graphic, see text links

Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help