home *** CD-ROM | disk | FTP | other *** search
- /*
- File: RlShSync.cpp
-
- Contains: Document-synchronization stuff in the shell
-
- Owned by: Jens Alfke
-
- Portions by Mark Linton (see issue 23 of 'develop')
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <6> 9/29/95 eeh 1287262: use ShellDef.h
- <5> 9/12/95 JP Check for null draft (build break)
- <4> 9/11/95 JP 1269048 & 1283405: Cope with multiple
- documents
- <3> 9/5/95 TÇ FBs: 1266428, 1274419, 1274421, 1274423,
- 1274429, 1274435 Fixed the Shell to handle
- multiple documents in a process. Needed for
- CyberDog.
- <2> 8/15/95 TÇ 1261899 DocUtils getters should be renamed
- Acquire___
- <1> 8/8/95 jpa first checked in
- */
-
-
- #ifndef _RLSHELL_
- #include "RlShell.h"
- #endif
-
- #ifndef _SHELLDEF_
- #include "ShellDef.h"
- #endif
-
- #ifndef SOM_ODDispatcher_xh
- #include <Disptch.xh>
- #endif
-
- #ifndef SOM_ODWindowState_xh
- #include <WinStat.xh>
- #endif
-
- #ifndef _DLOGUTIL_
- #include <DlogUtil.h>
- #endif
-
- #ifndef _DOCUTILS_
- #include <DocUtils.h>
- #endif
-
- #ifndef _INFOUTIL_
- #include <InfoUtil.h>
- #endif
-
- #ifndef _PASCLSTR_
- #include <PasclStr.h>
- #endif
-
- #ifndef _TEMPOBJ_
- #include <TempObj.h>
- #endif
-
- #include <AppleEvents.h>
- #include <AERegistry.h>
- #include <Aliases.h>
- #include <Drag.h>
- #include <Folders.h>
- #include <Script.h>
-
-
- #undef ASK_SAVE_TO_TRASH /* Define to ask user what to do when modified
- document is dragged to trash */
-
-
- //==============================================================================
- // Constants
- //==============================================================================
-
- enum { // Buttons for kSHLDragToTrashAlert
- kTrashSaveIndex = 1,
- kTrashDontSaveIndex,
- kTrashRetrieveIndex
- };
-
- #ifndef kAEFinderSuite
- #define kAEFinderSuite 'fndr'
- #endif
-
- #ifndef kAEPutAway
- #define kAEPutAway 'ptwy'
- #endif
-
- const ODSShort kNumBetween = 20;
-
-
- //==============================================================================
- // Static Function Prototypes
- //==============================================================================
-
- static void ZoomWindowToTrash( WindowPtr );
- static OSErr SendFinderEvent(AEEventClass, AEEventID, const FSSpec& );
- static ODULong GetMostRecentVolModDate();
-
-
- //==============================================================================
- // Static Globals
- //==============================================================================
- static ODULong lastChecked = 0; // time of the last disk check
-
- //==============================================================================
- // Shell Methods
- //==============================================================================
-
- //-------------------------------------------------------------------------------------
- // RealShell::CheckFileLocation
- //-------------------------------------------------------------------------------------
-
- ODBoolean
- RealShell::CheckFileLocation( )
- {
- ODULong n = 1;
- ODULong nowTime;
- char firstCStr[256], secondCStr[256];
-
- nowTime = GetMostRecentVolModDate();
- if (nowTime == lastChecked)
- return kODFalse; // bail if we've already checked during this second
-
- ODDocument* document = ODGetNthOpenDocument(fEV, fSession, n);
- RETURN_IF_NULL(document, kODFalse);
-
- while (document != kODNULL)
- {
- TempPlatformFile file = GetPlatformFileFromContainer(fEV,
- document->GetContainer(fEV));
- ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(fEV, fSession, document);
- if (tempDraft != kODNULL)
- {
- TempODPart root = ODAcquireRootPartOfDraft(fEV, tempDraft);
- TempODName partName = ODGetPOName(fEV, root, kODNULL);
- TempODName fileName = file->GetName();
-
- if(strcmp( GetITextString(partName, firstCStr),
- GetITextString(fileName, secondCStr) ) != 0)
- {
- // Filename changed: rename root part
-
- ODSetPOName(fEV, root, fileName);
- ODRenamePartWindows(fEV, fSession, root, partName, fileName);
- }
- }
-
- if(file->IsInTrash() ) {
- // File has been moved to trash: close document.
- #ifdef ASK_SAVE_TO_TRASH
- if( this->HasWriteAccess() && tempDraft && tempDraft->ChangedFromPrev(fEV) )
- this->Notify(&RealShell::NotifyDragToTrash);
- else
- #endif
- this->CloseTrashedDocument(document, kAEYes);
- return fDispatcher->ShouldExit(fEV);
- } else
- // If it's no longer in the trash, don't bother to notify:
- this->CancelNotification(&RealShell::NotifyDragToTrash);
- document = ODGetNthOpenDocument(fEV, fSession, ++n);
- }
- lastChecked = nowTime;
- return kODFalse;
- }
-
-
- //-------------------------------------------------------------------------------------
- // RealShell::NotifyDragToTrash
- //-------------------------------------------------------------------------------------
-
- void
- RealShell::NotifyDragToTrash( ODULong /*refCon*/ )
- {
- #ifdef ASK_SAVE_TO_TRASH
- char fileName[256];
- this->GetUserFileName(fileName, 255);
- CToPascalString(fileName);
- ParamText((ConstStr255Param)fileName, kODNULL,kODNULL,kODNULL);
-
- ODSShort result= ShowAlert(fEV,kSHLDragToTrashAlert,GetODDialogFilter(),fSession);
- if( result == kTrashRetrieveIndex )
- SendFinderEvent(kAEFinderSuite,kAEPutAway, fFile.GetFileSpec());
- else
- this->CloseTrashedDocument( result==kTrashSaveIndex ?kAEYes :kAENo);
- #endif
- }
-
-
- void
- RealShell::CloseTrashedDocument(ODDocument* document, DescType saveOptions )
- {
- ODSaveDocument(fEV, fSession, document);
- {
- TempODWindow w = fWindowState->AcquireFrontRootWindow(fEV);
- ZoomWindowToTrash(w->GetPlatformWindow(fEV));
- }
- if (ODCloseDocument(fEV, fSession, document))
- fDispatcher->Exit(fEV);
- }
-
-
- //==============================================================================
- // Static Functions
- //==============================================================================
-
-
- //-------------------------------------------------------------------------------------
- // GetTrashIconRect
- //-------------------------------------------------------------------------------------
-
- static OSErr
- GetTrashIconRect(Rect *aRect) {
- OSErr theError;
- short theVRefNum;
- long theDirID;
- Str255 theName;
- CInfoPBRec pb;
- Point thePoint;
-
- theError = FindFolder(kOnSystemDisk, kTrashFolderType, kDontCreateFolder,
- &theVRefNum, &theDirID);
- if (theError == fnfErr) {
- theError = FindFolder(kOnSystemDisk, kWhereToEmptyTrashFolderType, kDontCreateFolder,
- &theVRefNum, &theDirID);
- }
- if (theError == noErr) {
- pb.dirInfo.ioNamePtr = theName;
- pb.dirInfo.ioVRefNum = theVRefNum;
- pb.dirInfo.ioDrDirID = theDirID;
- pb.dirInfo.ioFDirIndex = -1; /* use ioDrDirID */
- theError = PBGetCatInfoSync(&pb);
- if (theError == noErr) {
- thePoint.v = pb.dirInfo.ioDrUsrWds.frLocation.v;
- thePoint.h = pb.dirInfo.ioDrUsrWds.frLocation.h;
- LocalToGlobal(&thePoint);
- aRect->top = thePoint.v;
- aRect->left = thePoint.h;
- aRect->bottom = aRect->top + 32;
- aRect->right = aRect->left + 32;
- }
- }
- return theError;
- }
-
-
- //-------------------------------------------------------------------------------------
- // UpdateDesktop
- //-------------------------------------------------------------------------------------
-
- static void
- UpdateDesktop( )
- {
- EventRecord theEvent;
- (void)WaitNextEvent(0, &theEvent, 10, kODNULL);
- }
-
- //-------------------------------------------------------------------------------------
- // ZoomWindowToTrash
- //-------------------------------------------------------------------------------------
-
- static void
- ZoomWindowToTrash( WindowPtr aWindow )
- {
- GrafPtr curPort, wmgrPort;
- GetPort(&curPort);
-
- Rect theStartingRect, theEndingRect;
- theStartingRect = aWindow->portRect;
- SetPort(aWindow);
- LocalToGlobal((Point*)&theStartingRect.top);
- LocalToGlobal((Point*)&theStartingRect.bottom);
-
- HideWindow(aWindow);
- UpdateDesktop();
- GetWMgrPort(&wmgrPort);
- SetPort(wmgrPort);
-
- OSErr theError = GetTrashIconRect(&theEndingRect);
- if( !theError )
- ZoomRects(&theStartingRect,&theEndingRect,kNumBetween,zoomNoAcceleration);
-
- SetPort(curPort);
- }
-
-
- #ifdef ASK_SAVE_TO_TRASH
-
- //-------------------------------------------------------------------------------------
- // FindFinder
- //-------------------------------------------------------------------------------------
-
- #define kSystemType 'FNDR'
- #define kFinderSig 'MACS'
-
- static OSErr
- FindFinder(ProcessSerialNumberPtr aPSN)
- {
- ProcessInfoRec theProcessInfo;
- FSSpec theProcessFile;
- Str31 theProcessName;
- OSErr theError = noErr;
-
- aPSN->lowLongOfPSN = 0;
- aPSN->highLongOfPSN = kNoProcess;
- theProcessInfo.processInfoLength = sizeof(ProcessInfoRec);
- theProcessInfo.processName = theProcessName;
- theProcessInfo.processAppSpec = &theProcessFile;
- do {
- theError = GetNextProcess(aPSN);
- if (theError == noErr) {
- GetProcessInformation(aPSN, &theProcessInfo);
- }
- } while(((theProcessInfo.processSignature != kFinderSig) ||
- (theProcessInfo.processType != kSystemType)) &&
- (theError == noErr));
- return(theError);
- }
-
-
- //-------------------------------------------------------------------------------------
- // SendFinderEvent
- //-------------------------------------------------------------------------------------
-
- static OSErr
- SendFinderEvent(AEEventClass aClass, AEEventID anID,
- const FSSpec &aFile)
- {
- OSErr theError;
- AppleEvent theAppleEvent, theReplyEvent;
- AEDesc targetAddrDesc, theFileDesc;
- AEDescList theFileDescList;
- AliasHandle theFileAlias;
- ProcessSerialNumber theFinder;
-
- theAppleEvent.dataHandle = nil;
- theFileDescList.dataHandle = nil;
- theFileDesc.dataHandle = nil;
- theFileAlias = nil;
- theError = FindFinder(&theFinder);
- if (theError == noErr) {
- theError = AECreateDesc(typeProcessSerialNumber,
- (Ptr)&theFinder, sizeof(ProcessSerialNumber),
- &targetAddrDesc);
- }
- if (theError == noErr) {
- theError = AECreateList(nil, 0, false, &theFileDescList);
- }
- if (theError == noErr) {
- theError = NewAlias(nil, &aFile, &theFileAlias);
- }
- if (theError == noErr) {
- HLock((Handle) theFileAlias);
- theError = AECreateDesc(typeAlias, (Ptr) *theFileAlias,
- GetHandleSize((Handle) theFileAlias), &theFileDesc);
- HUnlock((Handle) theFileAlias);
- }
- if (theError == noErr) {
- theError = AEPutDesc(&theFileDescList, 0, &theFileDesc);
- }
- if (theError == noErr) {
- theError = AECreateAppleEvent(aClass, anID,
- &targetAddrDesc, kAutoGenerateReturnID,
- kAnyTransactionID, &theAppleEvent);
- }
- if (theError == noErr) {
- theError = AEPutParamDesc(&theAppleEvent, keyDirectObject,
- &theFileDescList);
- }
- if (theError == noErr) {
- theError = AESend(&theAppleEvent, &theReplyEvent,
- kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer,
- kAENormalPriority, kAEDefaultTimeout, nil, nil);
- }
- if (theAppleEvent.dataHandle != nil) {
- (void)AEDisposeDesc(&theAppleEvent);
- }
- if (theFileDescList.dataHandle != nil) {
- (void)AEDisposeDesc(&theFileDescList);
- }
- if (theFileDesc.dataHandle != nil) {
- (void)AEDisposeDesc(&theFileDesc);
- }
- if (theFileAlias != nil) {
- DisposeHandle((Handle)theFileAlias);
- }
- return theError;
- }
-
- #endif /*ASK_SAVE_TO_TRASH*/
-
- ODULong
- GetMostRecentVolModDate()
- {
- ODULong bigModDate = 0;
- OSErr err = noErr;
- ODSShort index = 0;
- HParamBlockRec pb;
-
- pb.volumeParam.ioNamePtr = kODNULL; /* Don't care about name */
- pb.volumeParam.ioVRefNum = 0; /* Don't care about vRefNum */
- while (err == noErr)
- {
- pb.volumeParam.ioVolIndex = ++index;
- err = PBHGetVInfoSync(&pb);
- if (err == noErr && pb.volumeParam.ioVLsMod > bigModDate)
- bigModDate = pb.volumeParam.ioVLsMod;
- }
- return bigModDate;
- }
-