home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-07-15 | 12.9 KB | 423 lines | [TEXT/MPS ] |
- #include "ArrangeCallbacks.h"
- #include "PluginLibrary.h"
-
- #include <Dialogs.h>
- #include <Events.h> // for shiftKey constant
-
- // SelectSubnotes.cp - based on GenericPlugin.cp as of 7/15/94
-
-
- #define ModuleRsrcID 0xFFFF8800
-
- #define baseCmdCode 0x12000000 // replace this with a value obtained from
- // Common Knowledge.
-
- #define aboutCmdCode (baseCmdCode + 0)
- #define selSubnotesCode (baseCmdCode + 1)
-
-
- class Plugin
- {
- public:
- Plugin(const ArrangeCallbackTbl* theCalls);
- ~Plugin();
-
- arHookResult ClickNotify( arClickLocation loc, Point where, Short modifiers,
- Short clickCount, arNoteID note, arFieldID field,
- arPathID path );
- arHookResult KeyNotify ( Short theChar, Short key, Short modifiers );
- arHookResult MenuNotify ( Integer commandCode, Integer commandParam,
- Short modifiers );
- arHookResult FieldNotify( arNoteID note, arFieldID field, arFieldAction action,
- const char* choiceText );
- void TopicNotify( arTopicID newTopic, arWindowID newWindow,
- arTopicAction action );
- void TickNotify ( );
- arHookResult FileNotify ( arFileAction action );
- arHookResult QuitNotify ( );
- void ATMNotify ( );
-
- private:
- const ArrangeCallbackTbl* calls; // callback table
-
- void DoSelectSubnotes(Boolean doAdd);
- }; // Plugin
-
-
- /*************************************************************************/
- /**************************** Main entry point ***************************/
- /*************************************************************************/
-
- /* Root entry point for the module - must be the first function in the
- * file, so that the linker will place it first in the code segment.
- * This is the routine which Arrange calls at application startup time
- * (and again at quit time).
- *
- * Most plug-ins will not need to modify this routine or the Hook functions
- * immediately following. All customization can be done in the "Plugin"
- * section (below).
- */
- extern "C" Integer OurModuleRoot( ModuleParamBlock *pb, ModuleRootAction action,
- Integer /*p1*/ )
- {
- /* Extract the callback table from our parameter block, and coerce it
- * to the extended Arrange table.
- */
- ArrangeCallbackTbl* calls = (ArrangeCallbackTbl*)(pb->calls);
-
- switch (action)
- {
- case mrLoad:
- {
- // Allocate memory and create a new Plugin object.
- void* storage = calls->mem->AllocMem( sizeof(Plugin),
- amFreeStore | amErrIfNoMem );
- pb->moduleRefcon = uInteger(new(storage) Plugin(calls));
- return 1;
- }
-
- case mrUnload:
- {
- /* Dispose of the Plugin object and release the memory
- * it occupies.
- */
- delete (Plugin*)(pb->moduleRefcon);
- calls->mem->DeallocMem((void*)(pb->moduleRefcon), amFreeStore);
- return 0;
- }
-
- case mrFindEntry:
- default:
- {
- /* This module contains no extended entry points, so we always
- * return 0 for the mrFindEntry message. Most plug-ins will not
- * use extended entry points.
- */
- return 0;
- }
-
- } // switch (action)
-
- } // OurModuleRoot
-
-
- /* These hook functions simply pass control to the appropriate function
- * in the Plugin object.
- */
- static arHookResult OurClickHook( ModuleParamBlock* pb, arClickLocation loc,
- Point where, pShort modifiers, pShort clickCount,
- arNoteID note, arFieldID field,
- arPathID path ENDP )
- {
- return ((Plugin*)(pb->moduleRefcon))->ClickNotify( loc, where, modifiers,
- clickCount, note, field,
- path );
- }
-
-
- static arHookResult OurKeyHook( ModuleParamBlock* pb, pShort theChar, pShort key,
- pShort modifiers ENDP )
- {
- return ((Plugin*)(pb->moduleRefcon))->KeyNotify(theChar, key, modifiers);
- }
-
-
- static arHookResult OurMenuHook( ModuleParamBlock* pb, Integer commandCode,
- Integer commandParam, pShort modifiers ENDP )
- {
- return ((Plugin*)(pb->moduleRefcon))->MenuNotify( commandCode, commandParam,
- modifiers );
- }
-
-
- static arHookResult OurFieldHook( ModuleParamBlock* pb, arNoteID note,
- arFieldID field, arFieldAction action,
- const char* choiceText ENDP )
- {
- return ((Plugin*)(pb->moduleRefcon))->FieldNotify( note, field, action,
- choiceText );
- }
-
-
- static void OurTopicHook( ModuleParamBlock* pb, arTopicID newTopic,
- arWindowID newWindow, arTopicAction action ENDP )
- {
- ((Plugin*)(pb->moduleRefcon))->TopicNotify(newTopic, newWindow, action);
- }
-
-
- static void OurTickHook(ModuleParamBlock* pb ENDP)
- {
- ((Plugin*)(pb->moduleRefcon))->TickNotify();
- }
-
-
- static arHookResult OurFileHook(ModuleParamBlock* pb, arFileAction action ENDP)
- {
- return ((Plugin*)(pb->moduleRefcon))->FileNotify(action);
- }
-
-
- static arHookResult OurQuitHook(ModuleParamBlock* pb ENDP)
- {
- return ((Plugin*)(pb->moduleRefcon))->QuitNotify();
- }
-
-
- static void OurATMHook(ModuleParamBlock* pb ENDP)
- {
- ((Plugin*)(pb->moduleRefcon))->ATMNotify();
- }
-
-
- /*************************************************************************/
- /********************************* Plugin ********************************/
- /*************************************************************************/
-
- /* Construct a Plugin object. This is called once, from the OurModuleRoot
- * function, when the module is initialized (i.e. at application startup time).
- */
- Plugin::Plugin(const ArrangeCallbackTbl* theCalls)
- {
- // Record the callback table for future use.
- calls = theCalls;
-
- /* These commands, if un-commented-out, register this plugin to be called
- * by Arrange when various events occur. For example, if you un-comment-out
- * the call to SetClickHook, then Plugin::ClickNotify will be called
- * whenever the user clicks in any of the locations described in the
- * arClickLocation enum.
- */
- // calls->ui->SetClickHook(OurClickHook, 0, true);
- // calls->ui->SetKeyHook (OurKeyHook, 0, true, charFilter, keyFilter, modFilter);
- // calls->ui->SetMenuHook (OurMenuHook, 0, true, whichCommand);
- // calls->ui->SetFieldHook(OurFieldHook, 0, true, whichField);
- // calls->ui->SetTopicHook(OurTopicHook, 0, true);
- // calls->ui->SetTickHook (OurTickHook, 0, true);
- // calls->ui->SetFileHook (OurFileHook, 0, true);
- // calls->ui->SetQuitHook (OurQuitHook, 0, true);
- calls->ui->SetATMHook (OurATMHook, 0, true);
-
- // Add an item to the About Plugins menu for this plugin.
- calls->ui->AddMenuItem(mPluginAbout, "About Select Subnotes", 0, aboutCmdCode, 0);
-
- // Register ourselves to be called when our About command is chosen.
- calls->ui->SetMenuHook(OurMenuHook, 0, true, aboutCmdCode);
-
- // Create, and register for, a new command in the Select submenu.
- calls->ui->AddMenuItem(mSelect, "Select Subnotes", 0, selSubnotesCode, 0);
- calls->ui->SetMenuHook(OurMenuHook, 0, true, selSubnotesCode);
- } // Plugin constructor
-
-
- /* Dispose of a Plugin object. This is called when Arrange terminates. You
- * should free up any data structures which you allocation in the Plugin
- * constructor (above).
- */
- Plugin::~Plugin()
- {
- } // ~Plugin
-
-
- /* This function is called whenever the user clicks in an "interesting place"
- * in a document window. It should return true if we handle the click, false
- * (the normal case) when the click should be passed along to other plug-ins
- * or to Arrange's normal event processing. See the documentation for
- * SetClickHook for more details.
- */
- arHookResult Plugin::ClickNotify( arClickLocation /*loc*/, Point /*where*/,
- Short /*modifiers*/, Short /*clickCount*/,
- arNoteID /*note*/, arFieldID /*field*/,
- arPathID /*path*/ )
- {
- return false; // Let Arrange handle the event
- } // ClickNotify
-
-
- /* This function is called whenever the user types a key which matches the
- * filters we pass to SetKeyHook in Plugin's constructor. It should return
- * true if we handle the event, false (the normal case) when the event
- * should be passed along to other plug-ins or to Arrange's normal event
- * processing. See the documentation for SetKeyHook for more details.
- */
- arHookResult Plugin::KeyNotify( Short /*theChar*/, Short /*key*/,
- Short /*modifiers*/)
- {
- return false; // Let Arrange handle the event
- } // KeyNotify
-
-
- /* This function is called whenever the user chooses a menu item for which
- * we have registered (via the SetMenuHook function). It should return true
- * if we handle the command, false (the normal case) when the command should
- * be passed along to other plug-ins or to Arrange's normal event processing.
- * See the documentation for SetMenuHook for more details.
- */
- arHookResult Plugin::MenuNotify( Integer commandCode, Integer /*commandParam*/,
- Short modifiers )
- {
- /* If this is our About menu item, display our about-box dialog and return
- * true to indicate we handled the command.
- */
- if (commandCode == aboutCmdCode)
- {
- Alert(ModuleRsrcID, nil);
- return true;
- }
- else if (commandCode == selSubnotesCode)
- {
- DoSelectSubnotes((modifiers & shiftKey) != 0);
- return true;
- }
- else
- return false; // Let Arrange handle the event
-
- } // MenuNotify
-
-
- /* If we register to recieve events for a field by calling SetFieldHook, this
- * function will be called for any events in that field. It should return
- * false in almost all cases. See the documentation for SetFieldHook for
- * more details.
- */
- arHookResult Plugin::FieldNotify( arNoteID /*note*/, arFieldID /*field*/,
- arFieldAction /*action*/,
- const char* /*choiceText*/ )
- {
- return false;
- } // FieldNotify
-
-
- /* This function is called whenever the user switches windows or changes
- * the current folder/topic/view in the front window. See the documentation
- * for SetTopicHook for more details.
- */
- void Plugin::TopicNotify( arTopicID /*newTopic*/, arWindowID /*newWindow*/,
- arTopicAction /*action*/ )
- {
- } // TopicNotify
-
-
- /* This function is called periodically, whenever Arrange recieves a null
- * event from the Event Manager.
- */
- void Plugin::TickNotify()
- {
- } // TickNotify
-
-
- /* This function is called whenever various file-level events occur. It
- * should return true in almost all cases. See the documentation for
- * SetFileHook for more details.
- */
- arHookResult Plugin::FileNotify(arFileAction /*action*/)
- {
- return true;
- } // FileNotify
-
-
- /* This function is called if the user voluntarily quits Arrange. It should
- * return true to allow the user to quit, false to prevent it. See the
- * documentation for SetQuitHook for more details.
- */
- arHookResult Plugin::QuitNotify()
- {
- return true;
- } // QuitNotify
-
-
- /* This function is called whenever the user clicks in the menu bar or types
- * a command key, just before processing the event. It should do any fixing
- * up of menus which might be necessary based on the current state of affairs.
- * See the documentation for SetATMHook for more details.
- */
- void Plugin::ATMNotify()
- {
- /* Enable or disable the Select Subnotes command depending on whether there
- * is a selection.
- */
- arNoteID selNote;
- arFieldID selField;
- Integer selStart,selEnd;
- Boolean hasSel = (calls->sel->GetSelection( &selNote, &selField,
- &selStart, &selEnd ) != stNone);
-
- calls->ui->SetMenuItem( mSelect, selSubnotesCode, 0, nil, hasSel,
- 0, 0 );
- } // ATMNotify
-
-
- /* If doAdd is true, then add to the selection all subnotes of all notes
- * in the selection. Otherwise replace the current selection by the subnotes
- * of all notes in the selection.
- */
- void Plugin::DoSelectSubnotes(Boolean doAdd)
- {
- // Determine whether there is a selection and how many notes it contains.
- Integer selCount;
-
- arNoteID selNote;
- arFieldID selField;
- Integer selStart;
- Integer selEnd;
- switch (calls->sel->GetSelection(&selNote, &selField, &selStart, &selEnd))
- {
- case stNote:
- case stField:
- case stText:
- case stFieldContents:
- selCount = 1;
- break;
-
- case stMultipleNotes:
- case stMultipleFields:
- selCount = selStart;
- break;
-
- default:
- return;
-
- } // switch (GetSelection result)
-
- // Get a list of the IDs of the selected notes.
- arNoteID* selIDs = (arNoteID*) calls->mem->AllocMem( selCount * sizeof(arNoteID),
- amFreeStore );
- if (selIDs == nil)
- return;
-
- arNoteID parentNote;
- for (int i=0; i<selCount; i++)
- {
- calls->sel->GetSelEntry(i, &selNote, &selField, &parentNote);
- if (selField == nil)
- selIDs[i] = parentNote;
- else
- selIDs[i] = selNote;
- }
-
- // If doAdd is false, then drop the old selection.
- if (!doAdd)
- if (!calls->sel->FlushSelection(true))
- {
- calls->mem->DeallocMem(selIDs, amFreeStore);
- return;
- }
-
- // Add to the selection all subnotes of each note in selIDs.
- arFieldID subnotesField = calls->sysObj->GetBuiltInObject(boSubnotesField);
- for (i=0; i<selCount; i++)
- {
- arListID curSubnotes = calls->data->GetFieldList(selIDs[i], subnotesField);
- Integer subnoteCount = calls->list->GetListLen(curSubnotes);
-
- for (int j=0; j<subnoteCount; j++)
- calls->sel->SelectObject( selIDs[i], subnotesField,
- calls->list->GetListEntry(curSubnotes,j),
- false );
-
- calls->list->DisposeList(curSubnotes);
- }
-
- calls->mem->DeallocMem(selIDs, amFreeStore);
- } // DoSelectSubnotes
-