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 / Utilities / InfoUtil.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  55.7 KB  |  2,168 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        InfoUtil.cpp
  3.  
  4.     Contains:    implementation of Info getters & setters
  5.  
  6.     Owned by:    Doug Hill
  7.  
  8.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Change History (most recent first):
  11.  
  12.         <13>     7/10/96    EL        1366381: if there is no comment,
  13.                                     ODSetPOComments should delete comment
  14.                                     property.
  15.         <12>      7/8/96    EL        1364853: Add ODSetPartNameReturnError to do
  16.                                     set part name but get error code back.
  17.         <11>     6/24/96    RA        T10025: Wrapped obsoleted utils w/
  18.                                     _OD_IMPL_ ; they are not available to parts
  19.         <10>     6/19/96    EL        1348424: Deactivate file types that appears
  20.                                     in "kinds" popup
  21.          <9>     6/18/96    TJ        Don't use private ODPartWrapper class
  22.          <8>     6/12/96    RA        1301627, 1297102: ODGetIconFamily now looks
  23.                                     in all volume DTDB's , added StVolumeLoop;
  24.                                     ODGetPartName no longer crashes if window
  25.                                     isn't registered
  26.          <7>      6/5/96    EL        1355529: Move InitKindsPopUp from Info.cpp
  27.                                     to here for sharing, add parameters for
  28.                                     AddTypesToMenu to check for default data
  29.                                     kind.
  30.          <6>      6/4/96    EL        1279544: Move GetTypeListItem from
  31.                                     TransDlg.cpp to InfoUtil.cpp.
  32.          <5>     5/31/96    jpa        T10012: Added ODGetIconFilePlatformCreator.
  33.          <4>     5/28/96    EL        #1328903: slash and other meta characters
  34.                                     should be allowed in the kind popup menu.
  35.                                     #1348424: File Types should not appear in
  36.                                     kind popup menu.
  37.          <3>    .04.1996    NP        1330731: Don't use stationery property
  38.                                     anymore.
  39.          <2>     3/15/96    DH        1.0.2: OpenDoc: Drag of no-part to trash
  40.                                     rejected. Fixed
  41.                                     ODGetIconFilePlatformTypeFromPartSU so that
  42.                                     it has proper exception handling and a
  43.                                     default return value.
  44.  
  45.     To Do:
  46.     In Progress:
  47.     
  48. */
  49.  
  50. #ifndef _PLFMDEF_
  51. #include "PlfmDef.h"
  52. #endif
  53.  
  54. #ifndef _STDTYPIO_
  55. #include "StdTypIO.h"
  56. #endif
  57.  
  58. #ifndef _USERSRCM_
  59. #include "UseRsrcM.h"
  60. #endif
  61.  
  62. #ifndef SOM_ODSession_xh
  63. #include <ODSessn.xh>
  64. #endif
  65.  
  66. #ifndef SOM_ODDraft_xh
  67. #include <Draft.xh>
  68. #endif
  69.  
  70. #ifndef SOM_ODDocument_xh
  71. #include <Document.xh>
  72. #endif
  73.  
  74. #ifndef SOM_ODContainer_xh
  75. #include <ODCtr.xh>
  76. #endif
  77.  
  78. #ifndef SOM_ODWindowState_xh
  79. #include <WinStat.xh>
  80. #endif
  81.  
  82. #ifndef SOM_ODWindow_xh
  83. #include <Window.xh>
  84. #endif
  85.  
  86. #ifndef SOM_ODStorageUnit_xh
  87. #include <StorageU.xh>
  88. #endif
  89.  
  90. #ifndef SOM_Module_OpenDoc_StdProps_defined
  91. #include <StdProps.xh>
  92. #endif
  93.  
  94. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  95. #include <StdTypes.xh>
  96. #endif
  97.  
  98. #ifndef SOM_Module_OpenDoc_StdDefs_defined
  99. #include <StdDefs.xh>
  100. #endif
  101.  
  102. #ifndef _ODUTILS_
  103. #include <ODUtils.h>
  104. #endif
  105.  
  106. #ifndef _DLOGUTIL_
  107. #include <DlogUtil.h>
  108. #endif
  109.  
  110. #ifndef SOM_ODFrame_xh
  111. #include <Frame.xh>
  112. #endif
  113.  
  114. #ifndef SOM_ODFacet_xh
  115. #include <Facet.xh>
  116. #endif
  117.  
  118. #ifndef SOM_ODPart_xh
  119. #include <Part.xh>
  120. #endif
  121.  
  122. #ifndef SOM_ODBinding_xh
  123. #include <ODBindng.xh>
  124. #endif
  125.  
  126. #ifndef SOM_ODStorageUnitView_xh
  127. #include <SUView.xh>
  128. #endif
  129.  
  130. #ifndef _PASCLSTR_
  131. #include "PasclStr.h"
  132. #endif
  133.  
  134. #ifndef _ODMEMORY_
  135. #include "ODMemory.h"
  136. #endif
  137.  
  138. #ifndef _PLFMFILE_
  139. #include <PlfmFile.h>
  140. #endif
  141.  
  142. #ifndef _ITEXT_
  143. #include <IText.h>
  144. #endif
  145.  
  146. #ifndef SOM_ODTypeList_xh
  147. #include <TypeList.xh>
  148. #endif
  149.  
  150. #ifndef SOM_ODTypeListIterator_xh
  151. #include <TypLsItr.xh>
  152. #endif
  153.  
  154. #ifndef _EXCEPT_
  155. #include "Except.h"
  156. #endif
  157.  
  158. #ifndef _BNDNSUTL_
  159. #include "BndNSUtl.h"
  160. #endif
  161.  
  162. #ifndef _TRANSUTL_
  163. #include <TransUtl.h>
  164. #endif
  165.  
  166. #ifdef __SC__
  167. #ifndef __PACKAGES__
  168. #include <Packages.h>
  169. #endif
  170. #else
  171. #ifndef __TEXTUTILS__
  172. #include <TextUtils.h>
  173. #endif
  174. #endif
  175.  
  176. #ifndef __STRING__
  177. #include <String.h>
  178. #endif
  179.  
  180. #ifndef __GESTALTEQU__
  181. #include <GestaltEqu.h>
  182. #endif
  183.  
  184. #ifndef __DIALOGS__
  185. #include <Dialogs.h>
  186. #endif
  187.  
  188. #ifndef __TOOLUTILS__
  189. #include <ToolUtils.h>
  190. #endif
  191.  
  192. #ifndef __FONTS__
  193. #include <Fonts.h>
  194. #endif
  195.  
  196. #ifndef __CONTROLS__
  197. #include <Controls.h>
  198. #endif
  199.  
  200. #ifndef __ICONS__
  201. #include <Icons.h>
  202. #endif
  203.  
  204. #ifndef __FINDER__
  205. #include <Finder.h>
  206. #endif
  207.  
  208. #ifndef _INFOUTIL_
  209. #include "InfoUtil.h"
  210. #endif
  211.  
  212. #ifndef SOM_ODTranslation_xh
  213. #include <Translt.xh>
  214. #endif
  215.  
  216. #ifndef _EDITRSET_
  217. #include "EditrSet.h"
  218. #endif
  219.  
  220. #ifndef _STORUTIL_
  221. #include <StorUtil.h>
  222. #endif
  223.  
  224. #ifndef _ISOSTR_
  225. #include "ISOStr.h"
  226. #endif
  227.  
  228. #ifndef SOM_ODWindowIterator_xh
  229. #include <WinIter.xh>
  230. #endif
  231.  
  232. #ifndef SOM_ODNameSpaceManager_xh
  233. #include <NmSpcMg.xh>
  234. #endif
  235.  
  236. #ifndef SOM_ODValueNameSpace_xh
  237. #include <ValueNS.xh>
  238. #endif
  239.  
  240. #ifndef SOM_ODStorageSystem_xh
  241. #include <ODStor.xh>
  242. #endif
  243.  
  244. #ifndef _NMSPCUTL_
  245. #include <NmSpcUtl.h>
  246. #endif
  247.  
  248. #ifndef _UTILDEFS_
  249. #include "UtilDefs.h"
  250. #endif
  251.  
  252. #ifndef _TEMPOBJ_
  253. #include <TempObj.h>
  254. #endif
  255.  
  256. #ifndef _ORDCOLL_
  257. #include "OrdColl.h"
  258. #endif
  259.  
  260. #ifndef _STDTYPIO_
  261. #include <StdTypIO.h>
  262. #endif
  263.  
  264. #ifndef _DOCUTILS_
  265. #include "DocUtils.h"
  266. #endif
  267.  
  268. #pragma segment Info
  269.  
  270. //==============================================================================
  271. // Constants
  272. //==============================================================================
  273.  
  274. // this duplicate the definition from StorDef.h
  275. const    ODValueType    kODAppleFileTypePrefix    = "+//ISO 9070/ANSI::113722::US::CI LABS::MacOS:FileType:";
  276.  
  277. const short kControlInactive = 255;
  278. const short kControlActive = 0;
  279. #define SKIPOMPARSE
  280. #ifdef SKIPOMPARSE
  281. static const char* const kODIconFamilyBaseString = kODIconFamily ":";
  282. #else
  283. static const char* const kODIconFamilyBaseString = "^^^^correct def.^^^^^";
  284. #endif
  285. static const ResType            kIconType[6] = {'ICN#','icl4','icl8','ics#','ics4','ics8'};
  286. static const short                kIconSize[6] = {256,   512,   1024,  64,    128,   256   };
  287.  
  288. const ODPlatformType kODFileType_hfs = 0x68667320;    // 'hfs '
  289.  
  290. //==============================================================================
  291. // Static Function declarations
  292. //==============================================================================
  293.  
  294. ODTime    ODGetDateProperty(Environment* ev, 
  295.             ODStorageUnit* su,
  296.             ODPropertyName prop);
  297.  
  298. void    ODSetDateProperty(Environment* ev, 
  299.             ODStorageUnit* su,
  300.             ODPropertyName prop,
  301.             ODTime dateTime);
  302.  
  303. ODStatic ODBoolean         ODUserRenameFile(Environment* ev,
  304.                                 ODSession* session,
  305.                                 PlatformFile*    usersFile, 
  306.                                 ODIText* name,
  307.                                 DescType replaceOption);
  308. // If PlatformFile is made a shared utility, then the above function should probably be
  309. // integrated into the PlatformFile::Rename method.
  310.  
  311. ODStatic ODIconFamily    GetGenericIcon( short iconID );
  312.  
  313. ODStatic OSErr             DetachIconProc( ResType, Handle *theIcon, void */*yourDataPtr*/ );
  314.  
  315. ODStatic ODBoolean        CommentsDontMatch(ODIText* dtComments, ODIText* propComments);
  316.  
  317. //==============================================================================
  318. // Info functions
  319. //==============================================================================
  320.  
  321.  
  322. ODStorageUnit* ODGetSUFromPstObj(Environment* ev, ODPersistentObject* pstobj)
  323. {
  324.     return pstobj->GetStorageUnit(ev);
  325. }
  326.  
  327. //-------------------------------------------------------------------------------------
  328. // Part & Frame Property getters and setters
  329. //-------------------------------------------------------------------------------------
  330.  
  331. ODIText*
  332. ODGetPOComments(Environment* ev, ODPart *part, ODIText* comments)
  333. {
  334.     ODStorageUnit*    su = ODGetSUFromPstObj(ev, part);
  335.     ODIText*        propComments;
  336.  
  337.     propComments = ODGetITextProp(ev, su, kODPropComments, kODMacIText, comments);
  338.     return propComments;
  339. }
  340.  
  341. void    ODSetPOComments(Environment* ev, ODPart *part, ODIText* comments)
  342. {
  343.     ODStorageUnit*    su = ODGetSUFromPstObj(ev, part);
  344.     
  345.     if (comments)
  346.         ODSetITextProp(ev, su, kODPropComments, kODMacIText, comments);
  347.     else {
  348.         if ( ODSUExistsThenFocus(ev, su, kODPropComments, kODMacIText) )
  349.             su->Remove(ev);
  350.         if ( ODSUExistsThenFocus(ev, su, kODPropComments, kODIntlText) )
  351.             su->Remove(ev);
  352.     }
  353. }
  354.  
  355.  
  356. ODIText*
  357. ODGetComments(Environment* ev, ODFrame* frame, ODIText* comments)
  358. {
  359.     TempODPart        part = frame->AcquirePart(ev);
  360.     ODIText*        propComments;
  361.     ODIText*        dtComments;
  362.  
  363.     propComments = ODGetPOComments(ev, part, comments);
  364.     if (comments && !propComments)
  365.         propComments = comments;
  366.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  367.     if (usersFile)
  368.     {
  369.         dtComments = usersFile->GetComments();
  370.         if (dtComments && GetITextStringLength(dtComments) == 0)
  371.         {
  372.             // since there are no desktop comments
  373.             // make the desktop comments match the property
  374.             usersFile->SetComments(propComments);
  375.         }
  376.         else if (CommentsDontMatch(dtComments, propComments) && dtComments)
  377.         {
  378.             // if there are desktop comments and the property comments don't match
  379.             // then the desktop comments take precedence, so return the desktop comments
  380.             DisposeIText(propComments);
  381.             propComments = dtComments;
  382.             dtComments = kODNULL;
  383.         }
  384.         DisposeIText(dtComments);
  385.     }
  386.     return propComments;
  387. }
  388.  
  389. void    ODSetComments(Environment* ev, ODFrame* frame, ODIText* comments)
  390. {
  391.     TempODPart        part = frame->AcquirePart(ev);
  392.     ODSetPOComments(ev, part, comments);
  393.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  394.     if (usersFile)
  395.         usersFile->SetComments(comments);
  396. }
  397.  
  398.  
  399. ODULong    ODGetPOSize(Environment* ev, ODPersistentObject* pstobj)
  400. {
  401.     ODStorageUnit* su = ODGetSUFromPstObj(ev, pstobj);
  402.     su->Focus(ev, kODNULL, kODPosAll, kODNULL,0, kODPosAll);
  403.     return su->GetSize(ev);
  404. }
  405.  
  406. ODID ODGetPOID(Environment* ev, ODPersistentObject* pstobj)
  407. {
  408.     ODStorageUnit* su = ODGetSUFromPstObj(ev, pstobj);
  409.     su->Focus(ev, kODNULL, kODPosAll, kODNULL,0, kODPosAll);
  410.     return su->GetID(ev);
  411. }
  412.  
  413. ODTime    ODGetDateProperty(Environment* ev, 
  414.             ODStorageUnit* su,
  415.             ODPropertyName prop)
  416. {    return ODGetTime_TProp(ev, su, prop, kODTime_T);}
  417.  
  418. void    ODSetDateProperty(Environment* ev, 
  419.             ODStorageUnit* su,
  420.             ODPropertyName prop,
  421.             ODTime dateTime)
  422. {    ODSetTime_TProp(ev, su, prop, kODTime_T, dateTime);}
  423.  
  424.  
  425. ODULong    ODGetCreationDate(Environment* ev, 
  426.                 ODStorageUnit* su)
  427. {    return ODGetDateProperty(ev, su, kODPropCreateDate);}
  428.  
  429. void    ODSetCreationDate(Environment* ev, 
  430.                 ODStorageUnit* su,
  431.                 ODTime dateTime)
  432. {    ODSetDateProperty(ev, su, kODPropCreateDate, dateTime);}
  433.  
  434.  
  435. ODULong    ODGetModificationDate(Environment* ev, 
  436.                 ODStorageUnit* su)
  437. {    return ODGetDateProperty(ev, su, kODPropModDate);}
  438.  
  439. void    ODSetModificationDate(Environment* ev, 
  440.                 ODStorageUnit* su,
  441.                 ODTime dateTime)
  442. {    ODSetDateProperty(ev, su, kODPropModDate, dateTime);}
  443.  
  444.  
  445. ODIText*    ODGetModifiedBy(Environment* ev, 
  446.                 ODStorageUnit* su, ODIText* userName)
  447. {
  448.     return ODGetITextProp(ev, su, kODPropModUser,
  449.             kODMacIText, userName);
  450. }
  451.  
  452. void        ODSetModifiedBy(Environment* ev, 
  453.                 ODStorageUnit* su, ODIText* userName)
  454. {
  455.     ODSetITextProp(ev, su, kODPropModUser,
  456.             kODMacIText, userName);
  457. }
  458.  
  459.  
  460. //-------------------------------------------------------------------------------------
  461. // Part only Property getters and setters
  462. //-------------------------------------------------------------------------------------
  463. ODIText*    ODGetPartName(Environment* ev, 
  464.                 ODFrame* frame, ODIText* name)
  465. {
  466.     TempODPart part = frame->AcquirePart(ev);
  467.     TempODIText partName = ODGetPOName(ev, part, name);
  468.     
  469.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  470.     if (usersFile)
  471.     {
  472.         TempODIText fileName = usersFile->GetName();
  473.         if ( CommentsDontMatch( fileName, partName ) )
  474.             return CopyIText( fileName );
  475.     }
  476.     return CopyIText( partName );
  477. }
  478.  
  479. ODError    ODSetPartNameReturnError(Environment* ev, 
  480.                 ODFrame* frame, ODIText* name, DescType replaceOption)
  481.         // Renames the part of the frame passed in.
  482.         // If there is any error return the error.
  483.         // The frame helps more easily determine whether
  484.         // the part is the root part of the document or not.
  485.         // For example, renaming the root part of the document could fail
  486.         // if there was a file with the same name and the user canceled the
  487.         // "Replace?" dialog.
  488. {
  489.     ASSERT(frame != kODNULL, kODErrIllegalNullInput);
  490.     
  491.     TempODPart part = frame->AcquirePart(ev);
  492.     TempODWindow window = frame->AcquireWindow(ev);
  493.                 
  494.     ODFrame*     contFrame = frame->AcquireContainingFrame(ev);
  495.     ODBoolean     isRootPart = (contFrame == kODNULL);
  496.     ODReleaseObject(ev, contFrame);
  497.     
  498.     ODBoolean    isRootPartOfDocument = isRootPart && window->IsRootWindow(ev);
  499.     
  500.     ODName*        oldName = kODNULL; ODVolatile(oldName);
  501.     PlatformFile*    usersFile = kODNULL; ODVolatile(usersFile);
  502.     ODError        error = noErr;
  503.  
  504.     TRY
  505.         ODStorageUnit*    partSU    = ODGetSUFromPstObj(ev, part);
  506.         ODSession*        session = partSU->GetSession(ev);
  507.         oldName = ODGetPartName(ev, frame, kODNULL); 
  508.  
  509.         if (isRootPartOfDocument)
  510.         {
  511.             ODDraft*        draft = partSU->GetDraft(ev);
  512.             usersFile = 
  513.                 GetPlatformFileFromContainer(ev, draft->GetDocument(ev)->GetContainer(ev));
  514.  
  515.             if (ODUserRenameFile(ev, session, usersFile, name, replaceOption))
  516.             {
  517.                 ODWindowState* windowState = session->GetWindowState(ev);
  518.                 windowState->SetDefaultWindowTitles(ev, draft);
  519.                 ODSetPOName(ev, part, name);
  520.                 ODRenamePartWindows(ev,session,part,oldName,name);
  521.                 if (isRootPart)
  522.                 {
  523.                     Str255 pName;
  524.                     GetITextPString(name, pName);
  525.                     SetWTitle(window->GetPlatformWindow(ev), pName);
  526.                 }
  527.             }
  528.         }
  529.         else
  530.         {
  531.             ODSetPOName(ev, part,name);
  532.             ODRenamePartWindows(ev,session,part,oldName,name);
  533.         }
  534.         
  535.     CATCH_ALL
  536.         error = ErrorCode();
  537. #if ODDebug
  538.         if (error != userCanceledErr)
  539.             WARN("ODSetPartName failed, error %ld",error);
  540. #endif
  541.     ENDTRY
  542.  
  543.     ODDeleteObject(usersFile);
  544.     DisposeIText(oldName);
  545.     
  546.     return error;
  547. }
  548.  
  549. ODBoolean    ODSetPartName(Environment* ev, 
  550.                 ODFrame* frame, ODIText* name, DescType replaceOption)
  551.         // Renames the part of the frame passed in.
  552.         // Returns whether or not it succeeded.
  553.         // Just call ODSetPartNameReportError and return false if there is error
  554. {
  555.     return (ODSetPartNameReturnError(ev, frame, name, replaceOption) == noErr);
  556. }
  557.  
  558. void
  559. ODRenamePartWindows( Environment *ev, ODSession *session,
  560.                      ODPart *part, ODIText *oldName, ODIText *name )
  561. {
  562.     // go through all windows which have this part as their root, and
  563.     // have the current name of the part as a prefix
  564.     // rename their prefix to be the new name
  565.     Str255    pOldName;
  566.     Str255    pNewName;
  567.     Str255    pWinTitle;
  568.     ODUByte pOldNameLen;
  569.     ODUByte pNewNameLen;
  570.     
  571.     GetITextPString(oldName, pOldName);
  572.     pOldNameLen = pOldName[0];
  573.     GetITextPString(name, pNewName);
  574.     pNewNameLen = pNewName[0];
  575.     
  576.     ODWindowIterator* iter = session->GetWindowState(ev)->CreateWindowIterator(ev);
  577.     for (ODWindow* window = iter->First(ev); 
  578.          iter->IsNotComplete(ev);
  579.          window = iter->Next(ev))
  580.     {
  581.         TempODPart winPart = window->GetRootFrame(ev)->AcquirePart(ev);
  582.         if (ODObjectsAreEqual(ev, part, winPart))
  583.         {
  584.             // Check to see if name of window has pOldName as prefix
  585.             ODPlatformWindow pwindow = window->GetPlatformWindow(ev);
  586.             GetWTitle(pwindow, pWinTitle);
  587.             if (!strncmp((char*)&pWinTitle[1], (char*)&pOldName[1], pOldNameLen) &&
  588.                     !EqualPascalStrings(pWinTitle, pNewName))
  589.             {
  590.                 ODUByte suffixLen = pWinTitle[0] - pOldNameLen;
  591.                 if (suffixLen + pNewNameLen > 255) 
  592.                     suffixLen = 255 - pNewNameLen;
  593.                 strncpy((char*)&pNewName[pNewNameLen+1], 
  594.                         (char*)&pWinTitle[pOldNameLen+1],
  595.                         suffixLen);
  596.                 pNewName[0] = pNewNameLen+suffixLen;
  597.                 SetWTitle(pwindow, pNewName);
  598.             }
  599.         }
  600.     }
  601.     ODDeleteObject(iter);
  602. }
  603.  
  604.  
  605. ODIText*    ODGetPOName(Environment* ev, ODPersistentObject* pstobj,ODIText* name)
  606. {
  607.     return ODGetITextProp(ev, ODGetSUFromPstObj(ev, pstobj), kODPropName, kODMacIText,name);
  608. }
  609.  
  610. void        ODSetPOName(Environment* ev, ODPersistentObject* pstobj,ODIText* name)
  611. {
  612.     ODSetITextProp(ev, ODGetSUFromPstObj(ev, pstobj), kODPropName, kODMacIText, name);
  613. }
  614.  
  615. void        ODSetPONameUsingSU(Environment* ev, ODStorageUnit* su, ODIText* name)
  616. {
  617.     ODSetITextProp(ev, su, kODPropName, kODMacIText, name);
  618. }
  619.  
  620. ODName*    ODGetCategory(Environment* ev, ODPart* part, ODNameSpaceManager* nsm)
  621. {
  622.     return ODGetCatFromPartSU(ev, ODGetSUFromPstObj(ev, part), nsm);
  623. }
  624.  
  625. ODName*    ODGetCatFromPartSU(Environment* ev, ODStorageUnit* su, ODNameSpaceManager* nsm)
  626. {
  627.     ODType kind = ODGetKindFromPartSU(ev, su);
  628.     ODName*    categoryName = ODGetCatFromKind(ev, kind, nsm);
  629.     ODDisposePtr( kind );
  630.  
  631.     return categoryName;
  632. }
  633.  
  634. #ifdef _OD_IMPL_
  635. ODName*    ODGetCatFromKind(Environment* ev, ODType kind, ODNameSpaceManager* nsm)
  636. {
  637.     StringHandle strHandle = 0;
  638.     ODTypeList* categoryList = GetCategoriesOfKind(nsm, kind);
  639.     ODTypeListIterator* catIter = kODNULL;
  640.     ODType category = kODNULL;
  641.     ODName*    categoryName = kODNULL;
  642.     
  643.     if (categoryList)
  644.     {
  645.         catIter = categoryList->CreateTypeListIterator(ev);
  646.         category = catIter->First(ev);
  647.         ODDeleteObject(catIter);
  648.     }
  649.     
  650.     if (category == kODNULL || !GetUserCatFromCat(nsm, category, &categoryName)) {
  651.         CUsingLibraryResources r;
  652.         categoryName = GetODIText(kODPartInfoStrUnknownID);
  653.     }
  654.     //else // make a disposable copy // NO NEED TO! GetUserCatFromCat returns a copy!
  655.     //    categoryName = CopyIText(categoryName);
  656.         
  657.     ODDisposePtr(category);
  658.  
  659.     return categoryName;
  660. }
  661. #endif
  662.  
  663. ODType    ODGetKindFromPartSU(Environment* ev, ODStorageUnit* su)
  664. {
  665.     ODULong unused;
  666.     ODType kind = ODGetISOStrProp(ev, su, kODPropPreferredKind, kODISOStr, kODNULL, &unused);
  667.     if ( kind == kODNULL )
  668.         if ( su->Exists(ev, kODPropContents, (ODValueType) kODNULL,1) )
  669.         {
  670.             su->Focus(ev, kODPropContents, kODPosSame, (ODValueType) kODNULL,1, kODPosSame);
  671.             kind = su->GetType(ev);
  672.  
  673.             ODTranslation* translation = su->GetSession(ev)->GetTranslation(ev);
  674.             TempODType hfsType = 
  675.                 translation->GetISOTypeFromPlatformType(ev, kODFileType_hfs, kODPlatformDataType);
  676.  
  677.             if ( ODISOStrEqual(kind, hfsType) )
  678.             {
  679.                 ODDisposePtr(kind);
  680.                 kind = kODNULL;
  681.                 if ( su->Exists(ev, kODPropContents, (ODValueType) kODNULL,2) )
  682.                 {
  683.                     su->Focus(ev, kODPropContents, kODPosSame, (ODValueType) kODNULL,2, kODPosSame);
  684.                     kind = su->GetType(ev);
  685.                 }
  686.             }
  687.         }
  688.     return kind;
  689. }
  690.  
  691. ODType    ODGetKind(Environment* ev, ODPart* part)
  692. {
  693.     return ODGetKindFromPartSU(ev, ODGetSUFromPstObj(ev, part));
  694. }
  695.  
  696. ODPlatformType ODGetIconFilePlatformTypeFromPartSU(Environment* ev, ODStorageUnit* su)
  697. {
  698.     ODType partKind = kODNULL;
  699.     ODPlatformType partOSType;
  700.     ODVolatile(partKind);
  701.     ODVolatile(partOSType);
  702.     
  703.     TRY
  704.         ODSession* session = su->GetSession(ev);
  705.     
  706.         partKind = ODGetKindFromPartSU(ev, su);
  707.         partOSType = session->GetTranslation(ev)->
  708.                                 GetPlatformTypeFromISOType(ev, partKind);
  709.         if (partOSType != kODNULL)
  710.         {
  711.             ((ODUByte*)(&partOSType))[0] = kODPlatformKindFileChar1;
  712.         }
  713.         else
  714.         {
  715.             ODBoolean    partOSTypeFound = kODFalse;
  716.             ODValueNameSpace*    osTypeNameSpace = (ODValueNameSpace*)
  717.                 (session->GetNameSpaceManager(ev)->HasNameSpace(ev, kODKindOldMacOSType));
  718.         
  719.             if (osTypeNameSpace)
  720.             {
  721.                 ODPlatformType* typePtr;
  722.                 ODULong        unusedLength;
  723.                 partOSTypeFound = ValueNameSpaceGetEntry(osTypeNameSpace, 
  724.                                                         ev, partKind, 
  725.                                                         (ODPtr*) &typePtr, 
  726.                                                         &unusedLength);
  727.                 if (partOSTypeFound)
  728.                 {
  729.                     partOSType = *typePtr;
  730.                     ODDeleteObject( typePtr );
  731.                 }
  732.             }
  733.             if (!partOSTypeFound)
  734.                 partOSType = kODShellSignature;
  735.         }
  736.         
  737.         ODDisposePtr(partKind);
  738.     CATCH_ALL
  739.         ODDisposePtr(partKind);
  740.         partOSType = kODShellSignature;
  741.     ENDTRY
  742.  
  743.     return partOSType;
  744. }
  745.  
  746.  
  747. static ODPlatformType
  748. LookupEditorCreator( Environment *ev, ODSession *session, ODEditor editor )
  749. {
  750.     ODPlatformType creator = kODShellSignature;
  751.     
  752.     if( editor ) {
  753.         ODNameSpaceManager *nsm = session->GetNameSpaceManager(ev);
  754.         ODValueNameSpace *ns = (ODValueNameSpace*)
  755.                                 nsm->HasNameSpace(ev, kODEditorPlatformSignature);
  756.         if (ns) {
  757.             ODPlatformType* typePtr;
  758.             ODULong        unusedLength;
  759.             if( ValueNameSpaceGetEntry(ns, ev, editor,  (ODPtr*) &typePtr, &unusedLength) ) {
  760.                 creator = *typePtr;
  761.                 ODDeleteObject( typePtr );
  762.             }
  763.         }
  764.     }
  765.     return creator;
  766. }
  767.  
  768.  
  769. ODPlatformType ODGetIconFilePlatformCreatorFromPartSU( Environment *ev, ODStorageUnit *su )
  770. {
  771.     // Ask Binding which editor will be used for this storage unit:
  772.     TempODISOStr editor = ODGetSession(ev,su)->GetBinding(ev)
  773.                                 ->ChooseEditorForPart(ev,su,kODNULL);
  774.     return LookupEditorCreator(ev, ODGetSession(ev,su), editor);
  775. }
  776.  
  777.  
  778. ODPlatformType ODGetIconFilePlatformCreator( Environment *ev, ODPart *part )
  779. {
  780.     return LookupEditorCreator( ev, ODGetSession(ev,part),
  781.                                 part->GetRealPart(ev)->somGetClassName() );
  782. }
  783.  
  784.  
  785. //--------------------------------------------------------------------
  786. // ODGetPOIconFamily
  787. //--------------------------------------------------------------------
  788.  
  789. ODIconFamily
  790. ODGetPOIconFamily(Environment* ev, ODPart* part)
  791. {
  792.     //// FIRST, get the Mac icon value if one exists:
  793.     ODStorageUnit*    su = ODGetSUFromPstObj(ev, part);
  794.     ODIconFamily icons = ODGetIconFamilyProp(ev, su, 
  795.                                 kODPropCustomIcon, kODIconFamily, kAllIconsMask);
  796.     if (icons )
  797.         return icons;
  798.         
  799.     //// OTHERWISE, look for other platform icon values:
  800.     if (ODSUExistsThenFocus(ev,su, kODPropCustomIcon, kODNULL))
  801.     {
  802.         ODULong numValues = su->CountValues(ev);
  803.         for( ODULong i = 1; i <= numValues; i++ )
  804.         {
  805.             su->Focus(ev, kODNULL, kODPosSame, kODNULL, 0, kODPosNextSib);    // Next value
  806.             TempODValueType type = su->GetType(ev);
  807.             if( strncmp(type,kODIconFamilyBaseString,strlen(kODIconFamilyBaseString)) == 0 )
  808.             {
  809.                 // This value is an icon family for some platform. Use the b/w icons
  810.                 // because we don't know what color table the color ones may use.
  811.                 icons = ODGetIconFamilyProp(ev, su, kODPropCustomIcon, type, kBWIconsMask);
  812.                 if( icons )
  813.                     return icons;
  814.             }
  815.         }
  816.         return kODNULL;
  817.     }
  818.     return icons;
  819. }
  820.  
  821.  
  822.  
  823. //--------------------------------------------------------------------
  824. // ODSetPOIconFamily
  825. //--------------------------------------------------------------------
  826.  
  827. void    ODSetPOIconFamily(Environment* ev, ODPart* part, 
  828.             ODIconFamily icons, ODBoolean deleteOtherPlatformIcons)
  829. {
  830.     ODSetIconFamilyProp(ev, ODGetSUFromPstObj(ev, part), 
  831.                                 kODPropCustomIcon, kODIconFamily,
  832.                                 icons, deleteOtherPlatformIcons);
  833. }
  834.  
  835. //==============================================================================
  836. //    StVolumeLoop
  837. //==============================================================================
  838.  
  839. //——————————————————————————————————————————————————————————————————————————————
  840. //    StVolumeLoop::StVolumeLoop
  841. //——————————————————————————————————————————————————————————————————————————————
  842.  
  843. const short kSystemVolumeID = -1;    // -1 is the refnum of the System Volume.
  844.  
  845. //——————————————————————————————————————————————————————————————————————————————
  846. //    StVolumeLoop::StVolumeLoop
  847. //——————————————————————————————————————————————————————————————————————————————
  848.  
  849. StVolumeLoop::StVolumeLoop()
  850. {
  851.     mInitialVRefNum    = kSystemVolumeID;
  852.     
  853.     mVolumePass        = kInitialPass;
  854.     mVolumeIndex    = 0;
  855. }
  856.  
  857. //——————————————————————————————————————————————————————————————————————————————
  858. //    StVolumeLoop::StVolumeLoop
  859. //——————————————————————————————————————————————————————————————————————————————
  860.  
  861. StVolumeLoop::StVolumeLoop(short inInitialVolume)
  862. {
  863.     mInitialVRefNum    = inInitialVolume;
  864.     
  865.     mVolumePass        = kInitialPass;
  866.     mVolumeIndex    = 0;
  867. }
  868.  
  869. //——————————————————————————————————————————————————————————————————————————————
  870. //    StVolumeLoop::NextVolume
  871. //——————————————————————————————————————————————————————————————————————————————
  872. Boolean 
  873. StVolumeLoop::NextVolume(short& outVolume) 
  874. {
  875.     Boolean foundVolumeToReturn = false;
  876.  
  877.     do
  878.     {
  879.         if (mVolumePass == kInitialPass)
  880.         {
  881.             // if we're on the initial pass (kInitialPass) just use
  882.             // the vRefNum of the initial volume itself.
  883.             
  884.         //    desktopParams.ioVRefNum = initialVRefNum;
  885.             outVolume = mInitialVRefNum;
  886.             foundVolumeToReturn = true;
  887.             
  888.             SetupNextVolumePass();
  889.         }
  890.         else
  891.         {
  892.             // Find the vRefNum of the next volume appropriate for this pass.
  893.             
  894.             mVolumeIndex++;
  895.             
  896.             // Convert the volumeIndex into a vRefNum.
  897.             
  898.             HParamBlockRec hfsParams;
  899.             hfsParams.volumeParam.ioNamePtr = nil;
  900.             hfsParams.volumeParam.ioVRefNum = 0;
  901.             hfsParams.volumeParam.ioVolIndex = mVolumeIndex;
  902.             OSErr error = ::PBHGetVInfoSync(&hfsParams);
  903.             
  904.             // A nsvErr indicates that the current pass is over.
  905.             
  906.             if (error != nsvErr)
  907.                 THROW_IF_ERROR(error);
  908.             
  909.             if (error == nsvErr)
  910.             {
  911.                 SetupNextVolumePass();
  912.             }
  913.             else if (hfsParams.volumeParam.ioVRefNum == mInitialVRefNum)
  914.             {
  915.                 // Since we handled the document volume during the initialPass,
  916.                 // skip it if we have hit that volume again.
  917.             
  918.                 // Don’t do anything, just let it continue to the next volume.
  919.             }
  920.             else if (IsRemoteVolume(hfsParams) != (mVolumePass == kRemotePass)) 
  921.             {
  922.                 // The current volume should be ignored by this pass because
  923.                 // it's not of the right type.
  924.                 
  925.                 // Don’t do anything, just let it continue to the next volume.
  926.             }
  927.             else
  928.             {
  929.                 // Okay, now we’ve found the vRefNum to return.
  930.  
  931.         //        desktopParams.ioVRefNum = hfsParams.volumeParam.ioVRefNum;
  932.                 outVolume = hfsParams.volumeParam.ioVRefNum;
  933.                 foundVolumeToReturn = true;
  934.             }
  935.         }
  936.         
  937.         // ••• This is where we return the correct volume ref.
  938.     }
  939.     while (!foundVolumeToReturn && mVolumePass != kDonePass);
  940.     
  941.     return mVolumePass != kDonePass;
  942. }
  943.  
  944. //——————————————————————————————————————————————————————————————————————————————
  945. //    StVolumeLoop::SetupNextVolumePass
  946. //——————————————————————————————————————————————————————————————————————————————
  947. void
  948. StVolumeLoop::SetupNextVolumePass()
  949. {
  950.     mVolumePass  = (EPass) ((short) mVolumePass + 1);
  951.     mVolumeIndex = 0;
  952. }
  953.  
  954. //——————————————————————————————————————————————————————————————————————————————
  955. //    StVolumeLoop::IsRemoteVolume
  956. //——————————————————————————————————————————————————————————————————————————————
  957. Boolean
  958. StVolumeLoop::IsRemoteVolume(HParamBlockRec& inHFSParams)
  959. {
  960.     // Call GetVolParms to determine if this volume is a server
  961.     // (a remote volume).
  962.     
  963.     GetVolParmsInfoBuffer volumeInfoBuffer;
  964.  
  965.     inHFSParams.ioParam.ioBuffer    = (Ptr) &volumeInfoBuffer;
  966.     inHFSParams.ioParam.ioReqCount    = sizeof(GetVolParmsInfoBuffer);
  967.     THROW_IF_ERROR(::PBHGetVolParmsSync(&inHFSParams));
  968.     
  969.     inHFSParams.ioParam.ioBuffer    = NULL;    // Make sure it's not pointing to
  970.                                             // the stack anymore.
  971.     
  972.     // If the vMServerAdr field of the volume information buffer
  973.     // is zero, this is a local volume.
  974.     
  975.     return (volumeInfoBuffer.vMServerAdr != 0);
  976. }
  977. //==============================================================================
  978.  
  979. //--------------------------------------------------------------------
  980. // ODGetIconFamily
  981. //
  982. // Returns an ODIconFamily for the frames part or generic icons
  983. // if an associated ODIconFamily is not found. Throws only if it can't
  984. // get the generic icons.
  985. //--------------------------------------------------------------------
  986. ODIconFamily
  987. ODGetIconFamily(Environment* ev, ODFrame* frame)
  988. {
  989.     ODIconFamily        r             = kODNULL; ODVolatile(r);
  990.     TempPlatformFile     usersFile    = kODNULL; ODVolatile(usersFile);
  991.     
  992.     ASSERT_NOT_NULL(frame);
  993.     
  994.     TRY
  995.     {
  996.         usersFile = ODGetFileIfRoot(ev, frame);
  997.     }
  998.     CATCH_ALL
  999.         //Thanks for sharing, but I can still continue my search, so I will.
  1000.     ENDTRY
  1001.     
  1002.     // First search phase, get custom icon family or look in the storage unit
  1003.     if (usersFile)
  1004.     {
  1005.         TRY
  1006.         {
  1007.             r = usersFile->GetCustomIconFamily();
  1008.         }
  1009.         CATCH_ALL
  1010.             //Thanks for sharing, but I can still continue my search, so I will.
  1011.         ENDTRY
  1012.     }
  1013.     else
  1014.     {
  1015.         TRY
  1016.         {
  1017.             TempODPart    part = kODNULL;
  1018.             part = frame->AcquirePart(ev);
  1019.             r = ODGetPOIconFamily(ev, part);
  1020.             // TempODPart is released here &/or on exception
  1021.         }
  1022.         CATCH_ALL
  1023.         ENDTRY
  1024.     }
  1025.     
  1026.     // Second search phase, search the available desktop databases
  1027.     if (r == kODNULL)
  1028.     {
  1029.         TRY
  1030.         {
  1031.             ODPlatformType kInvalidFileType = '\0\0\0\0';
  1032.             ODPlatformType fileType = kInvalidFileType; ODVolatile(fileType);
  1033.             ODPlatformType fileCreator = kODShellSignature;
  1034.  
  1035.             TRY
  1036.             {
  1037.                 TempODPart    part = kODNULL;
  1038.                 ODStorageUnit*    su = kODNULL;
  1039.                 part = frame->AcquirePart(ev);
  1040.                 su = ODGetSUFromPstObj(ev, CAST(part,ODPart));
  1041.                 ASSERT_NOT_NULL(su);
  1042.                 fileType = ODGetIconFilePlatformTypeFromPartSU(ev, su);
  1043.                 // TempODPart is released here &/or on exception
  1044.             }
  1045.             CATCH_ALL
  1046.             ENDTRY
  1047.             
  1048.             // Ask the desktop database by filetype for suite
  1049.             if (fileType != kInvalidFileType)
  1050.                 r = ODGetIconSuiteFromDesktopDB(fileType,fileCreator);
  1051.         }
  1052.         CATCH_ALL
  1053.         ENDTRY
  1054.     }
  1055.  
  1056.     // Final search phase, use generic icons as last resort
  1057.     if (r == kODNULL)
  1058.     {
  1059.         ODBoolean isStationery = kODFalse;
  1060.         ODSShort id = 0;
  1061.         
  1062.         TRY
  1063.         {
  1064.             isStationery = ODGetIsStationery(ev, frame);
  1065.         }
  1066.         CATCH_ALL
  1067.         ENDTRY
  1068.         
  1069.         if (isStationery)
  1070.         {
  1071.             id = genericStationeryIconResource;
  1072.         }
  1073.         else
  1074.         {
  1075.             id = genericDocumentIconResource;
  1076.         }
  1077.         
  1078.         TRY
  1079.         {
  1080.             r = GetGenericIcon(id);
  1081.         }
  1082.         CATCH_ALL
  1083.             RERAISE;
  1084.         ENDTRY
  1085.     }
  1086.     
  1087.     return r;
  1088. }
  1089.  
  1090. // Allocates an IconSuite if found and returns a ptr to it.
  1091. ODIconFamily ODGetIconSuiteFromDesktopDB(ODPlatformType fileType,ODPlatformType fileCreator)
  1092. {
  1093.     ODIconFamily    r             = kODNULL; ODVolatile(r);
  1094.     StVolumeLoop     volumeLoop;
  1095.     short             theVolume;
  1096.  
  1097.     TRY
  1098.     {
  1099.         while (!r && volumeLoop.NextVolume(theVolume))
  1100.         {
  1101.             OSErr err = noErr;
  1102.             DTPBRec pb;
  1103.             memset(&pb,'\0',sizeof(DTPBRec));
  1104.             pb.ioNamePtr = kODNULL;
  1105.             pb.ioVRefNum = theVolume; // index
  1106.             err = ::PBDTGetPath( &pb );
  1107.                         
  1108.             if (err == noErr)
  1109.             {
  1110.                 short DTRefNum = pb.ioDTRefNum; ODVolatile(DTRefNum);
  1111.                 
  1112.                 TRY
  1113.                 {
  1114.                     r = BuildIconSuiteFromDesktop(DTRefNum,fileType,fileCreator);
  1115.                 }
  1116.                 CATCH_ALL
  1117.                 ENDTRY
  1118.             }
  1119.             else if (err == desktopDamagedErr)
  1120.             {
  1121.                 //if (!Finder) ::PBReset();
  1122.             }
  1123.             // if there is a PBDTGetPath() error we ignore it and continue to next volume
  1124.         }
  1125.     }
  1126.     CATCH_ALL
  1127.         // if volume iterator dies, we can't get icons...
  1128.     ENDTRY
  1129.     
  1130.     return r;
  1131. }
  1132.  
  1133. ODIconFamily BuildIconSuiteFromDesktop(short DTRefNum,ODPlatformType fileType,ODPlatformType fileCreator)
  1134. {
  1135.     ODIconFamily icons = kODNULL; ODVolatile(icons);
  1136.     char iconBuffer[kLarge8BitIconSize]; // make room for largest possible icon bitmap
  1137.     const ODBoolean kDisposeHandlesInIconSuite = kODTrue;
  1138.     
  1139.     THROW_IF_ERROR( NewIconSuite(&icons) );
  1140.  
  1141.     TRY
  1142.     {
  1143.         ODBoolean hasIcon = kODFalse;
  1144.         for(int i = 1; i <= 6; i++)
  1145.         {
  1146.             OSErr err = noErr;
  1147.             DTPBRec pb;
  1148.             memset(&pb,'\0',sizeof(DTPBRec));
  1149.             
  1150.             pb.ioCompletion = NULL;
  1151.             pb.ioDTRefNum     = DTRefNum;
  1152.             pb.ioTagInfo     = 0; // Reserved ; must be zero
  1153.             pb.ioDTBuffer     = (Ptr)&iconBuffer;
  1154.             pb.ioDTReqCount = sizeof(iconBuffer);
  1155.             pb.ioIconType     = i; // index
  1156.             pb.ioFileCreator= fileCreator;
  1157.             pb.ioFileType     = fileType;
  1158.             err = ::PBDTGetIconSync(&pb);
  1159.             
  1160.             if (err == noErr)
  1161.             {
  1162.                 WASSERT(pb.ioDTActCount == kIconSize[i-1]);
  1163.                 Handle hIcon =  ODNewHandle(kIconSize[i-1]);
  1164.                 HLock(hIcon);
  1165.                 ODBlockMove(iconBuffer,*hIcon,kIconSize[i-1]);
  1166.                 HUnlock(hIcon);
  1167.                 err = AddIconToSuite(hIcon ,icons, kIconType[i-1] );
  1168.                 if(err)
  1169.                 {
  1170.                     DisposeHandle(hIcon);
  1171.                     hIcon = kODNULL;
  1172.                     THROW_IF_ERROR(err);
  1173.                 }
  1174.                 hasIcon = kODTrue;
  1175.             }
  1176.             else if (err != afpItemNotFound)
  1177.             {
  1178.                 THROW_IF_ERROR(err);
  1179.             }
  1180.         } // For loop
  1181.             
  1182.         // return NULL if we could not find any icon data. 
  1183.         if (!hasIcon)
  1184.         {
  1185.             if (icons)
  1186.                 DisposeIconSuite(icons, kDisposeHandlesInIconSuite);
  1187.             icons = kODNULL;
  1188.         }
  1189.     } // TRY
  1190.     CATCH_ALL
  1191.         if (icons)
  1192.             DisposeIconSuite(icons, kDisposeHandlesInIconSuite);
  1193.         icons = kODNULL;
  1194.         RERAISE;
  1195.     ENDTRY
  1196.     
  1197.     return icons;
  1198. }
  1199.  
  1200.  
  1201. //--------------------------------------------------------------------
  1202. // ODSetIconFamily
  1203. //--------------------------------------------------------------------
  1204.  
  1205. void    ODSetIconFamily(Environment* ev, 
  1206.                 ODFrame* frame, ODIconFamily icons, ODBoolean deleteOtherPlatformIcons)
  1207. {
  1208.     TempODPart         part = frame->AcquirePart(ev);
  1209.     
  1210.     ODSetPOIconFamily(ev, part, icons, deleteOtherPlatformIcons);
  1211.     
  1212.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  1213.     if (usersFile)
  1214.         usersFile->SetCustomIconFamily(icons);
  1215. }
  1216.  
  1217. //--------------------------------------------------------------------
  1218. // ODGetFileIfRoot
  1219. //--------------------------------------------------------------------
  1220.  
  1221. PlatformFile*    ODGetFileIfRoot(Environment* ev, ODFrame* frame)
  1222. {
  1223.     ASSERT_NOT_NULL(frame);
  1224.  
  1225.     PlatformFile* file = kODNULL;
  1226.     
  1227.     TempODPart part = frame->AcquirePart(ev);
  1228.  
  1229.     // Get the root part of the document.
  1230.     ODDraft* draft = ODGetDraft(ev,part);
  1231.     TempODPart rootPart = ODAcquireRootPartOfDraft(ev, draft);
  1232.     
  1233.     // If the part is the root of the document, return the corresponding file.
  1234.     if ( ODObjectsAreEqual(ev, part, rootPart) )
  1235.     {
  1236.         ODContainer* container = draft->GetDocument(ev)->GetContainer(ev);
  1237.         file = GetPlatformFileFromContainer(ev, container);
  1238.     }
  1239.     
  1240.     return file;
  1241. }
  1242.  
  1243. //--------------------------------------------------------------------
  1244. // DetachIconProc
  1245. //--------------------------------------------------------------------
  1246.  
  1247. static OSErr DetachIconProc( ResType, Handle *theIcon, void */*yourDataPtr*/ )
  1248. {
  1249.     if( *theIcon ) {
  1250.         DetachResource(*theIcon);
  1251.         return ResError();
  1252.     } else
  1253.         return noErr;
  1254. }
  1255.  
  1256. //--------------------------------------------------------------------
  1257. // GetGenericIcon
  1258. //--------------------------------------------------------------------
  1259.  
  1260. ODStatic ODIconFamily GetGenericIcon( short iconID )
  1261. {
  1262.     ODIconFamily icon;
  1263.     THROW_IF_ERROR( GetIconSuite( &icon, iconID, svAllAvailableData ) );
  1264.     IconActionUPP detachProc = NewIconActionProc(&DetachIconProc);
  1265.     (void) ForEachIconDo(icon, svAllAvailableData, detachProc, kODNULL);
  1266.     DisposeRoutineDescriptor(detachProc);
  1267.     return icon;
  1268. }
  1269.  
  1270.  
  1271. //--------------------------------------------------------------------
  1272. // ODGetIsStationery
  1273. //--------------------------------------------------------------------
  1274.  
  1275. ODBoolean    ODGetIsStationery(Environment* ev, 
  1276.                 ODFrame* frame)
  1277. {
  1278.     TempODPart        part = frame->AcquirePart(ev);
  1279.     ODBoolean        isStationery = kODFalse;
  1280.     
  1281.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  1282.     if (usersFile)
  1283.         isStationery = usersFile->IsStationery();
  1284. //    else
  1285. //        isStationery = ODGetSUIsStationery(ev, ODGetSUFromPstObj(ev, part));
  1286.     return isStationery;
  1287. }
  1288.  
  1289. //--------------------------------------------------------------------
  1290. // ODSetIsStationery
  1291. //--------------------------------------------------------------------
  1292.  
  1293. void        ODSetIsStationery(Environment* ev, 
  1294.                 ODFrame* frame, ODBoolean isStationery)
  1295. {
  1296. //    { TempODPart part = frame->AcquirePart(ev);
  1297. //      ODSetBooleanProp( ev, ODGetSUFromPstObj(ev, part),
  1298. //                            kODPropIsStationery, kODBoolean, isStationery);
  1299. //    }
  1300.     TempPlatformFile usersFile = ODGetFileIfRoot(ev, frame);
  1301.     if (usersFile)
  1302.         usersFile->SetStationery(isStationery);
  1303. }
  1304. #if 0
  1305. //--------------------------------------------------------------------
  1306. // ODSetSUIsStationery
  1307. //--------------------------------------------------------------------
  1308.  
  1309. void        ODSetSUIsStationery(Environment* ev, 
  1310.                 ODStorageUnit* su, ODBoolean isStationery)
  1311. {
  1312.     ODSetBooleanProp( ev, su, kODPropIsStationery, kODBoolean, isStationery);
  1313. }
  1314.  
  1315. //--------------------------------------------------------------------
  1316. // ODGetSUIsStationery
  1317. //--------------------------------------------------------------------
  1318.  
  1319. ODBoolean        ODGetSUIsStationery(Environment* ev, 
  1320.                 ODStorageUnit* su)
  1321. {
  1322.     ODBoolean isStationery;
  1323.     
  1324.     if (su->Exists(ev, kODPropIsStationery, kODBoolean, 0))
  1325.         isStationery = ODGetBooleanProp( ev, su, kODPropIsStationery, kODBoolean);
  1326.     else
  1327.         isStationery = kODFalse;
  1328.         
  1329.     return isStationery;
  1330. }
  1331. #endif /* 0 */
  1332. //-------------------------------------------------------------------------------------
  1333. // Editor and Kind Menu manipulation functions
  1334. //-------------------------------------------------------------------------------------
  1335. // copied from LinkDlgs.cpp (with changes by TÇ)
  1336. //------------------------------------------------------------------------------
  1337. // InitKindsPopup
  1338. //------------------------------------------------------------------------------
  1339.  
  1340. void InitKindsPopup (     ODTypeList* kindList,
  1341.                         ODType theKind,
  1342.                         ControlHandle    itemHandle,
  1343.                         ODSShort* currentKindItem,
  1344.                         MenuHandle kindMenu,
  1345.                         ODSShort* translateItem,
  1346.                         ODSession* session)
  1347. {
  1348.     ODSShort        item = 1;
  1349.  
  1350.     Environment* ev = somGetGlobalEnvironment();
  1351.  
  1352.     ODUShort i;
  1353.  
  1354.     // remove all except last item in menu
  1355.     for (i = CountMItems(kindMenu) - 1;  i > 0;  --i) 
  1356.     {
  1357.         DeleteMenuItem(kindMenu, i);
  1358.     }
  1359.  
  1360.     AddTypesToMenu(kindList, kindMenu, theKind, currentKindItem, session);
  1361.  
  1362.     *translateItem = CountMItems(kindMenu);
  1363.     EnableItem(kindMenu, *translateItem);
  1364.  
  1365.     SetControlMinimum(itemHandle, 1);
  1366.     SetControlMaximum(itemHandle, *translateItem);
  1367.     SetControlValue(itemHandle, *currentKindItem);
  1368.  
  1369.     // Determine if translation is an option
  1370.     ODTypeList*    translateToList =
  1371.         session->GetStorageSystem(ev)->CreateTypeList(ev,(ODTypeList*)kODNULL);
  1372.     
  1373.     TRY
  1374.         GetDestinationKindsList(kindList, translateToList, kODNULL, session);
  1375.         if ( translateToList->Count(ev) == 0 )
  1376.             DisableItem(kindMenu, *translateItem);
  1377.     CATCH_ALL
  1378.         DisableItem(kindMenu, *translateItem);
  1379.     ENDTRY
  1380.     
  1381.     ODDeleteObject( translateToList );
  1382. }
  1383.  
  1384. #ifdef _OD_IMPL_
  1385. //------------------------------------------------------------------------------
  1386. // AddTypesToMenu
  1387. //------------------------------------------------------------------------------
  1388.  
  1389. void AddTypesToMenu(ODTypeList* typeList, MenuHandle kindMenu, ODType defaultKind, 
  1390.                     ODSShort* currentKindItem, ODSession* session)
  1391. {
  1392.     ODName*                name;
  1393.     ODSShort            item = 0;
  1394.     Environment*        ev = somGetGlobalEnvironment();
  1395.     ODNameSpaceManager*    nsm = session->GetNameSpaceManager(ev);
  1396.     ODULong                prefixSize = ODISOStrLength(kODAppleFileTypePrefix);
  1397.     
  1398.     ODTypeListIterator* typeIter = typeList->CreateTypeListIterator(ev);
  1399.     
  1400.     EditorSet*            editorList = new EditorSet;
  1401.     editorList->InitEditorSet();
  1402.  
  1403.     for (ODType type = typeIter->First(ev);
  1404.         typeIter->IsNotComplete(ev);
  1405.         type = typeIter->Next(ev))
  1406.     {
  1407.         ODBoolean isDefaultKind =  defaultKind ? ODISOStrEqual(type, defaultKind) : kODFalse;
  1408.         
  1409.         if ( GetUserKindFromKind(nsm, type, &name) )
  1410.         {
  1411.             Str255 itemString;
  1412.             IntlToPStr(name, itemString);
  1413.             InsertMenuItem(kindMenu, "\p ", item++);
  1414.             SetMenuItemText(kindMenu, item, itemString);
  1415.             
  1416.             ScriptCode itemScript = GetITextScriptCode(name);
  1417.             SetPopupItemScript(kindMenu, item, itemScript);
  1418.             
  1419.             DisposeIText( name );
  1420.         }
  1421.         else
  1422.         {
  1423.             // there's no name for this type
  1424.             Str255 pKindStr;
  1425.             ODTranslation* translation = session->GetTranslation(ev);
  1426.             ODPlatformType platformType = 
  1427.                 translation->GetPlatformTypeFromISOType(ev, type);
  1428.             if ( platformType == kODNULL )
  1429.             {
  1430.                 // Special menu item
  1431.                 CUsingLibraryResources r;
  1432.                 GetIndString(pKindStr, kODInfoUtilStrsID, kODStrIndNoKinds); 
  1433.             }
  1434.             else
  1435.             {
  1436.                 ODBlockMove(&platformType, &(pKindStr[1]), (ODULong) sizeof(ODPlatformType));
  1437.                 pKindStr[0] = (unsigned char) sizeof(ODPlatformType);
  1438.             }
  1439.             // Allow metacharacters in item text
  1440.             InsertMenuItem(kindMenu, "\p ", item++);
  1441.             SetMenuItemText(kindMenu, item, pKindStr);
  1442.         }
  1443.  
  1444.         // if it is a file type that is not the default type, we would disable it
  1445.         // we also disable it if if cannot find any editor for the kind
  1446.         if (((ODISOStrNCompare(kODAppleFileTypePrefix, (ODISOStr) type, prefixSize) == 0) && !isDefaultKind) ||
  1447.                 (!GetAllEditorsForKind(nsm, type, editorList)))
  1448.             DisableItem(kindMenu, item);
  1449.         editorList->RemoveAllEditors();
  1450.         
  1451.         if (isDefaultKind)
  1452.             *currentKindItem = item;
  1453.         
  1454.         ODDisposePtr(type);
  1455.     }
  1456.     ODDeleteObject( editorList );
  1457.     ODDeleteObject( typeIter );
  1458. }
  1459.  
  1460. //------------------------------------------------------------------------------
  1461. // EnableTypesInMenu
  1462. //------------------------------------------------------------------------------
  1463.  
  1464. ODUShort EnableTypesInMenu(
  1465.                     ODTypeList*            typeList,
  1466.                     MenuHandle            kindMenu,
  1467.                     ODEditor            editor,
  1468.                     ODNameSpaceManager*    nsm)
  1469. {
  1470.     Environment* ev = somGetGlobalEnvironment();
  1471.     ODUShort itemStart = 0;
  1472.  
  1473.     if ( kindMenu && typeList && (typeList->Count(ev) > 0) )
  1474.     {
  1475.         ODTypeListIterator* typeIter = typeList->CreateTypeListIterator(ev);
  1476.         
  1477.         for (ODType type = typeIter->First(ev);
  1478.             typeIter->IsNotComplete(ev);
  1479.             type = typeIter->Next(ev))
  1480.         {
  1481.             if ( editor == kODNULL )
  1482.             {
  1483.                 // Editor is not fixed; Aassume kind can be embedded even if there is
  1484.                 // no editor installed for it
  1485.                 EnableItem(kindMenu, ++itemStart);
  1486.             }
  1487.             else
  1488.             {
  1489.                 if ( EditorSupportsKind(nsm, editor, type) )
  1490.                     EnableItem(kindMenu, ++itemStart);
  1491.                 else
  1492.                     DisableItem(kindMenu, ++itemStart);
  1493.             }
  1494.             ODDisposePtr(type);
  1495.         }
  1496.     
  1497.         ODDeleteObject( typeIter );
  1498.     }
  1499.     
  1500.     return itemStart;
  1501. }
  1502. #endif
  1503.  
  1504. //------------------------------------------------------------------------------
  1505. // DeleteAllMenuItems
  1506. //------------------------------------------------------------------------------
  1507. ODStatic void DeleteAllMenuItems(MenuHandle theMenu)
  1508. {
  1509.     ODUShort i;
  1510.  
  1511.     for (i = CountMItems(theMenu);  i > 0;  --i)
  1512.     {
  1513.         DeleteMenuItem(theMenu, i);
  1514.     }
  1515. }
  1516.  
  1517. #ifdef _OD_IMPL_
  1518. //------------------------------------------------------------------------------
  1519. // SetupEditorMenu
  1520. //------------------------------------------------------------------------------
  1521. ODBoolean SetupEditorMenu(ODType kind,
  1522.                             EditorSet* editorList,
  1523.                             MenuHandle editorMenu, 
  1524.                             ControlHandle popupCtlHndl, 
  1525.                             ODSession* session)
  1526. {
  1527.     ODBoolean anyEditors = (editorList->GetEditorCount() > 0);
  1528.     
  1529.     Environment* ev = somGetGlobalEnvironment();
  1530.     ODNameSpaceManager* nsm = session->GetNameSpaceManager(ev);
  1531.  
  1532.     // And remove all items from the editors menu
  1533.     DeleteAllMenuItems(editorMenu);
  1534.     
  1535.     // Get all editors supporting that kind; Preferred editor must be first
  1536.     if ( kind && !anyEditors)
  1537.     {
  1538.         ODEditor prefEditor = GetSysPrefEditorForKind(nsm, kind);
  1539.         if ( prefEditor )
  1540.             editorList->AddEditor(prefEditor);
  1541.         ODDisposePtr((ODPtr) prefEditor);
  1542.         anyEditors = GetAllEditorsForKind(nsm, kind, editorList);
  1543.     }
  1544.  
  1545.     if ( anyEditors )
  1546.     {
  1547.         AddEditorsToMenu(editorList, editorMenu, session);
  1548.         if ( popupCtlHndl )
  1549.         {
  1550.             SetControlMaximum(popupCtlHndl, editorList->GetEditorCount());
  1551.             HiliteControl(popupCtlHndl, kControlActive);
  1552.         }
  1553.     }
  1554.     else
  1555.     {
  1556.         // The editor popup should be inactive, remove all editors
  1557.         editorList->InitEditorSet();
  1558.     }
  1559.  
  1560.     if ( popupCtlHndl )
  1561.     {
  1562.         SetControlMinimum(popupCtlHndl, 1);
  1563.         SetControlValue(popupCtlHndl, 1);
  1564.     }
  1565.     
  1566.     return anyEditors;
  1567. }
  1568. #endif
  1569.  
  1570. //------------------------------------------------------------------------------
  1571. // AddEditorsToMenu
  1572. //------------------------------------------------------------------------------
  1573.  
  1574. void AddEditorsToMenu(EditorSet* editorList,
  1575.                                 MenuHandle editorMenu, 
  1576.                                 ODSession* session)
  1577. {
  1578.     ODName*        name;
  1579.     Str255         pEditorString;
  1580.     ODSShort        item = 0;
  1581.     Environment*         ev = somGetGlobalEnvironment();
  1582.     ODNameSpaceManager*    nsm = session->GetNameSpaceManager(ev);
  1583.     
  1584.     EditorSetIterator* editorIter = editorList->CreateIterator();
  1585.     
  1586.     for (ODType editor = editorIter->First();
  1587.         editorIter->IsNotComplete();
  1588.         editor = editorIter->Next())
  1589.     {
  1590.         if (GetUserEditorFromEditor(nsm, editor, &name))
  1591.         {
  1592.             TempODName tempName = name; // DMc: ensure it's deleted
  1593.             IntlToPStr(name, pEditorString);
  1594.             InsertMenuItem(editorMenu, pEditorString, item);
  1595.             EnableItem(editorMenu, ++item);
  1596.             // comments for SetPopupItemScript say don't call unless the script
  1597.             // needs setting, but there's no way to test that here.  Sounds like
  1598.             // an optimization to me....
  1599.             SetPopupItemScript( editorMenu, item, GetITextScriptCode(name) );
  1600.         }
  1601.         else
  1602.         {
  1603.             // Special menu item in italics
  1604.             CUsingLibraryResources r;
  1605.             GetIndString(pEditorString, kODInfoUtilStrsID, kODStrIndNoEditors); 
  1606.  
  1607.             InsertMenuItem(editorMenu, pEditorString, item);
  1608.             DisableItem(editorMenu, ++item);
  1609.         }
  1610.     }
  1611.  
  1612.     ODDeleteObject( editorIter );
  1613. }
  1614.  
  1615. //------------------------------------------------------------------------------
  1616. // GetThisEditorFromList
  1617. //------------------------------------------------------------------------------
  1618. ODEditor GetThisEditorFromList(ODSShort editorIndex, EditorSet* editorList)
  1619. {
  1620.     ODEditor result = kODNULL;
  1621.     
  1622.     if ( editorIndex > 0 )
  1623.     {
  1624.         ODEditor editor;
  1625.         EditorSetIterator* iter = editorList->CreateIterator();
  1626.         
  1627.         for ( editor = iter->First(); 
  1628.               (--editorIndex > 0) && iter->IsNotComplete(); 
  1629.               editor = iter->Next() )
  1630.         {
  1631.         }
  1632.     
  1633.         delete iter;
  1634.         
  1635.         if ( editor != kODNULL )
  1636.             result = ODISOStrFromCStr((char *) editor);
  1637.     }
  1638.  
  1639.     return result;
  1640. }
  1641.  
  1642. //------------------------------------------------------------------------------
  1643. // IndexOfEditorInList
  1644. //------------------------------------------------------------------------------
  1645. ODSShort IndexOfEditorInList(EditorSet* editorList, ODEditor editor)
  1646. {
  1647.     ODSShort retVal = 0;
  1648.     
  1649.     if ( editorList->GetEditorCount() )
  1650.     {
  1651.         ODSShort i = 1;
  1652.         EditorSetIterator* editorIter = editorList->CreateIterator();
  1653.         
  1654.         for (ODEditor anEditor = editorIter->First();
  1655.             editorIter->IsNotComplete();
  1656.             anEditor = editorIter->Next())
  1657.         {
  1658.             if ( (anEditor == editor) || ODISOStrEqual(anEditor, editor) )
  1659.             {
  1660.                 retVal = i;
  1661.                 break;
  1662.             }
  1663.             i++;
  1664.         }
  1665.  
  1666.         ODDeleteObject( editorIter );
  1667.     }
  1668.     
  1669.     return retVal;
  1670. }
  1671.  
  1672. //------------------------------------------------------------------------------
  1673. // IndexOfKindInList
  1674. //------------------------------------------------------------------------------
  1675. ODSShort IndexOfKindInList(ODTypeList* kindList, ODType kind)
  1676. {
  1677.     ODSShort retVal = 0;
  1678.     
  1679.     Environment* ev = somGetGlobalEnvironment();
  1680.  
  1681.     if ( kindList->Count(ev) )
  1682.     {
  1683.         ODSShort i = 1;
  1684.         ODTypeListIterator* kindIter = kindList->CreateTypeListIterator(ev);
  1685.         
  1686.         TRY
  1687.         
  1688.             for (ODType type = kindIter->First(ev);
  1689.                 kindIter->IsNotComplete(ev);
  1690.                 type = kindIter->Next(ev), i++)
  1691.             {
  1692.                 if ( ODISOStrEqual(type, kind) )
  1693.                     retVal = i;
  1694.                 ODDisposePtr(type);
  1695.                 if ( retVal != 0 )
  1696.                     break;
  1697.             }
  1698.  
  1699.         CATCH_ALL
  1700.             ODDeleteObject(kindIter);
  1701.             RERAISE;
  1702.         ENDTRY
  1703.         
  1704.         ODDeleteObject(kindIter);
  1705.     }
  1706.     
  1707.     return retVal;
  1708. }
  1709.  
  1710. //------------------------------------------------------------------------------
  1711. // GetThisKindFromList
  1712. //------------------------------------------------------------------------------
  1713. ODType GetThisKindFromList(ODSShort kindItem, ODTypeList* kindList)
  1714. {
  1715.     Environment* ev = somGetGlobalEnvironment();
  1716.     ODType type = kODNULL;
  1717.     ODTypeListIterator* kindIter = kindList->CreateTypeListIterator(ev);
  1718.  
  1719.     for ( type = kindIter->First(ev); 
  1720.           (--kindItem > 0) && kindIter->IsNotComplete(ev); 
  1721.           type = kindIter->Next(ev) )
  1722.     {
  1723.         ODDisposePtr(type);
  1724.         type = kODNULL;
  1725.     }
  1726.  
  1727.     ODDeleteObject(kindIter);
  1728.  
  1729.     return type;
  1730. }
  1731.  
  1732.  
  1733. //------------------------------------------------------------------------------
  1734. // ContentValueTypes
  1735. //------------------------------------------------------------------------------
  1736. void ContentValueTypes(ODStorageUnit* contentSU, ODTypeList* typeList)
  1737. {
  1738.     TempODType hfsType = kODNULL;
  1739.  
  1740.     TRY
  1741.         ODULong        count;
  1742.         ODULong        index;
  1743.         
  1744.         Environment* ev = somGetGlobalEnvironment();
  1745.  
  1746.         ODTranslation* translation = contentSU->GetSession(ev)->GetTranslation(ev);
  1747.         hfsType = translation->GetISOTypeFromPlatformType(ev, kODFileType_hfs, kODPlatformDataType);
  1748.  
  1749.         contentSU->Focus(ev, kODPropContents, kODPosUndefined, 0, 0, kODPosUndefined);
  1750.         count = contentSU->CountValues(ev);
  1751.         for (index = 1; index <= count; ++index)
  1752.         {
  1753.             contentSU->Focus(ev, kODPropContents, kODPosUndefined, 0, index, kODPosUndefined);
  1754.             TempODType type = contentSU->GetType(ev);
  1755.             if ( !ODISOStrEqual(type, hfsType) )
  1756.                 typeList->AddLast(ev, type);
  1757.         }
  1758.     CATCH_ALL
  1759.     ENDTRY
  1760. }
  1761.  
  1762. //------------------------------------------------------------------------------
  1763. // ODUserRenameFile
  1764. //------------------------------------------------------------------------------
  1765.  
  1766.  
  1767. ODStatic ODBoolean ODUserRenameFile(Environment* ev,
  1768.                     ODSession* session, 
  1769.                     PlatformFile*    usersFile, 
  1770.                     ODIText* name,
  1771.                     DescType replaceOption)
  1772. {
  1773.     ODBoolean    fileRenamed = kODFalse;
  1774.     
  1775.     // name to aStr255
  1776.     Str255 aStr255;
  1777.     
  1778.     GetITextPString(name, aStr255);
  1779.  
  1780.     TRY
  1781.         usersFile->Rename(aStr255);
  1782.         fileRenamed = kODTrue;
  1783.     CATCH_ALL
  1784.         if (ErrorCode() == dupFNErr)
  1785.         {
  1786.             switch (replaceOption) {
  1787.             case kAEAsk:
  1788.                 ParamText(aStr255, "\p","\p","\p");
  1789.                 fileRenamed = ODAskUserReplace(ev, session);
  1790.                 if (!fileRenamed)
  1791.                     THROW(userCanceledErr);
  1792.                 break;
  1793.             case kAEYes:
  1794.                 fileRenamed = kODTrue; break;
  1795.             case kAENo:
  1796.                 fileRenamed = kODFalse; break;
  1797.             }
  1798.             
  1799.             if (fileRenamed)
  1800.             {
  1801.                 ODFileSpec fsspec = usersFile->GetFileSpec();
  1802.                 ODError result = HDelete(fsspec.vRefNum,fsspec.parID,aStr255);
  1803.                 if ( result!=wPrErr && result!=fLckdErr && 
  1804.                                     result!=fBsyErr && result!=afpAccessDenied )
  1805.                 {
  1806.                     TRY
  1807.                         usersFile->Rename(aStr255);
  1808.                     CATCH_ALL
  1809.                         WARN("File renaming failed, err %ld",ErrorCode());
  1810.                         fileRenamed = kODFalse;
  1811.                     ENDTRY
  1812.                 }
  1813.                 else
  1814.                 {
  1815.                     fileRenamed = kODFalse;
  1816.                     if (replaceOption == kAEAsk)
  1817.                         switch(result)
  1818.                         {
  1819.                             case wPrErr:
  1820.                             case fLckdErr:
  1821.                             case fBsyErr:
  1822.                             {
  1823.                                 CUsingLibraryResources res;
  1824.                                 StopAlert(kFilelockedAlrtID, GetODDialogFilter());
  1825.                                 break;
  1826.                             }
  1827.                             default:
  1828.                                 SysBeep(2);
  1829.                         }
  1830.                     else
  1831.                         SysBeep(2);
  1832.                 }
  1833.             }
  1834.         }
  1835.         else 
  1836.             RERAISE;
  1837.     ENDTRY
  1838.     return( fileRenamed );
  1839. }
  1840.  
  1841. //------------------------------------------------------------------------------
  1842. // ODAskUserReplace
  1843. //------------------------------------------------------------------------------
  1844.  
  1845. ODBoolean    ODAskUserReplace(Environment* ev,
  1846.                             ODSession* session)
  1847. // Pass in the name in question via ParamText(^0).
  1848. {  
  1849.     CUsingLibraryResources r;
  1850.     ODBoolean    doReplace    = kODFalse;
  1851.     short          itemHit     = 0;
  1852.     DialogPtr     dlg         = ODGetNewDialog(ev, kNameConflictDlgID, 
  1853.                                     session, kODFalse );
  1854.     if (dlg)
  1855.     {
  1856.         Handle        scratchHandle = kODNULL;
  1857.         Rect        scratchRect;
  1858.  
  1859.         SetPort(dlg);
  1860.         
  1861.             // Set the draw routine for the default button outline item
  1862.         GetDialogItem(dlg, kNameConflictDefaultButtonItem, &itemHit, &scratchHandle, &scratchRect);
  1863.         SetDialogItem(dlg, kNameConflictDefaultButtonItem, itemHit, 
  1864.                  (Handle)GetODOutlineDefaultButtonDrawProc(), &scratchRect);
  1865.                 
  1866.         ShowWindow(dlg);
  1867.  
  1868.         do {
  1869.             ModalDialog(GetODDialogFilter(), &itemHit);
  1870.             switch(itemHit)
  1871.             {
  1872.                 case kNameConflictReplaceBtn:
  1873.                     doReplace = kODTrue;
  1874.                     break;
  1875.                 case kNameConflictCancelBtn:
  1876.                     break;
  1877.             }
  1878.         } while ((itemHit != kNameConflictReplaceBtn) && 
  1879.                                         (itemHit != kNameConflictCancelBtn));
  1880.                 
  1881.         ODDisposeDialog(dlg);
  1882.     }
  1883.     return doReplace;
  1884. }
  1885.  
  1886. //------------------------------------------------------------------------------
  1887. //    CommentsDontMatch
  1888. //
  1889. //    This compares 2 ODIText strings to see if they match and returns TRUE if
  1890. //    they do not match.  It take into account the fact that the comments field
  1891. //    of the desktop database clips its string to 200 characters.
  1892. //
  1893. //    Returns false if the strings are identical but the script/language are
  1894. //    not.  This is because these values in dtComments have been set using
  1895. //    system defaults while those in propComments were actually saved, and
  1896. //    should therefore take precedence. <eeh>
  1897. //
  1898. //    propComments can be NULL, dtComments cannot
  1899. //------------------------------------------------------------------------------
  1900.  
  1901. ODBoolean
  1902. CommentsDontMatch(ODIText* dtComments, ODIText* propComments)
  1903. {
  1904.     ODBoolean    result;
  1905.     ODULong        dtLen, propLen;
  1906.     Str255        dtStr, propStr;
  1907.     
  1908.     if (dtComments != kODNULL)
  1909.         dtLen = GetITextStringLength(dtComments);
  1910.     else
  1911.         dtLen = 0;
  1912.     if (propComments == kODNULL)
  1913.         return (dtLen != 0);
  1914.     propLen = GetITextStringLength(propComments);
  1915.     if (dtLen == 0)
  1916.         return (propLen != 0);
  1917.     
  1918.     // if either string is length 0 (or NULL) we won't get here
  1919.     WASSERT(dtComments && propComments);
  1920.     result = kODTrue;
  1921.  
  1922.     // because the Finder does not store script and language with the
  1923.     // comments or file names, we ignore these in comparing strings.  That
  1924.     // is, if the strings are identical byte-for-byte, we consider them
  1925.     // to be equal.  That way, the string *we* stored will be used, as will
  1926.     // the script and language information we stored with it.
  1927.  
  1928.     ODBoolean lengthsMatch =
  1929.             (dtLen == propLen) || (dtLen == 200 && propLen >= 200);
  1930.     if ( lengthsMatch )
  1931.     {
  1932.         GetITextPString(dtComments, (StringPtr) &dtStr);
  1933.         GetITextPString(propComments, (StringPtr) &propStr);
  1934.         propStr[0] = dtStr[0];            // fix the 200 case
  1935.         result = !EqualString( dtStr, propStr, kODTrue, kODTrue );
  1936.     }
  1937.     return result;
  1938.  
  1939. }
  1940.  
  1941.  
  1942. void SetAllWindowShowLinks(Environment* ev, ODWindowState* winState, ODBoolean showLinks)
  1943. {
  1944.     ODWindowIterator* iter = kODNULL; ODVolatile(iter);
  1945.             
  1946.     TRY
  1947.  
  1948.         iter = winState->CreateWindowIterator(ev);
  1949.     
  1950.         for (ODWindow* window = iter->First(ev); iter->IsNotComplete(ev);
  1951.                 window = iter->Next(ev))
  1952.         {
  1953.             if (window)
  1954.             {
  1955.                 window->SetShouldShowLinks(ev, showLinks);
  1956.                 ODFrame* root = window->GetRootFrame(ev);
  1957.                 root->Invalidate(ev, kODNULL, kODNULL);
  1958.             }
  1959.         }
  1960.         ODDeleteObject(iter);
  1961.  
  1962.     
  1963.     CATCH_ALL
  1964.  
  1965.         ODDeleteObject(iter);
  1966.         RERAISE;
  1967.  
  1968.     ENDTRY
  1969. }
  1970.  
  1971. //------------------------------------------------------------------------------
  1972. // TranslateValueTypes
  1973. //------------------------------------------------------------------------------
  1974. void TranslateValueTypes(
  1975.                 ODTypeList*    kindList,
  1976.                 ODTypeList*    translateToList,
  1977.                 OrderedCollection* translateFromList,
  1978.                 ODSession*    session)
  1979. {
  1980.     Environment* ev = somGetGlobalEnvironment();
  1981.  
  1982.     ODTranslation* translation = session->GetTranslation(ev);
  1983.  
  1984.     ODTypeListIterator* kindIter = kindList->CreateTypeListIterator(ev);
  1985.     
  1986.     ODUShort kindIndex = 0;
  1987.  
  1988.     for (ODType kind = kindIter->First(ev);
  1989.         kindIter->IsNotComplete(ev);
  1990.         kind = kindIter->Next(ev))
  1991.     {
  1992.         ++kindIndex;
  1993.  
  1994.         TRY
  1995.             ODTypeList* toList = translation->GetTranslationOf(ev, kind);
  1996.             
  1997.             ODTypeListIterator* toIter = toList->CreateTypeListIterator(ev);
  1998.             
  1999.             for (ODType toKind = toIter->First(ev);
  2000.                 toIter->IsNotComplete(ev);
  2001.                 toKind = toIter->Next(ev))
  2002.             {
  2003.                 TRY
  2004.                 
  2005.                     if ( (kindList->Contains(ev, toKind) == kODFalse)
  2006.                         &&
  2007.                          (translateToList->Contains(ev, toKind) == kODFalse)
  2008.                        )
  2009.                     {
  2010.                         translateToList->AddLast(ev, toKind);
  2011.                         translateFromList->AddLast((void*) kindIndex);
  2012.                     }
  2013.                 
  2014.                 CATCH_ALL
  2015.                 ENDTRY
  2016.                 ODDisposePtr(toKind);
  2017.             }
  2018.             delete toIter;
  2019.             delete toList;
  2020.  
  2021.         CATCH_ALL
  2022.         ENDTRY
  2023.  
  2024.         ODDisposePtr(kind);
  2025.     }
  2026.     delete kindIter;
  2027. }
  2028.  
  2029. //------------------------------------------------------------------------------
  2030. // StringPtrFromStrHandle
  2031. //------------------------------------------------------------------------------
  2032.  
  2033. ODStatic StringPtr StringPtrFromStrHandle(StringHandle strHandle)
  2034. {
  2035.     StringPtr result = kODNULL;
  2036.  
  2037.     if ( strHandle )
  2038.     {
  2039.         ODULong size = GetHandleSize((Handle) strHandle);
  2040.         StringPtr strPtr = (StringPtr) ODLockHandle((ODHandle) strHandle);
  2041.         result = (StringPtr) ODNewPtr(size);
  2042.         ODBlockMove(strPtr, result, size);
  2043.         ODUnlockHandle((ODHandle) strHandle);
  2044.     }
  2045.  
  2046.     return result;
  2047. }
  2048.  
  2049. //------------------------------------------------------------------------------
  2050. // DefaultMenuStringForKind
  2051. //------------------------------------------------------------------------------
  2052.  
  2053. ODStatic StringPtr DefaultMenuStringForKind()
  2054. {
  2055.     CUsingLibraryResources r;
  2056.  
  2057.     StringPtr result = kODNULL;
  2058.  
  2059.     StringHandle strHandle = GetString(kODPartInfoStrUnknownID);
  2060.     if ( strHandle )
  2061.     {
  2062.         result = StringPtrFromStrHandle(strHandle);
  2063.         ReleaseResource((Handle) strHandle);
  2064.     }
  2065.     else
  2066.     {
  2067.         strHandle = NewString("\p");
  2068.         result = StringPtrFromStrHandle(strHandle);
  2069.         ODDisposeHandle((ODHandle) strHandle);
  2070.     }
  2071.     return result;
  2072. }
  2073.  
  2074. //------------------------------------------------------------------------------
  2075. // GetMenuStringForKind
  2076. //------------------------------------------------------------------------------
  2077.  
  2078. ODStatic void GetMenuStringForKind(
  2079.     ODSession*        session,
  2080.     ODType            kind,
  2081.     StringPtr*        itemString,
  2082.     ODScriptCode*    itemScript)
  2083. {
  2084.     ODName*                name;
  2085.     Environment*        ev = somGetGlobalEnvironment();
  2086.     ODNameSpaceManager*    nsm = session->GetNameSpaceManager(ev);
  2087.  
  2088.     if ( GetUserKindFromKind(nsm, kind, &name) )
  2089.     {
  2090.         TempODName tempName = name; // DMc: ensure it's deleted
  2091.         *itemString = (StringPtr) ODNewPtr(GetITextStringLength(name)+1);
  2092.         IntlToPStr(name, *itemString);
  2093.         *itemScript = GetITextScriptCode(name);
  2094.     }
  2095.     else
  2096.     {
  2097.         // No available editors support this kind
  2098.         ODTranslation* translation = session->GetTranslation(ev);
  2099.         ODPlatformType platformType = translation->GetPlatformTypeFromISOType(ev, kind);
  2100.         if ( platformType != kODNULL )
  2101.         {
  2102.             *itemString = (StringPtr) ODNewPtr(sizeof(ODPlatformType) + 1);
  2103.             ODBlockMove(&platformType, &((*itemString)[1]), (ODULong) sizeof(ODPlatformType));
  2104.             (*itemString)[0] = (unsigned char) sizeof(ODPlatformType);
  2105.         }
  2106.         else
  2107.         {
  2108.             *itemString = DefaultMenuStringForKind();
  2109.         }
  2110.         *itemScript = smSystemScript;
  2111.     }
  2112. }
  2113.  
  2114. //------------------------------------------------------------------------------
  2115. // AddTranslationKindToMenu
  2116. //------------------------------------------------------------------------------
  2117.  
  2118. void AddTranslationKindToMenu(
  2119.         ODType        kind, 
  2120.         MenuHandle    kindMenu,
  2121.         short        item,
  2122.         ODBoolean    insert,
  2123.         ODSession*    session)
  2124. {
  2125.     StringPtr itemString;
  2126.     ODScriptCode itemScript;
  2127.     
  2128.     GetMenuStringForKind(session, kind, &itemString, &itemScript);
  2129.     TempODString tempItemString = (char*) itemString; // DMc: ensure it's deleted
  2130.  
  2131.     if ( insert )
  2132.     {
  2133.         InsertMenuItem(kindMenu, itemString, item);
  2134.         item += 1;
  2135.     }
  2136.     else
  2137.         SetMenuItemText(kindMenu, item, itemString);
  2138.     
  2139.     SetPopupItemScript(kindMenu, item, itemScript);
  2140. }
  2141.  
  2142. //------------------------------------------------------------------------------
  2143. // GetTypeListItem 
  2144. //------------------------------------------------------------------------------
  2145.  
  2146. ODType GetTypeListItem(ODTypeList* typeList, ODUShort index)
  2147. {
  2148.     Environment* ev = somGetGlobalEnvironment();
  2149.     ODType theType = kODNULL;
  2150.  
  2151.     if ( index > 0 )
  2152.     {
  2153.         ODTypeListIterator* typeIter = typeList->CreateTypeListIterator(ev);
  2154.     
  2155.         for (theType = typeIter->First(ev);
  2156.              (typeIter->IsNotComplete(ev)) && (index > 1);
  2157.              theType = typeIter->Next(ev), --index)
  2158.         {
  2159.             ODDisposePtr(theType);
  2160.         }
  2161.     
  2162.         delete typeIter;
  2163.     }
  2164.     
  2165.     return theType;
  2166. }
  2167.  
  2168.