#ifndef _c_Recent_Doc_Menu_Attachment_h #define _c_Recent_Doc_Menu_Attachment_h #include #include #include "cDocAlias.h" // =========================================================================== // cRecentDocMenuAttachment.h Version 1.1 ©1998 Joakim Braun All rights reserved. // =========================================================================== // // CONTENTS: cDocListMenu: A PowerPlant LAttachment subclass that manages a documents menu. // Provides facilities for "registering" and "unregistering" documents, // as well as handling menu selections by calling LDocApplication::SendAEOpenDoc(). // cSavedDocListMenu: A subclass of cDocListMenu that reads and writes the cDocListMenu state // into application's preferences file. Useful as a recent document menu. // cDirectoryDocListMenu: A subclass of cDocListMenu that scans a directory for files of a certain type. // cAppDirectoryDocListMenu: A subclass of cDirectoryDocListMenu that scans the parent directory // of the application for files of a certain type. // cInsertDocDirectoryDocListMenu: A subclass of cDirectoryDocListMenu that stores // an "insert document" CommandT. When user chooses a menu item, we check if a document // is active that accepts the "insert document" command. If so, we call its ObeyCommand() // function with the stored CommandT and the respective FSSpec as ioParam. // cInsertAppDirDocMenu: Same as cInsertDocDirectoryDocListMenu, except it scans application file's directory. // cInsertAppDirDocMenuWithChoice: Same as cInsertAppDirDocMenu, except it manages a "Choose file" item // at bottom of menu. // REQUIRES: my cDocAlias class (included in the archive containing this file). // Jim Luther's MoreFiles package (to be found on any infoMac site). // HOW TO USE: cSavedDocListMenu // If you'd like to have a recent documents menu that's restored between application sessions, // do like this: // * Your application must derive from LDocApplication. // * After your LMenuBar (or derived class) has been constructed, // add a cSavedDocListMenu attachment to the application object. // You'll want to save a pointer to the cSavedDocListMenu as a member variable. So you write: // mRecentDocMenuPtr = new cSavedDocListMenu(kRecentDocMenuID, kRecentDocMaxCount, "\pMy preferences file name", true, true); // AddAttachment(mRecentDocMenuPtr); // This will create a recent doc menu object that looks for the 'rDoc' 128 resource // in your app's preferences file and recreates itself from that. Upon destruction, it will // update the resource in the preferences file to reflect the current menu contents. // When user chooses a document in the menu, your application object's SendAEOpenDoc() function gets called. // * Whenever a file is opened, call RegisterFile(). Typically, you'll do that // in your app's OpenDocument() function: // mRecentDocMenuPtr->RegisterFile(*inMacFSSpec); // NOTE: Newly created and saved documents will not be added to the menu using the above strategy - only opened docs. // Another strategy is to register the document each time a save operation happens. // The framework is provided, the details are up to you. // HOW TO USE: cAppDirectoryDocListMenu // If you'd like to have a menu with documents of a certain file type that are in the same directory // as your application, do like this: // * Your application must derive from LDocApplication. // * After your LMenuBar (or derived class) has been constructed, // add a cAppDirectoryDocListMenu attachment to the application object. // AddAttachment(new cAppDirectoryDocListMenu(kAppDirDocMenuID, kAppDirDocMaxCount, kMyDocumentFileType, false); // When user chooses a document in the menu, your application object's SendAEOpenDoc() function gets called. // These classes are free for any and all use. // Do not distribute modified source code under my name. // No support promised, no liability accepted. Provided "as is". // That said, I can be reached at braun@swipnet.se. // Change history: // 1.0 August 16, 1998 First release // 1.1 August 30, 1998 Changed class names to reflect new, modular design // (if you used cRecentDocMenu before, you'll want to use cDocListMenu; // if you used cSavedRecentDocMenu, you'll want to use cSavedDocListMenu.) // Added static pointer in cSavedDocListMenu // Clarified some points in documentation // Rewrote RebuildMenu() to use PowerPlant menu objects // Fixed bug in RebuildMenu() where some metacharacters in file names // were filtered by Menu manager. // Added directory scanning menu classes class cDocListMenu : public LAttachment{ public: cDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount); virtual ~cDocListMenu(void); void SetFileCount(Uint32 inMaxDocCount); OSErr RegisterFile(AliasHandle inAliasHandle); void RegisterFile(LFile& inFile); void RegisterFile(FSSpec& inFSSpec); void UnregisterFile(AliasHandle inAliasHandle); void UnregisterFile(LFile& inFile); void UnregisterFile(FSSpec& inFSSpec); protected: ResIDT mMenuID; Uint32 mMaxDocCount; TArray mAliasArray; virtual void ExecuteSelf( MessageT inMessage, void *ioParam ); virtual void RebuildMenu(void); virtual Boolean HandleCommandStatus(SCommandStatus& ioCommandStatus); virtual Boolean HandleDocListMenuChoice(Int16 inMenuItem); virtual OSErr GetSelectedFSSpec(Int16 inMenuItem, FSSpec& outFSSpec); virtual void HandleSelectedFSSpec(FSSpec& inFSSpec); void DeleteAliasArrayItems(void); }; //************************************************************************ class cSavedDocListMenu : public cDocListMenu{ public: enum { eDocListResType = 'rDoc', eDocListMenuResID = 128 }; cSavedDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, Str255 inPrefsFileName = "\p", Boolean inReadFromPrefsInConstructor = false, Boolean inWriteToPrefsInDestructor = false); virtual ~cSavedDocListMenu(void); virtual void SaveToPreferences(OSType inResType = eDocListResType, ResIDT inResID = eDocListMenuResID); virtual void ReadFromPreferences(OSType inResType = eDocListResType, ResIDT inResID = eDocListMenuResID); virtual Handle GetResourceData(void); virtual void SetResourceData(Handle inResData, Boolean inAdoptHandle = true); static cSavedDocListMenu* GetSavedDocListMenu(void); protected: LStr255 mPrefsFileName; Boolean mWriteToPrefsInDestructor; static cSavedDocListMenu* sSavedDocListMenu; Int16 OpenPrefsResFile(void); }; //************************************************************************ class cDirectoryDocListMenu : public cDocListMenu{ public: cDirectoryDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, FSSpec& inDirectory, Boolean inRescanDirectoryOnRebuild = false, Boolean inScanInConstructor = false); cDirectoryDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, Boolean inRescanDirectoryOnRebuild = false); void SetDirectory(FSSpec& inDirectory, Boolean inRescanDirectory = true); virtual void ScanDirectoryItems(void); protected: FSSpec mDirectory; Boolean mRescanDirectoryOnRebuild; OSType mFileTypeToScanFor; virtual void RebuildMenu(void); enum{ eFSSpecBufferSize = 20 }; }; //************************************************************************ class cAppDirectoryDocListMenu : public cDirectoryDocListMenu{ public: cAppDirectoryDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, Boolean inRescanDirectoryOnRebuild = false); static void MakeAppFSSpec(FSSpec& outSpec); }; //************************************************************************ class cInsertDocDirectoryDocListMenu : public cDirectoryDocListMenu{ public: cInsertDocDirectoryDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, FSSpec& inDirectory, CommandT inInsertDocumentCommand = cmd_Nothing, Boolean inRescanDirectoryOnRebuild = false, Boolean inScanInConstructor = false); cInsertDocDirectoryDocListMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, CommandT inInsertDocumentCommand = cmd_Nothing, Boolean inRescanDirectoryOnRebuild = false); protected: CommandT mInsertDocCommand; static Boolean sRecursionSemaphore; virtual Boolean HandleCommandStatus(SCommandStatus& ioCommandStatus); virtual void HandleSelectedFSSpec(FSSpec& inFSSpec); LDocument* GetFrontDocument(void); }; //************************************************************************ class cInsertAppDirDocMenu : public cInsertDocDirectoryDocListMenu{ public: cInsertAppDirDocMenu( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, CommandT inInsertDocumentCommand = cmd_Nothing, Boolean inRescanDirectoryOnRebuild = false); }; //************************************************************************ class cInsertAppDirDocMenuWithChoice : public cInsertAppDirDocMenu{ public: cInsertAppDirDocMenuWithChoice( ResIDT inMenuID, Uint32 inMaxDocCount, OSType inFileType, CommandT inInsertDocumentCommand = cmd_Nothing, Boolean inRescanDirectoryOnRebuild = false); protected: virtual void RebuildMenu(void); virtual Boolean HandleDocListMenuChoice(Int16 inMenuItem); Boolean DoStandardFile(FSSpec& outSpec); }; #endif