adobe indesign cs4 porting guide

52
ADOBE ® INDESIGN ® CS4 ADOBE INDESIGN CS4 PORTING GUIDE

Upload: laiscostay

Post on 18-Jan-2016

115 views

Category:

Documents


3 download

DESCRIPTION

Adobe InDesign CS4 Porting Guide

TRANSCRIPT

Page 1: Adobe InDesign CS4 Porting Guide

ADOBE® INDESIGN® CS4

ADOBE INDESIGN CS4PORTING GUIDE

Page 2: Adobe InDesign CS4 Porting Guide

© 2008 Adobe Systems Incorporated. All rights reserved.Adobe InDesign CS4 Porting GuideIf this guide is distributed with software that includes an end user agreement, this guide, as well as the software described in it, is furnished under license and may be used or copied only in accordance with the terms of such license. Except as permitted by any such license, no part of this guide may be reproduced, stored in a retrieval system, or transmitted, in any form or by any means, electronic, mechanical, recording, or otherwise, without the prior written permission of Adobe Systems Incorporated. Please note that the content in this guide is protected under copyright law even if it is not distributed with software that includes an end user license agreement.The content of this guide is furnished for informational use only, is subject to change without notice, and should not be construed as a commitment by Adobe Systems Incorporated. Adobe Systems Incorporated assumes no responsibility or liability for any errors or inaccuracies that may appear in the informational content contained in this guide.Please remember that existing artwork or images that you may want to include in your project may be protected under copyright law. The unauthorized incorporation of such material into your new work could be a violation of the rights of the copyright owner. Please be sure to obtain any permission required from the copyright owner.Any references to company names in sample templates are for demonstration purposes only and are not intended to refer to any actual organization.Adobe, the Adobe logo, Adobe Bridge, Creative Suite, InCopy, InDesign, Reader, and Version Cue are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States and/or other countries. Microsoft and Windows are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. Macintosh and Mac OS are trademarks of Apple Computer, Incorporated, registered in the United States and other countries. All other trademarks are the property of their respective owners.Adobe Systems Incorporated, 345 Park Avenue, San Jose, California 95110, USA. Notice to U.S. Government End Users. The Software and Documentation are “Commercial Items,” as that term is defined at 48 C.F.R. §2.101, consisting of “Commercial Computer Software” and “Commercial Computer Software Documentation,” as such terms are used in 48 C.F.R. §12.212 or 48 C.F.R. §227.7202, as applicable. Consistent with 48 C.F.R. §12.212 or 48 C.F.R. §§227.7202-1 through 227.7202-4, as applicable, the Commercial Computer Software and Commercial Computer Software Documentation are being licensed to U.S. Government end users (a) only as Commercial Items and (b) with only those rights as are granted to all other end users pursuant to the terms and conditions herein. Unpublished-rights reserved under the copyright laws of the United States. Adobe Systems Incorporated, 345 Park Avenue, San Jose, CA 95110-2704, USA. For U.S. Government End Users, Adobe agrees to comply with all applicable equal opportunity laws including, if appropriate, the provisions of Executive Order 11246, as amended, Section 402 of the Vietnam Era Veterans Readjustment Assistance Act of 1974 (38 USC 4212), and Section 503 of the Rehabilitation Act of 1973, as amended, and the regulations at 41 CFR Parts 60-1 through 60-60, 60-250, and 60-741. The affirmative action clause and regulations contained in the preceding sentence shall be incorporated by reference.

Page 3: Adobe InDesign CS4 Porting Guide

3

Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Before you begin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Notation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Terminology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Key concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Major Changes in CS4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Links Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Summary of changes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

What is a link in InDesign? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Frequently asked questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Porting CS3 links to the CS4 links architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

doScript . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

IScriptRunner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

IScriptEngine. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

IScriptProvider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

IScriptErrorUtils . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

IScriptEventData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Metadata resource . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

RepresentScriptProvider . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

Text-attribute scripting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

TypeDef and TypeDefType . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Changes to Support Rotated Spreads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

A new enumerator for commonly referenced coordinate systems . . . . . . . . . . . . . . . . . . 32

ISpread::GetPagesBounds and ILayoutUtils::GetIntersectingPageUID . . . . . . . . . . . . . . . . 33

IShape::GetPaintedBBox and GetPrintedBBOx . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

IMasterSpreadUtils::AppendMasterPageItems. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

IDrawMgr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

gSession Removed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

User Interface APIs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Workspace preference reading/writing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Palette management. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Document management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

Contents

Page 4: Adobe InDesign CS4 Porting Guide

Contents

4 Adobe InDesign CS4 Porting Guide

General Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

SDK folder structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

MLocaleIds.h and WLocaleIds.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

Replace gSession with GetExecutionContextSession() . . . . . . . . . . . . . . . . . . . . . . . . . 40

Bring resource definitions up-to-date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

PMString constructor change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Replace IScriptEventData::SetReturnData. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Utility APIs are accessed only through kUtilsBoss . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

XCode Warning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Porting Recipes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

IDFile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

IImportManager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

IInCopyBridgeCmdSuite. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

ISnippetExport. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

IStaticTextAttributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

IStyleGroupListControlData . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

ITextColumnSizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

kInvalidUIDRef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44

PMString . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

Style matching. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

XML parser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Custom story thread . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

kHyperlinkTextMarkerBoss and kHyperlinkTextSourceEndMarkerBoss deprecated . . . . . . . 49

ISnippetExportSuite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Miscellaneous changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

Page 5: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 5

Adobe InDesign CS4 Porting GuideIntroduction

Adobe InDesign CS4 Porting Guide

Introduction

This document describes changes to plug-in code and development environments caused bychanges in the public API and other aspects of the SDK for the Adobe® InDesign® CS4 family ofapplications.

Before you begin

Before you begin, do the following:

1. Read the introductory sections of this document, including “Terminology” on page 5.

2. Ensure your development environment meets the requirements to compile applicationplug-ins. For Windows®, you need Microsoft® Visual C++ 8.0. For Mac OS®, you need AppleXcode 2.4.1. For more information, see “Required components” on page 6.

3. Install the SDK, including the documentation. There are two valuable porting resources in<SDK>/docs/references/: the .chm file containing all SDK documentation, and the APIAd-visor, APIAdvisorID5_vs_ID6.html. On Windows, you probably will use the built-inMicrosoft HTML Help viewer to view the CHM version of the SDK documentation. OnMac OS, you can either decompress the TAR file and then use your browser to view theHTML, or use a CHM viewer.

4. You should have a basic understanding of concepts related to links, scripting, and spreads,and the InDesign API in general.

Notation

SDK root folder — <SDK> refers to your local installed SDK root folder. The actual file pathof the root depends on the operating system.Menu names — For example, Tools > Options refers to the Options menu item in the Toolsmenu.Computer input or output, including source code, is presented in a monospace font. Forexample:

> sh dollyxsgui.shCannot find specified file

Terminology

API — Application Programming Interface.

Page 6: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideIntroduction

6

Application — InDesign CS4, unless otherwise specified.Applications — Members of the InDesign CS4 family of applications (Adobe InDesign CS4,Adobe InCopy® CS4, and Adobe InDesign CS4 Server).ODF — OpenDoc Development Framework, a cross-platform software effort, initiated byApple and IBM, which defines an object-oriented extension of the Apple Rez language tospecify user-interface resources.ODFRC — OpenDoc Development Framework Resource Compiler, the compiler for frame-work resource .fr files. This is included with the SDK. SDK — Software development kit for the application.

Key concepts

SDK organization

The InDesign CS4 SDK inherits its folder structure from the InDesign CS3 SDK with a fewmodifications as outlined in “SDK folder structure” on page 39.

Development environment

Table 1 lists the components required to build SDK plug-ins.TABLE 1 Required components

Required component Notes

Windows or Mac OS:

Applications: InDesign CS4, InCopy CS4, InDesign CS4 Server

We recommend you have both the debug and release applications. The debug application is instrumented to detect bugs and is essential to successful plug-in development.

OpenDoc Development Framework Resource Compiler (ODFRC)

Included with the InDesign SDK.

Adobe Reader® 6.0 or later For viewing PDF documents.

256 MB memory (minimum), 512 MB memory (recommended)

Windows:

Pentium III or equivalent (minimum), Pentium 4 or equivalent (recommended)

Windows XP with Service Pack 2

Visual C++ 8 A component of Visual Studio 2005.

Page 7: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 7

Adobe InDesign CS4 Porting GuideMajor Changes in CS4

Major Changes in CS4

The major CS4 modifications to the InDesign API include the following:Links Architecture Restructuring — See “Links Architecture” on page 8.Scripting Undo — See “Scripting” on page 24.Rotated spreads — See “Changes to Support Rotated Spreads” on page 32.gSession removal — See “gSession Removed” on page 35.User Interface — See “User Interface APIs” on page 36.

There also are changes that affect all plug-ins but do not involve a major feature change. Theseare described in “General Changes” on page 39.

Windows HTML Help (included with Windows)

For viewing compiled HTML documentation (index.chm).

Mac OS:

G3 processor (minimum), G4 processor (recommended)

Mac OS 10.4 or later

Xcode 2.4.1

Apple Safari To view the HTML version of the SDK reference documentation in the sdkdocs.tar.gz file, you must use a Web browser that understands long Mac OS filenames. Current versions of Navigator and Internet Explorer do not support long Mac OS filenames in local href links.

CHM viewer To view compiled HTML documentation (index.chm) on Mac OS, you must use a CHM viewer for Mac OS. Two such viewers are xCHM (an open-source application found at http://sourceforge.net/projects/xchm) and CHM Viewer (a shareware application found at www.jouledata.com).

Required component Notes

Page 8: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

8

Links Architecture

Datalink is re-engineered in CS4. The core mechanisms for storing and maintaining links wasreplaced with new code. All pre-CS4 main datalink interfaces, like IDataLink and ICoreFile-name, are deprecated.

Summary of changes

The new link architecture in CS4 offers the following advantages:Removes the assumptions that all links are file-based, so we can support links to URLs,databases, etc.Provides three new link types — import only, export only, and bi-directional.Improves performance by providing asynchronous link-state updates.Allows third-party developers to create custom links much more easily.Improves the user experience by updating the Links UI panel.

What is a link in InDesign?

When you place a graphic file in an InDesign publication, InDesign does not include thegraphic file in the publication. Instead, it creates a page item to host the graphic object andestablishes a link between the page item and the graphic file. What you see on screen is a low-resolution proxy image of the graphic. A link helps InDesign avoid redundantly storing largeamounts of data in the publication, and it enables us to automatically update page items whenthe external file is modified.To see the link information associated with the page item, you need to display the Links UIpanel. If the current selected page item has an associated link, its link information is high-lighted in the Links UI panel. The link information includes where the linked file comes fromand the link’s status.When a user uses the default InDesign menu item File > Place..., the InDesign File Chooserdialog appears, and when the user selects a file from the InDesign Place dialog, kImportAnd-LoadPlaceGunCmdBoss is processed. kImportAndLoadPlaceGunCmdBoss requires its clientto set up a command data-interface IImportResourceCmdData. IImportResourceCmdDatacan store the UID of a link resource or a URI (Uniform Resource Identifier) that is a referenceto the link resource. The URI is used in a kImportResourceCmdBoss to create a link resourcefrom an URI. Internally, kImportResourceCmdBoss calls ILinkFacade::CreateResource to cre-ate the link resource from an URI, which in turn uses kLinkResourceCreateCmdBoss. Finally,ILinkManager::CreateResource() is used to create the resource (kLinkResourceBoss) using theInDesign link client ID.

NOTE: A link client ID identifies a link client, You should use the same link client ID when creating the link resource and the link. If you use kIDLinkClientID, the link shows up in the Links UI panel. If you do not want to have your links in the Links UI panel, use an ID other than kIDLinkClientID when you create the link and link resource.

Page 9: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 9

Adobe InDesign CS4 Porting GuideLinks Architecture

The ILinkManager will query a resource handler based on the URI’s scheme. The first resourcehandler that knows how to handle (import, export, and resolve) the particular URI scheme isused to import the resource. The resource handler is asked to supply a resource’s read stream,and it is given to an import provider that knows how to import the particular file format. Oncethe file is imported, a series of checks is performed to determine if a link is wanted before a linkis created. For example, by default, a text file always is embedded, not linked, unless it is anAdobe InCopy file. Figure 1 illustrate the sequence of how the link and link resource are cre-ated during the processing of a kImportAndLoadPlaceGunCmdBoss.

Page 10: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

10

FIGURE 1 Link creation duing a kImportAndLoadPlaceGunCmdBoss

Determine if link is wanted for the text file

Yes

Yes

Check link resource state

Does link resource

(kLinkResourceBoss) exist?

Create link resource using

ILinkFacade::CreateResource with the URI

Resource missing?

Resource available & a

valid read stream is available

Link Resource queries an IPMStream for read

from an ILinkResourceHandler

Identify an import provider that knows

how to handle the file format, and give it the

stream for import.

Import successful?

Is the import file a text file?

Import to an existing page

item?

Is it InCopy import?

Set link is wanted flag to the P.I's old

state

Set link is wanted flag to

ITextOptions::GetLinkTextFiles on

doc's workspace

Is link wanted?

Create link using ILinkFacade::Create

Link

Yes

No

Yes

Yes

link state is managed by ILinkState on the link object

boss such as kTextStoryBoss. If a link is wanted,

ILinkState::SetIsLinkWanted is used to set the status.

Set link is wanted flag to true

end

Yes

Yes

No

No

Yes

Yes

No

Check using ILinkResource::GetState()

against ILinkResource::kMissing

startNo

No

No

If the link already exists?

No

Yes

Page 11: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 11

Adobe InDesign CS4 Porting GuideLinks Architecture

What if you do not store your graphics as desktop files? For example, many workflows storetheir assets in a database. The CS4 link architecture supports generalized, abstract links: itallows data to come from a file, URL, database record, or any external or internal source thatcan be read or written via a stream. In the remainder of this document, we refer to the resourcedata as a link resource. Link resources are referenced using an abstract URI.

Architecture

What is a link?

A link establishes a relationship between a linked resource and a link object. When an image isplaced in an InDesign publication, a link is created between the image file and the page itemthat contains the image. Think of a link as a bridge that connects a source to a destination: onone side is the link resource (the source), and we call the other, destination side the link object.A link object should be an InDesign object, but it is not limited to a page item; it can be anXML element, swatch, style set, chunk of text, etc.

Types of links

InDesign supports three types of links:Import-only link — This is represented by kImportLinkBoss, which maintains an importassociation between an object and a linked resource. If the linked resource changes, theobject can be updated via an import.Export-only link — This is represented by kExportLinkBoss, which maintains an exportassociation between an object and a linked resource. If the object changes, the linked assetcan be updated via an exportBi-directional link — This is represented by kBidirectionalLinkBoss, which maintains a bi-directional association between an object and a linked resource. If the object changes, thelinked resource can be updated via an export. If the linked resource changes, the object canbe updated via an import. A bi-directional link requires conflict-resolution handling in thecase when both the object and the linked asset change.

NOTE: There also is a kChildLinkBoss, whose purpose is to allow placing an InDesign publication which may contains links. In this case, the links in the placed document become a child link. You cannot update a child link directly; you must open the original document to update the links it contains.

A link is created and maintained by ILinkManager. All the overridden ILinkManager::Cre-ateLink methods create a link between a given link object and linked resource.

The ILink interface

All three link bosses aggregate a key interface, ILink, which establishes a relationship between alink resource and a link object. A link resource is represented by kLinkResourceBoss, whichaggregates the ILinkResource interface. ILinkResource has methods to access and maintain alinked resource. A link object is any boss that aggregates the ILinkObject interface. There is anILinkManager that manages linked resources and linksFigure 2 shows the relationship between a linked resource and linked object.

Page 12: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

12

FIGURE 2 Links object model

Linked resource and ILinkResourceHandler

A linked resource is referenced by a URI. According to the URI specification, a URI consists ofa hierarchical sequence of five components, referred to as the scheme, authority, path, query,and fragment. For URI format syntax, see the specification (http://gbiv.com/proto-cols/uri/rfc/rfc3986.html#components).There is an InDesign class, URI, which can be used to construct and parse a well formed URI.The link architecture classifies link resources based on the link resource’s scheme from its URI.All link resources of the same type must share the same scheme in their URIs. There should bea link-resource handler (represented by ILinkResourceHandler) for each type of scheme avail-able in InDesign. For example, most traditional InDesign datalinks are file-based links; i.e., thelink is between a page item and an external file established though a “Place” action. The linkresources for these type of links are the external file, and all their URIs have the scheme of“file”; i.e., their URIs all look like “file://path_to_file”. During import (through Place), aresource handler that knows how to handle URIs with a “file” scheme is used to create aresource read stream, and the stream is given to an import provider that knows how to handlethe particular file format to import the resource.What makes up a resource handler? A resource handler implements the ILinkResourceHandlerinterface and is aggregated by a generic InDesign boss class. The convention to invoke aresource handler is through a service-provider boss that supports the kLinkResourceServiceservice ID. In this service-provider boss, an ILinkResourceFactory should be aggregated. TheILinkResourceFactory indicates what kind of URI scheme the resource handler can handlethrough its GetSchemes method, and ILinkResourceFactory::QueryHandler returns aninstance of the handler upon request, based on a URI. For example, the CustomDataLink SDKsample allows you to place assets specified in a CSV file. Since only CustomDataLink knowshow data is stored in the CSV file, it must implement a resource handler for assets from theCSV. CustomDataLink defines its own URI that can uniquely identify any asset in the CSV.CustomDataLink’s resource handler knows how to retrieve data from the CSV based on theURI. The URI defined in CustomDataLink has its own scheme, CSVLink, and its URI lookssomething like this:CSVLink://csv_fullpath?recordID

The resource handler in CustomDataLink declares it knows how to handle resources whoseURI scheme is CSVLink. When CustomDataLink’s client asks to place a resource from the CSV,CustomDataLink processes a kImportAndLoadPlaceGunCmdBoss by giving the command aIImportResourceCmdData that consists of an URI to the resource client specified. kIm-portAndLoadPlaceGunCmdBoss does all the ground work for an import action; when it comestime to import the real resource, it sends the URI to the link manager. The link manager que-

kImportLinkBossILink... ILink::

GetObject

kTextStoryBossILinkObject

kLinkResourceBossILinkResource

ILink::GetResource

Page 13: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 13

Adobe InDesign CS4 Porting GuideLinks Architecture

ries all the service providers that support kLinkResourceService, to see if anyone can handle aURI scheme of CSVLink. Since CustomDataLink implements one, it is chosen to import thedata from the URI. The CustomDataLink’s implementation of ILinkResourceHandler definesmethods like CreateResourceReadStream(), which returns an IPMStream to the resource towhich the selected CSV record points. Since CustomDataLink knows how to access the CSV,given its own URI, it knows exactly what record its client is requesting and handles the request.Table 2 lists the URI schemes handled by a default InDesign resource handler.TABLE 2 InDesign URI schemes and their resource handler

If you provide you own resource handler, you should implement your own Place dialog andadd it under your own Place menu.

Link object

A link object is any boss that aggregates the ILinkObject interface. ILinkObject is a proxy usedto represent the item in an InDesign publication being linked to; for example, a page item,XML element, or range of text. Depending on the type of link associated with the item,ILinkObject specifies how the item is imported, exported, or resolved. A link (ILink) stores theUID of the link object with which it is associated, and the link object can be retrieved from theILink::GetObject() method. Normally, if your link object is a regular page item, it has anILinkObject with kPageItemLinkObjectImpl as its default implementation. kPageItemLinkOb-jectImpl specifies kPageItemUpdateLinkServiceProviderBoss as its import provider. When thelink needs an update, kPageItemUpdateLinkServiceProviderBoss is used to update the link.Internally, kPageItemUpdateLinkServiceProviderBoss’s IUpdateLinkService implementation(kPageItemUpdateLinkServiceImpl) processes a kReimportCmdBoss to update the link. Even-tually, kReimportCmdBoss uses the link resource’s resource handler to provide a data stream tothe resource, just like the initial Place.Table 3 lists the InDesign bosses that aggregates an ILinkObject by default.TABLE 3 Default InDesign bosses that aggregates ILinkObject

Scheme Purpose

file Used when InDesign Place... is used to import file

adobevc For handling assets from Version Cue.

ADBEapli Used in assignment link

Boss name Note

kDocBoss kPageItemLinkObjectImpl

kTextStoryBoss kPageItemLinkObjectImpl

kSplineItemBoss kPageItemLinkObjectImpl

kMediaPageItemBoss kPageItemLinkObjectImpl

kGroupItemBoss kPageItemLinkObjectImpl

Page 14: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

14

NOTE: kJBXLinkObjectBoss also has kJBXLinkObjectImpl.If you are trying to create a link on an object not listed in Table 3, make sure you aggregateILinkObject to the object’s boss. The SDK sample ExtendedLink illustrates this situation, wherea link object is derived from kXMLLinkObjectReferenceBoss.

Link manager

There is a link manager, represented by ILinkManager, in every InDesign document (kDoc-Boss). ILinkManager is used to create and delete links and link resources. ILinkManager alsoprovides many ways to query links and link resources.To query links through ILinkManager, first you should construct a LinkQuery object.LinkQuery is a class that allows you to easily specify what you want the ILinkManager tosearch for and pass the LinkQuery object to the ILinkManager::QueryLinks method. ILink-Manager returns the query result in a ILinkManager::QueryResult, which is a std::vector thatcontains the UID of the links. Once you have the UID of a link, you can query its ILink inter-face.ILinkManager also uses the link client ID as a filter when it returns the LinkQuery result. If youspecify a client ID, ILinkManager::QueryLinks returns the link with the same client ID. This isconvenient if you used a unique client ID to identify your link and link resource: you can easilyquery all your links with an empty LinkQuery and your client ID.To query a link resource through ILinkManager, construct a LinkResourceQuery object.LinkResourceQuery is similar to LinkQuery, in that it allows you to specify the criteria (such asresource URI scheme) to look for when ILinkManager searches for a link resource in a docu-ment. Once you construct a LinkResourceQuery, you then pass it to ILinkManager::QueryRe-sources for the query. ILinkManager also returns the query result in aILinkManager::QueryResult.

Link status

For every link resource handler made available in the link architecture through the kLinkRe-sourceService service provider, you should provide an implementation of ILinkResourceState-Updater, which provides the link manager with link-resource status information. There aretimes when link manager will ask each link resource to provide a status update; for example,

kDisplayListPageItemBoss kPageItemLinkObjectImpl

kImageItem kPageItemLinkObjectImpl

kPlacedPDFItemBoss kPageItemLinkObjectImpl

kXMLLinkObjectReferenceBoss kXMLElementLinkObjectImpl

kTestSplineItemBoss kPageItemLinkObjectImpl

kSPPlaceHolderPageItemBoss kPageItemLinkObjectImpl

kBookContentBoss kBookLinkObjectImpl

Boss name Note

Page 15: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 15

Adobe InDesign CS4 Porting GuideLinks Architecture

when the application resumes from background to foreground. ILinkManager calls ILinkRe-sourceStateUpdater::UpdateResourceStateAsync. ILinkResourceStateUpdater should be aggre-gated on the boss where ILinkResourceHandler is aggregated. In “Linked resource andILinkResourceHandler” on page 12, we discuss how ILinkResourceHandler normally is instan-tiated through the ILinkResourceFactory. ILinkResourceFactory has a method called QueryS-tateUpdater, which is used to instantiate a status updater for the URI scheme supported by thesame ILinkResourceFactory.ILinkManager may call for a link-resource status report synchronously or asynchronously,depending on the situation; therefore ILinkResourceStateUpdater declares two update meth-ods: UpdateResourceStateSync and UpdateResourceStateAsync. In UpdateResourceStateSync,the status update should be completed on the return of the function. In UpdateResourceS-tateAsync, it is expected that status update is done in the background or during idle time.Both ILinkResourceStateUpdater::UpdateResourceStateSync and ILinkResourceStateUp-dater::UpdateResourceStateAsync are passed in an UIDRef of a link resource (kLinkResource-Boss). ILinkResource stores resource-status information like resource state(ILinkResource::ResourceState), modification time, and size.Also, there is a “stamp” (of type ResourceStamp, which is essentially a WideString) stored inILinkResource. You can use the ResourceStamp to construct any custom stamp you need forstatus-update purposes. ILinkResource has declared get/set methods for maintaining theseresource attributes.In UpdateResourceStateSync/UpdateResourceStateAsync, a comparison should be madebetween the link-resource object passed in and the external link resource (available from theURI, which can be queried through the link-resource object). If you decide the link is out ofdate, a kLinkResourceStateUpdateCmdBoss should be processed. This causes the link resourceto be updated with the new status data. The corresponding link (ILink) also maintains alinked-resource modification state, which is set to ILink::kResourceModified, indicating thelink resource was modified since the last update. If the link is displayed in the Links UI panel,the status shows it is out of date, and the Update Link option becomes available; this allows theuser to manually update the link on demand.

NOTE: Each ILinkResourceStateUpdater implementation may have its own policy to decide what should be regarded as a status change. For example, InDesign’s ILinkResourceStateUpdater for URI scheme “file” uses the file’s modification date and file size as its criteria.

There are several approaches you can take to accomplish link-state updates. For example, Ver-sion Cue links are updating via a push approach. Version Cue notifies InDesign whenever thestate of a Version Cue link changes. File links use a pull approach to update link states, by get-ting current information from the file system. The SDK ExtLink sample uses an idle-task-based solution. It is important to consider the case where there are many links in a document.When the link architecture asks for a link-status update, it asks all links to provide updates;therefore, the performance issue is critical and deserves a good implementation strategy.

Link update

When a link status is outdated, a link-update action becomes available. If the link informationis available on the Links UI panel, a contextual-menu item, “Update Link,” is enabled when a

Page 16: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

16

link is selected in the panel. When the “Update Link” menu action is selected on an importlink, kLinkUpdateCmdBoss is processed; this queries the ILink on the kImportLinkBoss andcalls its ILink::Update() method. Inside the ILink::Update(), it queries its associated link object(ILinkObject) to see if there is an import provider available for the link object through theILinkObject::GetImportProvider(). If there is one, that import provider is used to re-importthe link resource; otherwise, ILinkObject::Import() is called. In ILinkObject::GetImportPro-vider(), you can specify a update-link service-provider boss that implements IUpdateLinkSer-vice or kInvalidClass. In the later case, you should then implement ILinkObject::Import. Forexample, if the link object is a kPageItemLinkObjectImpl, it defines an kPageItemUpdateLink-ServiceProviderBoss in its GetImportProvider, which is used to update the link. kPageItemUp-dateLinkServiceProviderBoss processes a kReimportCmdBoss, which asks the link-resourcehandler to create a read stream from the resource for import purposes.What if your link object is not a page-item type, or you do not want to (or cannot) use kReim-portCmdBoss to update your link? In these cases, you must implement your own link objectthat will use your own IUpdateLinkService or ILinkObject::Import.

Link Notification

When a link or link resource is added, deleted, or changed, a lazy notification is sent on theprotocol of IID_ILINK or IID_ILINKRESOURCE (depending on what was changed). TheUID of the link or link resource is sent in the notification via the notification cookie, LazyNoti-ficationData. Using LazyNotificationData::BreakoutChanges, you can determine which items(UIDs) were added, deleted, or changed. There is another lazy notification sent via the IID_ILINKDATA_CHANGED protocol. Thisoccurs not only when a link or link resource is added, deleted, or changed, but also when alink’s link resource is changed. The notification cookie is passed in a type called ILinkMan-ager::ChangeData, a wrapper of UID, which tells you what kind of UID is referenced.You need not send any links-related notification from your plug-in—the links manager takescare of that.

Data conversion for pre-CS4 link objects

To open a pre-CS4 document that contains an old data-link object, you need a phase 2 con-verter. In the converter, you can iterate through all the old data-link objects and convert themto new ones. To allow you to iterate through the old links, some of the old data-links API wasretained in the InDesign CS4 code base; however, you should use it only for data conversion,because most of the architecture code that supports the old data-links API was removed.To get a list of old data-link objects, use the old ILinksManager available on the kDocBoss.ILinksManager::GetNthLinkUID returns the UID of the old data-link boss object; this proba-bly is the boss that aggregated the old IDataLink. For example, the InDesign CS3 SDK sampleCustomDataLink defines a boss object called kCusDtLnkAliasedDataLinkBoss, based onkDataLinkBoss, that aggregates IDataLink. When a CS3 publication saved with data links thatwere created by CustomDataLink is opened in CS4, the new CustomDataLink sample’s phase 2converter uses ILinksManager::GetNthLinkUID to return the UIDs of kCusDtLnkAliased-DataLinkBoss objects saved in the document.

Page 17: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 17

Adobe InDesign CS4 Porting GuideLinks Architecture

Once you have access to the old data-link object, you should try to convert the link using thenew link architecture. That is, an ILink should be instantiated to connect an ILinkResource andan ILinkObject. You should be able to figure out the link resource for the old link through theold IDataLink. The kDataLinkBoss also aggregates an ILinkObjectReference, which is a refer-ence to the InDesign object, such as a page item, with which the link is associated. “Linkobject” on page 13 discusses objects that have aggregated an ILinkObject beginning in CS4; insuch cases, the UID of the InDesign object should be used as the link object associated with thelink.The ILink and ILinkResource created from the old kDataLinkBoss should be initiated with thedata saved in IDataLink from the same boss. Both ILink and ILinkResource have a methodcalled CopyAttributes, which can be used to copy the data from the old kDataLinkBoss. Forconversion purposes, you can aggregate an ILink and ILinkResource in your old data-link boss.Then, you initialize ILink and ILinkResource with the data from IDataLink. Finally, you callthe ILink::CopyAttributes, and ILinkResource::CopyAttributes, passing in the UIDRef of theold data-link boss. In this way, the new ILink and ILinkResource are initialized properly.Note that you still need a schema-based null converter.

Links panel extensibility

You can add your own column into the Links panel (through a service-provider boss withkLinkInfoServiceImpl as IK2ServiceProvider) and provide your own ILinkInfoProvider imple-mentation. The column will be available in the Links panel’s option dialog for the user to turnon or off. Providing an ILinkInfoProvider implementation can be as easy as providing staticinformation, or you can indicate that the information needs to be updated dynamically basedon certain protocol’s notification. You can elect to listen to any command-notification protocolin ILinkInfoProvider and update your information when the command notifies your sub-scribed protocol. For a simple ILinkInfoProvider implementation, see the CustomDataLinksample in the SDK.

Frequently asked questions

Does the links architecture support the ability to programmatically alter links notifications to support a “push scenario” versus pull/polling?

To provide a links manager with your link-resource status, implement ILinkResourceStateUp-dater as described in “Link status” on page 14. The links sybsystem does not care when youprovide the update, and it does not enforce any update request; it is entirely up to you to imple-ment your own update-timing strategy. The ExtLink SDK sample provides a links subsystemthrough a manual menu action; it updates only when user decides to do so. It is the most prim-itive form of “push scenario”: the plug-in does not have any idle task polling the database forthe latest information; instead, it waits for the user to tell it to grab the latest status from thedatabase.

Page 18: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

18

Does the links architecture support the ability to support a permissions-based, bi-directional, update solution?

Bi-directional linking is supported. ExtLink SDK sample uses bi-directional linking to updatedatabase content with data from an InDesign linked object. You must manage the access rightto the update, as there is no built-in mechanism for that purpose. One way to achieve this isthrough the suppressed user interface, enabling the feature only for a specific user.

Can I programmatically define conditional links?

Suppose you have an image with both low-resolution and high-resolution versions. You wantto have the ability to define a link to alternate images, depending on whether the high-resolu-tion image is available. The easiest way to achieve this workflow is to define a custom URI thathas paths to both images. The URI is opaque, the links subsystem cares about only the schemepart of the URI, and each scheme is tied to a link-resource handler. In your link resource, youmust parse the URI to get the paths to both versions of the image (link resources). Then, youalso will build the logic for determining when to use each image in the link resource (and thelink-resource state updater). For example, you might have a flag in the database for each high-resolution image, to indicate if it is ready to publish. In your link-resource handler, you wouldcheck that flag, to see if you should import the low- or high-resolution image.

Is the InDesign links user interface customizable?

You can add your own column into the links user interface and provide your own informationin that column. For details, see “Links panel extensibility” on page 17.

How can I search and create/define custom sorts for the links user interface?

CS4 does not support the search and custom-sort functions for the links user interface.

Can I define how links are displayed in the links user interface, so I can provide a hierarchical view of my links?

There is no easy way to achieve this in CS4. Only parent/children links are grouped together.An example of this is a placed InDesign file which has links in it. These links show up as childlinks in the Links panel, and its parent, the InDesign file that is placed, is shown as the top-levelnode in the links user interface. In theory, you can manage the user interface by manipulatingthe links model; in reality, this is very complicated.

Porting CS3 links to the CS4 links architecture

This section describes how to port a CS3 CustomDataLink to CS4. It should provide some helpin porting your own custom data links.

How things worked in CS3

In CS3, a kCusDtLnkAliasedDataLinkBoss, which is based on kDataLinkBoss, provided majorfunctionality for the CSV link for the sample. The boss aggregated an IStringData interface(with ID IID_ICUSDTLNKUNIQUEKEYSTRINGDATA), which stored a unique identifier

Page 19: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 19

Adobe InDesign CS4 Porting GuideLinks Architecture

key for the asset stored in the database; in this case, a CSV file. When the user tried to place anasset from the CSV file, CustomDataLink formed a unique identifier key based on the user’sselection, instantiated a kCusDtLnkAliasedDataLinkBoss object, and initialized the IDataLinkon the object with the unique key’s information. IDataLink used the NameInfo class to identifya link, so CustomDataLink formed a NameInfo based on the unique key. If the unique keyreally referenced a file, it got the file path and used it to populate NameInfo; otherwise, it pop-ulated the NameInfo’s filename with the unique key, and the volume name was set to 0. This isfine, because the IDataLink implementation, CusDtLnkAliasedDataLink, knows how theNameInfo is formatted, so it can provide operations like Combine and CompareBaseName.CusDtLnkAliasedDataLink also implemented IDataLink::GetCurrentState, which providedlink-status information to the old links manager. kCusDtLnkAliasedDataLinkBoss also aggre-gated ILinkedStream, which created an IPMStream read stream from the linked asset whenrequested. It primarily used the unique key stored in the kCusDtLnkAliasedDataLinkBoss toget access to the file the key references. Finally, kCusDtLnkAliasedDataLinkBoss also aggre-gated IDataLinkAction, which provided functions for most of the contextual menu in the oldLinks Panel when a link was right-clicked. To place the file selected by the user, Custom-DataLink processed kImportAndLoadPlaceGunCmdBoss, whose command-data interface,IImportFileCmdData, took an IDataLink pointer that was created from the unique identifierkey.CustomDataLink also implemented IUpdateLinkService with kCusDtLnkUpdateLinkService-Impl, which was called by the old links manager when the link was out of date and the userrequested an update on the link. Essentially, it re-imported the linked resource, created a newkCusDtLnkAliasedDataLinkBoss, and re-initialized the IDataLink. Also, to support copyingand pasting of the page item with the custom data link, CustomDataLink implemented anIReferenceConverter, which added or embedded the link to the copied page item.

Converting from CS3 to CS4

First, you need to devise a URI to replace the unique key stored in theIID_ICUSDTLNKUNIQUEKEYSTRINGDATA of kCusDtLnkAliasedDataLinkBoss. In CS3, aunique identifier key on the database alias-database-1.csv was defined as something like this:alias-database-1.csv/recordID

In CS4, the unique identifier is defined as an URI as follows:CSVLink://fullpath_to_alias-database-1.csv?recordID

When the user tries to place an asset from the CSV file, the new CustomDataLink forms a URI,then processes a kImportAndLoadPlaceGunCmdBoss. Notice that the kImportAndLoadPlace-GunCmdBoss now aggregates an IImportResourceCmdData as its command-data interfaceinstead of IImportFileCmdData. IImportResourceCmdData takes a URI as an input parameter,and that is all you need to do to process kImportAndLoadPlaceGunCmdBoss. As discussed in“What is a link in InDesign?” on page 8, when it is time to import the resource during the pro-cessing of kImportAndLoadPlaceGunCmdBoss, a link-resource handler that knows how tohandle the type of URI scheme of the resource the user is trying to place is queried to provide aresource read stream for the import provider that is doing the import. Since CustomDataLinkis the client that creates the scheme CSVLink, it needs to provide a link-resource handler(ILinkResourceHandler), which is implemented and aggregated by the kCusDtLnkLinkRe-

Page 20: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

20

sourceHandlerBoss. Most of the methods in the ILinkResourceHandler are passed in a URI asa parameter. As the creator/owner of the URI scheme CSVLink, CustomDataLink can decidewhat to return as the short/long name of the resource, it would know how to open the resourceas a read stream given its URI, and it can decide if it wants to allow the typical datalink actionsuch as Edit Original and how it should be done.ILinkResourceHandler::CreateResourceReadStream basically replaces the deprecated ILinked-Stream. The only difference is that ILinkedStream was aggregated on a kDataLinkBoss, so itaccessed the link resource through the reference stored in IDataLink or whatever data interfaceits plug-in chose to carry. ILinkResourceHandler::CreateResourceReadStream, on the otherhand, is passed in a URI, which represents the reference to the link resource currently beingasked for the resource stream.In CS3, IDataLink::GetCurrentState provided link status. Its functionality was ported toILinkResourceStateUpdater, and it was implemented using an idle task. “Link status” onpage 14 provides details on how ILinkResourceStateUpdater should be implemented.IDataLinkAction is now aggregated on the kImportLinkBoss. Normally, you should not have tooverride the kImportLinkBoss; thus, you should not have to override the IDataLinkAction.Besides, the IDataLinkAction was stripped to contain only GoToLink action. Much of the orig-inal IDataLinkAction methods were moved to ILinkResourceHandler, or the actions were pro-vided automatically. For example, to embed a link, you only need to enable the embed action inthe ILinkResourceHandler::CanEmbedResource; the link architecture does the rest for youwhen the embed action is requested. You still need to implement your own action, such as Edi-tOriginal or RevealResource.Finally, in CS4, IUpdateLinkService and IReferenceConverter are not needed for Custom-DataLink, because the architecture takes care of this automatically. IReferenceConverter isneeded only when you have your own customized link boss; i.e., your link boss is not one of thethree types of links (e.g., kImportLinkBoss) specified in “Types of links” on page 11; in thiscase, you must implement your own IReferenceConvert to support copy and paste operationsof your links. Customization of the link boss, however, should never be necessary.In summary, the old way of implementing your own kDataLinkBoss-based custom data-linkboss is no longer supported. You should implement a resource-handler boss that aggregates anILinkResourceHandler and ILinkResourceStateUpdater, and provide a ILinkResourceFactoryto instantiate the handler on demand, as described in the procedure below.To provide your own type of links support, follow these steps:

1. Define how your resource can be represented by a URI. You will need your own URIscheme to identify the type of resource for which you will provide support.

2. Implement a link-resource handler that knows how to import the type of resource youdefined in your URI.

3. Provide a link-resource state-updater service provider that reports back to the link managerthe current state of a link resource.

4. Provide a phase 2 converter, if you have custom data-link data for a pre-CS4 InDesign pub-lication and you want your user to be able to convert those links to CS4-compatible links.

Page 21: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 21

Adobe InDesign CS4 Porting GuideLinks Architecture

Table 4 provides a high level comparison of links-related tasks in InDesign CS3 and CS4.TABLE 4 Comparison of common link tasks in InDesign CS3 and CS4

CS3 links-related APIs deprecated in CS4

Table 5 lists CS3 links-related APIs that are deprecated in CS4. You might still see these APIs inthe SDK, but they exist only for conversion purposes; their core functionalities were removedfrom the InDesign code base.TABLE 5 InDesign CS3 APIs that are deprecated in CS4

Task CS3 CS4

Support your own type of link

Create your own data-link boss based on kDataLinkBoss, which implements IDataLink, ILinkedStream, and IDataLinkAction.

Provide an ILinkResourceHandler that knows how to handle a particular URI scheme. It knows how to open a read stream from the link resource, for import purposes. Most IDataLinkAction functionalities are provided by the new link architecture; some (like EditResource) were moved to ILinkResourceHandler.

Provide link status to the link’s manager

Implement IDataLink::GetCurrentState.

Implement ILinkResourceStateUpdater, which should queue an LinkResourceStatePacket for processing in an idle time, on completion of the packet. Process an kLinkResourceStateUpdateCmdBoss if the resource state has changed.

Support updating a link from the Links UI panel

Implement an IUpdateLinkService service provider.

If your link object is a page-item type and your ILinkResourceHandler::CreateResourceReadStream returns a stream that is ready to import into the page item, you do not need to do anything: kReimportCmdBoss is processed for you, and your ILinkResourceHandler::CreateResourceReadStream is used to supply an IPMStream to the resource. There are situations when you might still need to implement an IUpdateLinkService; for details, see “Link update” on page 15.

Support copy and paste of a page item that has your own type of link

Implement a IReferenceConverter, which adds or embeds a link in the new page item.

You do nothing. The new links architecture takes care of copying the links to the new page item.

Deprecated API Notes

ICoreFilename Do not assume the link always is to a file.

IDataLink See “Porting CS3 links to the CS4 links architecture” on page 18.

IDataLinkHelper The main helper class you should use is ILinkFacade, although there is not a 1:1 mapping between the two APIs.

Page 22: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideLinks Architecture

22

Porting recipes for links-related code

This following sections present several recipes for porting links-related code to CS4.

Porting recipe: ILinkFacade

ILinkFacade is a high-level API for dealing with links, link resources, and link objects. It hasmethods to create, delete, update, and re-link a link. Also, it has methods to create linkresources and update resource state. Use ILinkFacade whenever possible.

Porting recipe: Getting to the associated InDesign link object like page item from a link

CS3:Given an IDataLink, query the ILinkObjectReference on the kDataLinkBoss and call ILinkOb-jectReference::GetUID.CS4:Given an ILink, use ILink::GetObject to return the UID of the object.

Porting recipe: Getting to a link from a page item

CS3:Used IDataLinkReference as the bridge between a page item and an IDataLink:// assume childHierarchy is an IHierarchy InterfacePtr<IDataLinkReference> dataLinkReference(childHierarchy, UseDefaultIID());if(!dataLinkReference) {break;}PMString datalinkPath("UNDEFINED");IDataBase* db = docRef.GetDataBase();

IDataLinkReference This was used mainly to get to the associated kDataLinkBoss from a page item. In CS4, use ILinkManager::QueryLinksByObjectUID.

IEditFile If you want to allow the Edit Original menu to b e available in the Links UI panel., return true in ILinkResourceHandler::CanEditResource and implement ILinkResourceHandler::EditResource.

ILinkObjectReference This was used mainly to get to the associated page item from a kDataLinkBoss. In CS4, use ILink::GetObject.

ILinksManager This was replaced by ILinkManager.

ILinkState This may be needed for backward compatibility.

IUpdateLink This was moved from kDataLinkHelperBoss to kImportLinkBoss. During an update link, it queries the service provider that supports IUpdateLinkService, to handle link update.

Deprecated API Notes

Page 23: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 23

Adobe InDesign CS4 Porting GuideLinks Architecture

UID itemUID = dataLinkReference->GetUID();InterfacePtr<IDataLink> dataLink(db, itemUID, UseDefaultIID());ASSERT(dataLink);if(!dataLink) {break;}PMString* namePtr = dataLink->GetFullName();

CS4:Use ILinkManager::QueryLinksByObjectUID to get to ILink. It returns the result in an ILink-Manager::QueryResult, which is a UID vector that holds the ILink UID. For details, see “Linkmanager” on page 14.InterfacePtr<IHierarchy> childHierarchy(frameHierarchy->QueryChild(0));// If we're on a placed image we should have a data link to source itemInterfacePtr<ILinkObject> iLinkObject(childHierarchy,UseDefaultIID());// get the link for this objectIDataBase* iDataBase = ::GetDataBase(childHierarchy);InterfacePtr<ILinkManager> iLinkManager(iDataBase,iDataBase->GetRootUID(),UseDefaultIID());ILinkManager::QueryResult linkQueryResult;if (iLinkManager->QueryLinksByObjectUID(::GetUID(childHierarchy), linkQueryResult)){

ASSERT_MSG(linkQueryResult.size()==1,"Only expecting single link with this object");

ILinkManager::QueryResult::const_iterator iter = linkQueryResult.begin();InterfacePtr<ILink> iLink (iDataBase, *iter,UseDefaultIID());if (iLink!=nil){InterfacePtr<ILinkResource> iLinkResource(iLinkManager-

>QueryResourceByUID(iLink->GetResource()));ASSERT_MSG(iLinkResource,"CHMLFiltHelper::addGraphicFrameDescription - Link

with no associated asset?");if(iLinkResource!=nil)

PMString datalinkPath = iLinkResource->GetLongName();}

}

Porting recipe: Updating a link

CS3:UID newDataLinkUID;InterfacePtr<IUpdateLink> update((IUpdateLink *)::CreateObject(kDataLinkHelperBoss, IID_IUPDATELINK));if ( !update)

return;// assume dl is a valid IDataLinkErrorCode result = update->DoUpdateLink(dl, &newDataLinkUID) ;

CS4:Use ILinkFacade::UpdateLinks, which processes (or schedules) a kLinkUpdateCmdBoss. Youneed to pass in the UID of a kImportLinkBoss.

Page 24: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideScripting

24

Scripting

New for CS4 is the ability to undo an entire script in one step. A script typically contains manyundoable operations - one for each script request. For CS4, all of these operations can be storedand undone as a single undo operation. This feature is accessed from IScriptRunner and fromthe doScript method of the scripting DOM.This feature also provides the ability to access the error code for individual scripting requests,as defined in RepresentScriptProvider. The sections below explain the modified scripting-related APIs surrounding these new features, along with other changes to improve the scriptingAPI.

doScript

The doScript method of the scripting DOM has two additional parameters:undoMode defines how the script is to be undone.undoName defines the undo menu item for the script.

Possible values for undoMode are defined by the undoMode enumType, including:scriptRequest — This is the default value. An undo history entry is added for every scripttransaction that occurs within your script. After executing the example script below, theEdit menu holds an item corresponding to the last script transaction that occurred withinmyScript.jsx. If that transaction creates a new rectangle, for example, the undo menu item is“Undo Add New Item.”

app.doScript( File("C:\\myScript.jsx"), ScriptLanguage.JAVASCRIPT, undefined,UndoModes.scriptRequest);

entireScript — One undo history entry is added for your entire script. The name of the entryis defined by the undoName parameter. If undoName is undefined, “Script” is used bydefault. After executing the example script below, the Edit menu holds the item “Undo myscript.”

app.doScript( File("C:\\myScript.jsx"), ScriptLanguage.JAVASCRIPT, undefined,UndoModes.entireScript, "my script");

autoUndo — No undo history entry is added for the script. Instead, all script transactionswithin the script are attached to the preceding history entry and undone when that entry isundone. After executing the example script below, the Edit menu holds the item “Undo AddNew Item” for the rectangles.add transaction. No item is added for doScript.

app.activeDocument.rectangles.add(undefined, undefined, undefined,{geometricBounds:[10, 10, 20, 20], contentType:ContentType.graphicType});

app.doScript( File("C:\\myScript.jsx"), ScriptLanguage.JAVASCRIPT, undefined,UndoModes.autoUndo);

Page 25: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 25

Adobe InDesign CS4 Porting GuideScripting

IScriptRunner

IScriptRunner provides the C++ API functionality for running a script. In CS4, this functional-ity includes the new entireScript undo functionality. When this new feature was implemented,the parameter lists of the methods in IScriptRunner got too long. To solve this problem, a newRunScriptParameter class was developed to contain parameters related to running a script. Forexample:CS3:virtual ErrorCode RunFile(const IDFile& idFile, bool16 showErrorAlert = kTrue,

bool16 invokeDebugger = kFalse) = 0;

Call to RunFile:ErrorCode err = scriptRunner->RunFile(scriptFile, kFalse, kTrue);

CS4:virtual ErrorCode RunFile(const IDFile& idFile, const RunScriptParams& params) = 0;

Call to RunFile:RunScriptParams params( scriptRunner);params.SetInvokeDebugger(kTrue);ErrorCode err = scriptRunner->RunFile(scriptFile, params);

IScriptEngine

CS4 introduces a new scripting interface, IScriptEngine. As its name suggests, IScriptEngineprovides support for engine-specific information within the scripting architecture. For exam-ple, several methods that were on the IScriptManager interface for CS3 were moved toIScriptEngine:

GetRequestContext() CreateScriptEventData() IncrementActiveScriptCount() DecrementActiveScriptCount() GetShowAlerts() GetShowDialogs()

In addition, the IScriptPreferences and IScriptRunner interfaces were moved from the IScript-Manager boss to the IScriptEngine boss. In practice, most scripting clients have only oneengine. These clients will be able to aggregate IScriptEngine with their existing IScriptManagerboss and use a default implementation of IScriptEngine intended for single-engine clients.The main beneficiary of these changes will be the JavaScript client, which supports an arbitrarynumber of engines. In CA3, all engines inherit identical preferences, including the activescripting DOM version. That means if one engine sets the current scripting DOM version to“4.0,” the scripts running in all JavaScript engines suddenly will be executed against the Fire-drake DOM. With the CS4 change, each engine has its own DOM version. Prior to CS4, therewas no way to determine which engine initiated a scripting request. The biggest problem withthis was that when an engine executed a DoScript request, the sub-script was processed in the

Page 26: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideScripting

26

default (“main”) engine instead of the originating engine. For CS4, the RequestContext class isupdated to include a pointer to the IScriptEngine for the engine that initiated the request; thus,a DoScript request is processed in the engine that initiated it.With this change, it is conceivable that versioned scripts may break in the case where script Aexecutes script B in a different engine (i.e., by calling DoScript). In CS3, if script A changes thecurrent scripting DOM version in engine A, script B inherits that change in engine B. In CS4,engine B and, thus, script B no longer inherit that change; script B executes against the script-ing DOM version in engine B.Furthermore, in CS3, the preferences for the JavaScript, AppleScript, and VBScript engineswere all tied together; that is, changing the current scripting DOM version in AppleScript alsoaffected JavaScripts and VBScripts (and vice versa for all combinations). In CS4, the engines forthese clients each have separate preferences. This change in behavior (from application-wide toengine-specific) also includes the preference for “user interaction level” (that is, whether alertsand dialogs are displayed during script execution); however, the “enable redraw” preferenceremains a global setting.

IScriptProvider

Previously, CScriptProvider overloaded the HandleEvent, AccessProperty, and AccessProper-ties methods. Subclasses were forced to override these methods, but generally only one of theoverloads. This resulted in hidden virtual functions, which generate an error when the relevantflag is turned on in XCode.In CS4, the versions of HandleEvent and AccessProperty that accepted a list of objects wererenamed to HandleEventOnObjects and AccessPropertyOnObjects, and the version ofAccessProperties that accepted a list of objects was removed. These methods also wererenamed in classes that implement IScriptProvider (e.g., CScriptProvider) and those thatinherit from CScriptProvider.CS3:virtual ErrorCode HandleEvent(ScriptID eventID, IScriptEventData* data,

const ScriptList& scriptList);virtual ErrorCode HandleEvent(ScriptID eventID, IScriptEventData* data,

IScript* script);

virtual ErrorCode AccessProperty(ScriptID propID, IScriptEventData* data, const ScriptList& scriptList);

virtual ErrorCode AccessProperty(ScriptID propID, IScriptEventData* data, IScript* script);

virtual ErrorCode AccessProperties(IScriptEventData* data, const ScriptList& scriptList);

virtual ErrorCode AccessProperties(IScriptEventData* data, IScript* script);

CS4:virtual ErrorCode HandleEventOnObjects(ScriptID eventID, IScriptEventData* data,

const ScriptList& scriptList);virtual ErrorCode HandleEvent(

ScriptID eventID, IScriptEventData* data, IScript* script);

Page 27: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 27

Adobe InDesign CS4 Porting GuideScripting

virtual ErrorCode AccessPropertyOnObjects(ScriptID propID, IScriptEventData* data,const ScriptList& scriptList);

virtual ErrorCode AccessProperty(ScriptID propID, IScriptEventData* data, IScript* script);

virtual ErrorCode AccessProperties(IScriptEventData* data, IScript* script);

Typical CS3 code looked like this:ErrorCode MyScriptProvider::HandleEvent(ScriptID eventID, IScriptEventData* data,

const ScriptList& scriptList){

if (eventID.Get() == e_Delete)return DeleteErrors();

elsereturn CScriptProvider::HandleEvent(eventID, data, scriptList);

}

The CS3 code above now causes the following compiler error:Error C2664: 'CScriptProvider::HandleEvent' : cannot convert parameter 3 from

'const ScriptList' to 'IScript *'No user-defined-conversion operator available that can perform thisconversion, or the operator cannot be called

To fix this, write your CS4 code as follows:ErrorCode MyScriptProvider::HandleEventOnObjects(ScriptID eventID,

IScriptEventData* data, const ScriptList& scriptList){

if (eventID.Get() == e_Delete)return DeleteErrors();

elsereturn CScriptProvider::HandleEventOnObjects(eventID, data, scriptList);

}

NOTE: Both the name of the subclass method and the call to the base-class method must be changed to maintain the desired overridden virtual function behavior.

IScriptErrorUtils

All script providers that returned kReadOnlyPropertyError in CS3 should now use the SetRea-dOnlyPropertyErrorData API instead. The following example is from the BasicShape SDKsample, in BscShpScriptProvider::AccessParentStory().CS3:if (data->IsPropertyPut()){

return kReadOnlyPropertyError;}

CS4:if (data->IsPropertyPut()){

Page 28: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideScripting

28

return Utils<IScriptErrorUtils>()->SetReadOnlyPropertyErrorData( data,p_ParentStory);

}

IScriptEventData

As part of the change to give INX (and other scripting clients) access to the error code for everyscript request (e.g., each individual property when doing a get or set of multiple properties), theAPIs in IScriptEventData related to return data were revised.These changes will require edits in every script provider. The highest impact change is therequirement to call IScriptEventData::AppendReturnData() with multiple parameters, in placeof IScriptEventData::SetReturnData() with a single parameter, to return a result from a script-ing request. (The methods were renamed to enforce the change via the compiler and clarify theimplementation—“append” and “replace” rather than “set.”)Previously, the return data comprised a list of return values (K2Vector<ScriptData>) accessedvia one method IScriptEventData::GetReturnData(). One error code and error string wereavailable via the IScriptError interface on the same boss. (For certain requests to get/set multi-ple properties at once, it was possible to retrieve a list of error codes through IScriptRequest-Handler, but there was no way to tell which properties generated which results.)Now, the return data comprises a list of ScriptReturnData objects. The declaration of this fairlystraightforward class is available at <SDK>/source/public/includes/ScriptReturnData.h. Theseobjects record the request (property/event) ID, return value, error code, and error string. Forreasons of compiler enforcement, performance, and precision, the method to retrieve thereturn data was replaced with separate IScriptEventData::GetNumReturnData(), GetNthRe-turnData(), and GetAllReturnData() APIs. Furthermore, all return-data APIs take a targetparameter corresponding to the object in the scripting DOM on which the request was pro-cessed.Therefore, it is now possible to determine which requests were processed on which targets withwhich results. (Note: The IScriptError interface remains as a way to pass back a single, overallerror code and error string from the IScriptRequestHandler to scripting clients that do not careabout the new functionality.)CS3 IScriptEventData API:virtual void ClearReturnData() = 0 ;

virtual void SetReturnData( const ScriptData* data ) = 0 ;virtual void SetReturnData( const ScriptData& data ) = 0 ;virtual void SetReturnData( IScript* object ) = 0 ;virtual void SetReturnData( const ScriptList& objectList ) = 0 ;virtual void SetReturnData( const ScriptListData& data ) = 0 ;

virtual const ScriptListData& GetReturnData() const = 0;

CS4 IScriptEventData API:virtual void ClearReturnData( const IScript* target) = 0;virtual void ClearReturnData( const ScriptList& targets) = 0;

Page 29: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 29

Adobe InDesign CS4 Porting GuideScripting

virtual void AppendReturnData( const IScript* target, const ScriptID requestID, const ErrorCode errorCode) = 0;virtual void AppendReturnData( const ScriptList& targets, const ScriptID requestID, const ErrorCode errorCode) = 0;virtual void AppendReturnData( const IScript* target, const ScriptID requestID, const ScriptData& returnValue) = 0;virtual void AppendReturnData( const ScriptList& targets, const ScriptID requestID, const ScriptData& returnValue) = 0;virtual void AppendReturnData( const IScript* target, const ScriptReturnData& data) = 0;virtual void AppendReturnData( const ScriptList& targets, const ScriptReturnData& data) = 0;virtual void ReplaceReturnData( const IScript* target, const ScriptReturnDataList& data) = 0;virtual void ReplaceReturnData( const ScriptList& targets, const ScriptReturnDataList& data) = 0;virtual void AppendReturnData( const IScript* target, const ScriptReturnDataList& data) = 0;virtual void AppendReturnData( const ScriptList& targets, const ScriptReturnDataList& data) = 0;

virtual uint32 GetNumReturnData( const IScript* target ) const = 0;virtual uint32 GetNumReturnData( const ScriptList& targets ) const = 0;

virtual ScriptReturnData GetNthReturnData( const IScript* target, uint32 n ) const = 0;virtual ScriptReturnData GetNthReturnData( const ScriptList& targets, uint32 n ) const = 0;

virtual ScriptReturnDataList GetAllReturnData( const IScript* target ) const = 0;virtual ScriptReturnDataList GetAllReturnData( const ScriptList& targets ) const = 0;

API usage for CS3:ErrorCode MyScriptProvider::AccessProperty(ScriptID propID,

IScriptEventData* data, IScript* parent){

ScriptData scriptData;scriptData.SetWideString(myWideString);data->SetReturnData(&scriptData);

}

API usage for CS4:ErrorCode MyScriptProvider::AccessProperty(ScriptID propID,

IScriptEventData* data, IScript* parent){

ScriptData scriptData;scriptData.SetWideString(myWideString);data->AppendReturnData( parent, propID, scriptData ) ;

}

Page 30: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideScripting

30

Metadata resource

Metadata resources are used to add arbitrary information to elements in the scripting DOM.INX uses them extensively to customize the handling of various objects during import andexport. They also are used to control type information, to support properties on thefind/change objects for scripting clients.Adding a ScriptElementID to metadata scripting resources makes it possible to version themetadata resources included in a DOM based on the client. For example, we can indicate thatthe INX client does not want certain metadata included in its DOMs. The addition of theScriptElementID requires all existing metadata scripting resources to add this field.Below is an example from the TransparencyEffect sample plug-in (TranFX.fr).CS3:Metadata{

{kTranFxSettingsObjectScriptElement,

}{

m_INXSnippetAttrImportState, Int32Value(e_SetElementAttributes),}

}

CS4:Metadata{

kTranFxSettingsINXPoliciesMetadataScriptElement,{

kTranFxSettingsObjectScriptElement, }{

m_INXSnippetAttrImportState, Int32Value(e_SetElementAttributes), }

}

RepresentScriptProvider

CS4 gives scripting clients the ability to access the error code for every script request. The Rep-resentScriptProvider base class was modified to clarify expectations about how the methods'implementations should return data and error codes. This change affects every subclass of Rep-resentScriptProvider. Note that two of these methods are pure virtual functions, so the com-piler will enforce the change in existing implementations. Also, the compiler will catch theAppendAllObjects method if the hidden virtual functions warning is enabled.CS3:virtual int32 GetNumObjects( IScriptEventData* data, IScript* parent) = 0;virtual ErrorCode AppendNthObject( IScriptEventData* data, IScript* parent,

int32 n, ScriptList& objectList) = 0;virtual ErrorCode AppendAllObjects( IScriptEventData* data, IScript* parent,

ScriptList& objectList);

Page 31: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 31

Adobe InDesign CS4 Porting GuideScripting

CS4:virtual int32 GetNumObjects( const IScriptEventData* data, IScript* parent) = 0;virtual ErrorCode AppendNthObject( const IScriptEventData* data, IScript* parent,

int32 n, ScriptList& objectList) = 0;virtual ErrorCode AppendAllObjects( const IScriptEventData* data, IScript* parent,

ScriptList& objectList);

Text-attribute scripting

Script-provider implementations that get and set text attributes should use the new TextAttr-ScriptUtility class. This ensures consistent handling of text attributes across scripting objects.Use of TextAttrScriptUtility is demonstrated in the BasicTextAdornment sample’s script pro-vider (BscTAScriptProvider.cpp). Notice that this code implements the PreAccessProperty andPostAccessProperty methods that use a TextAttrScriptUtility instance to access and modify textattributes.Before moving to this code, the BasicTextAdornment sample used an ITextAttributeSuite to getand set text attributes. This worked for scripting and INX, but it failed for IDML, because ituses a new type of scripting object. Using the TextAttrScriptUtility class fixes that problem.

TypeDef and TypeDefType

A new feature added to the scripting resources is a TypeDef element and corresponding Type-DefType. A TypeDef resource defines a synonym for another type. A TypeDef type may beused wherever a type is required, by using a TypeDefType declaration; for example, the storagetype of a property resource or the return type or parameter types of an event resource.Two TypeDefs in the core DOM corresponding to user-interface colors in InDesign andInCopy were re-implemented using this technique. The new TypeDefs are shown below.TypeDef{

kInDesignUIcolortypeDefScriptElement,t_IDUIColorType,"InDesign UI color type","Properties or parameters using the InDesign UI Colors enumeration use this to

specify the type as either one of the enumerated UI colors or a list ofRGB values for a custom color.",

VariableType {

RealMinMaxArrayType(3, 0, 255), EnumType( kUIColorsEnumScriptElement )

}}

TypeDef{

kInCopyUIColorTypeDefScriptElement,t_ICUIColorType,"InCopy UI color type","Properties or parameters using the InCopy UI Colors enumeration use this to

specify the type as either one of the enumerated UI colors or a list of

Page 32: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideChanges to Support Rotated Spreads

32

RGB values for a custom color."VariableType {

RealMinMaxArrayType(3, 0, 255), EnumType( kInCopyUIColorsEnumScriptElement )

}}

Because these types were re-implemented, the following old #defines were removed fromScriptingScriptInfo.fh:#define UIColorType TypeDefType(kInDesignUIColorTypeDefScriptElement)#define UIColorDefaultType(def)

TypeDefDefaultType(kInDesignUIColorTypeDefScriptElement) EnumValue(def){}#define InCopyUIColorType TypeDefType( kInCopyUIColorTypeDefScriptElement)

The old #define constants that were used in properties and events were replaced with the newTypeDefs. For example:Property{

kWatermarkFontColorPropertyScriptElement,p_WatermarkFontColor,"watermark font color","Watermark font color for a document",TypeDefType(kInDesignUIColorTypeDefScriptElement), // changed for CS4{},kNoAttributeClass,

}

Changes to Support Rotated Spreads

Rotated spread is a new CS4 feature. A spread can be rotated in increments of 90 degrees. Thisallows for easier design of calendars, packaging, annuals reports, and other content thatrequires placement of text and imagery that is not right-side-up relative to the rest of the docu-ment. Users no longer need to temporarily rotate frames or their monitors. To support this fea-ture, some APIs need to be changed; they are summarized in this section.

A new enumerator for commonly referenced coordinate systems

In CS3, enumerators for three commonly referenced coordinate systems were added to Trans-formTypes.h:Transform::PasteboardCoordinates()Transform::ParentCoordinates()Transform::InnerCoordinates()

These named values are used throughout the transform and geometry API stacks. They are oftype Transform::CoordinateSpace. Here, pasteboard coordinates is the single coordinate sys-tem used to draw every spread on the “floor” within a layout window. It often is used as thecommon ancestor of all page items on a spread. This was a mistake. Instead, spread coordinates

Page 33: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 33

Adobe InDesign CS4 Porting GuideChanges to Support Rotated Spreads

could have been used in most cases and must be used in some cases in the presence of rotatedspreads. Pasteboard coordinates really is of interest only to the layout control view.In CS4, a new enumerator is added to TransformTypes.h:Transform::SpreadCoordinates()

The companion change to scripting is to add “spread coordinates” (en_SpreadCoordinates) tothe allowable coordinate systems used by the “transform” and “resize” script events.

NOTE: No function signature needed to change as a result of this addition.

ISpread::GetPagesBounds and ILayoutUtils::GetIntersectingPageUID

CS3:PBPMRect ISpread::GetPagesBounds();

CS4:PMRect ISpread::GetPagesBounds( Transform::CoordinateSpace coords = Transform::PasteboardCoordinates());

The legal values for coords are the default PasteboardCoordinates() and SpreadCoordinates().Its return type is changed to PMRect from PBPMRect. Actually, these are the same C++ type.The “PB” in the name was just suggestive to clients that the return value was in pasteboardcoordinates. If you pass in default parameter, the function returns exactly the same data to allunmodified existing callers.A similar change was made to ILayoutUtils::GetIntersectingPageUID.CS3:ILayoutUtils::GetIntersectingPageUID(... const PMRect& itemBounds, ....)

CS4:ILayoutUtils::GetIntersectingPageUID(... const PMRect& itemBounds, ...., Transform::CoordinateSpace s = Transform::PasteboardCoordinates())

IShape::GetPaintedBBox and GetPrintedBBOx

Similar to “ISpread::GetPagesBounds and ILayoutUtils::GetIntersectingPageUID” on page 33,the following IShape methods now return bounds in coordinate space specified by the caller.CS3:PMRect GetPaintedBBox(const PMMatrix& m);PMRect GetPrintedBBox(const PMMatrix& m);

CS4:PMRect GetPaintedBBox(const PMMatrix& m, Transform::CoordinateSpace coords = Transform::PasteboardCoordinates());PMRect GetPrintedBBox(const PMMatrix& m, Transform::CoordinateSpace coords = Transform::PasteboardCoordinates());

The legal values for coords are the default PasteboardCoordinates() or SpreadCoordinates().The previous behavior matches the new default, so previously correct code remains correct.

Page 34: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideChanges to Support Rotated Spreads

34

The previous behavior returns PMRects in pasteboard coordinates modified by the matrix m.For example, if m were the pasteboard to view matrix, the result would be in view coordinates.The new behavior allows one to optionally specify m relative to spread coordinates. For exam-ple, if m were the identity matrix and coords were SpreadCoordinates(), the resulting PMRectswould be in spread coordinates.

IMasterSpreadUtils::AppendMasterPageItems

The meaning of the pageBounds parameter to IMasterSpreadUtils::AppendMasterPageItemshas been changed, so the PMRects are provided in spread coordinates rather than pasteboardcoordinates. A typical caller of this function would have to make a change when asking for thepage bounds from IGeometryFacade using Transform::SpreadCoordinates() rather than Trans-form::PasteboardCoordinates().

IDrawMgr

For the draw manager's filter mechanism to be general enough for rotated spreads, the filterrectangles passed to IDrawMgr::BeginFilter need to be able to be specified in coordinate sys-tems other than view coordinates.CS3:void BeginFilter( const PMRect& r);

CS4:void BeginFilter( const PMRect& r, const PMMatrix& m = PMMatrix());

where m, if provided, is the view-to-filter space transformation. Usually, this is the view-to-spread matrix, provided by the default value; therefore, you old code probably will continue towork without any change.The member function IDrawMgr::GetFilter also changes from:PMRect GetFilter();

to:IDrawMgr::FilterInfo GetFilter();

where:struct FilterInfo{

PMRect fFilterRect;PMMatrix fFilterTransform;

}

Among other things, this fixes problems where master page items with transparency get drawntwice, hence too dark.

Page 35: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 35

Adobe InDesign CS4 Porting GuidegSession Removed

gSession Removed

Beginning in CS4, InDesign is moving toward a multi-threading environment. Multi-threadingwill not be complete until a future release, but in preparation, there have been minor changes tothe CS4 API. Namely, global and static variables were removed. One of the most visible and widely used globals was gSession, a pointer of type ISession on thesession boss. The session boss aggregates multiple interfaces (such as workspace, application,and preferences). In the multi-threading environment, there are multiple session objects, onefor each concurrent thread, so a single session global will no longer do. Each thread of execution now has its own execution context (environment). Your code shouldnot make any assumptions about the context in which it runs, so your code must now accessthe session pointer by using the global GetExecutionContextSession() method.CS3:InterfacePtr<IApplication> app(gSession->QueryApplication());

CS4:InterfacePtr<IApplication> app(GetExecutionContextSession()->QueryApplication());

In most places, a simple find/replace for gSession with GetExecutionContextSession() shouldsuffice, but keep in mind the following:

GetExecutionContextSession() has more overhead than de-referencing a pointer (gSes-sion). In most cases, this overhead will not make any difference in the execution time. Insome cases, including drawing code and frequently called observers, it can make a differ-ence if GetExecutionContextSession() is called carelessly.When determining where it is necessary to optimize the number of calls to GetExecution-ContextSession(), we recommend you use a profiler.GetExecutionContextSession() can return nil in some extreme cases (very early on startupor very late on shutdown). This should not affect you, but if you have code that you want toexecute very early on startup or very late on shutdown, check to make sure you have a validsession before using it.

You could use the following are replacement techniques:If the call to GetExecutionContextSession() happens in a function that is called often (like aloop), see what you are querying the session for (workspace, preferences, database, etc.) andpass that as a parameter to the function. This eliminates the repetitive call to GetExecution-ContextSession().Do not cache the session pointer in a class static variable. This would prevent the code fromrunning concurrently in multiple threads. If possible, refrain from using statics.You can and should store the result of GetExecutionContextSession() in a variable insideyour function, if the function queries the session for multiple things (like workspace, theapplication, command processor, and error state). For example:

void Foo() {// Use a regular variable. DO NOT use a static.ISession* session = GetExecutionContextSession();

Page 36: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideUser Interface APIs

36

InterfacePtr<IApplication> theApp(session->QueryApplication());InterfacePtr<IWorkspace> ws(session->QueryWorkspace());...InterfacePtr<IFoo> myFoo(session->QueryFoo());

}

User Interface APIs

This section discusses the impact of user-interface changes on third-party developers.When you first launch InDesign CS4, you will notice a new look to the document windows andapplication. All Creative Suite 4 applications have similar changes, as a result of adopting a newAdobe common user interface. The common user interface is provided by an internal librarycalled OWL. The transition from InDesign’s own user interface to the common user interfaceprovided by OWL will take time. It began in CS3 with the use of palette windows. In CS4, thenew application container presents the most significant visual change to users.

Workspace preference reading/writing

OWL takes over workspace reading/writing; however, the old way of using InDesign APIs,such as BasePanelSAXHandler and BasePanelXMLGenerator, is still supported.

Palette management

PaletteRef.h and PaletteRefUtils.h have detailed information about the palette hierarchy. Every-thing you see in the InDesign application workspace is an object hosted inside the paletteworkspace.The CS3 Tab group cluster is no longer a valid object in the palette hierarchy; instead there is anew, floating-dock object to host a palette and a document. As a result PaletteRe-fUtils::NewTabGroupClusterPalette and PaletteRefUtils::IsTabGroupCluster are obsolete;instead, PaletteRefUtils::NewFloatingTabGroupContainerPalette and PaletteRefUtils::IsFloa-tingTabbedPaletteDock are used.Floating palette docks can contain multiple tab panes, whereas the cluster was the pane, socode that walks the widget hierarchy must change. Also, in CS3, tab panes were always docked,but in CS4, tab panes can live in the new floating docks.

Document management

In InDesign CS3, a document is hosted in an layout window, represented by kDocumentWin-dowBoss. The IWindow in the CS3 kDocumentWindowBoss actually uses the system windowto host the document. In CS4, kLayoutWindowBoss is deprecated; instead, a kDocumentPre-sentationBoss is used to host a document, and IDocumentPresentation replaces IWindow asthe new key interface for views onto documents.

Page 37: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 37

Adobe InDesign CS4 Porting GuideUser Interface APIs

NOTE: IWindow is not completed deprecated; rather, is not used mainly in the document window. It continues to serve as the main interface for things like kDialogWindowBoss, which represents a dialog window.

See Table 6 for a list of API changes related to document windows.TABLE 6 API changes related to document windows

The following sections include porting recipes related to document windows.

Finding the front document window

CS3:IWindow* frontDocWindow = Utils<IWindowUtils>()->GetFrontDocWindow(); // or GetFrontDocLayerWindow();IWindow* frontmostDocWindow = Utils<IWindowUtils>()->GetFrontDocWindow(document); // or GetFrontDocLayerWindow(document);

CS4:IDocumentPresentation* frontDocPresentation = Utils<IDocumentUIUtils>()->GetActivePresentation();

CS3 CS4

IID_ICLOSELAYOUTWINCMDDATA IID_IPRESENTATIONCMDDATA

IID_IDOCUMENTWINDOW IID_IDOCUMENTPRESENTATION

IID_IDOCUMENTWINDOWTITLEPROVIDER IID_IDOCUMENTPRESENTATONLABELPROVIDER

IID_IOPENLAYOUTWINCMDDATA IID_IOPENLAYOUTCMDDATA

IID_IWINDOWLIST IID_IPRESENTATIONLIST

kCloseLayoutWinCmdBoss kCloseLayoutCmdBoss

kCloseLayoutWinCmdImpl kCloseLayoutPresentationCmdImpl

kDocumentWindowBoss kDocumentPresentationBoss

kDocumentWindowService kDocumentPresentationService

kLayoutWindowBoss kLayoutPresentationBoss

kOpenLayoutWinCmdBoss kOpenLayoutCmdBoss

kOpenLayoutWinCmdDataImpl kOpenLayoutPresentationCmdDataImpl

kOpenLayoutWinCmdImpl kOpenLayoutPresentationCmdImpl

kOpenLayoutWinSignalBoss kOpenLayoutSignalBoss

kOpenLayoutWinSignalRespServiceImpl kOpenLayoutSignalRespServiceImpl

kOpenLayoutWinSignalServiceID kOpenLayoutSignalServiceID

kUpdateDocWindowStateCmdBoss kUpdateDocumentUIStateCmdBoss

Page 38: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideUser Interface APIs

38

IDocumentPresentation* frontmostDocPresentation = Utils<IDocumentUIUtils>()->GetFrontPresentationForDocument(document);

Document-window list iteration

The document presentation list IPresentationList replaces the document window list IWin-dowList, used to aggregated on kDocBoss.CS3:InterfacePtr<IWindowList> winList(document, UseDefaultIID());if (winList && winList.WindowCount() > 0){ for (int32 i = 0; i <= winList.WindowCount(); i++) { InterfacePtr<IControlView> containerView(winList->GetNthWindow(i), UseDefaultIID()); ...

CS4:InterfacePtr<IPresentationList> presList(document, UseDefaultIID());if (presList && presList.size() > 0){ for (IPresentationList::iterator iter = presList.begin(); iter != presList.end(); ++iter) { InterfacePtr<IControlView> containerView(*iter, UseDefaultIID()); ...

Iterating all layout windows in front-to-back order

With multiple panes, multiple tab groups, and multiple docs per group, what “front to back”means gets confusing. By using IDocumentUIUtils::FindPresentationsForDocument() with the“refer” criteria, you can get some semblance of front-to-back ordering. You will get the activedocument first, then the front-most documents in tab groups (in no particular order), followedby the remaining documents (not the front document in their tab group). The following showsan example:PresentationSequence plist;FindPresentation_Criteria require = nil; // no requirement = all presentationsFindPresentation_PreferCriteria prefer;prefer.push_back(FindPresCriteria::is_active);prefer.push_back(FindPresCriteria::is_activeincontext);Utils<IDocumentUIUtils>()->FindPresentationsForDocument(nil, plist, require, prefer);if (!plist.empty()){

for (PresentationSequence::iterator iter = plist.begin(); iter != plist.end(); ++iter)

{// do something with presentation here:IDocumentPresentation* pres =_*iter;...}

}

Page 39: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 39

Adobe InDesign CS4 Porting GuideGeneral Changes

Document-subject-window list notification

When a document presentation is opened or closed, the IID_IPRESENTATIONLIST interfacewith kPresentationOpenedMessage and kPresentationClosedMessage messages is broadcast.This replaces the IID_IWINDOWLIST interface with kWindowAddedMessage and kWindow-RemovedMessage messages used in CS3.

General Changes

This section lists some of the changes we recommend you make to your existing CS3 projectbefore you start working on specific porting tasks.

SDK folder structure

Update include paths

There was some reorganization of the SDK’s source folder for CS4. Specifically, the widgetbinand publiclib folders were moved from /source/public/components/ to /source/public/libs/. Asa result, you must update your plug-in’s project configuration files. Simply modify the includepaths to use the new /source/public/libs/ folder.If your plug-in uses the configuration files supplied in the SDK, you need to make sure you areusing CS4 config files. On Windows, there are two config files: SDKCPPOptions.rsp andSDKODFRCOptions.rsp. To update to the CS4 Windows config files, no action is necessary, astheir names have not changed. On Mac OS, the config file is plugin.sdk.xcconfig. On Mac OS,the config file name has changed from plugin.xcconfig to plugin.sdk.xcconfig.To update your plug-in’s XCode project on Mac OS, follow these steps:

1. Add plugin.sdk.xcconfig from <SDK>/build/mac/prj to the project's xcconfig group.

2. Remove plugin.xcconfig from the project's xcconfig group or from wherever you originallyadded plugin.xcconfig.

3. Click on the project under “Group & Files” to select it, then click Info, and select the Buildtab. In the “Based on:” pop up, select plugin.sdk

MLocaleIds.h and WLocaleIds.h

In CS4, the public, platform-specific, locale-identifier header files, WLocaleIds.h and MLoca-leIds.h, are deprecated and consolidated into a single header file, PMLocaleIds.h. No sourcecode should include the platform-specific headers. Doing so now generates a compiler errornotifying the user to include the proper PMLocaleIds.h header.This was done to ensure that both platforms (Windows and Mac OS) share the same values forlocale identifiers; previously, they did not.

Page 40: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuideGeneral Changes

40

Replace gSession with GetExecutionContextSession()

You should do a global search and replace gSession with GetExecutionContextSession().Chances are you are using gSession in some of your code. For more information about thegSession change, see “gSession Removed” on page 35.

Bring resource definitions up-to-date

There are a few resource-declaration changes to some often used resources. Table 7 summa-rizes the changes. You should modify your .fr file if you use one of the resources in the table.TABLE 7 ODFRC resource change summary

Widget interface orresource with newdefinition

Changes Widgets affected Action

StaticTextAttributes A new integer was added at the end to indicate if Ampersands should be converted to underline character. See “IStaticTextAttributes” on page 43.

StaticTextWidget, StaticTextWidgetWithAction, FittedStaticTextWidget, StaticMultiLineTextWidget, InLineEditBaseWidget,

Add a new “convert ampersands” attribute (either kTrue, or kFalse) in the StaticTextAttributes portion of every affected widgets and their derivatives.

KitViewData The constant used to represent the view resizable attribute has changed.

KitPanelWidget, ErasableKitPanelWidget, DetailKitPanelWidget.

Change the integer that represents the view’s resizable attribute from notResizable to kNotResizable and from isResizable to kIsResizable.

KitList and PanelList

The constant used to represent the view resizable attribute has changed.

Change the integer that represents the view’s resizable attribute from notResizable to kNotResizable and from isResizable to kIsResizable.

Page 41: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 41

Adobe InDesign CS4 Porting GuideGeneral Changes

PMString constructor change

In CS4, several PMString API were removed. The one you most likely will run into while port-ing is the removal of the translate parameter to the constructor, as detailed below. For moredetail about the changes to PMString, see “PMString” on page 45.CS3 constructor:PMString(ConstCString string, PMString::StringEncoding encoding,

TranslationSpecifier translate = kNeedsTranslate);

CS4 constructor:PMString(ConstCString string, PMString::StringEncoding encoding);

For most cases in CS3, you probably created a PMString object like this:PMString someString("SomeString", -1, PMString::kNoTranslate);

You can port it to CS4 using:PMString someString("Root", PMString::kUnknownEncoding);

Replace IScriptEventData::SetReturnData

The APIs in IScriptEventData related to return data were modified to allow access to the errorcode for every script request. Part of this change involves replacing IScriptEventData::SetRe-turnData with IScriptEventData::AppendReturnData. For details, see “IScriptEventData” onpage 28.

StyleGroupDropDownListWidget

ActionIDData and CControlViewObservers were added to the definition of StyleGroupDropDownListWidget.

Add an ActionID of an extra menu item to add to the bottom of this style drop-down list. Add kInvalidActionID if there is no extra menu item. The list of observers to attach when showing this style widget typically includes IID_IOBSERVER, and also IID_ISTYLEGROUPOBSERVER when ActionIDData contains a non-kInvalidActionID value. This also could also be empty.

Widget interface orresource with newdefinition

Changes Widgets affected Action

Page 42: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

42

Utility APIs are accessed only through kUtilsBoss

This is more of a clean-up change, since most utilities were like this since the prior release;however, the old way of accessing a utility method directly will not work any more. If you werecalling a utility method like this:SomeUtils::foo();

You should now call it through the Utils template:Utils<ISomeUtils>()->foo();

This also means you need to change your header include for the utility from:include "SomeUtils.h"

to:#include "ISomeUtils.h"

One implication of this change is that the often used inline, GetFrontDocument(), which isdefined in LayoutUIUtils.h, is no longer available Use Utils<ILayoutUIUtils>()->GetFront-Document() instead.PathUtils.h, PageItemUtils.h, and EncodingUtils.h are utilities used in the SDK. To work inCS4, they needed to be ported using the above strategy.

XCode Warning

If you declare a variable with the same name more than once in the same scope, Xcode now willwarn: warning: declaration of 'myVar' shadows a member of 'this'. Rename the variable, or re-useit if possible.

Porting Recipes

This section describes what changes are required to client code as a result of changes in theInDesign CS4 API. If your code uses an affected API, follow these procedures to change yourcode as required.

IDFile

The following APIs were removed from IDFile:CString GrabCString();ConstCString GrabCString() const;WString GrabWString();

For CS4, you can get a CString for the file’s path using this code:myIDFile.GetString().GetCString();

For CS4, you can get a WString for the file’s path using this code:

Page 43: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 43

Adobe InDesign CS4 Porting GuidePorting Recipes

myIDFile.GetString().GrabUTF16Buffer(nil);

IImportManager

IImportManager::DoImportDialog() now requires the caller to supply a dialog for import. Inmost cases (for regular file import), unless you are handling a specific type of resource forimport, you can provide the default file dialog in this manner:InterfacePtr<IImportCore> iImportCore(importManager,IID_IIMPORTCORE);InterfacePtr<IPlaceDialog> iPlaceDialog(iImportCore->QueryPlaceFileDialog());

Note that importManager used above can be obtained through IK2ServiceRegistry, with the IDkImportManagerService.The IImportManager::DoImportDialog() returns a list of URIs for import, as opposed to Sys-FileList. URI uniquely identifies a resource for import. If you know the URI represents a file,and SysFileList is required for your situation, you can use IURIUtils::URIListToSysFileList toconvert the URIList to SysFileList.

IInCopyBridgeCmdSuite

For CS4, the IInCopyBridgeCmdSuite public interface was removed and replaced with a new,ILiveEditFacade public interface. Rather than creating your own instance of the IInCopy-BridgeCmdSuite, you can now use the ILiveEditFacade to check in/out. For an example, see theincopyfileactions sample (InCopyDocUtils.cpp).

ISnippetExport

The ISnippetExport interface was modified to accommodate IDML export. The major changeis that the ExportToStream methods were changed to ExportXMLElements and ExportPage-Items. For details, see ISnippetExport.h.

IStaticTextAttributes

The static-text widget was modified to allow/disallow automatic conversion of ampersands tounderlines. Two new, pure virtual methods were added to the IStaticTextAttributes interface(see IStaticTextAttributes.h):virtual void SetConvertAmpersandsToUnderline(bool16 convertAmpersands) = 0;virtual bool16 GetConvertAmpersandsToUnderline() = 0;

A new field, fConvertAmpersandsToUnderline, was added to the StaticTextAttributes type(Widgets.fh):type StaticTextAttributes : Interface (IID = IID_ISTATICTEXTATTRIBUTES){

integer; // fAlignmentinteger; // ellipsize ...integer; // fConvertAmpersandsToUnderline

};

Page 44: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

44

To port existing StaticTextWidgets, add the new fConvertAmpersandsToUnderline field to thestatic text-resource definition in your .fr file. Use kTrue to convert ampersands to underlines(old default), or use kFalse to not convert. Here is an example:StaticTextWidget(

// CControlView propertieskBscL10NStaticTextWidgetID, // widget ID...

// StaticTextAttributes propertieskAlignLeft, // AlignmentkDontEllipsize, // Ellipsize stylekTrue, // ==> ADDED for CS4 to convert ampersands...

)

IStyleGroupListControlData

A misspelled method name was corrected in the IStyleGroupListControlData interface. Theold method name (with “Child” misspelled) was:virtual void AppendChlidTypeIID(const PMIID& childType) = 0;

This was changed to:virtual void AppendChildTypeIID(const PMIID& childType) = 0;

The API functionality remains the same. To use the new API, simply change the spelling to thenew version.

ITextColumnSizer

The APIs for navigating MultiColumnTextFrame were changed. Of note is that the ITextCol-umnSizer class no longer has a method named GetLastFrameIndex. To check that a frame thatis being linked from is not the last one in its frame list, use IMultiColumnTextFrame::GetIs-LastMCF instead of comparing ItextColumnSizer::GetLastFrameIndex() to the total framecount.

kInvalidUIDRef

kInvalidUIDRef is now defined in UIDRef.h. Prior versions of the InDesign API allowed sepa-rate definitions of this constant; for example:#ifndef kInvalidUIDRef

#define kInvalidUIDRef UIDRef(nil, kInvalidUID)#endif

To avoid the possibility of getting “multiply defined” compile errors for kInvalidUIDRef,replace your definition with:#include "UIDRef.h".

Page 45: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 45

Adobe InDesign CS4 Porting GuidePorting Recipes

PMString

Many APIs are continuing to move from PMString to WideString. To port your code to useWideString, it is common to simply create a WideString by passing the PMString to the con-structor:PMString myOldString;SomeAPI(WideString(myOldString));

Also, some clean-up work was done to PMString. This involved removing the APIs listedbelow.

The constructor using translation parameter no longer uses a translation specifier. For CS4,remove the TranslationSpecificer parameter if it is kNoTranslate. If it is kAutoTranslate,remove encoding and pass kTranslateDuringCall. If it is kNeedsTranslate (keep in mindthat if nothing was passed, this was the default), remove kNeedsTranslate and the encodingspecifier.

CS3 API:PMString(ConstCString string, PMString::StringEncoding encoding,

TranslationSpecifier translate = kNeedsTranslate);

CS4 API:PMString(ConstCString string, PMString::StringEncoding encoding);

CS3 usage:PMString someString("SomeString", -1, PMString::kNoTranslate);

CS4 usage:PMString someString("Root", PMString::kUnknownEncoding);

Translation enums — kNeedsTranslate, kAutoTranslate, and kNoTranslate were removed. InCS3, these enums were passed to the translation constructor to define how to translate thestring. This enums are no longer needed in CS4.

To replace kNeedsTranslate:Use constructor without encoding, or call SetKey.

To replace kAutoTranslate:Use constructor without encoding and pass kTranslateDuringCall.

To replace kNoTranslate: Remove if using constructor. As long as encoding is passed to the constructor, the string is marked as no translate. If calling SetCString, pass encoding and string will be set to no translate.

Constructor specifying a character buffer, size, and encoding — The encoding parameter wasremoved. In CS4, use encoding only when you get the string as a platform string. At thattime, you can specify encoding.

Removed CS3 API:PMString(const UTF16TextChar * string, int32 nDblBytes,

StringEncoding encoding);

CS4 API:PMString(const UTF16TextChar * string, int32 nDblBytes);

Page 46: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

46

Constructor using ConstPString parameter — To port to CS4, use the default constructor,then use SetPString to assign the value of the string.

Removed CS3 API:explicit PMString(ConstPString p);

CS3:PString pItsName = (PString) resPtr;PMString itsName(pItsName);

CS4:PMString itsName;PString pItsName = (PString) resPtr;itsName.SetPString (pItsName, PMString::kUnknownEncoding);

GrabPString — When porting, first see if this API is used for a Mac OS API call, then see ifthere is a new version of the Mac OS API that takes a CFString. If not, use GetPString.

Removed CS3 APIs:PString GrabPString(void);ConstPString GrabPString(void) const;

CS3:err = FSMakeFSSpec(tSpec.vRefNum, tSpec.parID, tmpName.GrabPString(),

&fSpec);

CS4:Str255 pstrTmpName;tmpName.GetPString(pstrTmpName, 255);err = FSMakeFSSpec(tSpec.vRefNum, tSpec.parID, pstrTmpName, &fSpec);

GetByteIndexFromCharPos and GetCharPosFromByteIndex — If this is for a Windows APIcall, you might already have a bug. Windows uses the Unicode API, and indexes should becharacter indexes, so you should remove this call and use the CharCounter or indexdirectly. If this is used for a Mac OS API call, see if there is a new one that takes a characterindex.

Removed CS3 APIs:int32 GetByteIndexFromCharPos(CharCounter charIndex) const;CharCounter GetCharPosFromByteIndex(int32 byteIndex) const;

SubWString — Replace calls to SubWString with Substring.Removed CS3 API:PMString* SubWString(int32 pos, int32 count = kMaxInt32) const;

CS4:PMString* Substring(CharCounter pos, CharCo unter count = kMaxInt32) const;

GrabCString — Replace calls to GrabCString with GetCString or GetPlatform-String().c_str().

Removed CS3 APIs:CString GrabCString(void);

CS4 usage:Trace("myTrace(%s)", myPMString.GetPlatformString().c_str());

Page 47: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 47

Adobe InDesign CS4 Porting GuidePorting Recipes

Shrink — Replace calls to Shrink with reserve (inherited from UnicodeSavvyString).Removed CS3 API:void Shrink(bool16 maxshrink = kFalse);

CS4:myPMString.reserve(5);

SetHexChar — Replace calls to SetHexChar with SetXString, passing count = 1.Removed CS3 API:void SetHexChar(const uchar x, PMString::StringEncoding encoding =

kUnknownEncoding);

CS4:convertedString.SetXString((textchar*)&commaTextChar, 1);

Style matching

IStyleSyncService and ISelectivelyLoadStyleCmdData were modified to allow you to set andget the style-matching strategy. A new enum, StyleMatchingStrategyEnum, was added to Style-ClashResolutionTypes, and two pure virtual methods were added to IStyleSyncService and ISe-lectivelyLoadStyleCmdData.virtual void SetStyleMatchingStrategy(

StyleClashResolutionTypes::StyleMatchingStrategyEnum styleMatchingStrategy)=0;virtual StyleClashResolutionTypes::StyleMatchingStrategyEnum

GetStyleMatchingStrategy() const = 0;

To add the style-matching strategy code to your implementation of IStyleSyncService or ISelec-tivelyLoadStyleCmdData, follow these steps:

1. Add a private data member (fUseStyleMatchingStrategy) to store a StyleClashResolution-Types::StyleMatchingStrategyEnum.

2. Add SetStyleMatchingStrategy(), and set fUseStyleMatchingStrategy to the parameter value.

3. Add GetStyleMatchingStrategy(), and return fUseStyleMatchingStrategy.

4. Initialize fUseStyleMatchingStrategy in your constructor.

For example:class MyStyleSyncService : public CPMUnknown<IStyleSyncService>{public:

MyStyleSyncService(IPMUnknown* boss) :CPMUnknown<IStyleSyncService>(boss),fUseStyleMatchingStrategy(StyleClashResolutionTypes::kMatchStyleFullPath)

{}...virtual void SetStyleMatchingStrategy(

StyleClashResolutionTypes::StyleMatchingStrategyEnum styleMatchingStrategy){ fUseStyleMatchingStrategy = styleMatchingStrategy; }

virtual StyleClashResolutionTypes::StyleMatchingStrategyEnumGetStyleMatchingStrategy () const

Page 48: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

48

{ return fUseStyleMatchingStrategy;}

private:StyleClashResolutionTypes::StyleMatchingStrategyEnum

fUseStyleMatchingStrategy;};

XML parser

The underlying XML parser library was changed from AXEParser to a new parser called Expat.This new parser also uses SAX (Simple API for XML), so no changes to our parser interface,ISAXContentHandler, were required; however, some parser options on ISAXParserOptions areno longer available. The following methods in ISAXParserOptions were removed:

IsNamespacePrefixesFeatureEnabled() and SetNamespacePrefixesFeature() — This allowedusers to decide whether namespace prefixes are preserved. In Expat, namespace prefixesalways are preserved.IsValidationFeatureEnabled() and SetValidationFeature() — this allowed users to validatethe XML file against a DTD. Expat does not have validation functionality. A workaround isto import the XML file into InDesign, then use the DTD validation support (IXMLValida-tor) in InDesign.IsAutoValidationFeatureEnabled() and SetAutoValidationFeature() — When both the vali-dation option and this option were enabled, the parser validated the document if it con-tained a DTD. Again, a workaround is to import the XML file into InDesign, then use theDTD validation support (IXMLValidator) in InDesign.IsWarnCaseXMLDECLFeatureEnabled() and SetWarnCaseXMLDECLFeature() — Whenthis was enabled, an incorrect case in the XML declaration was treated as a warning but notan error. This option was a workaround for XML files that contained an incorrect case inthe XML declaration. These files are not well formed XML files, and they should no longerbe used.IsWarnCaseDTDFeatureEnabled() and SetWarnCaseDTDFeature() — Like the previousoption, this allowed the parser to treat an incorrect case in the DOCTYPE declaration as awarning. Again, XML files that are not well formed should be fixed or not used.IsValidateDTDEnabled() and SetValidateDTD() — This allowed users to check the syntax ofthe DTD in an XML file. A workaround is to import the XML file into InDesign or load theDTD using XMLLoadDTDCmd.

Custom story thread

If you implement a custom story thread and owned item for a feature like the HiddenText sam-ple, there are some new methods in ITextStoryThread and ITextParcelListData that you need tobe aware of:

ITextStoryThread::QueryParent should return the IScript object that is considered to be theparent of any TextObject in the thread. If your story thread is not a host to a generic, text-script object like words or lines, you do not need to return anything; otherwise, you should

Page 49: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 49

Adobe InDesign CS4 Porting GuidePorting Recipes

query the IScript interface that may be aggregated on the same boss as the ITextStoryTh-read, and return the interface pointer of the IScript.ITextStoryThread::GetAdjustedTextStart should return the adjusted thread start/end for thespecified scripting context. Some implementations do not support making the full range ofthe StoryThread available to scripting and this method allows them to clip off the beginningand/or end of the thread. This adjusted range will limit the natural extensions that takeplace for scripting objects like words, lines, and paragraphs, that occur beyond a subrangeof the thread. For most of the implementation, you will be passed in an int32* that is theadjusted span. Pass this into ITextStoryThread::GetTextStart to get the index of the adjustedtext start.ITextParcelListData::GetIsRightToLeft should be true or false, indicating (especially at theend of a line) whether to attach the caret to the right side of the left character or the left sideof the right character.

kHyperlinkTextMarkerBoss and kHyperlinkTextSourceEndMarkerBoss deprecated

These two bosses are no longer valid, owned item bosses, as a result of the re-write of thehyperlink feature. We no longer track hyperlink text sources by marker pairs; instead, they aretracked by a new strand, TextRangeListStrand. The only marker we need now is for the hyper-linktext destination, which is represented as kHyperlinkTextDestinationMarkerBoss. Forhyperlink text sources, if you have a text index (range) and want to find out if the index (range)is contained in a hyperlink text-source range, you may call IHyperlinkUtils::IsRangeCon-tainedByAHyperlink. If you want to find out whether a text range contains any hyperlink textsources, use IHyperlinkUtils::GetRangesContainedHyperlinks.

ISnippetExportSuite

ISnippetExportSuite::DoExport now requires you to pass in an INXOptions, An INXOptionscan be initialized with an INXStyle, which is defined in INXOptions.h. Also, there is anIID_ISNIPPETPREFERENCES on the session workspace, which indicates whether the INX-Options should be in traditional or expanded style as a fallback option. For an example of theuse of IID_ISNIPPETPREFERENCES, see SnpManipulateXMLSelection::ExportXMLSnippet-FromSelection.

Miscellaneous changes

IPageItemUtils::QuerySpread no longer exists. Use IPasteboardUtils::QuerySpread instead.Text::GetParcelContentBounds was moved to ITextUtils.IXMLTagList::GetTag now asks for a WideString instead of PMString. Wrap the oldPMString in a WideString.

Page 50: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

50

Page 51: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting Guide 51

Adobe InDesign CS4 Porting GuidePorting Recipes

Page 52: Adobe InDesign CS4 Porting Guide

Adobe InDesign CS4 Porting GuidePorting Recipes

52