home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-13 | 12.9 KB | 362 lines | [TEXT/R*ch] |
- // ===========================================================================
- // File: UMPDialogHandler.cp
- // Version: 1.0 - Feb 1, 1996
- // Author: Mike Shields (mshields@inconnect.com)
- //
- // Copyright ©1996 Mike Shields. All rights reserved.
- // I hereby grant users of UMPDialogHandler permission to use it (or any modified
- // version of it) in applications (or any other type of Macintosh software
- // like extensions -- freeware, shareware, commercial, or other) for free,
- // subject to the terms that:
- //
- // (1) This agreement is non-exclusive.
- //
- // (2) I, Mike Shields, retain the copyright to the original source code.
- //
- // These two items are the only required conditions for use. However, I do have
- // an additional request. Note, however, that this is only a request, and
- // that it is not a required condition for use of this code.
- //
- // (1) That I be given credit for UMPDialogHandler code in the copyrights or
- // acknowledgements section of your manual or other appropriate documentation.
- //
- //
- // I would like to repeat that this last item is only a request. You are prefectly
- // free to choose not to do any or all of them.
- //
- // This source code is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- // ===========================================================================
- // UMPDialogHandler.h <- double-click + Command-D to see class declaration
- //
- // StDialogHandler subclass which is the manager of a multipanel dialog. It is
- // responsible for handling the creation, deletetion and all messages generated
- // by the main dialog controls.
-
- #include "UMPDialogHandler.h"
-
- #include <LWindow.h>
- #include <PP_Messages.h>
- #include <LTabGroup.h>
- #include <LArray.h>
- #include <UMemoryMgr.h>
-
- #include "CMPDIncludeView.h"
- #include "CMPDPanelSelectControl.h"
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::StMPDialogHandler
- //---------------------------------------------------------------------------
- // Constructor
- StMPDialogHandler::StMPDialogHandler(ResIDT inDialogResID, LCommander *inSuper,
- PanelIDIndexT inInitialPaneIndex, ResIDT inMPDResID)
- : StDialogHandler(inDialogResID, inSuper), mCurrentPanelIndex(inInitialPaneIndex),
- mIncludeView(nil), mTabGroup(nil), mPanelSelectControl(nil),
- mPanelDataHandles(sizeof(Handle))
- {
- LPane* aPane;
-
- // Inititalize our include view member. This points to the view which manages
- // the communication between this handler and the panel.
- aPane = mDialog->FindPaneByID(MPD_IncludeView);
- mIncludeView = dynamic_cast<CMPDIncludeView*>(aPane);
- ThrowIfNil_(mIncludeView);
-
- // Now get the MPDPaneSelectControl.
- aPane = mDialog->FindPaneByID(MPD_PanelSelectControl);
- mPanelSelectControl = dynamic_cast<CMPDPanelSelectControl*>(aPane);
- ThrowIfNil_(mPanelSelectControl);
-
- UpdateMenus();
-
- // now we go about the process the populating the PanelSelect control. We load in the
- // definition resource from field, interate through it and add a PanelID to the
- // control for each item in it. Then we select the item to be the displayed one in the
- // control
- mMPDData.Load('MPD#', inMPDResID, true, false);
- {
- StHandleLocker locker(mMPDData);
- mPanelSelectControl->InsertPanelIDs(*(MPDHandle)mMPDData);
- }
-
- // Our internal storage needs to be initialized at this time. We pass in a pointer to a nil
- // handle so we can flag panels which have not been visited before later in the code.
- Handle panelData = nil;
- mPanelDataHandles.InsertItemsAt((**(MPDHandle)mMPDData).numItems, LArray::index_First, &panelData);
-
- mPanelSelectControl->SelectPanelID(mCurrentPanelIndex);
-
- // We want to know about things that happen to the control.
- mPanelSelectControl->ConnectToHandler(this);
-
- // now we select the dialog so we can begin processing it.
- mDialog->Select();
-
- // before we show the dialog, but after we select it (so we make it the target) we need
- // to walk it's command chain looking for the TabGroup associated with the window (if
- // there is one). If we find it we store a pointer to it so we can use it later when we
- // are switching panels so we get the correct tab behavior.
- LCommander* aSub = LCommander::GetTarget();
- while ( aSub != nil )
- {
- if ( dynamic_cast<LTabGroup*>(aSub) != nil )
- {
- mTabGroup = (LTabGroup*)aSub;
- break;
- }
-
- aSub = aSub->GetSuperCommander();
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::FinishCreate
- //---------------------------------------------------------------------------
- // Load in the correct initial panel and set up the initial data. We need to do
- // it here and not in the contstructor, because the derived-class constructor will
- // have to run before we can get at the data for the panels (thru GetInitialPanelData).
- // Since GetInitialPanelData is a pure virtual function we cannot have any possiblity
- // that it will be called before all constructors have been called.
- void StMPDialogHandler::FinishCreate()
- {
- LCommander* defaultCommander;
-
- // if this window has a tab group we need to set that as the default commander
- // so that tabbing works properly.
- if ( mTabGroup != nil )
- {
- defaultCommander = LCommander::GetDefaultCommander();
- LCommander::SetDefaultCommander(mTabGroup);
- }
-
- // and then switch the panel to the new one...
- mIncludeView->IncludeView((**(MPDHandle)mMPDData).MPDList[mCurrentPanelIndex-1].panelID,
- true);
-
- // Grab the panel data for the initial panel...
- // and set the MPD data into the initial panel
- Handle newPanelData = GetInitialPanelData(mCurrentPanelIndex);
- SignalIf_(newPanelData == nil);
- mPanelDataHandles.AssignItemsAt(1, mCurrentPanelIndex, &newPanelData);
- mIncludeView->UseNewPanelData(newPanelData, false);
-
- // reset the default commander
- if ( mTabGroup != nil )
- {
- LCommander::SetDefaultCommander(defaultCommander);
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::~StMPDialogHandler
- //---------------------------------------------------------------------------
- // Destructor
- StMPDialogHandler::~StMPDialogHandler()
- {
- // Since we took posession of the handles passed back from GetXXXPanelData
- // methods, we need to make sure they're disposed of properly.
- for ( short i = 1; i <= (**(MPDHandle)mMPDData).numItems; i++ )
- {
- Handle newPanelData = RetrievePanelData(i);
- if ( newPanelData != nil )
- ::DisposeHandle(newPanelData);
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::RetrievePanelData
- //---------------------------------------------------------------------------
- // This method gets the panel data out of the internal storage maintained by the
- // StMPDialogHandler class. If the data passed back is nil, the panel
- // was never visited and the data has not changed.
- Handle StMPDialogHandler::RetrievePanelData(Int16 inPanelIndex)
- {
- Handle panelData;
- mPanelDataHandles.FetchItemAt(inPanelIndex, &panelData);
- return panelData;
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::ListenToMessage
- //---------------------------------------------------------------------------
- void StMPDialogHandler::ListenToMessage(MessageT inMessage, void* ioParam)
- {
- StDialogHandler::ListenToMessage(inMessage, ioParam);
-
- switch ( inMessage )
- {
- case msg_MPDRevert:
- HandleRevert();
- break;
-
- case msg_MPDUseDefaults:
- HandleUseDefaults();
- break;
-
- case msg_OK:
- // Before we do ANYTHING, we need to make sure that the panel is validated. We do
- // this by calling ValidatePanel which should be overidden by the panel subclass
- // to do the appropriate checking
- if ( mIncludeView->ValidatePanel() )
- {
- // Now that the panel has validated we can do our normal OK processing.
- HandleOK();
- }
- else
- {
- // Panel didn't validate, so we don't want this message handled by anyone
- // else. It is as if nothing happened.
- mMessage = msg_Nothing;
- }
- break;
-
- case msg_Cancel:
- HandleCancel();
- break;
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::HandlePanelChange
- //---------------------------------------------------------------------------
- // Setup for correctly switching to a new panel. Check the validity of the old
- // panel data and if it's OK, switch, else tell the control to select the old
- // selection.
- void StMPDialogHandler::HandlePanelChange(Int16 inNewPanelIndex)
- {
- // This check will not only make sure we don't try to do anything on the
- // panel if we aren't actually switching, but will prevent infinite recusion
- // from the call below to SelectPanelID if the ValidatePanel call returns
- // false.
- if ( inNewPanelIndex != mCurrentPanelIndex )
- {
- // Before we do ANYTHING, we need to make sure that the panel is validated. We do
- // this by calling ValidatePanel which should be overidden by the panel subclass
- // to do the appropriate checking
- if ( mIncludeView->ValidatePanel() )
- {
- SwitchToPanel(inNewPanelIndex);
-
- LPane* aPane;
- aPane = mDialog->FindPaneByID(MPD_UseDefaultsButton);
- if ( aPane ) // This button doesn't have to be present
- {
- if ( mIncludeView->WantDefaultsButton() )
- aPane->Enable();
- else
- aPane->Disable();
- }
-
- aPane = mDialog->FindPaneByID(MPD_RevertButton);
- if ( aPane ) // This button doesn't have to be present
- {
- if ( mIncludeView->WantRevertButton() )
- aPane->Enable();
- else
- aPane->Disable();
- }
- }
- else
- {
- // This will cause the control to broadcast the fact that the cell
- // has changed but this case is caught by the test above for the
- // new index being the same as the current index.
- mPanelSelectControl->SelectPanelID(mCurrentPanelIndex);
- }
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::HandleRevert
- //---------------------------------------------------------------------------
- void StMPDialogHandler::HandleRevert(void)
- {
- Handle newPanelData = RetrievePanelData(mCurrentPanelIndex);
- SignalIf_(newPanelData == nil);
- mIncludeView->UseNewPanelData(newPanelData, true);
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::HandleUseDefaults
- //---------------------------------------------------------------------------
- void StMPDialogHandler::HandleUseDefaults(void)
- {
- Handle newPanelData = GetPanelDefaultData(mCurrentPanelIndex);
- SignalIf_(newPanelData == nil);
- Try_
- {
- mIncludeView->UseNewPanelData(newPanelData, true);
- ::DisposeHandle(newPanelData);
- }
- Catch_(inErr)
- {
- ::DisposeHandle(newPanelData);
- Throw(inErr);
- }
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::HandleOK
- //---------------------------------------------------------------------------
- void StMPDialogHandler::HandleOK(void)
- {
- Handle newPanelData = RetrievePanelData(mCurrentPanelIndex);
- SignalIf_(newPanelData == nil);
- mIncludeView->GetPanelData(newPanelData);
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::HandleCancel
- //---------------------------------------------------------------------------
- void StMPDialogHandler::HandleCancel(void)
- {
- }
-
- //---------------------------------------------------------------------------
- // StMPDialogHandler::SwitchToPanel
- //---------------------------------------------------------------------------
- // Change the currently displayed panel in the dialog to the new one. Get the
- // data from the panel being displaced and set the data for the new panel.
- void StMPDialogHandler::SwitchToPanel(Int16 inNewPanelIndex)
- {
- SignalIf_(inNewPanelIndex < 1 || inNewPanelIndex > (**(MPDHandle)mMPDData).numItems);
- SignalIf_(mCurrentPanelIndex < 1 || mCurrentPanelIndex > (**(MPDHandle)mMPDData).numItems);
-
- LCommander* defaultCommander;
-
- // if this window has a tab group we need to set that as the default commander
- // so that tabbing works properly.
- if ( mTabGroup != nil )
- {
- defaultCommander = LCommander::GetDefaultCommander();
- LCommander::SetDefaultCommander(mTabGroup);
- }
-
- // Grab the panel data for the new and current panels...
- // and then switch the panel to the new one, getting the updated data for the current
- // panel in the process.
- Handle currPanelData = RetrievePanelData(mCurrentPanelIndex);
- SignalIf_(currPanelData == nil);
-
- Handle newPanelData = RetrievePanelData(inNewPanelIndex);
- if ( newPanelData == nil )
- {
- newPanelData = GetInitialPanelData(inNewPanelIndex);
- mPanelDataHandles.AssignItemsAt(1, inNewPanelIndex, &newPanelData);
- }
- SignalIf_(newPanelData == nil);
- mIncludeView->LoadNewMPDPanel((**(MPDHandle)mMPDData).MPDList[inNewPanelIndex-1].panelID,
- newPanelData, currPanelData, true);
-
- // reset the default commander
- if ( mTabGroup != nil )
- {
- LCommander::SetDefaultCommander(defaultCommander);
- }
-
- // remember the panel we've switched to.
- mCurrentPanelIndex = inNewPanelIndex;
- }
-
-