home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc™ Source Code / Storage / LinkDlgs.cpp < prev    next >
Encoding:
Text File  |  1996-08-28  |  75.7 KB  |  2,475 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        LinkDlgs.cpp
  3.  
  4.     Contains:    implementation of the Paste As and Link Info dialogs
  5.  
  6.     Owned by:    Craig Carper
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.          <7>      6/7/96    eeh        T10017: function ptrs must be extern C
  13.          <6>      6/7/96    eeh        T10017: return CFM errors
  14.          <5>      6/7/96    eeh        T10017: call Dialogs lib to put up dialogs
  15.          <4>      6/5/96    EL        1355529: Use menu item count to determine
  16.                                     the translation menu item.
  17.          <3>     5/30/96    CC        1299865: ShowPasteAsDialog: When embedding,
  18.                                     if the kind popup is changed, keep the same
  19.                                     editor unless it doesn't support the new
  20.                                     kind.
  21.          <2>     1/12/96    CC        1301094: Hide static text obscuring Editor
  22.                                     popup.
  23.                                     1298118: Disable manual/automatic buttons
  24.                                     if Paste with Link unchecked.
  25.         <58>    10/16/95    CC        GM 1292157: Moved TranslateValueTypes,
  26.                                     AddTranslationKindToMenu,
  27.                                     GetMenuStringForKind,
  28.                                     DefaultMenuStringForKind,
  29.                                     StringPtrFromStrHandle to InfoUtil.cpp.
  30.         <57>    10/10/95    DM        1285040: GM: PasteAs into part viewed in
  31.                                     window hangs (dont assume persistent frame
  32.                                     in ShowPasteAsDialog())
  33.         <56>     10/3/95    eeh        1284995: new default param to
  34.                                     SetDialogTextStyle
  35.         <55>     10/3/95    TJ        Changes done by RefBall Team
  36.         <54>     9/12/95    DM        1280020 FB1 part trans dlg mem leaks
  37.         <53>      9/8/95    TÇ        1281096 FB2:Many constants in ODTypesB
  38.                                     without kOD prefix!
  39.         <52>      9/1/95    CC        1279449: Initialize dlg to null & use
  40.                                     ODVolatile.
  41.                                     ShowLinkSourceInfo,
  42.                                     ShowLinkDestinationInfo: Use ODVolatile.
  43.         <51>     8/29/95    DM        1221778, 1276165: [ShowLinkUpdateAlert]
  44.                                     drop count arg in ShowLinkUpdateAlert
  45.         <50>     8/26/95    TÇ        1274606 FB2: Patching Remarks
  46.         <49>     8/25/95    eeh        1230007: new param to DrawITextInDlogBox
  47.         <48>     8/23/95    CC        1278378: ShowPasteAsDialog behaves
  48.                                     incorrectly on switch from Embed to Merge.
  49.                                     1242581: ShowPasteAsDialog should respect
  50.                                     preferred editor.
  51.                                     1278840: ShowPasteAsDialog should respect
  52.                                     preferred kind.
  53.         <47>     8/15/95    CC        1276520: Adapted to changes to
  54.                                     ShowTranslateDialog.
  55.         <46>     8/12/95    TÇ        1276812 Need to use TempObjs and TempRefs
  56.                                     for exception safety and to avoid TRY
  57.                                     blocks, 1276807 Opt./Bug: use StdTypIO
  58.                                     routines for portable streaming & smaller
  59.                                     footprint
  60.         <45>     7/28/95    CC        1242576: Removed obsolete Others dialog
  61.                                     code.
  62.         <44>     7/24/95    CC        1236616: Use CreateTypeList factory method.
  63.         <43>     7/18/95    eeh        1222282: move constants to DlogUtil.h
  64.         <42>     6/21/95    CC        1260937: BB: ODTypeListIterator must return
  65.                                     copies of ODType values.
  66.         <41>     6/16/95    CC        1258538: ShowPasteAsDialog: Release kind
  67.                                     and editor menu resources and delete the
  68.                                     menu; also check GetMenu result.
  69.                                     1257141: TranslateValueTypes: Changed
  70.                                     translateFromList parameter to
  71.                                     OrderedCollection. Added
  72.                                     GetIndexedElement() function.
  73.                                     SetDateTimeStrings: Added
  74.                                     CUsingLibraryResources.
  75.                                     DefaultMenuStringForKind: Added
  76.                                     CUsingLibraryResources.
  77.         <40>      6/7/95    jpa        Fixed EndUsingLibRsrcs calls. [1255369]
  78.         <39>      6/7/95    CC        1236299:  Wrap individual calls with using
  79.                                     library resources calls.
  80.         <38>      6/2/95    CC        1255476: ShowPasteAsDialog: Release object
  81.                                     returned by ODFrame::AcquirePart().
  82.         <37>     5/30/95    CG        #1251234 Extraneous items in Paste As kind
  83.                                     popup.
  84.         <36>     5/26/95    VL        1251403: Multithreading naming support.
  85.         <35>     5/18/95    CG        #1249263 BB: BndNSUtl.cpp does not compile
  86.                                     standalone.
  87.         <34>      5/1/95    CG        #1240845    BB: Kinds popups need to include
  88.                                     all kinds that an editor can edit.
  89.         <33>     4/29/95    TÇ        1243222 BB: New documents from stationery
  90.                                     should have create/modinfo reset.
  91.         <32>     4/27/95    CC        1243348: Moved ShowAlert into
  92.                                     DlogUtils.cpp.
  93.                                     ShowLinkInfo: Don't alert user on break
  94.                                     link (problems with nested calls use
  95.                                     library resources).
  96.         <31>     4/25/95    CC        1242555: TranslateValueTypes: $5 entered as
  97.                                     bug 1242571.
  98.                                     1242555: ShowPasteAsDialog: $5 entered as
  99.                                     bug 1242581.
  100.                                     1242555:  OthersDlgFilterProc: Removed
  101.                                     obsolete $5 comment.
  102.         <30>     4/14/95    TÇ        #1235279 BB: InfoUtil & StdTypIO functions
  103.                                     should take Environment* and SU* when
  104.                                     possible
  105.         <29>     3/28/95    CC        1229640: Added LinkInfoFilterProc and
  106.                                     PasteAsFilterProc.
  107.                                     Added DeavtivateModalDialog routine.
  108.                                     DrawKindName and DrawEditorName calls
  109.                                     DrawITextInDlogBox utility.
  110.         <28>     3/27/95    CC        1229640: Use ODTranslation::
  111.                                     ShowTranslateDialog() in ShowPasteAsDialog.
  112.                                     Show editor in Paste As dialog.
  113.         <27>     3/22/95    CC        1230322: Changed parameter to
  114.                                     ShowPasteAsDialog(); removed
  115.                                     DefaultMergeSetting().
  116.         <26>     3/17/95    CC        1203315: Added DefaultMergeSetting(),
  117.                                     EnablePasteAsOkButton() and
  118.                                     DrawDeactivePICTItem().
  119.                                     Removed InitialMergeSetting() &
  120.                                     DrawDeactiveDialogItem().
  121.                                     Fix to PrepareToDrawGray to set the pen
  122.                                     pattern to gray if no gray color is
  123.                                     available.
  124.         <25>      3/9/95    CC        1221471: Added changesAllowed parameter to
  125.                                     ShowLinkDestinationInfo() and
  126.                                     ShowLinkSourceInfo().
  127.         <24>      3/9/95    CC        1220342: DrawIntlStaticText: Save and
  128.                                     restore font; don't change font if dialog
  129.                                     font is same script as intl text.
  130.                                     defined ODDisposeRoutineDescriptor and
  131.                                     ODDisposeDlg macros.
  132.                                     MakeOthersList(): don't set window font and
  133.                                     size; adopt font and size as determined by
  134.                                     'finf' resource.
  135.                                     ShowOthersDialog: removed okButtonEnabled.
  136.                                     Moved DrawDefaultButtonOutline to DlogUtils
  137.                                     and renamed.
  138.         <23>      3/7/95    CC        1226083: Removed SetKindText(); added
  139.                                     DrawIntlStaticText() and gKindName global.
  140.         <22>      3/6/95    jpa        Use dialog utilities (ODGetNewDialog,
  141.                                     ODDialogFilterProc) to make dlogs movable.
  142.                                     [1218957]
  143.         <21>      3/3/95    CC        1199186 Save and restore the current port
  144.                                     in ShowPasteAsDialog, ShowLinkSourceInfo,
  145.                                     and ShowLinkDestinationInfo.
  146.                                     1223607 Removed link size from info
  147.                                     dialogs;
  148.                                     GetBestKindAndSize->BestContentKind.
  149.                                     1224967 Time updated was incorrect.
  150.                                     1223861 Added ShowLinkStatusAlert().
  151.         <20>     2/24/95    jpa        Use ODNewRgn. [1220810]
  152.         <19>     2/24/95    CC        1220342: GetMenuStringForKind: Return
  153.                                     script code.
  154.                                     1220342: AddTranslationKindToMenu: Set
  155.                                     script code for menu item.
  156.                                     1220339: CreateTranslationStrings: Modified
  157.                                     to build StringWithScriptCodeArrayPtr.
  158.         <18>     2/15/95    CC        Lots of changes:
  159.                                     1194329 UpdateNow button in info dialogs is
  160.                                     enabled only if "Manually" is selected and
  161.                                     the link (or link destination) needs
  162.                                     updating.
  163.                                     1220318 Added LinkDialogFilter.
  164.                                     1220318 ShowLinkInfo -- Use
  165.                                     LinkDialogFilter in call to ModalDialog.
  166.                                     1205033 LinkInfo dialogs should be static
  167.                                     if draft is read-only
  168.                                     1218931 Link Info Dialog changes when draft
  169.                                     is read-only
  170.                                     1196831 Show link size in K bytes if 1K or
  171.                                     larger.
  172.                                     1220327 Data Interchange dialogs need to
  173.                                     use filter procs.
  174.                                     1153942    Changes to Destination Link Info
  175.                                     dialog
  176.         <17>      2/7/95    CC        1211295: Added GetOriginalDraft() and
  177.                                     SUClonedFromDraft().  ShowPasteAsDialog()
  178.                                     takes an isMove parameter.
  179.                                     1216124: ShowPasteAsDialog calls
  180.                                     ODWindowState::DeactivateFrontWindow() and
  181.                                     ActivateFrontWindow().
  182.         <16>     1/25/95    jpa        New ODIText format [1212619]
  183.         <15>     1/25/95    CC        1213198 ShowOthersDialog: Call LDispose
  184.                                     BEFORE disposing of the LDEF.
  185.                                     1213954 Initialize editor field of
  186.                                     ODPasteAsResult to kODNoEditor.
  187.         <14>     1/12/95    jpa        Don't use obsolete Toolbox names [1211211]
  188.         <13>     1/10/95    CC        1153930: Added translation dialog;
  189.                                     implemented new technique for dimming
  190.                                     inactive items in Paste As dialog.
  191.         <12>    11/17/94    CG        #1187128: Moved GetDestinationKindsList to
  192.                                     TransUtl.cpp to be shared with Part Info
  193.                                     and NoPart.
  194.         <11>    10/31/94    CG        #1147225: Moved ContentValueTypes to
  195.                                     InfoUtil.cpp.
  196.         <10>    10/27/94    CG        #1147225: Moved AddTypesToMenu to
  197.                                     InfoUtil.cpp.
  198.          <9>     10/7/94    CC        1160232 - Added calls to
  199.                                     EndUsingLibraryResources().
  200.          <8>     10/4/94    CC        1190299 - Use utility fcns in InfoUtil.h
  201.                                     and DlogUtil.h.
  202.          <7>     9/20/94    CC        1160232 - Added ShowLinkUpdateAlert()
  203.                                     1153930 - Added TranslateValueTypes() and
  204.                                     other mods to add translation choices to
  205.                                     Paste As dialog.
  206.          <6>     8/10/94    CC        1179943 - LinkInfo dialog functions take
  207.                                     ODBaseLink and ODBaseLinkSource parameters.
  208.          <5>      8/2/94    CC        #1178169 - ShowPasteAsDialog() takes
  209.                                     ODFacet* instead of ODFrame*.
  210.          <4>     7/31/94    CC        ShowLinkDestinationInfo - fix to display
  211.                                     dialog correctly.
  212.          <3>     7/27/94    CC        Allocate kindList (a SOM object) on the
  213.                                     heap, not the stack.
  214.          <2>      7/5/94    CC        Added typecasts of pascal strings for PPCC
  215.                                     compiler.
  216.          <1>     6/24/94    CC        first checked in
  217.          <0>     6/13/94    SV        SOMverted
  218.  
  219.         ------------------- CC ---- Converted to SOM
  220.  
  221.         <14>      6/1/94    CG        Changed to use new public binding object.
  222.         <13>     5/11/94    TÇ        #1162405 Removed explicit ASLM dependency
  223.                                     for using resources (missed a couple)
  224.         <12>     5/10/94    TÇ        #1162405 Removed explicit ASLM dependency
  225.                                     for using resources
  226.         <11>      5/9/94    MB        #1162181: Changes necessary to install MMM.
  227.         <10>      4/6/94    CC        XMPTypeInfo: Changed field "creationDate"
  228.                                     to "creationTime" and "modificationDate" to
  229.                                     "changeTime". (1154722)
  230.          <9>      4/4/94    CC        Convert from using XMPTypeSet to
  231.                                     XMPTypeList (1153046).
  232.          <8>      4/1/94    TÇ        #1154941: Get OpenDoc source to actually
  233.                                     compile for PowerPC
  234.          <7>     3/28/94    CG        1153547: Renamed XMPSessn.h to XMPSessM.h.
  235.          <6>     3/25/94    JA        Added missing #include (1147588)
  236.          <5>     3/25/94    eeh        bug #1153053: Changes for PPC nativity.
  237.          <4>     3/24/94    CC        ShowLinkSourceInfo() takes XMPUpdateID
  238.                                     parameter; XMPPasteAsResult specifies
  239.                                     original kind when selected kind is a
  240.                                     translation (1153068).
  241.          <3>     3/17/94    CC        Added ShowLinkSourceInfo() and
  242.                                     ShowLinkDestinationInfo(). (1151329)
  243.          <1>     3/14/94    CC        first checked in
  244.          <0>     3/14/94    CC        Create ShowPasteAsDialog (1144253).
  245.  
  246.     In Progress:
  247.         
  248. */
  249. #define _USE_DIALOGS_LIB_
  250.  
  251. #ifndef _PLFMDEF_
  252. #include <plfmdef.h>
  253. #endif
  254.  
  255. #ifndef _LINKDLGS_
  256. #include <LinkDlgs.h>
  257. #endif
  258.  
  259. #ifndef _INFOUTIL_
  260. #include <InfoUtil.h>
  261. #endif
  262.  
  263. #ifndef _DLOGUTIL_
  264. #include <DlogUtil.h>
  265. #endif
  266.  
  267. #ifndef _EXCEPT_
  268. #include <Except.h>
  269. #endif
  270.  
  271. #ifndef _LINKDEFS_
  272. #include <LinkDefs.h>
  273. #endif
  274.  
  275. #ifndef _USERSRCM_
  276. #include <UseRsrcM.h>
  277. #endif
  278.  
  279. #ifndef SOM_Module_OpenDoc_StdProps_defined
  280. #include <StdProps.xh>
  281. #endif
  282.  
  283. #ifndef SOM_Module_OpenDoc_Foci_defined
  284. #include <Foci.xh>
  285. #endif
  286.  
  287. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  288. #include <StdTypes.xh>
  289. #endif
  290.  
  291. #ifndef SOM_ODTypeList_xh
  292. #include <TypeList.xh>
  293. #endif
  294.  
  295. #ifndef SOM_ODTypeListIterator_xh
  296. #include <TypLsItr.xh>
  297. #endif
  298.  
  299. #ifndef SOM_ODStorageUnit_xh
  300. #include <StorageU.xh>
  301. #endif
  302.  
  303. #ifndef SOM_ODPart_xh
  304. #include <Part.xh>
  305. #endif
  306.  
  307. #ifndef SOM_ODFrame_xh
  308. #include <Frame.xh>
  309. #endif
  310.  
  311. #ifndef SOM_ODFacet_xh
  312. #include <Facet.xh>
  313. #endif
  314.  
  315. #ifndef SOM_ODBaseLink_xh
  316. #include <LinkB.xh>
  317. #endif
  318.  
  319. #ifndef SOM_ODBaseLinkSource_xh
  320. #include <LinkSrcB.xh>
  321. #endif
  322.  
  323. #ifndef SOM_ODBinding_xh
  324. #include <ODBindng.xh>
  325. #endif
  326.  
  327. #ifndef SOM_ODTranslation_xh
  328. #include <Translt.xh>
  329. #endif
  330.  
  331. #ifndef SOM_ODWindowState_xh
  332. #include <WinStat.xh>
  333. #endif
  334.  
  335. #ifndef _BINDNGH_
  336. #include <BindngH.h>
  337. #endif
  338.  
  339. #ifndef _BNDNSUTL_
  340. #include <BndNSUtl.h>
  341. #endif
  342.  
  343. #ifndef SOM_ODSession_xh
  344. #include <ODSessn.xh>
  345. #endif
  346.  
  347. #ifndef SOM_ODArbitrator_xh
  348. #include <Arbitrat.xh>
  349. #endif
  350.  
  351. #ifndef SOM_ODDispatcher_xh
  352. #include <Disptch.xh>
  353. #endif
  354.  
  355. #ifndef _ODUTILS_
  356. #include <ODUtils.h>
  357. #endif
  358.  
  359. #ifndef _PASCLSTR_
  360. #include <PasclStr.h>
  361. #endif
  362.  
  363. #ifndef _ISOSTR_
  364. #include <ISOStr.h>
  365. #endif
  366.  
  367. #ifndef _DOCUTILS_
  368. #include <DocUtils.h>
  369. #endif
  370.  
  371. #ifndef _ODMEMORY_
  372. #include <ODMemory.h>
  373. #endif
  374.  
  375. #ifdef __SC__
  376. #ifndef __PACKAGES__
  377. #include <Packages.h>
  378. #endif
  379. #else
  380. #ifndef __TEXTUTILS__
  381. #include <TextUtils.h>
  382. #endif
  383. #endif
  384.  
  385. #ifndef __STRING__
  386. #include <String.h>
  387. #endif
  388.  
  389. #ifndef __GESTALTEQU__
  390. #include <GestaltEqu.h>
  391. #endif
  392.  
  393. #ifndef __DIALOGS__
  394. #include <Dialogs.h>
  395. #endif
  396.  
  397. #ifndef __TOOLUTILS__
  398. #include <ToolUtils.h>
  399. #endif
  400.  
  401. #ifndef __FONTS__
  402. #include <Fonts.h>
  403. #endif
  404.  
  405. #ifndef __CONTROLS__
  406. #include <Controls.h>
  407. #endif
  408.  
  409. #ifndef __RESOURCES__
  410. #include <Resources.h>
  411. #endif
  412.  
  413. #ifndef _TRANSUTL_
  414. #include <TransUtl.h>
  415. #endif
  416.  
  417. #ifndef __LISTS__
  418. #include <Lists.h>
  419. #endif
  420.  
  421. #ifndef __PALETTES__
  422. #include <Palettes.h>
  423. #endif
  424.  
  425. #ifndef _STORUTIL_
  426. #include <StorUtil.h>
  427. #endif
  428.  
  429. #ifndef _EDITRSET_
  430. #include <EditrSet.h>
  431. #endif
  432.  
  433. #ifndef _STDTYPIO_
  434. #include <StdTypIO.h>
  435. #endif
  436.  
  437. #ifndef _TEMPOBJ_
  438. #include <TempObj.h>
  439. #endif
  440.  
  441. #ifndef _ORDCOLL_
  442. #include "OrdColl.h"
  443. #endif
  444.  
  445. #ifndef SOM_ODStorageSystem_xh
  446. #include "ODStor.xh"
  447. #endif
  448.  
  449. #pragma segment Info
  450.  
  451. #if ODDebug
  452. #define ODDebugLinkDlgs 0
  453. #else
  454. #define ODDebugLinkDlgs 0
  455. #endif
  456.  
  457. //==============================================================================
  458. // Global variables
  459. //==============================================================================
  460.  
  461. // Use a global to pass the current session to the LinkFilterProc
  462. // Globals are per process, and there is only one session per process.
  463. static ODSession* gSession = kODNULL;
  464.  
  465. #ifdef _USE_DIALOGS_LIB_
  466. OSErr LoadODSharedLibrary( Str63 libName, Str255 entryName,
  467.         CFragConnectionID* connID, void** entryPoint );
  468. void UnloadODSharedLibrary( CFragConnectionID* connID );
  469.  
  470. #ifdef __cplusplus
  471. extern "C" {
  472. #endif
  473. typedef ODError (*SPAD)(
  474.                 ODBoolean                canPasteLink,
  475.                 ODPasteAsMergeSetting    mergeSetting,
  476.                 ODBoolean                isMove,
  477.                 ODStorageUnit*            contentSU,
  478.                 ODFacet*                facet,
  479.                 ODTypeToken                viewType,
  480.                 ODPasteAsResult*        result,
  481.                 ODBoolean*                boolResult);
  482.  
  483. typedef ODError (*SLSI)(
  484.                 ODBaseLinkSource*    linkSource,
  485.                 ODUpdateID            change,
  486.                 ODBoolean            changesAllowed,
  487.                 ODLinkInfoResult*    infoResult,
  488.                 ODBoolean*            result);
  489.  
  490. typedef ODError (*SLDI)(
  491.                 ODBaseLink*            link,
  492.                 ODLinkInfo*         info,
  493.                 ODBoolean            changesAllowed,
  494.                 ODLinkInfoResult*    infoResult,
  495.                 ODBoolean*            result);
  496. #ifdef __cplusplus
  497. }
  498. #endif
  499.  
  500. #else
  501.  
  502. static ODName* gKindName = kODNULL;
  503. static ODName* gEditorName = kODNULL;
  504. static ODName* gEmbeddedEditorName = kODNULL;
  505.  
  506. //==============================================================================
  507. // Constants
  508. //==============================================================================
  509.  
  510. const Boolean kNoDefaultButton = kODFalse;
  511.  
  512. const short kButtonFrameInset = -4;
  513.  
  514. const short kControlInactive = 255;
  515. const short kControlActive = 0;
  516.  
  517. // Constants used in list manager calls
  518. const Boolean kDoDraw = true;
  519. const Boolean kNoGrow = false;
  520. const Boolean kIncludeScrollBar = true;
  521.  
  522. // Key codes
  523. // <eeh> moved to DlogUtil.h
  524. // const char kEnterKey        = 0x03;
  525. // const char kReturnKey        = 0x0D;
  526. // const char kEscapeKey        = 0x1B;
  527. // const char kUpArrowKey        = 0x1E;
  528. // const char kDownArrowKey    = 0x1F;
  529.  
  530. //==============================================================================
  531. // Scalar types
  532. //==============================================================================
  533. typedef char ODHandleState;
  534.  
  535. //==============================================================================
  536. // Function declarations
  537. //==============================================================================
  538. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name);
  539.  
  540. ODStatic void SetDateTimeStrings(
  541.                     ODULong        dateTime,
  542.                     Str255        dateString, 
  543.                     Str255        timeString);
  544.  
  545. ODStatic void InitItemActive(
  546.                     DialogPtr    dlg,
  547.                     short        itemNumber,
  548.                     UserItemUPP    itemUPP,
  549.                     ODBoolean    itemActive);
  550.  
  551. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem);
  552.  
  553. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su);
  554.  
  555. ODStatic void SetControlActive(
  556.                     DialogPtr    dlg,
  557.                     short        itemNumber,
  558.                     ODBoolean    itemActive);
  559.  
  560. ODStatic ODType BestContentKind(ODStorageUnit* contentSU);
  561.  
  562. ODStatic pascal void DrawKindName(DialogPtr dialog, SInt16 item);
  563. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item);
  564.  
  565. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  566.                                 ODUShort kindIndex,
  567.                                 ODTypeList* translateToList,
  568.                                 ODUShort translateToIndex,
  569.                                 EditorSet* editorList,
  570.                                 MenuHandle editorMenu, 
  571.                                 ControlHandle popupCtlHndl, 
  572.                                 ODSession* session);
  573.  
  574. static pascal Boolean
  575. PasteAsFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit);
  576.  
  577. ODStatic void SetPopupControlValue(ControlHandle popupControlHandle, short itemValue);
  578.  
  579. //------------------------------------------------------------------------------
  580. // DisposeGlobalODNameAndZeroPtr
  581. //------------------------------------------------------------------------------
  582. ODStatic void DisposeGlobalODNameAndZeroPtr(ODName** name)
  583. {
  584.     if (*name)
  585.     {
  586.         // simple way to force deletion of old name value without knowing
  587.         // that DisposeIText is the right way to destroy an ODName:
  588.         TempODName tempName = *name;
  589.         *name = kODNULL;
  590.     }
  591. }
  592. #endif /* _USE_DIALOGS_LIB_ */
  593.  
  594. //------------------------------------------------------------------------------
  595. // InitLinkDialogs
  596. //------------------------------------------------------------------------------
  597. void InitLinkDialogs(ODSession* session)
  598. {
  599.     gSession = session;
  600. }
  601.  
  602. #ifndef _USE_DIALOGS_LIB_
  603.  
  604. //------------------------------------------------------------------------------
  605. // DrawEditorName
  606. //------------------------------------------------------------------------------
  607.  
  608. ODStatic pascal void DrawEditorName(DialogPtr dialog, SInt16 item)
  609. {
  610.     short            itemType;
  611.     Handle            itemHandle;
  612.     Rect            itemRect;
  613.  
  614.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  615.  
  616.     if ( gEditorName )
  617.         DrawITextInDlogBox(gEditorName, &itemRect, dialog, kODTrue);
  618. }
  619.  
  620. //------------------------------------------------------------------------------
  621. // DrawEmbeddedEditorName
  622. //------------------------------------------------------------------------------
  623.  
  624. ODStatic pascal void DrawEmbeddedEditorName(DialogPtr dialog, SInt16 item)
  625. {
  626.     short            itemType;
  627.     Handle            itemHandle;
  628.     Rect            itemRect;
  629.  
  630.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  631.  
  632.     if ( gEmbeddedEditorName )
  633.         DrawITextInDlogBox(gEmbeddedEditorName, &itemRect, dialog, kODTrue);
  634. }
  635.  
  636. //------------------------------------------------------------------------------
  637. // GetSelectedType
  638. //------------------------------------------------------------------------------
  639. // $$$$$ Should be replaced by GetThisKindFromList in InfoUtil.h
  640.  
  641. ODStatic ODType GetSelectedType(ODTypeList* typeList, ODSShort typeIndex)
  642. {
  643.     Environment*        ev = somGetGlobalEnvironment();
  644.     ODType                type = kODNULL;
  645.     ODTypeListIterator*    iter = typeList->CreateTypeListIterator(ev);
  646.     
  647.     for ( type = iter->First(ev); 
  648.           (--typeIndex > 0) && iter->IsNotComplete(ev); 
  649.           type = iter->Next(ev) )
  650.     {
  651.         ODDisposePtr(type);
  652.         type = kODNULL;
  653.     }
  654.  
  655.     delete iter;
  656.     
  657.     return type;
  658. }
  659.  
  660. //------------------------------------------------------------------------------
  661. // GetSelectedEditor
  662. //------------------------------------------------------------------------------
  663.  
  664. ODStatic ODEditor GetSelectedEditor(EditorSet* editorList, ODSShort editorIndex)
  665. {
  666.     ODEditor            editor;
  667.     EditorSetIterator*    iter = editorList->CreateIterator();
  668.     
  669.     for ( editor = iter->First(); 
  670.           (--editorIndex > 0) && iter->IsNotComplete(); 
  671.           editor = iter->Next() )
  672.     {
  673.     }
  674.  
  675.     delete iter;
  676.     
  677.     if ( editor != kODNULL )
  678.         editor = ODISOStrFromCStr((char *) editor);
  679.  
  680.     return editor;
  681. }
  682.  
  683. //------------------------------------------------------------------------------
  684. // EnableKindPopupItems
  685. //------------------------------------------------------------------------------
  686.  
  687. ODStatic void EnableKindPopupItems(
  688.                     ODBoolean            forMerge,
  689.                     ODTypeList*            typeList,
  690.                     ODTypeList*            translateList,
  691.                     ODSShort            translationIndex,
  692.                     MenuHandle            kindMenu,
  693.                     ODEditor            editor,
  694.                     ODNameSpaceManager*    nsm)
  695. {
  696.     Environment* ev = somGetGlobalEnvironment();
  697.  
  698.     ODUShort item = EnableTypesInMenu(typeList, kindMenu, forMerge ? editor : kODNULL, nsm);
  699.  
  700.     // If a translation choice is present in the popup, enable it if appropriate;
  701.     if ( translationIndex != 0 )
  702.     {
  703.         TempODType translationKind = GetSelectedType(translateList, translationIndex);
  704.  
  705.         if ( !forMerge || EditorSupportsKind(nsm, editor, translationKind) )
  706.             EnableItem(kindMenu, ++item);
  707.         else
  708.             DisableItem(kindMenu, ++item);
  709.     }
  710.  
  711.     // Enable the "Translate to…" item in the kind popup if translation is possible
  712.     if ( translateList->Count(ev) > 0 )
  713.         EnableItem(kindMenu, ++item);
  714.     else
  715.         DisableItem(kindMenu, ++item);
  716. }
  717.  
  718. //------------------------------------------------------------------------------
  719. // EnablePasteAsOkButton
  720. //------------------------------------------------------------------------------
  721.  
  722. ODStatic void EnablePasteAsOkButton(DialogPtr dlog, MenuHandle kindMenu)
  723. {
  724.     Environment*    ev = somGetGlobalEnvironment();
  725.     short            itemType;
  726.     Handle            itemHandle;
  727.     Rect            itemRect;
  728.     ODSShort        kindItemSelected;
  729.     ODBoolean        shouldBeEnabled;
  730.  
  731.     GetDialogItem(dlog, kPasteAsKindPopup, &itemType, &itemHandle, &itemRect);
  732.     ASSERT_CONTROL_ITEM(itemType);
  733.     kindItemSelected = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  734.  
  735.     // Only the first 31 items of a menu may be disabled
  736.     if ( kindItemSelected > 31 )
  737.         shouldBeEnabled = kODTrue;
  738.     else
  739.         // BitTst numbers the bits hi to low
  740.         shouldBeEnabled = BitTst(&(**kindMenu).enableFlags, 31-kindItemSelected);
  741.  
  742.     EnableOkButton(dlog, shouldBeEnabled);
  743. }
  744.  
  745. //------------------------------------------------------------------------------
  746. // BestMergeKindSetting
  747. //------------------------------------------------------------------------------
  748.  
  749. ODStatic ODSShort BestMergeKindSetting(
  750.                     ODTypeList*            kinds,
  751.                     ODType                bestKind,
  752.                     ODEditor            editor,
  753.                     ODNameSpaceManager*    nsm)
  754. {
  755.     if ( bestKind && EditorSupportsKind(nsm, editor, bestKind) )
  756.         return IndexOfKindInList(kinds, bestKind);
  757.     
  758.     Environment*        ev = somGetGlobalEnvironment();
  759.     ODSShort            kindItem = 0;        // Default in case none are supported
  760.  
  761.     ODTypeListIterator*    iter = kinds->CreateTypeListIterator(ev);
  762.     
  763.     ODType                type;
  764.     ODSShort            i;
  765.     for ( type = iter->First(ev), i = 1; 
  766.           iter->IsNotComplete(ev); 
  767.           type = iter->Next(ev), ++i )
  768.     {
  769.         ODBoolean supports = EditorSupportsKind(nsm, editor, type);
  770.         ODDisposePtr(type);
  771.         if ( supports )
  772.         {
  773.             kindItem = i;
  774.             break;
  775.         }
  776.     }
  777.  
  778.     delete iter;
  779.     
  780.     return kindItem;
  781. }
  782.  
  783. //------------------------------------------------------------------------------
  784. // InitialViewSelection
  785. //------------------------------------------------------------------------------
  786. ODStatic void InitialViewSelection(DialogPtr dlg, ODTypeToken viewType, ODSession* session)
  787. {
  788.     short        itemType;
  789.     Handle        itemHandle;
  790.     Rect        itemRect;
  791.     ODSShort    viewItem;
  792.     
  793.     Environment* ev = somGetGlobalEnvironment();
  794.  
  795.     if (viewType == session->Tokenize(ev, kODViewAsFrame))
  796.         viewItem = kODPasteAsFrameMenuItem;
  797.     else if (viewType == session->Tokenize(ev, kODViewAsLargeIcon))
  798.         viewItem = kODPasteAsLargeIconMenuItem;
  799.     else if (viewType == session->Tokenize(ev, kODViewAsSmallIcon))
  800.         viewItem = kODPasteAsSmallIconMenuItem;
  801.     else if (viewType == session->Tokenize(ev, kODViewAsThumbnail))
  802.         viewItem = kODPasteAsThumbnailMenuItem;
  803.     else
  804.         viewItem = kODPasteAsFrameMenuItem;
  805.  
  806.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  807.     ASSERT_CONTROL_ITEM(itemType);
  808.     SetControlValue((ControlHandle)itemHandle, viewItem);
  809. }
  810.  
  811. //------------------------------------------------------------------------------
  812. // GetViewSelected
  813. //------------------------------------------------------------------------------
  814. ODStatic ODTypeToken GetViewSelected(DialogPtr dlg, ODSession* session)
  815. {
  816.     short        itemType;
  817.     Handle        itemHandle;
  818.     Rect        itemRect;
  819.  
  820.     Environment* ev = somGetGlobalEnvironment();
  821.  
  822.     GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  823.     ASSERT_CONTROL_ITEM(itemType);
  824.     ODSShort viewItem = (ODSShort) GetControlValue((ControlHandle)itemHandle);
  825.     ODType viewAs;
  826.     switch ( viewItem )
  827.     {
  828.     case kODPasteAsLargeIconMenuItem:
  829.             viewAs = kODViewAsLargeIcon;
  830.             break;
  831.     case kODPasteAsSmallIconMenuItem:
  832.             viewAs = kODViewAsSmallIcon;
  833.             break;
  834.     case kODPasteAsThumbnailMenuItem:
  835.             viewAs = kODViewAsThumbnail;
  836.             break;
  837.     default:
  838.             viewAs = kODViewAsFrame;
  839.             break;
  840.     }
  841.  
  842.     return session->Tokenize(ev, viewAs);
  843. }
  844.  
  845. //------------------------------------------------------------------------------
  846. // HaveColorQuickdraw
  847. //------------------------------------------------------------------------------
  848. ODStatic ODBoolean HaveColorQuickdraw()
  849. {
  850.     long response;
  851.  
  852.     Gestalt(gestaltQuickdrawFeatures, &response);
  853.         
  854.     /* check if Color QuickDraw is available */    
  855.     return BitTst(&response, 31-gestaltHasColor);
  856. }
  857.  
  858. //------------------------------------------------------------------------------
  859. // EnableDialogItem
  860. //------------------------------------------------------------------------------
  861. ODStatic void EnableDialogItem(DialogPtr dlg, short itemNumber, ODBoolean enable)
  862. {
  863.     short        itemType;
  864.     Handle        itemHandle;
  865.     Rect        itemRect;
  866.  
  867.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  868.     if ( enable )
  869.         itemType &= ~itemDisable;
  870.     else
  871.         itemType |= itemDisable;
  872.     SetDialogItem(dlg, itemNumber, itemType, itemHandle, &itemRect);
  873. }
  874.  
  875. //------------------------------------------------------------------------------
  876. // InvalDialogItem
  877. //------------------------------------------------------------------------------
  878. ODStatic void InvalDialogItem(DialogPtr dlg, short itemNumber)
  879. {
  880.     short        itemType;
  881.     Handle        itemHandle;
  882.     Rect        itemRect;
  883.     WindowPtr    savePort;
  884.  
  885.     GetPort(&savePort);
  886.     SetPort(dlg);
  887.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);    
  888.     InvalRect(&itemRect);
  889.     SetPort(savePort);
  890. }
  891.  
  892. //------------------------------------------------------------------------------
  893. // SetPopupControlValue
  894. //------------------------------------------------------------------------------
  895. ODStatic void SetPopupControlValue(ControlHandle popupControlHandle, short itemValue)
  896. {
  897.     // The resource file must be in the chain in order for the popup to redraw.
  898.     CUsingLibraryResources r;
  899.     SetControlValue(popupControlHandle, itemValue);
  900. }
  901.  
  902. //------------------------------------------------------------------------------
  903. // SetupControlItem
  904. //------------------------------------------------------------------------------
  905. ODStatic void SetupControlItem(
  906.                     DialogPtr    dlg,
  907.                     short        itemNumber,
  908.                     short        itemValue,
  909.                     ODBoolean    itemActive)
  910. {
  911.     short        itemType;
  912.     Handle        itemHandle;
  913.     Rect        itemRect;
  914.  
  915.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  916.     ASSERT_CONTROL_ITEM(itemType);
  917.     SetControlValue((ControlHandle)itemHandle, itemActive? itemValue : 0);
  918.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  919. }
  920.  
  921. //------------------------------------------------------------------------------
  922. // InactivateEmbedAsPopup
  923. //------------------------------------------------------------------------------
  924.  
  925. ODStatic void InactivateEmbedAsPopup(DialogPtr dlg)
  926. // Set clipping to just the display area of the popup so the radio button
  927. // label isn't dimmed.
  928. {
  929.     short        aItem;
  930.     Handle        aHandle;
  931.     Handle        embedPopupCntlHandle;
  932.     Rect        aRect;
  933.     RgnHandle    embedTextRgn = ODNewRgn();
  934.     RgnHandle    embedPopupRgn = ODNewRgn();
  935.     RgnHandle    clipRgn = ODNewRgn();
  936.  
  937.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &aItem, &aHandle, &aRect);
  938.     RectRgn(embedTextRgn,&aRect);
  939.  
  940.     GetDialogItem(dlg, kPasteAsEmbedPopup, &aItem, &embedPopupCntlHandle, &aRect);
  941.     RectRgn(embedPopupRgn,&aRect);
  942.  
  943.     GetClip(clipRgn);
  944.     DiffRgn(embedPopupRgn, embedTextRgn, embedPopupRgn);
  945.     SetClip(embedPopupRgn);
  946.     HiliteControl((ControlHandle)embedPopupCntlHandle, kControlInactive);
  947.     SetClip(clipRgn);
  948.     
  949.     ODDisposeHandle((Handle)clipRgn);
  950.     ODDisposeHandle((Handle)embedPopupRgn);
  951.     ODDisposeHandle((Handle)embedTextRgn);
  952. }
  953.  
  954. //------------------------------------------------------------------------------
  955. // ClipOutRect
  956. //------------------------------------------------------------------------------
  957.  
  958. ODStatic RgnHandle ClipOutRect(Rect* r)
  959. {
  960.     RgnHandle    saveRgn = ODNewRgn();
  961.     RgnHandle    rectRgn = ODNewRgn();
  962.     RgnHandle    clipRgn = ODNewRgn();
  963.  
  964.     GetClip(saveRgn);
  965.  
  966.     RectRgn(rectRgn, r);
  967.  
  968.     GetClip(clipRgn);
  969.     DiffRgn(clipRgn, rectRgn, clipRgn);
  970.     SetClip(clipRgn);
  971.  
  972.     ODDisposeHandle((Handle)rectRgn);
  973.     ODDisposeHandle((Handle)clipRgn);
  974.     
  975.     return saveRgn;
  976. }
  977.  
  978. //------------------------------------------------------------------------------
  979. // SetAutomaticUpdateControls
  980. //------------------------------------------------------------------------------
  981. ODStatic void SetAutomaticUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  982. {
  983.     short    itemType;
  984.     Handle    itemHandle;
  985.     Rect    itemRect;
  986.  
  987.     GetDialogItem(dlg, kPasteAsAutomaticRadioBtn, &itemType, &itemHandle, &itemRect);
  988.     ASSERT_CONTROL_ITEM(itemType);
  989.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  990.     GetDialogItem(dlg, kPasteAsManualRadioBtn, &itemType, &itemHandle, &itemRect);
  991.     ASSERT_CONTROL_ITEM(itemType);
  992.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  993. }
  994.  
  995. //------------------------------------------------------------------------------
  996. // SetMergeEmbedControls
  997. //------------------------------------------------------------------------------
  998. ODStatic void SetMergeEmbedControls(DialogPtr dlg, ODBoolean mergeSetting)
  999. {
  1000.     short    itemType;
  1001.     Handle    itemHandle;
  1002.     Rect    itemRect;
  1003.  
  1004.     CUsingLibraryResources r;    // Necessary to change embed popup
  1005.  
  1006.     GetDialogItem(dlg, kPasteAsMergeRadioBtn, &itemType, &itemHandle, &itemRect);
  1007.     ASSERT_CONTROL_ITEM(itemType);
  1008.     SetControlValue((ControlHandle)itemHandle, mergeSetting);
  1009.     
  1010.     GetDialogItem(dlg, kPasteAsEmbedRadioBtn, &itemType, &itemHandle, &itemRect);
  1011.     ASSERT_CONTROL_ITEM(itemType);
  1012.     SetControlValue((ControlHandle)itemHandle, !mergeSetting);
  1013.  
  1014.     if ( mergeSetting )
  1015.     {
  1016.         InactivateEmbedAsPopup(dlg);
  1017.     }
  1018.     else
  1019.     {
  1020.         GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  1021.         ASSERT_CONTROL_ITEM(itemType);
  1022.         HiliteControl((ControlHandle)itemHandle, kControlActive);
  1023.     }
  1024. }
  1025.  
  1026. //------------------------------------------------------------------------------
  1027. // GetIndexedElement
  1028. //------------------------------------------------------------------------------
  1029.  
  1030. ODStatic ODULong GetIndexedElement(OrderedCollection* translateFromList, ODULong translationIndex)
  1031. {
  1032.     OrderedCollectionIterator* oci = translateFromList->CreateIterator();
  1033.  
  1034.     ODULong elem = 0;
  1035.  
  1036.     for (    elem = (ODULong) oci->First();
  1037.             oci->IsNotComplete(); 
  1038.             elem = (ODULong) oci->Next() )
  1039.     {
  1040.         if ( --translationIndex == 0 )
  1041.             break;
  1042.     }
  1043.  
  1044.     ODDeleteObject(oci);
  1045.  
  1046.     return elem;
  1047. }
  1048.  
  1049. //------------------------------------------------------------------------------
  1050. // GetOriginalDraft
  1051. //------------------------------------------------------------------------------
  1052. // Returns 0 if the original draft is unknown.  This is the case when content
  1053. // was placed in the draft without cloning.  This code is dependent on properties
  1054. // created by the argument storage unit's container suite.
  1055.  
  1056.  
  1057. static ODULong GetOriginalDraft(Environment* ev, ODDraft* draft)
  1058. {
  1059.     TempODStorageUnit    draftProperties = draft->AcquireDraftProperties(ev);
  1060.     return ODGetULongProp(ev, draftProperties, kODPropOriginalDraft, kODULong);
  1061. }
  1062.  
  1063. //------------------------------------------------------------------------------
  1064. // SUClonedFromDraft
  1065. //------------------------------------------------------------------------------
  1066. // Returns kODTrue is the argument storage unit is the clone of a storage unit
  1067. // from the argument draft.  This code is dependent on properties created by
  1068. // the argument storage unit's container suite.
  1069.  
  1070. static ODBoolean SUClonedFromDraft(Environment* ev,
  1071.             ODStorageUnit* su,
  1072.             ODDraft* draft)
  1073. {
  1074.     return ((ODDraft*)GetOriginalDraft(ev, su->GetDraft(ev)) == draft &&
  1075.             su->Exists(ev, kODPropOriginalID, kODULong, 0));
  1076. }
  1077.  
  1078. //------------------------------------------------------------------------------
  1079. // DeactivateModalDialog
  1080. //------------------------------------------------------------------------------
  1081.  
  1082. ODStatic void DeactivateModalDialog(ModalFilterUPP filterProc)
  1083. {
  1084.     DialogPtr dialog = (DialogPtr) FrontWindow();
  1085.  
  1086.     if ( dialog )
  1087.     {
  1088.         EventRecord event;
  1089.         
  1090.         event.what = activateEvt;
  1091.         event.message = (long) dialog;
  1092.         event.modifiers = 0;
  1093.  
  1094.         CallModalFilterProc(filterProc, dialog, &event, 0);
  1095.     }
  1096. }
  1097.  
  1098. //------------------------------------------------------------------------------
  1099. // PasteAsFilterProc
  1100. //------------------------------------------------------------------------------
  1101.  
  1102. static pascal Boolean
  1103. PasteAsFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit)
  1104. {    
  1105.     // If the event is a deactivate event, the ok button must be deactivated
  1106.     // before the surrounding outline is drawn so it is drawn dim.
  1107.     ODBoolean rslt = ODButtonKeyFilterProc(dialog,event,itemHit);
  1108.  
  1109.     if ( event->what == activateEvt )
  1110.     {
  1111.         ODOutlineDefaultButtonDrawProc(dialog, kPasteAsDefaultButtonItem);
  1112.     }
  1113.  
  1114.     return rslt;
  1115. }
  1116. #endif /* ndef _USE_DIALOGS_LIB_ */
  1117.  
  1118. //------------------------------------------------------------------------------
  1119. // ShowPasteAsDialog
  1120. //------------------------------------------------------------------------------
  1121.  
  1122. ODBoolean ShowPasteAsDialog(
  1123.                 ODBoolean                canPasteLink,
  1124.                 ODPasteAsMergeSetting    mergeSetting,
  1125.                 ODBoolean                isMove,
  1126.                 ODStorageUnit*            contentSU,
  1127.                 ODFacet*                facet,
  1128.                 ODTypeToken                viewType,
  1129.                 ODPasteAsResult*        result)
  1130.  
  1131. {
  1132. #ifdef _USE_DIALOGS_LIB_
  1133.     SPAD spad = kODNULL;
  1134.     CFragConnectionID connID;
  1135.     THROW_IF_ERROR( LoadODSharedLibrary( "\pDialogsLib",
  1136.             "\pShowPasteAsDialogEx", &connID, (void**)&spad ) );
  1137.     ODBoolean boolResult = false;
  1138.     ODError err = (*spad)( canPasteLink, mergeSetting, isMove,
  1139.             contentSU, facet, viewType, result, &boolResult );
  1140.     UnloadODSharedLibrary( &connID );
  1141.     THROW_IF_ERROR( err );
  1142.     return boolResult;
  1143. #else
  1144.     Environment* ev = somGetGlobalEnvironment();
  1145.  
  1146.     WindowPtr    savePort;                            ODVolatile(savePort);
  1147.     GetPort(&savePort);
  1148.  
  1149.     short          itemHit = kPasteAsCancelBtn;
  1150.     short        itemType;
  1151.     DialogPtr      dlg = kODNULL;                        ODVolatile(dlg);
  1152.     Handle        itemHandle;
  1153.     Rect        itemRect;
  1154.     Rect        kindPopupRect;
  1155.     Rect        editorPopupRect;
  1156.     short        kindItemSelected;
  1157.     short        kindItemOthers;
  1158.     short        kindItemCurrent;
  1159.     ODBoolean    kindPopupHasNoTranslationKind = kODTrue;
  1160.     ODUShort    translationIndex = 0;
  1161.  
  1162.     ODSLong        refSaved;
  1163.     OSErr        resErr;
  1164.  
  1165.     ODBoolean    userChangedKind = kODFalse;
  1166.  
  1167.     ControlHandle kindPopupControlHandle;
  1168.     ControlHandle editorPopupControlHandle;
  1169.  
  1170.     ODEditor mergeEditorID = kODNULL;                ODVolatile(mergeEditorID);
  1171.     ODEditor embedEditorID = kODNULL;                ODVolatile(embedEditorID);
  1172.     ODEditor preferredEditorID = kODNULL;            ODVolatile(preferredEditorID);
  1173.  
  1174.     EditorSet* editorList = kODNULL;                ODVolatile(editorList);
  1175.  
  1176.     ODSShort bestKindIndex = 1;
  1177.     ODSShort bestMergeKind = 1;
  1178.  
  1179.     ODType bestKind = kODNULL;                        ODVolatile(bestKind);
  1180.     ODTypeList*    kindList = kODNULL;                    ODVolatile(kindList);
  1181.     ODTypeList*    translateToList = kODNULL;            ODVolatile(translateToList);
  1182.     OrderedCollection* translateFromList = kODNULL;    ODVolatile(translateFromList);
  1183.  
  1184.     MenuHandle kindMenu = kODNULL;                    ODVolatile(kindMenu);
  1185.     MenuHandle editorMenu = kODNULL;                ODVolatile(editorMenu);
  1186.  
  1187.     UserItemUPP DrawBoxItemUPP = kODNULL;            ODVolatile(DrawBoxItemUPP);
  1188.     UserItemUPP DrawDeactiveItemUPP = kODNULL;        ODVolatile(DrawDeactiveItemUPP);
  1189.     UserItemUPP    DrawEditorNameUPP = kODNULL;        ODVolatile(DrawEditorNameUPP);
  1190.     UserItemUPP    DrawEmbeddedEditorNameUPP = kODNULL;ODVolatile(DrawEmbeddedEditorNameUPP);
  1191.     UserItemUPP    DrawKindNameUPP = kODNULL;            ODVolatile(DrawKindNameUPP);
  1192.  
  1193.     ModalFilterUPP modalFilter = kODNULL;            ODVolatile(modalFilter);
  1194.  
  1195.     if ( canPasteLink )
  1196.         canPasteLink = contentSU->Exists(ev, kODPropLinkSpec, (ODValueType) kODLinkSpec, 0);
  1197.  
  1198.     result->pasteLinkSetting = (!isMove) && canPasteLink;
  1199.     result->autoUpdateSetting = kODTrue;
  1200.     result->selectedKind = (ODType) kODNULL;
  1201.     result->translateKind = (ODType) kODNULL;
  1202.     result->editor = kODNoEditor;
  1203.  
  1204.     ODSession* session;
  1205.     {
  1206.         TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  1207.         session = part->GetStorageUnit(ev)->GetSession(ev);
  1208.     }
  1209.  
  1210.     TRY
  1211.         ODBinding* binding = session->GetBinding(ev);
  1212.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  1213.  
  1214.         session->GetWindowState(ev)->DeactivateFrontWindows(ev);
  1215.  
  1216.         { TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  1217.           mergeEditorID = GetCurrentEditorForPart(part);
  1218.         }
  1219.         
  1220.         kindList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  1221.         ContentValueTypes(contentSU, kindList);
  1222.         
  1223.         // Now get all possible translations from the available kinds
  1224.         translateToList = session->GetStorageSystem(ev)->CreateTypeList(ev, (ODTypeList*) kODNULL);
  1225.         translateFromList = new OrderedCollection;
  1226.         TranslateValueTypes(kindList, translateToList, translateFromList, session);
  1227.         
  1228.         refSaved = BeginUsingLibraryResources();
  1229.         kindMenu = GetMenu(kPasteAsKindPopupMenu);
  1230.         resErr = ResError();
  1231.         EndUsingLibraryResources(refSaved);
  1232.         THROW_IF_NULL(kindMenu, resErr ? resErr : resNotFound);
  1233.     
  1234.         AddTypesToMenu(kindList, kindMenu, kODNULL, kODNULL, session);
  1235.         kindItemOthers = CountMItems(kindMenu);
  1236.  
  1237.         ODBoolean canMerge = (mergeSetting != kODPasteAsEmbedOnly);
  1238.         ODBoolean canEmbed = (mergeSetting != kODPasteAsMergeOnly);
  1239.  
  1240.         result->mergeSetting = (mergeSetting == kODPasteAsMerge) || (mergeSetting == kODPasteAsMergeOnly);
  1241.  
  1242.         {
  1243.             CUsingLibraryResources r;
  1244.             dlg = ODGetNewDialog(ev, kPasteAsDlgID, session, kNoDefaultButton);
  1245.             THROW_IF_NULL(dlg);
  1246.             SetPort(dlg);
  1247.             SetDialogTextStyle(dlg, kPasteAsDlgID, smCurrentScript);
  1248.         }
  1249.     
  1250.         /* Horizontal line needs to be drawn */
  1251.         GetDialogItem(dlg, kPasteAsHorizSep, &itemHit, &itemHandle, &itemRect);
  1252.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  1253.         SetDialogItem(dlg, kPasteAsHorizSep, itemHit, (Handle)DrawBoxItemUPP, &itemRect);
  1254.     
  1255.         // Set the draw routine for the default button outline item
  1256.         GetDialogItem(dlg, kPasteAsDefaultButtonItem, &itemHit, &itemHandle, &itemRect);
  1257.         SetDialogItem(dlg, kPasteAsDefaultButtonItem, itemHit, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  1258.         
  1259.         // Create one UPP for all user items used to draw deactive PICTs
  1260.         DrawDeactiveItemUPP = NewUserItemProc(DrawDeactivePICTItem);
  1261.  
  1262.         // Initialize state of "Paste with Link" checkbox and label
  1263.         SetupControlItem(dlg, kPasteAsLinkCheckbox, result->pasteLinkSetting, canPasteLink);
  1264.         
  1265.         // Initialize state of "Get Updates" radio buttons and labels
  1266.         if ( result->pasteLinkSetting)
  1267.             HideDialogItem(dlg, kPasteAsUpdateDisabledText);
  1268.         else
  1269.             HideDialogItem(dlg, kPasteAsUpdateText);
  1270.  
  1271.         SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  1272.         SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  1273.  
  1274.         // set up merge picture, radio button, and label
  1275.         InitItemActive(dlg, kPasteAsMergePict, DrawDeactiveItemUPP, canMerge);
  1276.         SetupControlItem(dlg, kPasteAsMergeRadioBtn, result->mergeSetting, canMerge);
  1277.  
  1278.         // set up embed picture, radio button, and label
  1279.         InitItemActive(dlg, kPasteAsEmbedPict, DrawDeactiveItemUPP, canEmbed);
  1280.         SetupControlItem(dlg, kPasteAsEmbedRadioBtn, !result->mergeSetting, canEmbed);
  1281.     
  1282.         // set up initial "Paste as:" popup selection
  1283.         InitialViewSelection(dlg, viewType, session);
  1284.  
  1285.         // inactivate the "Embed as:" popup if merge is initially selected
  1286.         if ( result->mergeSetting )
  1287.         {
  1288.             GetDialogItem(dlg, kPasteAsEmbedPopup, &itemType, &itemHandle, &itemRect);
  1289.             ASSERT_CONTROL_ITEM(itemType);
  1290.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  1291.         }
  1292.  
  1293.         // Determine the indices of the best kind and the best kind that can be merged
  1294.         bestKind = BestContentKind(contentSU);
  1295.         if ( bestKind )
  1296.             bestKindIndex = IndexOfKindInList(kindList, bestKind);
  1297.         if ( bestKindIndex == 0 )    // In case preferred kind property is bogus
  1298.             bestKindIndex = 1;
  1299.  
  1300.         bestMergeKind = BestMergeKindSetting(kindList, bestKind, mergeEditorID, nsm);
  1301.  
  1302.         // Suppress the preferred editor if it doesn't support the preferred kind
  1303.         preferredEditorID = ODGetISOStrProp(ev, contentSU, kODPropPreferredEditor, kODEditor, kODNULL, kODNULL);
  1304.         if ( preferredEditorID && bestKind && !EditorSupportsKind(nsm, preferredEditorID, bestKind) )
  1305.         {
  1306.             ODDisposePtr((ODPtr) preferredEditorID);
  1307.             preferredEditorID = kODNULL;
  1308.         }
  1309.  
  1310. #if ODDebugLinkDlgs
  1311.         somPrintf("ShowPasteAsDialog: mergeSetting = %u, best merge kind = %u\n", mergeSetting, (bestMergeKind != 0));
  1312. #endif
  1313.  
  1314.         // Set up the Kind popup items
  1315.         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, 0, kindMenu, mergeEditorID, nsm);
  1316.         GetDialogItem(dlg, kPasteAsKindPopup, &itemType, (Handle*) &kindPopupControlHandle, &kindPopupRect);
  1317.         ASSERT_CONTROL_ITEM(itemType);
  1318.         SetControlValue(kindPopupControlHandle, result->mergeSetting ? bestMergeKind : bestKindIndex);
  1319.     
  1320.         // Determine if the root storage unit is an existing part from the same draft
  1321.         // as the pasting part
  1322.  
  1323.         ODDraft* partDraft;
  1324.         // Get the draft from the part, not the frame, because the frame's storage
  1325.         // unit is null if non-persistent.
  1326.         {
  1327.             TempODPart part = facet->GetFrame(ev)->AcquirePart(ev);
  1328.             partDraft = part->GetStorageUnit(ev)->GetDraft(ev);
  1329.         }
  1330.         ODBoolean contentIsPart = SUClonedFromDraft(ev, contentSU, partDraft);
  1331.  
  1332.         // Set text of static "Kind:" label
  1333.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  1334.         if ( bestKind && GetUserKindFromKind(nsm, bestKind, &gKindName) )
  1335.         {
  1336.             GetDialogItem(dlg, kPasteAsKindText, &itemType, &itemHandle, &itemRect);
  1337.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  1338.             SetDialogItem(dlg, kPasteAsKindText, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  1339.         }
  1340.  
  1341.         // inactivate the "Kind:" popup if embedding is initially selected, the operation is
  1342.         // a move, and a cloned part is in the storage unit (not intrinsic content).
  1343.         if ( (!result->mergeSetting) && isMove && contentIsPart )
  1344.         {
  1345.             HideDialogItem(dlg, kPasteAsKindPopup);
  1346.         }
  1347.         else
  1348.         {
  1349.             HideDialogItem(dlg, kPasteAsKindLabel);
  1350.             HideDialogItem(dlg, kPasteAsKindText);
  1351.         }
  1352.  
  1353.         // Setup the static text for the merge editor
  1354.         DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1355.         if ( mergeEditorID && GetUserEditorFromEditor(nsm, mergeEditorID, &gEditorName) )
  1356.         {
  1357.             GetDialogItem(dlg, kPasteAsEditorText, &itemType, &itemHandle, &itemRect);
  1358.             DrawEditorNameUPP = NewUserItemProc(DrawEditorName);
  1359.             SetDialogItem(dlg, kPasteAsEditorText, userItem+itemDisable, (Handle) DrawEditorNameUPP, &itemRect);
  1360.         }
  1361.  
  1362.         // Setup the static text for the embedding editor
  1363.         // Since the contentSU will not be cloned during a move in the same document, this is a guess as to the
  1364.         // editor actually bound to the moved frame.
  1365.         if ( preferredEditorID )
  1366.             embedEditorID = ODISOStrFromCStr((char *) preferredEditorID);
  1367.         else
  1368.             embedEditorID = binding->ChooseEditorForPart(ev, contentSU, bestKind);
  1369.         
  1370.         DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1371.         if ( embedEditorID && GetUserEditorFromEditor(nsm, embedEditorID, &gEmbeddedEditorName) )
  1372.         {
  1373.             GetDialogItem(dlg, kPasteAsEmbedEditorText, &itemType, &itemHandle, &itemRect);
  1374.             DrawEmbeddedEditorNameUPP = NewUserItemProc(DrawEmbeddedEditorName);
  1375.             SetDialogItem(dlg, kPasteAsEmbedEditorText, userItem+itemDisable, (Handle) DrawEmbeddedEditorNameUPP, &itemRect);
  1376.         }
  1377.  
  1378.         // Setup the editor popup
  1379.         editorList = new EditorSet;
  1380.         editorList->InitEditorSet();
  1381.  
  1382.         refSaved = BeginUsingLibraryResources();
  1383.         editorMenu = GetMenu(kPasteAsEditorPopupMenu);
  1384.         resErr = ResError();
  1385.         EndUsingLibraryResources(refSaved);
  1386.         THROW_IF_NULL(editorMenu, resErr ? resErr : resNotFound);
  1387.  
  1388.         GetDialogItem(dlg, kPasteAsEditorPopup, &itemType, (Handle*) &editorPopupControlHandle, &editorPopupRect);
  1389.         SetupEditorMenu(bestKind, editorList, editorMenu, editorPopupControlHandle, session);
  1390.  
  1391.         if ( result->mergeSetting )
  1392.         {
  1393.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1394.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1395.         }
  1396.         else if ( isMove && contentIsPart )
  1397.         {
  1398.             HideDialogItem(dlg, kPasteAsEditorPopup);
  1399.             HideDialogItem(dlg, kPasteAsEditorText);
  1400.         }
  1401.         else
  1402.         {
  1403.             HideDialogItem(dlg, kPasteAsEditorLabel);
  1404.             HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1405.             HideDialogItem(dlg, kPasteAsEditorText);
  1406.         }
  1407.         
  1408.         modalFilter = NewModalFilterProc(PasteAsFilterProc);
  1409.  
  1410.         // Display the dialog
  1411.         ShowWindow(dlg);
  1412.     
  1413.         do {
  1414.             // Remember the currently selected kind
  1415.             kindItemCurrent = (ODSShort) GetControlValue(kindPopupControlHandle);
  1416.  
  1417.             {    CUsingLibraryResources r;
  1418.                 ModalDialog(modalFilter, &itemHit);
  1419.             }
  1420.     
  1421.             switch (itemHit)
  1422.             {
  1423.             case kPasteAsLinkCheckbox:
  1424.                     result->pasteLinkSetting = !result->pasteLinkSetting;
  1425.                     GetDialogItem(dlg, itemHit, &itemType, &itemHandle, &itemRect);
  1426.                     ASSERT_CONTROL_ITEM(itemType);
  1427.                     SetControlValue((ControlHandle)itemHandle, result->pasteLinkSetting);
  1428.  
  1429.                     if ( result->pasteLinkSetting )
  1430.                     {
  1431.                         GetDialogItem(dlg, kPasteAsUpdateDisabledText, &itemType, &itemHandle, &itemRect);
  1432.                         itemRect.left += 16384;
  1433.                         itemRect.right += 16384;
  1434.                         SetDialogItem(dlg, kPasteAsUpdateDisabledText, itemType, itemHandle, &itemRect);
  1435.                         ShowDialogItem(dlg, kPasteAsUpdateText);
  1436.                     }
  1437.                     else
  1438.                     {
  1439.                         GetDialogItem(dlg, kPasteAsUpdateText, &itemType, &itemHandle, &itemRect);
  1440.                         itemRect.left += 16384;
  1441.                         itemRect.right += 16384;
  1442.                         SetDialogItem(dlg, kPasteAsUpdateText, itemType, itemHandle, &itemRect);
  1443.                         ShowDialogItem(dlg, kPasteAsUpdateDisabledText);
  1444.                     }
  1445.  
  1446.                     SetupControlItem(dlg, kPasteAsAutomaticRadioBtn, result->autoUpdateSetting, result->pasteLinkSetting);
  1447.                     SetupControlItem(dlg, kPasteAsManualRadioBtn, !result->autoUpdateSetting, result->pasteLinkSetting);
  1448.                     break;
  1449.     
  1450.             case kPasteAsAutomaticRadioBtn:
  1451.                     result->autoUpdateSetting = kODTrue;
  1452.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1453.                     break;
  1454.     
  1455.             case kPasteAsManualRadioBtn:
  1456.                     result->autoUpdateSetting = kODFalse;
  1457.                     SetAutomaticUpdateControls(dlg, result->autoUpdateSetting);
  1458.                     break;
  1459.     
  1460.             case kPasteAsMergePict:
  1461.             case kPasteAsMergeRadioBtn:
  1462.                     if ( !result->mergeSetting )
  1463.                     {
  1464.                         result->mergeSetting = kODTrue;
  1465.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1466.  
  1467.                         TempODType selectedKind = kODNULL;
  1468.                         if ( kindItemCurrent <= kindList->Count(ev) )
  1469.                             selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1470.                         else
  1471.                             selectedKind = GetSelectedType(translateToList, translationIndex);
  1472.  
  1473.                         if ( !EditorSupportsKind(nsm, mergeEditorID, selectedKind) )
  1474.                         {
  1475.                             SetPopupControlValue(kindPopupControlHandle, bestMergeKind);
  1476.                             userChangedKind = kODFalse;    // Allow embed to automatically select best kind
  1477.                         }
  1478.  
  1479.                         EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, mergeEditorID, nsm);
  1480.     
  1481.                         if ( isMove && contentIsPart )
  1482.                         {
  1483.                             HideDialogItem(dlg, kPasteAsKindLabel);
  1484.                             HideDialogItem(dlg, kPasteAsKindText);
  1485.                             ShowDialogItem(dlg, kPasteAsKindPopup);
  1486.                         }
  1487.                         else
  1488.                         {
  1489.                             EnablePasteAsOkButton(dlg, kindMenu);
  1490.                         }
  1491.                         
  1492.                         HideDialogItem(dlg, kPasteAsEditorPopup);
  1493.                         HideDialogItem(dlg, kPasteAsEmbedEditorText);
  1494.                         ShowDialogItem(dlg, kPasteAsEditorLabel);
  1495.                         ShowDialogItem(dlg, kPasteAsEditorText);
  1496.                     }
  1497.                     break;
  1498.     
  1499.             case kPasteAsEmbedPict:
  1500.             case kPasteAsEmbedRadioBtn:
  1501.                     if ( result->mergeSetting )
  1502.                     {
  1503.                         result->mergeSetting = kODFalse;
  1504.                         SetMergeEmbedControls(dlg, result->mergeSetting);
  1505.     
  1506.                         // If the user has not changed the kind setting, switch to the preferred kind
  1507.                         kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1508.                         if ( !userChangedKind )
  1509.                         {
  1510.                             // Make sure item is enabled before drawing it!
  1511.                             EnableItem(kindMenu, bestKindIndex);
  1512.                             SetPopupControlValue(kindPopupControlHandle, bestKindIndex);
  1513.                             kindItemSelected = bestKindIndex;
  1514.                         }
  1515.  
  1516.                         // When embedding is chosen, determine the preferred editor, then enable the kind menu
  1517.                         ResetEditorPopup(kindList,
  1518.                                         kindItemSelected,
  1519.                                         translateToList,
  1520.                                         translationIndex,
  1521.                                         editorList,
  1522.                                         editorMenu, 
  1523.                                         editorPopupControlHandle, 
  1524.                                         session);
  1525.  
  1526.                         // Select the preferred editor if specified
  1527.                         ODSShort preferredEditorItem = IndexOfEditorInList(editorList, preferredEditorID);
  1528.                         if ( preferredEditorItem != 0 )
  1529.                             SetPopupControlValue(editorPopupControlHandle, preferredEditorItem);
  1530.  
  1531.                         if ( isMove && contentIsPart )
  1532.                         {
  1533.                             HideDialogItem(dlg, kPasteAsEditorText);
  1534.                             ShowDialogItem(dlg, kPasteAsEmbedEditorText);
  1535.                         }
  1536.                         else
  1537.                         {
  1538.                             HideDialogItem(dlg, kPasteAsEditorLabel);
  1539.                             HideDialogItem(dlg, kPasteAsEditorText);
  1540.                             ShowDialogItem(dlg, kPasteAsEditorPopup);
  1541.                         }
  1542.  
  1543.                         // Now enable the kind items
  1544.                         if ( isMove && contentIsPart )
  1545.                         {
  1546.                             HideDialogItem(dlg, kPasteAsKindPopup);
  1547.                             ShowDialogItem(dlg, kPasteAsKindLabel);
  1548.                             ShowDialogItem(dlg, kPasteAsKindText);
  1549.                         }
  1550.                         else
  1551.                         {
  1552.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1553.                             ODEditor selectedEditor = GetSelectedEditor(editorList, editorItem);
  1554.                             EnableKindPopupItems(result->mergeSetting, kindList, translateToList, translationIndex, kindMenu, selectedEditor, nsm);
  1555.                             ODDisposePtr((ODPtr) selectedEditor);
  1556.                             EnablePasteAsOkButton(dlg, kindMenu);
  1557.                         }
  1558.                     }
  1559.                     break;
  1560.     
  1561.             case kPasteAsKindPopup:
  1562.                     kindItemSelected = (ODSShort) GetControlValue(kindPopupControlHandle);
  1563.                     if ( kindItemSelected == kindItemOthers )
  1564.                     {
  1565.                         ODUShort selectedIndex;
  1566.                         ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1567.                         ODEditor initialEditorID;
  1568.                         if ( result->mergeSetting )
  1569.                             initialEditorID = ODISOStrFromCStr((char *) mergeEditorID);
  1570.                         else
  1571.                             initialEditorID = GetSelectedEditor(editorList, editorItem);
  1572.                         ODEditor newEditorID = kODNULL;
  1573.  
  1574.                         // Return the kind popup to its current value 
  1575.                         SetPopupControlValue(kindPopupControlHandle, kindItemCurrent);
  1576.                         DeactivateModalDialog(modalFilter);
  1577.                         
  1578.                         if ( session->GetTranslation(ev)->ShowTranslateDialog(
  1579.                                                                 ev,
  1580.                                                                 translateToList,
  1581.                                                                 translationIndex,
  1582.                                                                 &selectedIndex,
  1583.                                                                 initialEditorID,
  1584.                                                                 !result->mergeSetting,
  1585.                                                                 &newEditorID) )
  1586.                         {
  1587.                             // Add translationKind to the list just above "Translate to…", 
  1588.                             //  and make it the current selection.
  1589.                             translationIndex = selectedIndex;
  1590.  
  1591.                             { TempODType translationKind = GetSelectedType(translateToList, translationIndex);
  1592.                               AddTranslationKindToMenu(translationKind, kindMenu, kindItemOthers-1, 
  1593.                                                         kindPopupHasNoTranslationKind, session);
  1594.                             }
  1595.  
  1596.                             if ( kindPopupHasNoTranslationKind )
  1597.                             {
  1598.                                 kindPopupHasNoTranslationKind = kODFalse;
  1599.                                 kindItemOthers += 1;
  1600.                             }
  1601.  
  1602.                             SetPort(dlg);
  1603.                             SetControlValue(kindPopupControlHandle, kindItemOthers-1);
  1604.                             InvalRect(&kindPopupRect);    // Redraw the popup
  1605.  
  1606.                             if ( !result->mergeSetting )
  1607.                             {
  1608.                                 ResetEditorPopup(kindList,
  1609.                                                 kindItemSelected,
  1610.                                                 translateToList,
  1611.                                                 translationIndex,
  1612.                                                 editorList,
  1613.                                                 editorMenu, 
  1614.                                                 editorPopupControlHandle, 
  1615.                                                 session);
  1616.                                 // Select editorID in the list
  1617.                                 ODSShort editorItem = IndexOfEditorInList(editorList, newEditorID);
  1618.                                 if ( editorItem != 0 )
  1619.                                     SetControlValue(editorPopupControlHandle, editorItem);
  1620.                                 InvalRect(&editorPopupRect);    // Redraw the popup
  1621.                             }
  1622.                             ODDisposePtr((ODPtr) initialEditorID);
  1623.                             ODDisposePtr((ODPtr) newEditorID);
  1624.  
  1625.                             userChangedKind = kODTrue;
  1626.                         }
  1627.                     }
  1628.                     else if ( kindItemSelected != kindItemCurrent )
  1629.                     {
  1630.                         userChangedKind = kODTrue;
  1631.                         if ( !result->mergeSetting )
  1632.                         {
  1633.                             // Remember the currently selected editor
  1634.                             ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1635.                             TempODEditor lastEditorID = GetSelectedEditor(editorList, editorItem);
  1636.  
  1637.                             ResetEditorPopup(kindList,
  1638.                                             kindItemSelected,
  1639.                                             translateToList,
  1640.                                             translationIndex,
  1641.                                             editorList,
  1642.                                             editorMenu, 
  1643.                                             editorPopupControlHandle, 
  1644.                                             session);
  1645.  
  1646.                             // Reselect the last editor if it supports the new kind
  1647.                             TempODType selectedKind = kODNULL;
  1648.                             if ( kindItemCurrent <= kindList->Count(ev) )
  1649.                                 selectedKind = GetSelectedType(kindList, kindItemCurrent);
  1650.                             else
  1651.                                 selectedKind = GetSelectedType(translateToList, translationIndex);
  1652.  
  1653.                             ODSShort newEditorItem = 0;
  1654.                             if ( EditorSupportsKind(nsm, lastEditorID, selectedKind) )
  1655.                             {
  1656.                                 newEditorItem = IndexOfEditorInList(editorList, lastEditorID);
  1657.                             }
  1658.                             if ( newEditorItem != 0 )
  1659.                                 SetPopupControlValue(editorPopupControlHandle, newEditorItem);
  1660.                             else
  1661.                             {
  1662.                                 SetPort(dlg);
  1663.                                 InvalRect(&editorPopupRect);    // Redraw the popup
  1664.                             }
  1665.                         }
  1666.                     }
  1667.                     EnablePasteAsOkButton(dlg, kindMenu);
  1668.                     break;
  1669.             default:
  1670.                     break;
  1671.             }
  1672.         } while ((itemHit != kPasteAsOKBtn) && (itemHit != kPasteAsCancelBtn));
  1673.         
  1674.         if ( itemHit == kPasteAsOKBtn )
  1675.         {
  1676.             // update from "View" popup
  1677.             if ( !result->mergeSetting )
  1678.                 result->selectedView = GetViewSelected(dlg, session);
  1679.     
  1680.             // update from "Kind" popup
  1681.             if ( (!result->mergeSetting) && isMove && contentIsPart )
  1682.             {
  1683.                 // Selected kind is the best kind
  1684.                 result->selectedKind = GetSelectedType(kindList, bestKindIndex);
  1685.             }
  1686.             else
  1687.             {
  1688.                 ODSShort kindItem = (ODSShort) GetControlValue(kindPopupControlHandle);
  1689.                 ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1690.                 if (kindItem <= kindCount)
  1691.                 {
  1692.                     result->selectedKind = GetSelectedType(kindList, kindItem);
  1693.                 }
  1694.                 else
  1695.                 {
  1696.                     result->selectedKind = GetSelectedType(translateToList, translationIndex);
  1697.                     result->translateKind = GetSelectedType(kindList, GetIndexedElement(translateFromList, translationIndex));
  1698.                 }
  1699.             }
  1700.  
  1701.             // update from "Editor" popup
  1702.             if ( (!result->mergeSetting) && (!isMove || !contentIsPart) )
  1703.             {
  1704.                 ODSShort editorItem = (ODSShort) GetControlValue(editorPopupControlHandle);
  1705.                 result->editor = GetSelectedEditor(editorList, editorItem);
  1706.             }
  1707.         }
  1708.     
  1709.     CATCH_ALL
  1710.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  1711.         ODDisposeRoutineDescriptor(DrawDeactiveItemUPP);
  1712.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  1713.         ODDisposeRoutineDescriptor(DrawEditorNameUPP);
  1714.         ODDisposeRoutineDescriptor(DrawEmbeddedEditorNameUPP);
  1715.         ODDisposeRoutineDescriptor(modalFilter);
  1716.  
  1717.         refSaved = BeginUsingLibraryResources();
  1718.         if ( kindMenu )
  1719.         {
  1720.             DeleteMenu(kPasteAsKindPopupMenu);
  1721.             ReleaseResource((Handle) kindMenu);
  1722.         }
  1723.         if ( editorMenu )
  1724.         {
  1725.             DeleteMenu(kPasteAsEditorPopupMenu);
  1726.             ReleaseResource((Handle) editorMenu);
  1727.         }
  1728.         ODDisposeDialog(dlg);
  1729.         EndUsingLibraryResources(refSaved);
  1730.  
  1731.         ODDisposePtr((ODPtr) mergeEditorID);
  1732.         ODDisposePtr((ODPtr) embedEditorID);
  1733.         ODDisposePtr((ODPtr) preferredEditorID);
  1734.         ODDisposePtr((ODPtr) bestKind);
  1735.  
  1736.         ODDeleteObject(kindList);
  1737.         ODDeleteObject(translateToList);
  1738.         ODDeleteObject(translateFromList);
  1739.         delete editorList; editorList = kODNULL;
  1740.  
  1741.         DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1742.         DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1743.  
  1744.         SetPort(savePort);
  1745.         RERAISE;
  1746.     ENDTRY;
  1747.  
  1748.     DisposeRoutineDescriptor(DrawBoxItemUPP);
  1749.     DisposeRoutineDescriptor(DrawDeactiveItemUPP);
  1750.     DisposeRoutineDescriptor(DrawKindNameUPP);
  1751.     DisposeRoutineDescriptor(DrawEditorNameUPP);
  1752.     DisposeRoutineDescriptor(DrawEmbeddedEditorNameUPP);
  1753.     DisposeRoutineDescriptor(modalFilter);
  1754.  
  1755.     refSaved = BeginUsingLibraryResources();
  1756.     if ( kindMenu )
  1757.     {
  1758.         DeleteMenu(kPasteAsKindPopupMenu);
  1759.         ReleaseResource((Handle) kindMenu);
  1760.     }
  1761.     if ( editorMenu )
  1762.     {
  1763.         DeleteMenu(kPasteAsEditorPopupMenu);
  1764.         ReleaseResource((Handle) editorMenu);
  1765.     }
  1766.     DisposeDialog(dlg);
  1767.     EndUsingLibraryResources(refSaved);
  1768.  
  1769.     ODDisposePtr((ODPtr) mergeEditorID);
  1770.     ODDisposePtr((ODPtr) embedEditorID);
  1771.     ODDisposePtr((ODPtr) preferredEditorID);
  1772.     ODDisposePtr((ODPtr) bestKind);
  1773.  
  1774.     ODDeleteObject(kindList);
  1775.     ODDeleteObject(translateToList);
  1776.     ODDeleteObject(translateFromList);
  1777.     delete editorList; editorList = kODNULL;
  1778.  
  1779.     DisposeGlobalODNameAndZeroPtr(&gEditorName);
  1780.     DisposeGlobalODNameAndZeroPtr(&gEmbeddedEditorName);
  1781.  
  1782.     session->GetWindowState(ev)->ActivateFrontWindows(ev);
  1783.  
  1784.     SetPort(savePort);
  1785.  
  1786.     return (itemHit == kPasteAsOKBtn);
  1787. #endif
  1788. }
  1789.  
  1790. #ifndef _USE_DIALOGS_LIB_
  1791.  
  1792. //------------------------------------------------------------------------------
  1793. // ResetEditorPopup
  1794. //------------------------------------------------------------------------------
  1795.  
  1796. ODStatic void ResetEditorPopup(ODTypeList* kindList,
  1797.                                 ODUShort kindIndex,
  1798.                                 ODTypeList* translateToList,
  1799.                                 ODUShort translateToIndex,
  1800.                                 EditorSet* editorList,
  1801.                                 MenuHandle editorMenu, 
  1802.                                 ControlHandle popupCtlHndl, 
  1803.                                 ODSession* session)
  1804. {
  1805.     Environment* ev = somGetGlobalEnvironment();
  1806.     TempODType kind = kODNULL;
  1807.  
  1808.     ODSShort kindCount = (ODSShort) kindList->Count(ev);
  1809.     if (kindIndex <= kindCount)
  1810.         kind = GetSelectedType(kindList, kindIndex);
  1811.     else
  1812.         kind = GetSelectedType(translateToList, translateToIndex);
  1813.  
  1814.     editorList->RemoveAllEditors();
  1815.     SetupEditorMenu(kind,
  1816.                     editorList,
  1817.                     editorMenu,
  1818.                     popupCtlHndl,
  1819.                     session);
  1820. }
  1821.  
  1822. //------------------------------------------------------------------------------
  1823. // PrepareToDrawGray
  1824. //------------------------------------------------------------------------------
  1825. //
  1826. // Sets the foreground color to the best color midway between the forground and
  1827. // background colors; usually gray.  If no intermediate gray is available (4 or
  1828. // fewer colors available), the pen pattern is set to draw gray.
  1829.  
  1830. ODStatic Boolean PrepareToDrawGray(DialogPtr theDialog, short theItem, RGBColor* fgSaveColor)
  1831. {
  1832.     Boolean result = false;
  1833.     const short kColorPort = 0xC000;
  1834.     
  1835.     Boolean isColorPort = ((((CGrafPtr)theDialog)->portVersion & kColorPort) == kColorPort);
  1836.     
  1837.     if ( isColorPort )
  1838.     {
  1839.         RGBColor    fgNewColor;
  1840.         RGBColor    bgColor;
  1841.  
  1842.         Rect         itemRect;
  1843.         Handle        itemHandle;
  1844.         short        itemKind;
  1845.  
  1846.         GetBackColor(&bgColor);
  1847.         GetForeColor(fgSaveColor);
  1848.         fgNewColor = *fgSaveColor;
  1849.         
  1850.         GetDialogItem(theDialog, kPasteAsOKBtn, &itemKind, &itemHandle, &itemRect);
  1851.  
  1852.         Rect globalRect = itemRect;
  1853.         LocalToGlobal((Point *)&(globalRect.top));
  1854.         LocalToGlobal((Point *)&(globalRect.bottom));
  1855.         GDHandle targetDevice = GetMaxDevice(&globalRect);
  1856.         
  1857.         result = GetGray(targetDevice, &bgColor, &fgNewColor);
  1858.  
  1859.         if ( result )
  1860.             RGBForeColor(&fgNewColor);
  1861.     }
  1862.     
  1863.     if ( !result )
  1864.     {
  1865. #ifdef THINK_CPLUS
  1866.         PenPat(ODQDGlobals.gray);
  1867. #else
  1868.         PenPat(&ODQDGlobals.gray);
  1869. #endif
  1870.     }
  1871.  
  1872.     return result;
  1873. }
  1874.  
  1875. //------------------------------------------------------------------------------
  1876. // DrawDeactivePICTItem
  1877. //------------------------------------------------------------------------------
  1878. //
  1879. // Draws a dimmed image of the preceeding dialog item, which should be
  1880. // beyond the visible area of the dialog, in this item's rectangle.
  1881.  
  1882. ODStatic pascal void DrawDeactivePICTItem(DialogPtr theDialog, short theItem)
  1883. {
  1884.     Rect         itemRect, otherRect;
  1885.     Handle        itemHandle, otherHandle;
  1886.     short        itemKind, otherKind;
  1887.  
  1888.     WindowPtr    savePort;
  1889.     PenState    savePen;
  1890.     
  1891.     RGBColor    fgSaveColor;
  1892.     Boolean        isColor;
  1893.  
  1894.     GetPort(&savePort);
  1895.     SetPort(theDialog);
  1896.     GetPenState(&savePen);
  1897.     PenNormal();
  1898.  
  1899.     // Get this dialog item
  1900.     GetDialogItem(theDialog, theItem, &itemKind, &itemHandle, &itemRect);
  1901.  
  1902.     // Get the dialog item to be drawn disabled
  1903.     GetDialogItem(theDialog, theItem-1, &otherKind, &otherHandle, &otherRect);
  1904.     if ( (otherKind & ~itemDisable) == picItem )
  1905.     {
  1906.         DrawPicture((PicHandle) otherHandle, &itemRect);
  1907.         isColor = PrepareToDrawGray(theDialog, theItem, &fgSaveColor);
  1908.         if ( isColor )
  1909.             PenMode(addMax);
  1910.         else
  1911.             PenMode(patBic);
  1912.         PaintRect(&itemRect);
  1913.         if ( isColor )
  1914.             RGBForeColor(&fgSaveColor);
  1915.     }
  1916.  
  1917.     SetPenState(&savePen);
  1918.     SetPort(savePort);
  1919. }
  1920.  
  1921. //------------------------------------------------------------------------------
  1922. // InitItemActive
  1923. //------------------------------------------------------------------------------
  1924.  
  1925. ODStatic void InitItemActive(
  1926.                     DialogPtr    dlg,
  1927.                     short        itemNumber,
  1928.                     UserItemUPP    itemUPP,
  1929.                     ODBoolean    itemActive)
  1930. {
  1931.     Rect         itemRect, otherRect;
  1932.     Handle        itemHandle, otherHandle;
  1933.     short        itemKind, otherKind;
  1934.  
  1935.     // Get the rectangle from the actual item
  1936.     GetDialogItem(dlg, itemNumber, &otherKind, &otherHandle, &otherRect);
  1937.  
  1938.     // Establish the draw routine and rectangle for the user item
  1939.     GetDialogItem(dlg, itemNumber+1, &itemKind, &itemHandle, &itemRect);
  1940.     SetDialogItem(dlg, itemNumber+1, itemKind, (Handle)itemUPP, &otherRect);
  1941.  
  1942.     if ( itemActive )
  1943.         HideDialogItem(dlg, itemNumber+1);
  1944.     else
  1945.         HideDialogItem(dlg, itemNumber);
  1946. }
  1947.  
  1948. //------------------------------------------------------------------------------
  1949. // SetControlActive
  1950. //------------------------------------------------------------------------------
  1951. ODStatic void SetControlActive(
  1952.                     DialogPtr    dlg,
  1953.                     short        itemNumber,
  1954.                     ODBoolean    itemActive)
  1955. {
  1956.     short        itemType;
  1957.     Handle        itemHandle;
  1958.     Rect        itemRect;
  1959.  
  1960.     GetDialogItem(dlg, itemNumber, &itemType, &itemHandle, &itemRect);
  1961.     ASSERT_CONTROL_ITEM(itemType);
  1962.     HiliteControl((ControlHandle)itemHandle, itemActive ? kControlActive : kControlInactive);
  1963. }
  1964.  
  1965. //------------------------------------------------------------------------------
  1966. // BestContentKind
  1967. //------------------------------------------------------------------------------
  1968. ODStatic ODType BestContentKind(ODStorageUnit* contentSU)
  1969. {
  1970.     Environment* ev = somGetGlobalEnvironment();
  1971.  
  1972.     ODType bestKind = ODGetISOStrProp(ev, contentSU, kODPropPreferredKind, kODISOStr, kODNULL, kODNULL);
  1973.  
  1974.     if ( bestKind == kODNULL )
  1975.     {
  1976.         if (contentSU->Exists(ev, kODPropContents, (ODValueType)kODNULL, 1))
  1977.         {
  1978.             contentSU->Focus(ev, kODPropContents, kODPosUndefined, (ODValueType)kODNULL, 1, kODPosUndefined);
  1979.             bestKind = contentSU->GetType(ev);
  1980.         }
  1981.     }
  1982.     
  1983.     return bestKind;
  1984. }
  1985.  
  1986. //------------------------------------------------------------------------------
  1987. // SetLinkUpdateUpdateControls
  1988. //------------------------------------------------------------------------------
  1989. ODStatic void SetLinkUpdateUpdateControls(DialogPtr dlg, ODBoolean autoUpdateSetting)
  1990. {
  1991.     short    itemType;
  1992.     Handle    itemHandle;
  1993.     Rect    itemRect;
  1994.  
  1995.     GetDialogItem(dlg, kLinkInfoOnSaveRadioBtn, &itemType, &itemHandle, &itemRect);
  1996.     ASSERT_CONTROL_ITEM(itemType);
  1997.     SetControlValue((ControlHandle)itemHandle, autoUpdateSetting);
  1998.     GetDialogItem(dlg, kLinkInfoManualRadioBtn, &itemType, &itemHandle, &itemRect);
  1999.     ASSERT_CONTROL_ITEM(itemType);
  2000.     SetControlValue((ControlHandle)itemHandle, !autoUpdateSetting);
  2001. }
  2002.  
  2003. //------------------------------------------------------------------------------
  2004. // LinkInfoFilterProc
  2005. //------------------------------------------------------------------------------
  2006.  
  2007. static pascal Boolean
  2008. LinkInfoFilterProc(DialogPtr dialog, EventRecord *event, short *itemHit)
  2009. {    
  2010.     // If the event is a deactivate event, the ok button must be deactivated
  2011.     // before the surrounding outline is drawn so it is drawn dim.
  2012.     ODBoolean rslt = ODButtonKeyFilterProc(dialog,event,itemHit);
  2013.  
  2014.     if ( event->what == activateEvt )
  2015.     {
  2016.         ODOutlineDefaultButtonDrawProc(dialog, kLinkInfoDefaultButtonItem);
  2017.     }
  2018.  
  2019.     return rslt;
  2020. }
  2021.  
  2022. //------------------------------------------------------------------------------
  2023. // ShowLinkInfo
  2024. //------------------------------------------------------------------------------
  2025.  
  2026. ODStatic ODBoolean ShowLinkInfo(
  2027.                         DialogPtr              dlg,
  2028.                         ConstStr255Param    creationDate,
  2029.                         ConstStr255Param    creationTime,
  2030.                         ConstStr255Param    modificationDate,
  2031.                         ConstStr255Param    modificationTime,
  2032.                         ODBoolean            needsUpdate,
  2033.                         ODLinkInfoResult*    infoResult
  2034.                         )
  2035. {
  2036.     short    itemHit;
  2037.  
  2038.     ParamText(creationDate, creationTime, modificationDate, modificationTime);
  2039.  
  2040.     ShowWindow(dlg);
  2041.     
  2042.     ModalFilterUPP modalFilter = NewModalFilterProc(LinkInfoFilterProc);
  2043.  
  2044.     do {
  2045.         ODSLong refSaved = BeginUsingLibraryResources();
  2046.         ModalDialog(modalFilter, &itemHit);
  2047.         EndUsingLibraryResources(refSaved);
  2048.  
  2049.         switch (itemHit)
  2050.         {
  2051.         case kLinkInfoManualRadioBtn :
  2052.             if ( infoResult->autoUpdate )
  2053.             {
  2054.                 infoResult->autoUpdate = kODFalse;
  2055.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  2056.                 SetControlActive(dlg, kLinkInfoUpdateBtn, needsUpdate);
  2057.             }
  2058.             break;
  2059.             
  2060.         case kLinkInfoOnSaveRadioBtn :
  2061.             if ( !infoResult->autoUpdate )
  2062.             {
  2063.                 infoResult->autoUpdate = kODTrue;
  2064.                 SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  2065.                 SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2066.             }
  2067.             break;
  2068.         }
  2069.     } while ((itemHit != kLinkInfoOKBtn) && (itemHit != kLinkInfoCancelBtn) &&
  2070.              (itemHit != kLinkInfoUpdateBtn) && (itemHit != kLinkInfoBreakLinkBtn) &&
  2071.              (itemHit != kLinkInfoFindSrcBtn));
  2072.  
  2073.     switch (itemHit) {
  2074.     case kLinkInfoOKBtn:
  2075.             infoResult->action = kODLinkInfoOk;
  2076.             break;
  2077.     case kLinkInfoUpdateBtn:
  2078.             infoResult->action = kODLinkInfoUpdateNow;
  2079.             break;
  2080.     case kLinkInfoBreakLinkBtn:
  2081.             infoResult->action = kODLinkInfoBreakLink;
  2082.             break;
  2083.     case kLinkInfoFindSrcBtn:
  2084.             infoResult->action = kODLinkInfoFindSource;
  2085.             break;
  2086.     default:
  2087.             infoResult->action = kODLinkInfoCancel;
  2088.             break;
  2089.     }
  2090.  
  2091.     ODDisposeRoutineDescriptor(modalFilter);
  2092.  
  2093.     return (itemHit != kLinkInfoCancelBtn);
  2094. }
  2095.  
  2096. //------------------------------------------------------------------------------
  2097. // DrawKindName
  2098. //------------------------------------------------------------------------------
  2099.  
  2100. pascal void DrawKindName(DialogPtr dialog, SInt16 item)
  2101. {
  2102.     short    itemType;
  2103.     Handle    itemHandle;
  2104.     Rect    itemRect;
  2105.  
  2106.     GetDialogItem(dialog, item, &itemType, &itemHandle, &itemRect);
  2107.  
  2108.     DrawITextInDlogBox(gKindName, &itemRect, dialog, kODTrue);
  2109. }
  2110. #endif /* #ifndef _USE_DIALOGS_LIB_ */
  2111.  
  2112. //------------------------------------------------------------------------------
  2113. // ShowLinkSourceInfo
  2114. //------------------------------------------------------------------------------
  2115.  
  2116. ODBoolean ShowLinkSourceInfo(
  2117.                 ODBaseLinkSource*    linkSource,
  2118.                 ODUpdateID            change,
  2119.                 ODBoolean            changesAllowed,
  2120.                 ODLinkInfoResult*    infoResult)
  2121. {
  2122. #ifdef _USE_DIALOGS_LIB_
  2123.     SLSI slsi = kODNULL;
  2124.     CFragConnectionID connID;
  2125.     THROW_IF_ERROR( LoadODSharedLibrary( "\pDialogsLib",
  2126.             "\pShowLinkSourceInfoEx", &connID, (void**)&slsi ) );
  2127.     ODBoolean result = false;
  2128.     ODError err = (*slsi)( linkSource, change, changesAllowed,
  2129.             infoResult, &result );
  2130.     UnloadODSharedLibrary( &connID );
  2131.     THROW_IF_ERROR( err );
  2132.     return result;
  2133. #else
  2134.     Environment* ev = somGetGlobalEnvironment();
  2135.  
  2136.     WindowPtr    savePort;                        ODVolatile(savePort);
  2137.     GetPort(&savePort);
  2138.     ODSLong        refSaved;
  2139.  
  2140.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  2141.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  2142.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  2143.     short        itemType;
  2144.     Handle        itemHandle;
  2145.     Rect        itemRect;
  2146.     Str255        creationDate, modificationDate;
  2147.     Str255        creationTime, modificationTime;
  2148.     ODType        kind;
  2149.     ODBoolean    needsUpdate;
  2150.     ODBoolean    result;
  2151.  
  2152.     TRY
  2153.         ODSession* session = linkSource->GetStorageUnit(ev)->GetSession(ev);
  2154.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  2155.         
  2156.         {
  2157.             CUsingLibraryResources r;
  2158.             dlg = ODGetNewDialog(ev, kLinkSrcInfoDlgID, session, kNoDefaultButton);
  2159.             THROW_IF_NULL(dlg);
  2160.         }
  2161.  
  2162.         SetPort(dlg);
  2163.         
  2164.         {    CUsingLibraryResources r;
  2165.             SetDialogTextStyle(dlg, kLinkSrcInfoDlgID, smCurrentScript);
  2166.         }
  2167.     
  2168.         // Set the draw routine for the default button outline item
  2169.         GetDialogItem(dlg, kLinkInfoDefaultButtonItem, &itemType, &itemHandle, &itemRect);
  2170.         SetDialogItem(dlg, kLinkInfoDefaultButtonItem, itemType, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  2171.         
  2172.         // Vertical and horizontal lines need to be drawn
  2173.         GetDialogItem(dlg, kLinkInfoSeparator, &itemType, &itemHandle, &itemRect);
  2174.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  2175.         SetDialogItem(dlg, kLinkInfoSeparator, itemType, (Handle)DrawBoxItemUPP, &itemRect);
  2176.         
  2177.         ODLinkKey key;
  2178.         if (linkSource->Lock(ev, 0, &key))
  2179.         {
  2180.             TRY
  2181.                 ODStorageUnit*    contentSU = linkSource->GetContentStorageUnit(ev, key);
  2182.         
  2183.                 // Set up kind
  2184.                 kind = BestContentKind(contentSU);
  2185.                 DisposeGlobalODNameAndZeroPtr(&gKindName);
  2186.                 if ( kind && GetUserKindFromKind(nsm, kind, &gKindName) )
  2187.                 {
  2188.                     GetDialogItem(dlg, kLinkInfoKind, &itemType, &itemHandle, &itemRect);
  2189.                     DrawKindNameUPP = NewUserItemProc(DrawKindName);
  2190.                     SetDialogItem(dlg, kLinkInfoKind, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  2191.                 }
  2192.                 ODDisposePtr((ODPtr) kind);
  2193.     
  2194.                 // Set up creation date
  2195.                 SetDateTimeStrings(ODGetCreationDate(ev, ODGetSUFromPstObj(ev, linkSource)),
  2196.                                     creationDate, creationTime);
  2197.                 
  2198.                 // Set up modified date
  2199.                 SetDateTimeStrings(linkSource->GetChangeTime(ev), modificationDate, modificationTime);
  2200.             CATCH_ALL
  2201.                 linkSource->Unlock(ev, key);
  2202.                 RERAISE;
  2203.             ENDTRY
  2204.     
  2205.             linkSource->Unlock(ev, key);
  2206.         }
  2207.         
  2208.         // Set up Send Updates
  2209.         SetLinkUpdateUpdateControls(dlg, infoResult->autoUpdate);
  2210.         
  2211.         needsUpdate = (change == kODUnknownUpdate) || (change != linkSource->GetUpdateID(ev));
  2212.         
  2213.         // Disable Update Now button if updates are automatic or link is up to date.
  2214.         if ( infoResult->autoUpdate || !needsUpdate )
  2215.         {
  2216.             GetDialogItem(dlg, kLinkInfoUpdateBtn, &itemType, &itemHandle, &itemRect);
  2217.             ASSERT_CONTROL_ITEM(itemType);
  2218.             HiliteControl((ControlHandle)itemHandle, kControlInactive);
  2219.         }
  2220.     
  2221.         // Disable some items if changes are not allowed or draft is read only
  2222.         if ( !changesAllowed || DraftIsReadOnly(ev, linkSource->GetStorageUnit(ev)) )
  2223.         {
  2224.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  2225.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  2226.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  2227.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2228.         }
  2229.  
  2230.         result = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  2231.                                 modificationTime, needsUpdate, infoResult);
  2232.     
  2233.     CATCH_ALL
  2234.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2235.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2236.  
  2237.         refSaved = BeginUsingLibraryResources();
  2238.         ODDisposeDialog(dlg);
  2239.         EndUsingLibraryResources(refSaved);
  2240.  
  2241.         SetPort(savePort);
  2242.         RERAISE;
  2243.     ENDTRY
  2244.  
  2245.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2246.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2247.  
  2248.     refSaved = BeginUsingLibraryResources();
  2249.     ODDisposeDialog(dlg);
  2250.     EndUsingLibraryResources(refSaved);
  2251.  
  2252.     SetPort(savePort);
  2253.  
  2254.     return result;
  2255. #endif
  2256. }
  2257.  
  2258. #ifndef _USE_DIALOGS_LIB_
  2259.                 
  2260. //------------------------------------------------------------------------------
  2261. // SetDateTimeStrings
  2262. //------------------------------------------------------------------------------
  2263.  
  2264. ODStatic void SetDateTimeStrings(
  2265.                     ODULong        dateTime,
  2266.                     Str255        dateString, 
  2267.                     Str255        timeString)
  2268. {
  2269.     if ( dateTime == 0 )
  2270.     {
  2271.         CUsingLibraryResources r;
  2272.  
  2273.         StringHandle str = GetString(kODLinkInfoStrUnknownID);
  2274.         if ( str != kODNULL )
  2275.         {
  2276.             ODLockHandle((ODHandle) str);
  2277.             ODBlockMove((ODPtr) *str, (ODPtr) dateString, (ODULong) (*str[0])+1);
  2278.             ODUnlockHandle((ODHandle) str);
  2279.             ReleaseResource((Handle) str);
  2280.         }
  2281.         else
  2282.         {
  2283.             dateString[0] = (char) 0;
  2284.         }
  2285.         timeString[0] = (char) 0;
  2286.     }
  2287.     else
  2288.     {
  2289.         DateString(dateTime, abbrevDate, dateString, kODNULL);
  2290.         TimeString(dateTime, kODFalse, timeString, kODNULL);
  2291.     }
  2292. }
  2293.  
  2294. //------------------------------------------------------------------------------
  2295. // DraftIsReadOnly
  2296. //------------------------------------------------------------------------------
  2297. ODStatic ODBoolean DraftIsReadOnly(Environment* ev, ODStorageUnit* su)
  2298. {
  2299.     return (!HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
  2300. }
  2301. #endif
  2302.  
  2303. //------------------------------------------------------------------------------
  2304. // ShowLinkDestinationInfo
  2305. //------------------------------------------------------------------------------
  2306.  
  2307. ODBoolean ShowLinkDestinationInfo(
  2308.                 ODBaseLink*            link,
  2309.                 ODLinkInfo*         info,
  2310.                 ODBoolean            changesAllowed,
  2311.                 ODLinkInfoResult*    infoResult)
  2312. {
  2313. #ifdef _USE_DIALOGS_LIB_
  2314.  
  2315.     SLDI sldi = kODNULL;
  2316.     CFragConnectionID connID;
  2317.     THROW_IF_ERROR( LoadODSharedLibrary( "\pDialogsLib",
  2318.             "\pShowLinkDestinationInfoEx", &connID, (void**)&sldi ) );
  2319.     ODBoolean result = false;
  2320.     ODError err = (*sldi)( link, info, changesAllowed, infoResult, &result );
  2321.     UnloadODSharedLibrary( &connID );
  2322.     THROW_IF_ERROR( err );
  2323.     return result;
  2324.  
  2325. #else
  2326.     Environment* ev = somGetGlobalEnvironment();
  2327.  
  2328.     WindowPtr    savePort;                        ODVolatile(savePort);
  2329.     GetPort(&savePort);
  2330.     ODSLong        refSaved;
  2331.  
  2332.     short          itemType;
  2333.     DialogPtr      dlg = kODNULL;                    ODVolatile(dlg);
  2334.     UserItemUPP DrawBoxItemUPP = kODNULL;        ODVolatile(DrawBoxItemUPP);
  2335.     UserItemUPP DrawKindNameUPP = kODNULL;        ODVolatile(DrawKindNameUPP);
  2336.     Handle        itemHandle;
  2337.     Rect        itemRect;
  2338.     Str255        creationDate, modificationDate;
  2339.     Str255        creationTime, modificationTime;
  2340.     ODBoolean    needsUpdate;
  2341.     ODBoolean    result;
  2342.  
  2343.     TRY
  2344.         ODSession* session = link->GetStorageUnit(ev)->GetSession(ev);
  2345.         ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  2346.  
  2347.         {
  2348.             CUsingLibraryResources r;
  2349.             dlg = ODGetNewDialog(ev, kLinkDstInfoDlgID, session, kNoDefaultButton);
  2350.             THROW_IF_NULL(dlg);
  2351.         }
  2352.  
  2353.         SetPort(dlg);    
  2354.  
  2355.         {    CUsingLibraryResources r;
  2356.             SetDialogTextStyle(dlg, kLinkDstInfoDlgID, smCurrentScript);
  2357.         }
  2358.     
  2359.         // Set the draw routine for the default button outline item
  2360.         GetDialogItem(dlg, kLinkInfoDefaultButtonItem, &itemType, &itemHandle, &itemRect);
  2361.         SetDialogItem(dlg, kLinkInfoDefaultButtonItem, itemType, (Handle)GetODOutlineDefaultButtonDrawProc(), &itemRect);
  2362.         
  2363.         // Vertical and horizontal lines need to be drawn
  2364.         GetDialogItem(dlg, kLinkInfoSeparator, &itemType, &itemHandle, &itemRect);
  2365.         DrawBoxItemUPP = NewUserItemProc(DrawGrayBoxItem);
  2366.         SetDialogItem(dlg, kLinkInfoSeparator, itemType, (Handle) DrawBoxItemUPP, &itemRect);
  2367.         
  2368.         // Set up kind
  2369.         DisposeGlobalODNameAndZeroPtr(&gKindName);
  2370.         if ( info->kind && GetUserKindFromKind(nsm, info->kind, &gKindName) )
  2371.         {
  2372.             GetDialogItem(dlg, kLinkInfoKind, &itemType, &itemHandle, &itemRect);
  2373.             DrawKindNameUPP = NewUserItemProc(DrawKindName);
  2374.             SetDialogItem(dlg, kLinkInfoKind, userItem+itemDisable, (Handle) DrawKindNameUPP, &itemRect);
  2375.         }
  2376.  
  2377.         // Set up creation date
  2378.         SetDateTimeStrings(info->creationTime, creationDate, creationTime);
  2379.         
  2380.         // Set up modified date
  2381.         SetDateTimeStrings(info->changeTime, modificationDate, modificationTime);
  2382.  
  2383.         // Set up Send Updates
  2384.         SetLinkUpdateUpdateControls(dlg, info->autoUpdate);
  2385.         
  2386.         needsUpdate = (info->change == kODUnknownUpdate) || (info->change != link->GetUpdateID(ev));
  2387.         
  2388.         // Disable Update Now button if updates are automatic or destination is up to date.
  2389.         if ( info->autoUpdate || !needsUpdate )
  2390.         {
  2391.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2392.         }
  2393.  
  2394.         // Disable some items if changes are not allowed or draft is read only
  2395.         if ( !changesAllowed || DraftIsReadOnly(ev, link->GetStorageUnit(ev)) )
  2396.         {
  2397.             SetControlActive(dlg, kLinkInfoOnSaveRadioBtn, kODFalse);
  2398.             SetControlActive(dlg, kLinkInfoManualRadioBtn, kODFalse);
  2399.             SetControlActive(dlg, kLinkInfoBreakLinkBtn, kODFalse);
  2400.             SetControlActive(dlg, kLinkInfoUpdateBtn, kODFalse);
  2401.         }
  2402.  
  2403.         result = ShowLinkInfo(dlg, creationDate, creationTime, modificationDate, 
  2404.                                 modificationTime, needsUpdate, infoResult);
  2405.  
  2406.     CATCH_ALL
  2407.         ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2408.         ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2409.  
  2410.         refSaved = BeginUsingLibraryResources();
  2411.         ODDisposeDialog(dlg);
  2412.         EndUsingLibraryResources(refSaved);
  2413.  
  2414.         SetPort(savePort);
  2415.         RERAISE;
  2416.     ENDTRY
  2417.  
  2418.     ODDisposeRoutineDescriptor(DrawBoxItemUPP);
  2419.     ODDisposeRoutineDescriptor(DrawKindNameUPP);
  2420.  
  2421.     refSaved = BeginUsingLibraryResources();
  2422.     ODDisposeDialog(dlg);
  2423.     EndUsingLibraryResources(refSaved);
  2424.  
  2425.     SetPort(savePort);
  2426.  
  2427.     return result;
  2428. #endif
  2429. }
  2430.  
  2431. //------------------------------------------------------------------------------
  2432. // ShowLinkUpdateAlert
  2433. //------------------------------------------------------------------------------
  2434.  
  2435. ODBoolean ShowLinkUpdateAlert( /*ODUShort count*/ )
  2436. {
  2437.     Environment* ev = somGetGlobalEnvironment();
  2438.  
  2439.     // ODUnused(count);
  2440.  
  2441.     gSession->GetWindowState(ev)->DeactivateFrontWindows(ev);
  2442.     ODSShort alertResult = ShowAlert(ev, kLinkUpdateAlertID, GetODButtonKeyFilterProc(), gSession);
  2443.     gSession->GetWindowState(ev)->ActivateFrontWindows(ev);
  2444.  
  2445.     ResetAlertStage();
  2446.  
  2447.     return (alertResult == kLinkUpdateContinueBtn);
  2448. }
  2449.  
  2450. //------------------------------------------------------------------------------
  2451. // ShowLinkStatusAlert
  2452. //------------------------------------------------------------------------------
  2453.  
  2454. void ShowLinkStatusAlert(ODError error)
  2455. {
  2456.     Environment* ev = somGetGlobalEnvironment();
  2457.  
  2458.     ODSShort alertID;
  2459.     Str63 numberString;
  2460.  
  2461.     NumToString(error, numberString);
  2462.     ParamText(numberString, 0, 0, 0);
  2463.  
  2464.     if ( error == kODErrCannotFindLinkSourceEdition )
  2465.         alertID = kLinkEditionAlertID;
  2466.     else
  2467.         alertID = kLinkStatusAlertID;
  2468.  
  2469.     gSession->GetWindowState(ev)->DeactivateFrontWindows(ev);
  2470.     ShowAlert(ev, alertID, GetODButtonKeyFilterProc(), gSession);
  2471.     gSession->GetWindowState(ev)->ActivateFrontWindows(ev);
  2472.  
  2473.     ResetAlertStage();
  2474. }
  2475.