// =========================================================================== // CSimlabApp.cp ©1995 J. Rodden, DD/MF & Associates. All rights reserved // =========================================================================== #include #include "RuntimeTypes.h" #include "RuntimeMessages.h" #include "RuntimeResources.h" #include "CSimlabApp.h" #include "CSimlabDoc.h" #include "CSimlabPrefs.h" #include "CSimlabToolbar.h" #include "SimlabObClasses.h" #include #include #include #include #include // =========================================================================== const ResIDT kToolbarStateResID = 0; const ResIDT kPrefsDialogStateResID = 1; // =========================================================================== // € Prototypes for local functions // =========================================================================== static void SetupMenus(Str255 inModelFileName); static void ToggleWindowVisible( LWindow* inWindow, Boolean isVisible, ResIDT inStrResID, CommandT inOldCmd, CommandT inNewCmd); // =========================================================================== // € Main Program // =========================================================================== void main(void) { // Set Debugging options #ifdef Debug_Throw gDebugThrow = debugAction_Alert; #endif #ifdef Debug_Signal gDebugSignal = debugAction_Alert; #endif InitializeHeap(3); // Initialize Memory Manager // Parameter is number of Master Pointer // blocks to allocate // Initialize standard Toolbox managers UQDGlobals::InitializeToolbox(&qd); #ifdef Debug_Signal // Check for missing MBAR, which CheckForInitialMBAR(); // probably means that there is no #endif // project resource file new LGrowZone(20000); // Install a GrowZone function to catch // low memory situations. // Parameter is size of reserve memory // block to allocated. The first time // the GrowZone function is called, // there will be at least this much // memory left (so you'll have enough // memory to alert the user or finish // what you are doing). CSimlabApp theApp; // Create instance of your Application theApp.Run(); // class and run it } // =========================================================================== // € CSimlabApp Class // =========================================================================== // --------------------------------------------------------------------------- // € CSimlabApp // --------------------------------------------------------------------------- // Constructor CSimlabApp::CSimlabApp() : mCurrentDoc(nil) { UScreenPort::Initialize(); // Register classes needed by Simlab RegisterSimlabClasses(); // Setup list of models opened during this session mCurrentModelNum = 0; mModelSwitchList = new LList(sizeof(FSSpec)); // Setup Preferences file Str255 theString; GetIndString( theString, STRx_Standards, str_PrefFileName); mPrefs = new CSimlabPrefs(SimlabRuntimeSignature, theString); mPrefs->LoadPreferences(); // Setup Toolbar mToolbar = (CSimlabToolbar*) LWindow::CreateWindow(WIND_Toolbar, this); mToolbar->SetUserCon(cmd_HideToolbar); mToolbar->AddListener(this); // Adjust app state and toolbar/message displays, then show windows mToolbar->AdjustState(NoModel); mPrefs->RestoreWindowState( mToolbar, kToolbarStateResID); if ( mPrefs->IsToolbarShown() ) ObeyCommand(cmd_ShowToolbar); } // --------------------------------------------------------------------------- // € ~CSimlabApp // --------------------------------------------------------------------------- // Destructor CSimlabApp::~CSimlabApp() { // Save global preferences mPrefs->SavePreferences(); // Now store the size and position of each global window mPrefs->SaveWindowState( mToolbar, kToolbarStateResID); delete mPrefs; delete mToolbar; delete mModelSwitchList; } // --------------------------------------------------------------------------- // € ObeyCommand // --------------------------------------------------------------------------- // Respond to commands Boolean CSimlabApp::ObeyCommand( CommandT inCommand, void *ioParam) { Boolean cmdHandled = true; Int16 menuID; Int16 menuItem; if ( IsSyntheticCommand( inCommand, menuID, menuItem) && menuID == MENU_SwitchList ) { LMenu* theMenu = LMenuBar::GetCurrentMenuBar()->FetchMenu(MENU_SwitchList); if ( theMenu->IndexFromCommand(cmd_OpenDescription) != 0 ) menuItem -= 2; FSSpec theFileSpec; mModelSwitchList->FetchItemAt( menuItem, &theFileSpec); OpenDocument(&theFileSpec); return true; } switch (inCommand) { // Preferences commands case cmd_Preferences: LWindow::CreateWindow(DIAG_Preferences, this); break; case cmd_ChangePrefs: break; // Views Menu Commands case cmd_ShowToolbar: ToggleWindowVisible( mToolbar, false, str_HideToolbar, cmd_ShowToolbar, cmd_HideToolbar); mPrefs->IsToolbarShown(true); break; case msg_HideToolbar: case cmd_HideToolbar: ToggleWindowVisible( mToolbar, true, str_ShowToolbar, cmd_HideToolbar, cmd_ShowToolbar); mPrefs->IsToolbarShown(false); break; default: cmdHandled = LDocApplication::ObeyCommand(inCommand, ioParam); if ( !cmdHandled && mCurrentDoc != nil ) { cmdHandled = mCurrentDoc->DoCommand(inCommand, ioParam); } break; } return cmdHandled; } // --------------------------------------------------------------------------- // € ListenToMessage // --------------------------------------------------------------------------- void CSimlabApp::ListenToMessage(MessageT inMessage, void *ioParam) { switch ( inMessage ) { case msg_DocumentDied: if ( (CSimlabDoc*)ioParam == mCurrentDoc ) { mCurrentModelNum = 0; mCurrentDoc = nil; LMenu* theMenu; theMenu = LMenuBar::GetCurrentMenuBar()->FetchMenu(MENU_Views); theMenu->RemoveCommand(cmd_ProjectWindow); theMenu->RemoveItem(viewMenuLine1Pos); theMenu = LMenuBar::GetCurrentMenuBar()->FetchMenu(MENU_SwitchList); theMenu->RemoveCommand(cmd_OpenDescription); theMenu->RemoveItem(1); } break; default: if ( LoWord(inMessage) == msg_OpenSourceFile ) { FSSpecPtr theFileSpec = (FSSpecPtr) ioParam; LDocument* theDocument = LDocument::FindNamedDocument(theFileSpec->name); if ( theDocument == nil ) { OpenDocument( theFileSpec, IsBitOn(HiWord(inMessage),cmdKey) ); } else { ((CWindowedDoc*)theDocument)->SelectDeskWindow(); } } else { ObeyCommand( inMessage, ioParam); } break; } } // --------------------------------------------------------------------------- // € FindCommandStatus // --------------------------------------------------------------------------- // Pass back status of a (menu) command void CSimlabApp::FindCommandStatus( CommandT inCommand, Boolean &outEnabled, Boolean &outUsesMark, Char16 &outMark, Str255 outName) { outEnabled = false; outUsesMark = false; // If the front-most window is a dialog box, disable the menu item. if (UDesktop::FrontWindowIsModal()) { outEnabled = false; return; } ResIDT menuID; Int16 menuItem; if ( IsSyntheticCommand( inCommand, menuID, menuItem) && menuID == MENU_SwitchList ) { if ( menuItem != mCurrentModelNum ) outEnabled = true; return; } switch (inCommand) { // +++ Add cases here for the commands you handle. // // Set outEnabled to TRUE for commands that can be executed at // this time. // // If the associated menu items can have check marks, set // outUsesMark and outMark accordingly. // // Set outName to change the name of the menu item case cmd_Preferences: case MENU_SwitchList: case cmd_HideToolbar: case cmd_ShowToolbar: outEnabled = true; break; default: if ( mCurrentDoc != nil && mCurrentDoc->GetCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName) ) break; LDocApplication::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName); break; } } // --------------------------------------------------------------------------- // € GetToolbar // --------------------------------------------------------------------------- CSimlabToolbar* CSimlabApp::GetToolbar() { return mToolbar; } // --------------------------------------------------------------------------- // € OpenDocument // --------------------------------------------------------------------------- // This is necessary because CW's signature matching algorithm doesn't quite // work as it should. void CSimlabApp::OpenDocument( FSSpec *inMacFSSpec) { OpenDocument( inMacFSSpec, true); } // --------------------------------------------------------------------------- // € OpenDocument // --------------------------------------------------------------------------- // Open a Document file void CSimlabApp::OpenDocument( FSSpec *inMacFSSpec, Boolean inCloseProject) { FInfo fndrInfo; OSErr iErr = ::FSpGetFInfo( inMacFSSpec, &fndrInfo); if ( iErr || ( fndrInfo.fdType != SimlabModelFileType && fndrInfo.fdType != OldSimlabFileType) ) { SysBeep(1); return; } if ( mCurrentDoc == nil || (!mCurrentDoc->IsCurrentProjectFile(*inMacFSSpec) && inCloseProject) ) { // First close current document if (mCurrentDoc) mCurrentDoc->Close(); // Then open new document mCurrentDoc = new CSimlabDoc(this, inMacFSSpec); // Configure Views and Model Switch List menus SetupMenus(inMacFSSpec->name); // Add new filename to Model Switch List menu and internal list of FSSpecs FSSpec tempFSSpec; LListIterator theListIterator(*mModelSwitchList,iterate_FromStart); while ( theListIterator.Next(&tempFSSpec) ) { if( ::EqualString( tempFSSpec.name, inMacFSSpec->name, true, true) && tempFSSpec.vRefNum == inMacFSSpec->vRefNum && tempFSSpec.parID == inMacFSSpec->parID ) return; }; mCurrentModelNum = UDynamicMenu::AppendItem( MENU_SwitchList, inMacFSSpec->name, false); mModelSwitchList->InsertItemsAt( 1, arrayIndex_Last, inMacFSSpec); } } // --------------------------------------------------------------------------- // € MakeNewDocument // --------------------------------------------------------------------------- // Create a new Document LModelObject* CSimlabApp::MakeNewDocument() { return nil; } // --------------------------------------------------------------------------- // € CreateDocument // --------------------------------------------------------------------------- // Create a new Document LModelObject* CSimlabApp::CreateDocument(StandardFileReply& inFileReply) { LFile theFile(inFileReply.sfFile); theFile.CreateNewDataFile( SimlabRuntimeSignature, SimlabModelFileType, inFileReply.sfScript); return new CSimlabDoc(this, &(inFileReply.sfFile)); } // --------------------------------------------------------------------------- // € ChooseDocument // --------------------------------------------------------------------------- // Prompt the user to select a document to open void CSimlabApp::ChooseDocument() { StandardFileReply macFileReply; SFTypeList typeList; typeList[0] = SimlabModelFileType; typeList[1] = OldSimlabFileType; UDesktop::Deactivate(); ::StandardGetFile(nil, 2, typeList, &macFileReply); UDesktop::Activate(); if (macFileReply.sfGood) { SendAEOpenDoc(macFileReply.sfFile); } } // --------------------------------------------------------------------------- // € ToggleWindowVisible [static] // --------------------------------------------------------------------------- void ToggleWindowVisible( LWindow* inWindow, Boolean isVisible, ResIDT inStrResID, CommandT inOldCmd, CommandT inNewCmd) { Str255 theString; GetIndString( theString, STRx_MENU_Strs, inStrResID); ToggleMenuItem( inOldCmd, inNewCmd, theString); if (!isVisible) { inWindow->Show(); inWindow->Select(); } else { inWindow->Hide(); } } // --------------------------------------------------------------------------- // € SetupMenus [static] // --------------------------------------------------------------------------- void SetupMenus(Str255 inModelFileName) { Str255 theMenuItem; LMenu* theMenu = LMenuBar::GetCurrentMenuBar()->FetchMenu(MENU_Views); Int16 menuLength = CountMItems(theMenu->GetMacMenuH())+1; // Insert dotted line CopyPStr("\p(-", theMenuItem); theMenu->InsertCommand( theMenuItem, 0, ++menuLength); // Insert model filename CopyPStr(inModelFileName, theMenuItem); ConcatPStr(theMenuItem, "\p/0"); theMenu->InsertCommand( theMenuItem, cmd_ProjectWindow, ++menuLength); // Add cmd_OpenDescription to Model Switch List, followed by dotted line theMenu = LMenuBar::GetCurrentMenuBar()->FetchMenu(MENU_SwitchList); GetIndString( theMenuItem, STRx_MENU_Strs, str_OpenDescription); theMenu->InsertCommand( theMenuItem, cmd_OpenDescription, 0); CopyPStr("\p(-", theMenuItem); theMenu->InsertCommand( theMenuItem, 0, 1); }