Back to index

lightning-sunbird  0.9+nobinonly
UCustomNavServicesDialogs.cpp
Go to the documentation of this file.
00001 
00002 #include <Navigation.h>
00003 
00004 #include "CHeaderSniffer.h"   // for ESaveFormat, which needs a better home.
00005 
00006 #include "UCustomNavServicesDialogs.h"
00007 
00008 const ResIDT kCustomSaveFilePanelDITLResID = 1550;
00009 const Rect   kCustomSaveFilePanelSize = {0, 0, 48, 248};
00010 
00011 
00012 enum
00013 {
00014   eSaveFormatPanelStaticTextID     = 1,
00015   eSaveFormatPanelFormatPopupID
00016 };
00017 
00018 // ---------------------------------------------------------------------------
00019 //      CNavCallbackData
00020 // ---------------------------------------------------------------------------
00021 // generic callback data for any Nav Services extension
00022 class CNavCallbackData
00023 {
00024 public:
00025                 CNavCallbackData(const Rect& inPanelRect, ResIDT inPanelResID)
00026                 : mPanelRect(inPanelRect)
00027                 , mLastTryWidth(0)
00028                 , mLastTryHeight(0)
00029                 , mResource('DITL', inPanelResID, false /* don't throw */, false /* all res files */)
00030                 , mFirstControlID(0)
00031                 {
00032                 }
00033 
00034       virtual   ~CNavCallbackData()
00035                 {
00036                 }
00037                 
00038                 
00039       Handle    GetDITLHandle() { return mResource.Get(); }
00040       
00041       void      SetFirstControlID(short inFirstID) { mFirstControlID = inFirstID; }
00042       short     GetFirstControlID() { return mFirstControlID; };    // only valid after the NavCustomControl call
00043 
00044   virtual void  NegotiatePanelBounds(NavCBRecPtr inNavCallbackData);
00045   
00046   virtual void  InitControls(NavCBRecPtr inNavCallbackData) = 0;
00047   virtual void  SaveControlValues(NavCBRecPtr inNavCallbackData) = 0;
00048 
00049 protected:
00050 
00051   Rect          mPanelRect;
00052   short         mLastTryWidth;        // used during panel bounds negotiation
00053   short         mLastTryHeight;       // used during panel bounds negotiation
00054   StResource    mResource;
00055   short         mFirstControlID;
00056 };
00057 
00058 
00059 // ---------------------------------------------------------------------------
00060 //      NegotiatePanelBounds
00061 // ---------------------------------------------------------------------------
00062 void CNavCallbackData::NegotiatePanelBounds(NavCBRecPtr inNavCallbackData)
00063 {
00064   Rect&   offeredRect   = inNavCallbackData->customRect;
00065   short   neededWidth   = offeredRect.left + (mPanelRect.right - mPanelRect.left);
00066   short   neededHeight  = offeredRect.top  + (mPanelRect.bottom - mPanelRect.top);
00067 
00068   // first round of negotiations
00069   if (offeredRect.right == 0 && offeredRect.bottom == 0)
00070   {
00071     // just tell it what dimensions we want
00072     offeredRect.right   = neededWidth;
00073     offeredRect.bottom  = neededHeight;
00074   }
00075   else
00076   {
00077     // we are in the middle of negotiating
00078     if (mLastTryWidth != offeredRect.right)
00079       if (offeredRect.right < neededWidth)
00080         offeredRect.right = neededWidth;
00081 
00082     if (mLastTryHeight != offeredRect.bottom)
00083       if (offeredRect.bottom < neededHeight)
00084         offeredRect.bottom = neededHeight;
00085         
00086     mLastTryWidth   = offeredRect.right;
00087     mLastTryHeight  = offeredRect.bottom;
00088   }  
00089 }
00090 
00091 
00092 #pragma mark -
00093 
00094 // ---------------------------------------------------------------------------
00095 //      CNavCustomPutFileCallbackData
00096 // ---------------------------------------------------------------------------
00097 // callback data specific to our file saving dialog
00098 class CNavCustomPutFileCallbackData : public CNavCallbackData
00099 {
00100 public:
00101                 CNavCustomPutFileCallbackData(const Rect& inPanelRect, ResIDT inPanelResID, ESaveFormat inDefaultSaveFormat)
00102                 : CNavCallbackData(inPanelRect, inPanelResID)
00103                 , mSaveFormat(inDefaultSaveFormat)
00104                 , mSaveFormatPopupControl(nil)
00105                 {
00106                   if (mSaveFormat == eSaveFormatUnspecified)
00107                     mSaveFormat = eSaveFormatHTML;
00108                 }
00109 
00110   virtual       ~CNavCustomPutFileCallbackData()
00111                 {
00112                 }
00113             
00114   virtual void  InitControls(NavCBRecPtr inNavCallbackData);
00115   virtual void  SaveControlValues(NavCBRecPtr inNavCallbackData);
00116   
00117   ESaveFormat   GetSaveFormat() { return mSaveFormat; }
00118   
00119 protected:
00120   
00121   ESaveFormat   mSaveFormat;
00122   ControlHandle mSaveFormatPopupControl;
00123   
00124 };
00125 
00126 
00127 void CNavCustomPutFileCallbackData::InitControls(NavCBRecPtr inNavCallbackData)
00128 {
00129   OSErr err = ::GetDialogItemAsControl(::GetDialogFromWindow(inNavCallbackData->window), mFirstControlID + eSaveFormatPanelFormatPopupID, &mSaveFormatPopupControl);
00130   ThrowIfOSErr_(err);
00131   
00132   ::SetControlValue(mSaveFormatPopupControl, (SInt32)mSaveFormat);
00133 }
00134 
00135 
00136 void CNavCustomPutFileCallbackData::SaveControlValues(NavCBRecPtr inNavCallbackData)
00137 {
00138   if (mSaveFormatPopupControl)
00139     mSaveFormat = (ESaveFormat)::GetControlValue(mSaveFormatPopupControl);
00140 }
00141 
00142 #pragma mark -
00143 
00144 // ---------------------------------------------------------------------------
00145 //      NavEventProc                                                                                             [static]
00146 // ---------------------------------------------------------------------------
00147 //     Event filter callback routine for Navigation Services
00148 
00149 pascal void
00150 UNavServicesDialogs::NavCustomEventProc(
00151        NavEventCallbackMessage            inSelector,
00152        NavCBRecPtr                                     ioParams,
00153        NavCallBackUserData             ioUserData)
00154 {
00155   CNavCustomPutFileCallbackData *callbackData = reinterpret_cast<CNavCustomPutFileCallbackData*>(ioUserData);
00156   OSErr err = noErr;
00157   
00158        try                  // Can't throw back through the Toolbox
00159        {
00160     switch (inSelector)
00161     {
00162       case kNavCBStart:
00163         if (callbackData)
00164         {
00165           err = ::NavCustomControl(ioParams->context, kNavCtlAddControlList, callbackData->GetDITLHandle());
00166           ThrowIfOSErr_(err);
00167           
00168           short firstControlID;
00169           err = ::NavCustomControl(ioParams->context, kNavCtlGetFirstControlID, &firstControlID);
00170           ThrowIfOSErr_(err);
00171           
00172           callbackData->SetFirstControlID(firstControlID);
00173           
00174           callbackData->InitControls(ioParams);
00175         }
00176         break;
00177 
00178       case kNavCBCustomize:
00179         if (callbackData)
00180         {
00181           callbackData->NegotiatePanelBounds(ioParams);
00182         }
00183         break;
00184         
00185       case kNavCBTerminate:
00186         if (callbackData)
00187         {
00188           callbackData->SaveControlValues(ioParams);
00189         }
00190         break;  
00191     
00192       case kNavCBEvent:
00193         {
00194           short itemHit = ioParams->eventData.itemHit;
00195         
00196           if (itemHit == eSaveFormatPanelFormatPopupID)
00197           {
00198             // process control click?
00199             break;
00200           }
00201                        UModalAlerts::ProcessModalEvent(*(ioParams->eventData.eventDataParms.event));
00202                      }
00203         break;
00204     }
00205   }
00206   catch (...)
00207   {
00208     Assert_(0); // error
00209   }  
00210 }
00211 
00212 
00213 // ---------------------------------------------------------------------------
00214 //      LCustomFileDesignator
00215 // ---------------------------------------------------------------------------
00216 
00217 UNavServicesDialogs::LCustomFileDesignator::LCustomFileDesignator()
00218 {
00219 
00220 }
00221 
00222 // ---------------------------------------------------------------------------
00223 //      ~LCustomFileDesignator
00224 // ---------------------------------------------------------------------------
00225 UNavServicesDialogs::LCustomFileDesignator::~LCustomFileDesignator()
00226 {
00227 }
00228 
00229 // ---------------------------------------------------------------------------
00230 //      LCustomFileDesignator::AskDesignateFile                                                    [public]
00231 // ---------------------------------------------------------------------------
00232 
00233 bool
00234 UNavServicesDialogs::LCustomFileDesignator::AskDesignateFile(ConstStringPtr inDefaultName, ESaveFormat& ioSaveFormat)
00235 {
00236        StNavEventUPP        eventUPP(NavCustomEventProc);
00237 
00238   CNavCustomPutFileCallbackData callbackData(kCustomSaveFilePanelSize, kCustomSaveFilePanelDITLResID, ioSaveFormat);
00239   
00240        LString::CopyPStr(inDefaultName, mNavOptions.savedFileName);
00241 
00242        mNavReply.SetDefaultValues();
00243 
00244        AEDesc*              defaultLocationDesc = nil;
00245        if (not mDefaultLocation.IsNull()) {
00246               defaultLocationDesc = mDefaultLocation;
00247 
00248               if (mSelectDefault) {
00249                      mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
00250               } else {
00251                      mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation;
00252               }
00253        }
00254 
00255        UDesktop::Deactivate();
00256 
00257        OSErr err = ::NavPutFile(
00258                                           defaultLocationDesc,
00259                                           mNavReply,
00260                                           &mNavOptions,
00261                                           eventUPP,
00262                                           mFileType,
00263                                           mFileCreator,
00264                                           &callbackData);
00265 
00266        UDesktop::Activate();
00267 
00268        if ( (err != noErr) && (err != userCanceledErr) ) {
00269               Throw_(err);
00270        }
00271 
00272   ioSaveFormat = callbackData.GetSaveFormat();
00273        return mNavReply.IsValid();
00274 }
00275