home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / Composer / CToolsAttachment.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  9.0 KB  |  339 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "CToolsAttachment.h"
  20.  
  21. #include "CEditView.h"
  22. #include "CBrowserContext.h"        // operator MWContext*()
  23. #include "resgui.h"                    // TOOLS_MENU_BASE_LAST
  24. #include "macutil.h"                // CMediatedWindow
  25. #include "UMenuUtils.h"
  26. #include "edt.h"
  27. //#include "CSpellChecker.h"
  28. #include <LArray.h>
  29.  
  30.  
  31. #define PERM_TOOLS_ITEMS 2
  32. #define PERM_TOOLS_END_ITEMS 1
  33.  
  34. const CommandT cmd_ToolsHierItem = TOOLS_MENU_BASE_LAST;
  35.  
  36. LMenu *CToolsAttachment::sMenu = NULL;
  37. Boolean CToolsAttachment::sInvalidMenu = true;
  38. LArray CToolsAttachment::sMenusList;
  39.  
  40. //===========================================================
  41. // CToolsAttachment
  42. //===========================================================
  43. CToolsAttachment::CToolsAttachment()
  44. {
  45. }
  46.  
  47.  
  48. MWContext *CToolsAttachment::GetTopWindowContext()
  49. {
  50.     // Ok, ok. I know this is skanky,
  51.     // but there is no common way to get the context from a window: it depends on the window type.
  52.     // So, we look around for a CEditView somewhere in the top window.
  53.     // A CEditView we understand (and get an MWContext from).
  54.     
  55.     CMediatedWindow* topWin = NULL;        // find the top window to use the plugin in
  56.     CWindowIterator iter(WindowType_Any);
  57. //    do {
  58.         iter.Next(topWin);
  59. //    } while (topWin && topWin->GetWindowType() != WindowType_Editor && topWin->GetWindowType() != WindowType_Compose);
  60.                 
  61.     if (topWin == NULL)
  62.         return NULL;
  63.     
  64.     if ( topWin->GetWindowType() != WindowType_Editor && topWin->GetWindowType() != WindowType_Compose )
  65.         return NULL;
  66.     
  67.     CEditView *editView = (CEditView *)(topWin->FindPaneByID(CEditView::pane_ID));
  68.         
  69.     if (editView == NULL || editView->GetNSContext() == NULL)
  70.         return NULL;
  71.         
  72.     return editView->GetNSContext()->operator MWContext*();
  73. }
  74.  
  75.  
  76. // Processes:
  77. void CToolsAttachment::ExecuteSelf( MessageT inMessage, void* ioParam )
  78. {
  79.     mExecuteHost = FALSE;
  80.     switch ( inMessage )    
  81.     {
  82. //        case cmd_CheckSpelling:        // spell checker
  83. //            return;
  84.         
  85.         case cmd_EditorPluginStop:
  86.             MWContext *cntxt = GetTopWindowContext();
  87.             if (cntxt)
  88.                 EDT_StopPlugin(cntxt);
  89.             return;
  90.         
  91.         case msg_CommandStatus:
  92.         {
  93.             SCommandStatus*        status = (SCommandStatus*)ioParam;
  94.                 
  95.             switch ( status->command )
  96.             {
  97.                 case cmd_EditorPluginStop:
  98.                     MWContext *cntxt = GetTopWindowContext();
  99.                     *(status->enabled) = cntxt && EDT_IsPluginActive(cntxt);
  100.                     *(status->usesMark) = FALSE;
  101.                     return;
  102.                     
  103.                 default:
  104.                     if ( status->command >= TOOLS_MENU_BASE && status->command <= TOOLS_MENU_BASE_LAST )
  105.                     {
  106.                          *(status->enabled) = TRUE;
  107.                          *(status->usesMark) = FALSE;
  108.                         return;
  109.                     }
  110.                 break;
  111.             }
  112.         }
  113.         break;
  114.         
  115.         default:
  116.         {
  117.             if ( inMessage >= TOOLS_MENU_BASE && inMessage <= TOOLS_MENU_BASE_LAST )
  118.             {
  119.                 int32 index = inMessage - TOOLS_MENU_BASE;
  120.                 
  121.                 for (int32 CategoryIndex = 0; CategoryIndex < EDT_NumberOfPluginCategories(); CategoryIndex++)
  122.                     for (int32 PluginIndex = 0; PluginIndex < EDT_NumberOfPlugins(CategoryIndex); PluginIndex++)
  123.                         if (index-- == 0)
  124.                         {        // count down until we find which one...
  125.                             MWContext *cntxt = GetTopWindowContext();
  126.                             if (cntxt)
  127.                                 EDT_PerformPlugin(cntxt, CategoryIndex, PluginIndex, 0, 0);        // what is the result for?
  128.  
  129.                             return;
  130.                         }
  131.             }
  132.         }
  133.         break;            
  134.     }
  135.     mExecuteHost = TRUE;    // Let application handle it
  136. }
  137.  
  138.  
  139. LMenu *CToolsAttachment::GetMenu()
  140. {
  141.     if (!sMenu)
  142.         sMenu = new LMenu(cToolsMenuID);
  143.     
  144.     return sMenu;
  145. }
  146.  
  147. void CToolsAttachment::UpdateMenu()
  148. {
  149.     if (!sInvalidMenu || !GetMenu() || !LMenuBar::GetCurrentMenuBar())
  150.         return;
  151.     
  152.     int i;
  153.     
  154.     // Ñ delete all the dynamically created menus
  155.     // Ñ╩delete all the hierarchical menus we have added from the menubar
  156.     for ( i = 1; i <= sMenusList.GetCount(); i++ )
  157.     {
  158.         LMenu* m;
  159.         sMenusList.FetchItemAt( i, &m );
  160.         if ( m )
  161.             LMenuBar::GetCurrentMenuBar()->RemoveMenu( m );
  162.         delete m;
  163.     }
  164.  
  165.     // Ñ delete all the menu items after the line in Tools menu
  166.     MenuHandle menu = sMenu->GetMacMenuH();
  167.     if ( menu )
  168.     {
  169.         int howMany = ::CountMItems( menu );
  170.         for ( i = howMany - PERM_TOOLS_END_ITEMS; i > PERM_TOOLS_ITEMS; i-- )
  171.             sMenu->RemoveItem( i );
  172.     }
  173.     sMenusList.RemoveItemsAt( sMenusList.GetCount(), 1 );
  174.  
  175.     int    whichItem = PERM_TOOLS_ITEMS;
  176.     int    commandNum = TOOLS_MENU_BASE;
  177.     int nextMenuID = cEditorPluginsFirstHierMenuID;
  178.     
  179.     Try_
  180.     {
  181.         ThrowIfNil_( sMenu );
  182.         MenuHandle        mHand = sMenu->GetMacMenuH();
  183.     
  184.         ThrowIfNil_( mHand );
  185.     
  186.         for (int32 CategoryIndex = 0; CategoryIndex < EDT_NumberOfPluginCategories(); CategoryIndex++) {
  187.         
  188.             CStr255 headerName( EDT_GetPluginCategoryName( CategoryIndex ) );
  189.             CreateMenuString( headerName );                        // make sure it isn't too long
  190.  
  191.             whichItem = UMenuUtils::InsertMenuItem(mHand, headerName, whichItem); // returns actual insert loc
  192.             sMenu->SetCommand(whichItem, cmd_ToolsHierItem);
  193.                 
  194.             // Ñ Are there actually any menu items to put on this Hierarchical menu?
  195.             if (EDT_NumberOfPlugins(CategoryIndex)) {
  196.             
  197.                 // Ñ do we have any hierarchical menus left? 
  198.                 if (nextMenuID <= cEditorPluginsLastHierMenuID) {
  199.                 
  200.                     LMenu* subMenu = (LMenuBar::GetCurrentMenuBar())->FetchMenu( nextMenuID );
  201.                     if ( !subMenu )
  202.                     {
  203.                         StringHandle menuStringH = GetString( NEW_RESID );
  204.                         Assert_(menuStringH);
  205.                         if (menuStringH)
  206.                         {
  207.                             StHandleLocker locker((Handle)menuStringH);
  208.                             subMenu = new LMenu( nextMenuID,
  209.                                                 (unsigned char *)*menuStringH );
  210.                             LMenuBar::GetCurrentMenuBar()->InstallMenu( subMenu, hierMenu );
  211.                         }
  212.                     }
  213.                     else
  214.                         SysBeep( 1 );
  215.  
  216.                     nextMenuID++;
  217.                     
  218.                     if ( subMenu )
  219.                     {
  220.                         sMenusList.InsertItemsAt( 1, sMenusList.GetCount(),  &subMenu );
  221.                         // Ñ╩make item hierarchical
  222.                         ::SetItemCmd( mHand, whichItem, hMenuCmd );
  223.                         ::SetItemMark( mHand, whichItem, subMenu->GetMenuID() );
  224.                         FillMenu(
  225.                                 CategoryIndex,
  226.                                 subMenu,
  227.                                 commandNum,
  228.                                 0 );
  229.                     }
  230.                     
  231.                 } else {
  232.                     
  233.                     // Ñ There are no hierarchical menus left,
  234.                     // so we will just add these onto the bottom of the main tools menu.
  235.                     // We have already put the (disabled) category name in the main tools menu
  236.                     
  237.                     FillMenu(
  238.                             CategoryIndex,
  239.                             sMenu,
  240.                             commandNum,
  241.                             whichItem );
  242.                             
  243.                     whichItem += EDT_NumberOfPlugins(CategoryIndex);
  244.                 }
  245.                 
  246.             }
  247.             
  248.         }
  249.         
  250.         // this is a hack. The menu item "Stop Active Plug-in" gets pushed around and loses its command. So, reset it.
  251.         sMenu->SetCommand(++whichItem, cmd_EditorPluginStop);
  252.  
  253.     }
  254.     Catch_( inErr )
  255.     {
  256.     }
  257.     EndCatch_
  258.  
  259.  
  260.     sInvalidMenu = true;
  261. }
  262.  
  263. void CToolsAttachment::FillMenu(
  264.     int32 CategoryIndex,
  265.     LMenu* newMenu,
  266.     int& commandNum,        // next menu to create
  267.     int whichItem )            // id of the first item to insert
  268. {
  269.     Try_
  270.     {
  271.         ThrowIfNil_( newMenu );
  272.         MenuHandle        mHand = newMenu->GetMacMenuH();
  273.     
  274.         ThrowIfNil_( mHand );
  275.     
  276.         for (int32 PluginIndex = 0; PluginIndex < EDT_NumberOfPlugins(CategoryIndex); PluginIndex++) {
  277.  
  278.              // Ñ should really convert this to sMenu chars
  279.             CStr255 pluginName( EDT_GetPluginName( CategoryIndex, PluginIndex) );
  280.             CreateMenuString( pluginName );
  281.  
  282.             whichItem = UMenuUtils::InsertMenuItem(mHand, pluginName, whichItem); // returns actual insert loc
  283.             newMenu->SetCommand(whichItem, commandNum++);
  284.             
  285.         }
  286.     }
  287.     Catch_( inErr )
  288.     {
  289.     }
  290.     EndCatch_
  291. }
  292.  
  293. void CToolsAttachment::RemoveMenus()
  294. {
  295.     if (sMenu)
  296.     {
  297.         LMenuBar *currentMenuBar = LMenuBar::GetCurrentMenuBar();
  298.         
  299.         if (currentMenuBar)
  300.         {
  301.             currentMenuBar->RemoveMenu(sMenu);
  302.             
  303.             for (ArrayIndexT index = 1; index <= sMenusList.GetCount(); ++index)
  304.             {
  305.                 LMenu *menu;
  306.                 sMenusList.FetchItemAt(index, &menu);
  307.                 
  308.                 if (menu)
  309.                     currentMenuBar->RemoveMenu(menu);
  310.             }
  311.         }
  312.     }
  313. }
  314.  
  315. void CToolsAttachment::InstallMenus()
  316. {
  317.     if (sMenu)
  318.     {
  319.         LMenuBar *currentMenuBar = LMenuBar::GetCurrentMenuBar();
  320.         
  321.         if (currentMenuBar)
  322.         {
  323.             for (ArrayIndexT index = sMenusList.GetCount(); index > 0; --index)
  324.             {
  325.                 LMenu *menu;
  326.                 sMenusList.FetchItemAt(index, &menu);
  327.                 
  328.                 if (menu)
  329.                 {
  330.                     StValueChanger<EDebugAction> okayToFail(gDebugThrow, debugAction_Nothing);
  331.                     currentMenuBar->InstallMenu(menu, hierMenu);
  332.                 }
  333.             }
  334.             StValueChanger<EDebugAction> okayToFail(gDebugThrow, debugAction_Nothing);
  335.             currentMenuBar->InstallMenu(sMenu, InstallMenu_AtEnd);
  336.         }
  337.     }
  338. }
  339.