Back to index

lightning-sunbird  0.9+nobinonly
nsAEApplicationClass.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla Communicator client code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Simon Fraser <sfraser@netscape.com>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 
00040 #include <Sound.h>
00041 #include <Scrap.h>
00042 
00043 #include "nsAEUtils.h"
00044 #include "nsAETokens.h"
00045 #include "nsAECoreClass.h"
00046 #include "nsAEDocumentClass.h"
00047 #include "nsAEWindowClass.h"
00048 
00049 #include "nsAEApplicationClass.h"
00050 
00051 #include "nsINativeAppSupport.h"
00052 #include "nsCommandLineServiceMac.h"
00053 #include "nsCOMPtr.h"
00054 #include "nsIAppStartup.h"
00055 #include "nsXPFEComponentsCID.h"
00056 
00057 #include "nsComponentManagerUtils.h"
00058 #include "nsServiceManagerUtils.h"
00059 
00060 #ifdef MOZ_XUL_APP
00061 #include "nsAppRunner.h"
00062 #endif
00063 
00064 /*----------------------------------------------------------------------------
00065        AEApplicationClass 
00066        
00067 ----------------------------------------------------------------------------*/
00068 AEApplicationClass::AEApplicationClass()
00069 :      AEGenericClass(cApplication, typeNull)
00070 {
00071 }
00072 
00073 /*----------------------------------------------------------------------------
00074        ~AEApplicationClass 
00075        
00076 ----------------------------------------------------------------------------*/
00077 AEApplicationClass::~AEApplicationClass()
00078 {
00079 }
00080 
00081 #pragma mark -
00082 
00083 
00084 
00085 /*----------------------------------------------------------------------------
00086        GetPropertyFromApp 
00087        
00088        Override default to customize behaviour.
00089 ----------------------------------------------------------------------------*/
00090 void   AEApplicationClass::GetProperty(                 DescType                    desiredClass,
00091                                                                       const AEDesc*        containerToken,
00092                                                                       DescType                    containerClass,
00093                                                                       DescType                    keyForm,
00094                                                                       const AEDesc*        keyData,
00095                                                                       AEDesc*                     resultToken)
00096 {
00097        OSErr                err;
00098        CoreTokenRecord      token;
00099        DescType                    requestedProperty = **(DescType**)keyData->dataHandle;
00100        
00101        token.dispatchClass  = GetClass();
00102        token.objectClass           = GetClass();
00103        token.propertyCode   = requestedProperty;
00104 
00105        if (CanGetProperty(requestedProperty) || CanSetProperty(requestedProperty))
00106        {
00107               err = AECreateDesc(cProperty, (Ptr)&token, sizeof(CoreTokenRecord), resultToken);
00108               ThrowIfOSErr(err);
00109        }
00110        else
00111        {
00112               ThrowIfOSErr(errAEEventNotHandled);
00113        }
00114 }
00115 
00116 
00117 
00118 /*----------------------------------------------------------------------------
00119        GetItemFromContainer 
00120        
00121        Not appropriate for the application
00122 ----------------------------------------------------------------------------*/
00123 void AEApplicationClass::GetItemFromContainer(   DescType                    desiredClass,
00124                                                                       const AEDesc*        containerToken,
00125                                                                       DescType                    containerClass, 
00126                                                                       DescType                    keyForm,
00127                                                                       const AEDesc*        keyData,
00128                                                                       AEDesc*                     resultToken)
00129 {
00130        ThrowIfOSErr(errAEEventNotHandled);
00131 }
00132 
00133 
00134 #pragma mark -
00135 
00136 /*----------------------------------------------------------------------------
00137        HandleClose 
00138        
00139 ----------------------------------------------------------------------------*/
00140 void AEApplicationClass::HandleClose(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00141 {
00142        OSErr  err    = noErr;
00143 
00144        StAEDesc      saving;
00145        StAEDesc      savingIn;
00146               
00147        // Extract the [saving yes/no/ask] optional parameter, if present
00148        err = AEGetParamDesc(appleEvent, 
00149                                                           keyAESaveOptions, 
00150                                                           typeWildCard, 
00151                                                           &saving);
00152                                                           
00153        if (err != errAEDescNotFound)
00154               ThrowIfOSErr(err);
00155               
00156        // Extract the [saving in <alias>] optional parameter, if present
00157        err = AEGetParamDesc(appleEvent, 
00158                                                           keyAEFile, 
00159                                                           typeWildCard, 
00160                                                           &savingIn);
00161                                                           
00162        if (err != errAEDescNotFound)
00163               ThrowIfOSErr(err);
00164                      
00165        // Check for any required parameters we may have missed
00166        err = CheckForUnusedParameters(appleEvent);
00167        ThrowIfOSErr(err);
00168               
00169        // Now, do the application-related work
00170        SysBeep(2);
00171               
00172 
00173 }
00174 
00175 /*----------------------------------------------------------------------------
00176        HandleCount 
00177        
00178 ----------------------------------------------------------------------------*/
00179 void AEApplicationClass::HandleCount(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00180 {
00181        OSErr  err                         = noErr;
00182        long          numberOfObjects      = 0L;
00183 
00184        DescType      objectClass;
00185 
00186        if (!reply->dataHandle)
00187               return;
00188        
00189        // Get the class of object that we will count
00190        err = GetObjectClassFromAppleEvent(appleEvent, &objectClass);
00191        ThrowIfOSErr(err);
00192 
00193        // Make sure we got & handled all of the required paramters
00194        err = CheckForUnusedParameters(appleEvent);
00195        ThrowIfOSErr(err);
00196        
00197        // Send back the results
00198        numberOfObjects = CountApplicationObjects(token, objectClass);
00199        err = AEPutParamPtr(reply, keyAEResult, typeLongInteger, (Ptr)&numberOfObjects, sizeof(long));
00200        ThrowIfOSErr(err);
00201 }
00202 
00203 
00204 /*----------------------------------------------------------------------------
00205        HandleDataSize 
00206        
00207 ----------------------------------------------------------------------------*/
00208 void AEApplicationClass::HandleDataSize(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00209 {
00210        OSErr  err = noErr;
00211        StAEDesc      data;
00212        long          size  = 0L;
00213        
00214        // First, get the data
00215        HandleGetData(token, appleEvent, reply);
00216        
00217        // now, extract it from the reply
00218        err = AEGetKeyDesc(reply, keyDirectObject, typeWildCard, &data);
00219        ThrowIfOSErr(err);
00220        
00221        size = data.GetDataSize();
00222        
00223        // do we leak all the data here?
00224        err = AEPutParamPtr(reply, 
00225                                                          keyAEResult, 
00226                                                          typeLongInteger, 
00227                                                          (Ptr)&size, 
00228                                                          sizeof(long));
00229        ThrowIfOSErr(err);
00230 }
00231 
00232 
00233 /*----------------------------------------------------------------------------
00234        HandleDelete 
00235 
00236        All attempts to delete an empty list are handled here
00237        Application contains documents and windows, and they can't be deleted
00238        
00239 ----------------------------------------------------------------------------*/
00240 void AEApplicationClass::HandleDelete(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00241 {
00242        OSErr  err = noErr;
00243               
00244        if (AEListUtils::TokenContainsTokenList(token))
00245        {
00246               long                 numItems;
00247               
00248               AECountItems(token, &numItems);
00249 
00250               if (numItems > 0)
00251                      err = errAEEventNotHandled;
00252        }
00253 
00254        ThrowIfOSErr(err);
00255 }
00256 
00257 /*----------------------------------------------------------------------------
00258        HandleDuplicate 
00259        
00260 ----------------------------------------------------------------------------*/
00261 void AEApplicationClass::HandleDuplicate(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00262 {
00263        ThrowIfOSErr(errAEEventNotHandled);
00264 }
00265 
00266 /*----------------------------------------------------------------------------
00267        HandleExists 
00268 
00269        If <referenceToObject> exists...
00270        The AEResolve() function in AERCoreSuite.c will already have filtered
00271        out all cases where the object did not exist, so this function should
00272        always return TRUE.
00273        
00274 ----------------------------------------------------------------------------*/
00275 void AEApplicationClass::HandleExists(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00276 {
00277        OSErr  err           = noErr;
00278        Boolean       foundIt       = true;
00279 
00280        err = AEPutParamPtr(reply, 
00281                                     keyAEResult, 
00282                                     typeBoolean, 
00283                                     (Ptr)&foundIt, 
00284                                     sizeof(Boolean));
00285               
00286        ThrowIfOSErr(err);
00287 }
00288 
00289 
00290 /*----------------------------------------------------------------------------
00291        HandleMake 
00292 
00293        
00294 ----------------------------------------------------------------------------*/
00295 void AEApplicationClass::HandleMake(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00296 {
00297        ThrowIfOSErr(errAEEventNotHandled);
00298 }
00299 
00300 /*----------------------------------------------------------------------------
00301        HandleMove 
00302 
00303        
00304 ----------------------------------------------------------------------------*/
00305 void AEApplicationClass::HandleMove(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00306 {
00307        ThrowIfOSErr(errAEEventNotHandled);
00308 }
00309 
00310 /*----------------------------------------------------------------------------
00311        HandleRun 
00312 
00313        
00314 ----------------------------------------------------------------------------*/
00315 void AEApplicationClass::HandleRun(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00316 {
00317        OSErr  err = noErr;
00318 
00319         // do stuff on startup that we want to do
00320         
00321        err = CheckForUnusedParameters(appleEvent);
00322        ThrowIfOSErr(err);
00323 }
00324 
00325 /*----------------------------------------------------------------------------
00326        HandleReOpen 
00327 
00328        
00329 ----------------------------------------------------------------------------*/
00330 void AEApplicationClass::HandleReOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00331 {
00332   OSErr       err = noErr;
00333   nsresult rv = NS_OK;
00334   nsCOMPtr<nsINativeAppSupport> nas;
00335 
00336 #ifdef MOZ_XUL_APP
00337   nas = do_CreateInstance(NS_NATIVEAPPSUPPORT_CONTRACTID);
00338   if (!nas) ThrowIfOSErr(errAEEventNotHandled);
00339 #else
00340   nsCOMPtr<nsIAppStartup> appStartup(do_GetService(NS_APPSTARTUP_CONTRACTID));
00341   NS_WARN_IF_FALSE(appStartup, "Failed to get appstartup service");
00342   if(!appStartup) ThrowIfOSErr(errAEEventNotHandled);
00343   
00344   rv = appStartup->GetNativeAppSupport(getter_AddRefs(nas));
00345   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to get NativeAppSupport");  
00346   if(NS_FAILED(rv)) ThrowIfOSErr(errAEEventNotHandled);
00347 #endif
00348 
00349   rv = nas->ReOpen();
00350   if(NS_FAILED(rv)) ThrowIfOSErr(errAEEventNotHandled);    
00351 
00352        err = CheckForUnusedParameters(appleEvent);
00353        ThrowIfOSErr(err);
00354 }
00355 
00356 /*----------------------------------------------------------------------------
00357        HandleOpen 
00358 
00359        
00360 ----------------------------------------------------------------------------*/
00361 void AEApplicationClass::HandleOpen(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00362 {
00363        OSErr  err;
00364        
00365        err = CheckForUnusedParameters(appleEvent);
00366        ThrowIfOSErr(err);
00367 
00368        long                 numItems, i;
00369        Boolean              openedGroups = false;
00370 
00371        err = ::AECountItems(token, &numItems);
00372        ThrowIfOSErr(err);
00373        
00374        for (i = 1; i <= numItems; i++)
00375        {
00376               FSSpec               fSpec;
00377               FInfo         fndrInfo;
00378               AEKeyword     keywd;
00379               DescType             returnedType;
00380               Size                 actualSize;
00381 
00382               err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
00383               ThrowIfOSErr(err);
00384               
00385               err = ::FSpGetFInfo(&fSpec, &fndrInfo);
00386               ThrowIfOSErr(err);
00387 
00388               nsMacCommandLine&  cmdLine = nsMacCommandLine::GetMacCommandLine();
00389               cmdLine.HandleOpenOneDoc(fSpec, fndrInfo.fdType);
00390        }
00391 }
00392 
00393 
00394 /*----------------------------------------------------------------------------
00395        HandlePrint 
00396 
00397        
00398 ----------------------------------------------------------------------------*/
00399 void AEApplicationClass::HandlePrint(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00400 {
00401        OSErr  err=noErr;
00402        
00403        err = CheckForUnusedParameters(appleEvent);
00404        ThrowIfOSErr(err);
00405 
00406        long                 numItems, i;
00407        Boolean              openedGroups = false;
00408 
00409        err = ::AECountItems(token, &numItems);
00410        ThrowIfOSErr(err);
00411        
00412        for (i = 1; i <= numItems; i++)
00413        {
00414               FSSpec               fSpec;
00415               FInfo         fndrInfo;
00416               AEKeyword     keywd;
00417               DescType             returnedType;
00418               Size                 actualSize;
00419 
00420               err = ::AEGetNthPtr(token, i, typeFSS, &keywd, &returnedType, (Ptr)&fSpec, sizeof(fSpec), &actualSize);
00421               ThrowIfOSErr(err);
00422               
00423               err = ::FSpGetFInfo(&fSpec, &fndrInfo);
00424               ThrowIfOSErr(err);
00425 
00426               nsMacCommandLine&  cmdLine = nsMacCommandLine::GetMacCommandLine();
00427               cmdLine.HandlePrintOneDoc(fSpec, fndrInfo.fdType);
00428        }
00429 }
00430 
00431 /*----------------------------------------------------------------------------
00432        HandleQuit 
00433 
00434        
00435 ----------------------------------------------------------------------------*/
00436 void AEApplicationClass::HandleQuit(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00437 {
00438        // get optional saving param
00439        StAEDesc             savingParam;
00440        TAskSave             askSave = eSaveUnspecified;
00441        
00442        OSErr  err = ::AEGetKeyDesc(appleEvent, keyAESaveOptions, typeEnumeration, &savingParam);
00443        if (err != errAEDescNotFound)
00444        {
00445               DescType             enumValue = savingParam.GetEnumType();
00446               
00447               switch (enumValue)
00448               {
00449                      case 'yes ':         askSave = eSaveYes;         break;
00450                      case 'no  ':         askSave = eSaveNo;                 break;
00451                      case 'ask ':         askSave = eSaveAsk;         break;
00452               }
00453        }
00454        
00455        err = CheckForUnusedParameters(appleEvent);
00456        ThrowIfOSErr(err);
00457 
00458        nsMacCommandLine&  cmdLine = nsMacCommandLine::GetMacCommandLine();
00459        err = cmdLine.Quit(askSave);
00460        ThrowIfOSErr(err);
00461 }
00462 
00463 /*----------------------------------------------------------------------------
00464        HandleSave 
00465 
00466        
00467 ----------------------------------------------------------------------------*/
00468 void AEApplicationClass::HandleSave(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00469 {
00470        ThrowIfOSErr(errAEEventNotHandled);
00471 }
00472 
00473 #if 0
00474 /*----------------------------------------------------------------------------
00475        HandleSetData 
00476 
00477        
00478 ----------------------------------------------------------------------------*/
00479 void AEApplicationClass::HandleSetData(AEDesc *token, const AppleEvent *appleEvent, AppleEvent *reply)
00480 {
00481        OSErr                err           = noErr;      
00482        StAEDesc                    tokenData;
00483        AETokenDesc          tokenDesc(token);
00484        DescType                    propertyCode;
00485                      
00486        if (token->descriptorType == cProperty)
00487        {
00488               propertyCode = tokenDesc.GetPropertyCode();
00489 
00490               if (CanSetProperty(propertyCode))
00491               {
00492                      // only the clipboard property is writeable
00493                      // the clipboard data should be in a list, so we extract that list
00494                      switch (propertyCode)
00495                      {
00496                             case pClipboard:
00497                                    err = AEGetKeyDesc(appleEvent, keyAEData, typeAEList, &tokenData);
00498                                    ThrowIfOSErr(err);
00499                                    
00500                                    SetDataForObject(token, &tokenData);             // may throw
00501 
00502                                    err = AEPutKeyDesc(reply, keyDirectObject, &tokenData); // return the requested data
00503                                    ThrowIfOSErr(err);
00504                                    break;
00505                                    
00506                             default:
00507                                    ThrowIfOSErr(errAENotModifiable);  // "Can't set xxx to nnn"
00508                                    break;
00509                      }
00510               }
00511               else
00512               {
00513                      ThrowIfOSErr(errAENotModifiable);
00514               }
00515        }
00516        else
00517        {
00518               ThrowIfOSErr(errAEEventNotHandled);
00519        }
00520        
00521 }
00522 #endif
00523 
00524 #pragma mark -
00525 
00526 /*----------------------------------------------------------------------------
00527        CountObjects 
00528        
00529 ----------------------------------------------------------------------------*/
00530 void AEApplicationClass::CountObjects(                         DescType                    desiredType,
00531                                                                              DescType                    containerClass,
00532                                                                              const AEDesc *              container,
00533                                                                              long *               result)
00534 {
00535        long          numberOfObjects = CountApplicationObjects(container, desiredType);
00536        *result = numberOfObjects;
00537 }
00538 
00539 #pragma mark -
00540 
00541 /*----------------------------------------------------------------------------
00542        GetDataFromObject 
00543        
00544 ----------------------------------------------------------------------------*/
00545 void AEApplicationClass::GetDataFromObject(const AEDesc *token, AEDesc *desiredTypes, AEDesc *data)
00546 {
00547        OSErr                              err    = noErr;
00548        
00549        Str255                             applicationName = "\p";
00550        Str255                             versionString;
00551        
00552        ConstAETokenDesc                          tokenDesc(token);
00553        
00554        ProcessSerialNumber         applicationProcessNumber;
00555        ProcessInfoRec                            applicationInfo;
00556        FSSpec                             appFSSpec;
00557 
00558        Boolean                                   isFrontProcess              = true;       // еее !gInBackground;
00559        
00560        DescType                                  aDescType            = cApplication;
00561        
00562        long                                      documentNumber       = 0L;
00563        unsigned long                      elementNumber        = 0L;
00564               
00565        Boolean                                   usePropertyCode      = tokenDesc.UsePropertyCode();
00566        DescType                                  propertyCode;
00567        
00568        long                                      free;
00569        long                                      contiguous;
00570        unsigned long                             ticks;
00571 
00572        err = GetCurrentProcess(&applicationProcessNumber);     
00573        
00574        if (err == noErr)
00575        {
00576               applicationInfo.processInfoLength  = sizeof(ProcessInfoRec);
00577               applicationInfo.processName               = applicationName;
00578               applicationInfo.processAppSpec     = &appFSSpec;
00579               err = GetProcessInformation(&applicationProcessNumber, &applicationInfo);
00580        }
00581                             
00582        GetShortVersionString(2, versionString);
00583        PurgeSpace(&free, &contiguous);
00584                             
00585        ticks = TickCount();
00586 
00587        propertyCode = tokenDesc.GetPropertyCode();
00588        
00589        switch (propertyCode)
00590        {
00591               case pProperties:
00592                      err = AECreateList(nil, 0, true, data);
00593                      ThrowIfOSErr(err);
00594 
00595                      err = AEPutKeyPtr(data, pObjectType,             typeType,            &aDescType, sizeof(DescType));
00596                      err = AEPutKeyPtr(data, pName,                   typeChar,            &applicationName[1], applicationName[0]);
00597                      err = AEPutKeyPtr(data, pVersion,                typeChar,            &versionString[1], versionString[0]);
00598                      err = AEPutKeyPtr(data, pIsFrontProcess,  typeBoolean,         &isFrontProcess, sizeof(Boolean));
00599                      err = AEPutKeyPtr(data, pFreeMemory,             typeLongInteger,     &free, sizeof(long));
00600                      err = AEPutKeyPtr(data, pLargestFreeBlock,       typeLongInteger,     &contiguous, sizeof(long));
00601                      err = AEPutKeyPtr(data, pTicks,                  typeLongInteger,     &ticks, sizeof(long));
00602                      break;
00603                      
00604               case pBestType:
00605               case pClass:
00606               case pDefaultType:
00607               case pObjectType:
00608                      err = AECreateDesc(typeType, &aDescType, sizeof(DescType), data);
00609                      break;
00610                      
00611               case pName:   
00612                      err = AECreateDesc(typeChar, &applicationName[1], applicationName[0], data);
00613                      break;
00614 
00615               case pVersion:
00616                      err = AECreateDesc(typeChar, &versionString[1], versionString[0], data);
00617                      break;
00618 
00619               case pIsFrontProcess:
00620                      err = AECreateDesc(typeBoolean, &isFrontProcess, sizeof(Boolean), data);
00621                      break;
00622 
00623               case pFreeMemory:
00624                      err = AECreateDesc(typeLongInteger, &free, sizeof(long), data);
00625                      break;
00626                      
00627               case pLargestFreeBlock:
00628                      err = AECreateDesc(typeLongInteger, &contiguous, sizeof(long), data);
00629                      break;
00630                      
00631               case pTicks:
00632                      err = AECreateDesc(typeLongInteger, &ticks, sizeof(long), data);
00633                      break;
00634                      
00635               case pClipboard:
00636 #if !TARGET_CARBON          
00637                      {
00638                             //     Return all of the items currently on the clipboard.
00639                             //     The returned information is an AEList, and each data type
00640                             //     on the scrap gets its own entry in the list
00641                             //     Since the OS doesn't supply the tools for getting all
00642                             //     of the types in the scrap, we have to scan the scrap ourselves
00643 
00644                             char                 *scrapPtr;
00645                             char                 *scrapEnd;
00646                             PScrapStuff    scrapInfo;
00647                             OSType         itemType;
00648                             long                  itemLength;
00649                             long                  index;
00650                             
00651                             err = AECreateList(NULL, 0, false, data);
00652                             ThrowIfOSErr(err);
00653                             
00654                             err = LoadScrap();                                                                  //     Make sure the scrap is in memory, not on disk.
00655                             ThrowIfOSErr(err);
00656                             
00657                             scrapInfo = InfoScrap();                                                     //     Get the base address of the scrap in RAM
00658                             MoveHHi(scrapInfo->scrapHandle);
00659                             HLock  (scrapInfo->scrapHandle);                                      // ...and lock it
00660                             
00661                             scrapPtr = (char *)*scrapInfo->scrapHandle;
00662                             scrapEnd = scrapPtr + scrapInfo->scrapSize;
00663                             
00664                             // scan the scrap in memory and extract each scrap type
00665                             
00666                             index = 1;
00667                             while (scrapPtr < scrapEnd) 
00668                             {
00669                                    itemType = *(OSType *)scrapPtr;
00670                                    scrapPtr += sizeof(itemType);
00671                                    itemLength = *(long *)scrapPtr;
00672                                    scrapPtr += sizeof(itemLength);
00673                                    
00674                                    // Move this information into the next entry on the list
00675                                    err = AEPutPtr(data, index, itemType, scrapPtr, itemLength);
00676                                    ThrowIfOSErr(err);
00677                                           
00678                                    index++;
00679                                    
00680                                    // Adjust the pointer to the start of the next item
00681                                    
00682                                    if (itemLength & 1) 
00683                                           itemLength++;                                                                       // If it's odd, make it even
00684                                           
00685                                    scrapPtr += itemLength;
00686                             }
00687                             HUnlock  (scrapInfo->scrapHandle);
00688                      }
00689 #endif
00690                      break;
00691 
00692               default:
00693                      Inherited::GetDataFromObject(token, desiredTypes, data);
00694                      break;
00695        }
00696 
00697        ThrowIfOSErr(err);
00698 }
00699 
00700 /*----------------------------------------------------------------------------
00701        SetDataForObject 
00702        
00703        Assumption: HandleSetData() has already filtered out all attempts
00704        to write to a read-only property.
00705        
00706 ----------------------------------------------------------------------------*/
00707 void AEApplicationClass::SetDataForObject(const AEDesc *token, AEDesc *data)
00708 {
00709        OSErr                       err                  = noErr;
00710        ConstAETokenDesc                   tokenDesc(token);
00711        Boolean                            usePropertyCode     = tokenDesc.UsePropertyCode();
00712        DescType                           propertyCode;
00713        
00714        if (usePropertyCode)
00715        {
00716               propertyCode = tokenDesc.GetPropertyCode();
00717               
00718 #if !TARGET_CARBON
00719               long                 numItems;
00720 #endif
00721               switch (propertyCode)
00722               {
00723                      // the clipboard is the only writeable property for the application object
00724                      case pClipboard:
00725                             //     The data should be an AE list containing a series of things to be placed on the
00726                             //     clipboard. The data type of each item is also the clipboard type for that data
00727 #if !TARGET_CARBON
00728                             err = ZeroScrap();
00729                             ThrowIfOSErr(err);
00730                             
00731                             AECountItems(data, &numItems);
00732                             
00733                             //  Copy each item onto the clipboard
00734                             
00735                             for (long index = 1; index <= numItems; index++) 
00736                             {
00737                                    StAEDesc             currentItemDesc;
00738                                    AEKeyword            theAEKeyword;
00739                                    err = AEGetNthDesc(data, index, typeWildCard, &theAEKeyword, &currentItemDesc);
00740                                    ThrowIfOSErr(err);
00741                                           
00742                                    HLock(currentItemDesc.dataHandle);
00743                                    err = PutScrap(GetHandleSize(currentItemDesc.dataHandle), 
00744                                                                         currentItemDesc.descriptorType,
00745                                                                       *currentItemDesc.dataHandle);
00746                                    ThrowIfOSErr(err);
00747                             }
00748 #endif
00749                             break;
00750                             
00751                      default:
00752                             ThrowIfOSErr(errAENotModifiable);
00753               }
00754        }
00755        
00756 }
00757 
00758 
00759 /*----------------------------------------------------------------------------
00760        GetKeyEventDataAs 
00761 
00762 ----------------------------------------------------------------------------*/
00763 DescType AEApplicationClass::GetKeyEventDataAs(DescType propertyCode)
00764 {
00765        DescType             returnType;
00766 
00767        switch (propertyCode)
00768        {
00769               case pClipboard:
00770                      returnType = typeAEList;
00771                      break;
00772                      
00773               default:
00774                      returnType = typeWildCard;
00775        
00776        }
00777        return returnType;
00778 }
00779 
00780 
00781 #pragma mark -
00782 
00783 /*----------------------------------------------------------------------------
00784        CanSetProperty 
00785               
00786 ----------------------------------------------------------------------------*/
00787 Boolean AEApplicationClass::CanSetProperty(DescType propertyCode)
00788 {
00789        Boolean result = false;
00790        
00791        switch (propertyCode)
00792        {
00793               // Properties we can set:
00794               
00795               case pClipboard:
00796                      result = true;
00797                      break;
00798                      
00799               // Properties we should be able to set, but they're not implemented yet:
00800               
00801                                    
00802               // Properties that are read-only
00803 
00804               case pBestType:
00805               case pClass:
00806               case pDefaultType:
00807               case pObjectType:
00808               
00809               case pProperties:
00810               
00811               case pFreeMemory:
00812               case pLargestFreeBlock:
00813               case pTicks:
00814 
00815               case pIsFrontProcess:
00816               case pName:
00817               case pVersion:
00818               case pInsertionLoc:
00819               case pSelection:
00820               case pUserSelection:
00821                      result = false;
00822                      break;
00823               
00824               default:
00825                      result = Inherited::CanSetProperty(propertyCode);
00826                      break;
00827        }
00828        
00829        return result;
00830 }
00831 
00832 
00833 /*----------------------------------------------------------------------------
00834        CanGetProperty 
00835        
00836 ----------------------------------------------------------------------------*/
00837 Boolean AEApplicationClass::CanGetProperty(DescType propertyCode)
00838 {
00839        Boolean result = false;
00840        
00841        switch (propertyCode)
00842        {
00843               // Properties we can get:
00844 
00845               case pBestType:
00846               case pClass:
00847               case pDefaultType:
00848               case pObjectType:
00849                      
00850               case pProperties:
00851               
00852               case pFreeMemory:
00853               case pLargestFreeBlock:
00854               case pTicks:
00855 
00856               case pIsFrontProcess:
00857               case pName:
00858               case pVersion:
00859               case pInsertionLoc:
00860               case pSelection:
00861               case pUserSelection:
00862                      result = true;
00863                      break;
00864                      
00865               // Properties we should be able to get, but they're not implemented yet:
00866                                    
00867               // Properties we should not be able to get:
00868               
00869               default:
00870                      result = Inherited::CanGetProperty(propertyCode);
00871                      break;
00872        }
00873        
00874        return result;
00875 }
00876 
00877 
00878 #pragma mark -
00879 
00880 /*----------------------------------------------------------------------------
00881        CreateSelfSpecifier 
00882 
00883 ----------------------------------------------------------------------------*/
00884 void AEApplicationClass::CreateSelfSpecifier(const AEDesc *token, AEDesc *outSpecifier)
00885 {
00886        OSErr  err = ::AECreateDesc(typeNull, nil, 0, outSpecifier);
00887        ThrowIfOSErr(err);
00888 }
00889 
00890 #pragma mark -
00891 
00892 /*----------------------------------------------------------------------------
00893        CountApplicationObjects 
00894        
00895 ----------------------------------------------------------------------------*/
00896 long AEApplicationClass::CountApplicationObjects(const AEDesc *token, DescType desiredType)
00897 {
00898        long          numberOfObjects = 0;
00899        OSErr  err = noErr;
00900        
00901        if (AEListUtils::TokenContainsTokenList(token))
00902        {
00903               err = AECountItems(token, &numberOfObjects);
00904        }
00905        else
00906        {
00907               AEDispatchHandler*   countHandler = AECoreClass::sAECoreHandler->GetDispatchHandler(desiredType);
00908               if (countHandler == nil)
00909                      ThrowOSErr(errAEEventNotHandled);
00910               
00911               countHandler->CountObjects(desiredType, typeNull, token, &numberOfObjects);
00912               /*
00913               switch (desiredType)
00914               {
00915                      case cDocument:
00916                             numberOfObjects = AEDocumentClass::CountDocuments();
00917                             break;
00918 
00919                      case cWindow:
00920                             numberOfObjects = AEWindowClass::CountWindows(kAnyWindowKind);
00921                             break;
00922                      
00923                      // application specific classes
00924                      case cGroupWindow:
00925                             numberOfObjects = AEWindowClass::CountWindows(kUserGroupWindowKind);
00926                             break;
00927                      
00928                      
00929                      default:
00930                             err = errAEEventNotHandled;
00931                             break;
00932               }
00933               */
00934        }
00935 
00936        ThrowIfOSErr(err);
00937        return numberOfObjects;
00938 }